diff --git a/.github/actions/build-sign-publish-chainlink/action.yml b/.github/actions/build-sign-publish-chainlink/action.yml index 9e0f8c62739..feef0e78d3b 100644 --- a/.github/actions/build-sign-publish-chainlink/action.yml +++ b/.github/actions/build-sign-publish-chainlink/action.yml @@ -93,7 +93,7 @@ runs: - if: inputs.publish == 'true' # Log in to AWS for publish to ECR name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@67fbcbb121271f7775d2e7715933280b06314838 # v1.7.0 + uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0 with: role-to-assume: ${{ inputs.aws-role-to-assume }} role-duration-seconds: ${{ inputs.aws-role-duration-seconds }} @@ -101,7 +101,7 @@ runs: - if: inputs.publish == 'true' name: Login to ECR - uses: docker/login-action@42d299face0c5c43a0487c477f595ac9cf22f1a7 # v1.12.0 + uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.2.0 with: registry: ${{ inputs.ecr-hostname }} diff --git a/.github/actions/build-test-image/action.yml b/.github/actions/build-test-image/action.yml index 6ee74eb5c18..4384fe23e65 100644 --- a/.github/actions/build-test-image/action.yml +++ b/.github/actions/build-test-image/action.yml @@ -32,7 +32,7 @@ runs: steps: - name: Check if image exists id: check-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@ab595504ae9cf10c60eb8d2c5ce025284e58b210 #v2.1.5 + uses: smartcontractkit/chainlink-github-actions/docker/image-exists@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 with: repository: ${{ inputs.repository }} tag: ${{ inputs.tag }} @@ -40,7 +40,7 @@ runs: AWS_ROLE_TO_ASSUME: ${{ inputs.QA_AWS_ROLE_TO_ASSUME }} - name: Build and Publish Test Runner if: steps.check-image.outputs.exists == 'false' - uses: smartcontractkit/chainlink-github-actions/docker/build-push@ab595504ae9cf10c60eb8d2c5ce025284e58b210 #v2.1.5 + uses: smartcontractkit/chainlink-github-actions/docker/build-push@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 with: tags: | ${{ inputs.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ inputs.QA_AWS_REGION }}.amazonaws.com/${{ inputs.repository }}:${{ inputs.tag }} diff --git a/.github/actions/goreleaser-build-sign-publish/README.md b/.github/actions/goreleaser-build-sign-publish/README.md index 5dc1f3c29ea..49edfb25d51 100644 --- a/.github/actions/goreleaser-build-sign-publish/README.md +++ b/.github/actions/goreleaser-build-sign-publish/README.md @@ -27,7 +27,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v3 - name: Configure aws credentials - uses: aws-actions/configure-aws-credentials@67fbcbb121271f7775d2e7715933280b06314838 # v1.7.0 + uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0 with: role-to-assume: ${{ secrets.aws-role-arn }} role-duration-seconds: ${{ secrets.aws-role-dur-sec }} diff --git a/.github/actions/goreleaser-build-sign-publish/action.yml b/.github/actions/goreleaser-build-sign-publish/action.yml index e0756d579f3..0cc144564c0 100644 --- a/.github/actions/goreleaser-build-sign-publish/action.yml +++ b/.github/actions/goreleaser-build-sign-publish/action.yml @@ -89,7 +89,7 @@ runs: cosign-release: ${{ inputs.cosign-version }} - name: Login to docker registry if: inputs.enable-docker-publish == 'true' - uses: docker/login-action@42d299face0c5c43a0487c477f595ac9cf22f1a7 # v1.12.0 + uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.2.0 with: registry: ${{ inputs.docker-registry }} - name: Goreleaser release diff --git a/.github/actions/setup-wasmd/action.yml b/.github/actions/setup-wasmd/action.yml new file mode 100644 index 00000000000..46fb84ba3ef --- /dev/null +++ b/.github/actions/setup-wasmd/action.yml @@ -0,0 +1,22 @@ +name: Setup Cosmos wasmd +description: Setup Cosmos wasmd, used for integration tests +runs: + using: composite + steps: + - uses: actions/cache@v3 + id: cache + name: Cache wasmd-build + with: + path: ~/wasmd-build + # this caching works without cloning the repo because the install_wasmd contains + # the commit hash. + key: ${{ runner.os }}-wasmd-cli-${{ hashFiles('./tools/ci/install_wasmd') }} + + - if: ${{ steps.cache.outputs.cache-hit != 'true' }} + name: Install wasmd + shell: bash + run: ./tools/ci/install_wasmd + + - name: Export wasmd path to env + shell: bash + run: echo "PATH=$HOME/wasmd-build/bin:$PATH" >> $GITHUB_ENV diff --git a/.github/actions/split-tests/src/handlers/golang.mts b/.github/actions/split-tests/src/handlers/golang.mts new file mode 100644 index 00000000000..c017d56db6b --- /dev/null +++ b/.github/actions/split-tests/src/handlers/golang.mts @@ -0,0 +1,51 @@ +import { execSync } from "child_process"; +import { + GolangConfig, + GoSplits, + GoPackageData, + TestsBySplit, +} from "../types.mjs"; +import { simpleSplit } from "../splitter.mjs"; + +export interface GetGoPackagesReturn { + packages: string[]; + testsBySplit: TestsBySplit; + splits: GoSplits; + serializedSplits: string +} + +export function getPackageList( + config: GolangConfig, +): GetGoPackagesReturn { + const { numOfSplits } = config; + const rawPackages = execSync( + "go list -json ./... | jq -s '[.[] | {ImportPath, TestGoFiles, XTestGoFiles}]'", + { encoding: "utf8" } + ); + const packages: GoPackageData[] = JSON.parse(rawPackages.trimEnd()); + const filteredData = packages.filter( + (item) => (item.TestGoFiles && item.TestGoFiles.length > 0) || (item.XTestGoFiles && item.XTestGoFiles.length > 0) + ); + const packagePaths = filteredData.map((item) => item.ImportPath); + return handleSplit(packagePaths, numOfSplits); +} + +function handleSplit( + packages: string[], + numOfSplits: number +): GetGoPackagesReturn { + console.log(`${packages.length} packages to split...`); + const packagesBySplit = simpleSplit(packages, [], numOfSplits); + const splits: GoSplits = packagesBySplit.map((pkgs, i) => ({ + idx: `${i + 1}`, + id: `${i + 1}/${numOfSplits}`, + pkgs: pkgs.join(" "), + })); + const o: GetGoPackagesReturn = { + packages, + testsBySplit: packagesBySplit, + splits, + serializedSplits: JSON.stringify(splits), + }; + return o; +} diff --git a/.github/actions/split-tests/src/index.mts b/.github/actions/split-tests/src/index.mts index d67354942e5..5befde03dc6 100644 --- a/.github/actions/split-tests/src/index.mts +++ b/.github/actions/split-tests/src/index.mts @@ -11,6 +11,7 @@ import { } from "./types.mjs"; import {sieveSlowTests} from "./sieve.mjs"; import {simpleSplit} from "./splitter.mjs"; +import { getPackageList, GetGoPackagesReturn } from "../src/handlers/golang.mjs"; /** * Get a JSON formatted config file @@ -47,19 +48,9 @@ async function main() { main(); async function handleGolang(config: GolangConfig) { - const {numOfSplits} = config; - const rawPackages = await $`go list ./...`; - const packages = rawPackages.stdout.trimEnd().split("\n"); - console.log(`${packages.length} packages to split...`); - const packagesBySplit = simpleSplit(packages, [], numOfSplits); - const splits: GoSplits = packagesBySplit.map((pkgs, i) => ({ - idx: `${i + 1}`, - id: `${i + 1}/${numOfSplits}`, - pkgs: pkgs.join(" "), - })); - const serializedSplits = JSON.stringify(splits); - setOutput("splits", serializedSplits); - createSummary(packages, packagesBySplit, splits); + const p: GetGoPackagesReturn = getPackageList(config) + setOutput("splits", p.serializedSplits); + createSummary(p.packages, p.testsBySplit, p.splits); } async function handleSolidity(config: SolidityConfig) { diff --git a/.github/actions/split-tests/src/types.mts b/.github/actions/split-tests/src/types.mts index cbc550a63a5..1b978ef2e94 100644 --- a/.github/actions/split-tests/src/types.mts +++ b/.github/actions/split-tests/src/types.mts @@ -93,3 +93,20 @@ export interface SolidityConfig { slowTests?: string[]; }[]; } + +export interface GoPackageData { + /** + * The package path + */ + ImportPath: string; + /** + * The list of go files asociated with the package + */ + TestGoFiles: string[] | undefined; + /** + * The list of go files not associated with a specific package + * Things like integration tests + */ + XTestGoFiles: string[] | undefined; + // there are many other variables in the data but they are not needed yet +} diff --git a/.github/workflows/automation-benchmark-tests.yml b/.github/workflows/automation-benchmark-tests.yml index daf1c74ee90..38c75ccbcef 100644 --- a/.github/workflows/automation-benchmark-tests.yml +++ b/.github/workflows/automation-benchmark-tests.yml @@ -107,7 +107,7 @@ jobs: QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@ad22fbd6f4d108b82aaf49b527bcf40f32babea8 # v2.2.1 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 env: DETACH_RUNNER: true TEST_SUITE: benchmark @@ -128,7 +128,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} diff --git a/.github/workflows/automation-ondemand-tests.yml b/.github/workflows/automation-ondemand-tests.yml index 7b02462d895..ed60a4d4e55 100644 --- a/.github/workflows/automation-ondemand-tests.yml +++ b/.github/workflows/automation-ondemand-tests.yml @@ -36,7 +36,7 @@ jobs: - name: Collect Metrics if: inputs.chainlinkImage == '' id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@8163dcea2f01a0a8fec84b284406ff7af1d2e1c0 + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -49,7 +49,7 @@ jobs: - name: Check if image exists if: inputs.chainlinkImage == '' id: check-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@ad22fbd6f4d108b82aaf49b527bcf40f32babea8 #v2.2.1 + uses: smartcontractkit/chainlink-github-actions/docker/image-exists@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 with: repository: chainlink tag: ${{ github.sha }}${{ matrix.image.tag-suffix }} @@ -57,7 +57,7 @@ jobs: AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - name: Build Image if: steps.check-image.outputs.exists == 'false' && inputs.chainlinkImage == '' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@ad22fbd6f4d108b82aaf49b527bcf40f32babea8 # v2.2.1 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 with: cl_repo: smartcontractkit/chainlink cl_ref: ${{ github.sha }} @@ -81,7 +81,7 @@ jobs: steps: - name: Collect Metrics id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@8163dcea2f01a0a8fec84b284406ff7af1d2e1c0 + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -160,7 +160,7 @@ jobs: echo "version=develop" >>$GITHUB_OUTPUT fi - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@ad22fbd6f4d108b82aaf49b527bcf40f32babea8 #v2.2.1 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 env: PYROSCOPE_SERVER: ${{ matrix.tests.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 PYROSCOPE_ENVIRONMENT: ${{ matrix.tests.pyroscope_env }} @@ -192,7 +192,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@8163dcea2f01a0a8fec84b284406ff7af1d2e1c0 + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} diff --git a/.github/workflows/build-publish-develop.yml b/.github/workflows/build-publish-develop.yml index f7ade04b5b5..67bf3e1f78e 100644 --- a/.github/workflows/build-publish-develop.yml +++ b/.github/workflows/build-publish-develop.yml @@ -40,7 +40,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} diff --git a/.github/workflows/build-publish.yml b/.github/workflows/build-publish.yml index 0b76b96d466..b1efc9fa9a8 100644 --- a/.github/workflows/build-publish.yml +++ b/.github/workflows/build-publish.yml @@ -50,7 +50,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d2de350a96c..d18946b76e6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,7 +22,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index f9072837379..7378a227ecb 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -31,7 +31,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index 93db23ab46f..4ef0fb68688 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -78,15 +78,10 @@ jobs: cache: false - name: golangci-lint if: needs.init.outputs.on_trigger_lint == 'true' - ## - # XXX: change this to the official action once multiple --out-format args are supported. - # See: https://github.com/golangci/golangci-lint-action/issues/612 - ## - uses: smartcontractkit/golangci-lint-action@54ab6c5f11d66a92d14c3f7cc41ea13f676644bd # feature/multiple-output-formats-backup + uses: golangci/golangci-lint-action@3a919529898de77ec3da873e3063ca4b10e7f5cc # v3.7.0 with: - version: v1.53.2 + version: v1.53.3 only-new-issues: ${{ github.event.schedule == '' }} # show only new issues, unless it's a scheduled run - allow-extra-out-format-args: true args: --out-format checkstyle:golangci-lint-report.xml - name: Print lint report artifact if: always() @@ -100,7 +95,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -129,7 +124,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -160,6 +155,8 @@ jobs: uses: ./.github/actions/setup-go - name: Setup Solana uses: ./.github/actions/setup-solana + - name: Setup wasmd + uses: ./.github/actions/setup-wasmd - name: Setup Postgres uses: ./.github/actions/setup-postgres - name: Touching core/web/assets/index.html @@ -176,7 +173,17 @@ jobs: echo "TIMEOUT=10m" >> $GITHUB_ENV echo "COUNT=50" >> $GITHUB_ENV - name: Run tests + id: run-tests + env: + OUTPUT_FILE: ./output.txt + USE_TEE: false run: ./tools/bin/${{ matrix.cmd }} "${{ matrix.split.pkgs }}" + - name: Print Filtered Test Results + if: failure() + uses: smartcontractkit/chainlink-github-actions/go/go-test-results-parsing@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 + with: + results-file: ./output.txt + output-file: ./output-short.txt - name: Store logs artifacts if: always() uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0 @@ -184,6 +191,7 @@ jobs: name: ${{ matrix.cmd }}_${{ matrix.split.idx }}_logs path: | ./output.txt + ./output-short.txt ./race.* ./coverage.txt - name: Print postgres logs @@ -193,11 +201,12 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} this-job-name: Core Tests (${{ matrix.cmd }}) ${{ matrix.split.id }} + test-results-file: '{"testType":"go","filePath":"./output.txt"}' continue-on-error: true # Satisfy required check for core tests @@ -216,10 +225,18 @@ jobs: - name: Check test results if: needs.core.result != 'success' run: exit 1 + - name: Notify Slack + if: ${{ failure() && matrix.cmd == 'go_core_race_tests' && github.event.schedule != '' }} + uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + env: + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + with: + channel-id: '#topic-data-races' + slack-message: "Race tests failed: ${{ job.html_url }}\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}" - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@8163dcea2f01a0a8fec84b284406ff7af1d2e1c0 + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -272,7 +289,7 @@ jobs: -gh_sha=$GITHUB_SHA \ -gh_event_path=$GITHUB_EVENT_PATH \ -command=./tools/bin/go_core_tests \ - `ls -R ./artifacts/go_core_tests*/output.txt` + `ls -R ./artifacts/go_core_tests*/output-short.txt` - name: Store logs artifacts if: always() uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0 @@ -300,7 +317,7 @@ jobs: echo "sonarqube_tests_report_paths=$(find go_core_tests_*_logs -name output.txt | paste -sd "," -)" >> $GITHUB_OUTPUT echo "sonarqube_coverage_report_paths=$(find go_core_tests_*_logs -name coverage.txt | paste -sd "," -)" >> $GITHUB_OUTPUT - name: SonarQube Scan - uses: sonarsource/sonarqube-scan-action@a6ba0aafc293e03de5437af7edbc97f7d3ebc91a # v1.2.0 + uses: sonarsource/sonarqube-scan-action@4b0bfc149f5e285930eeb5e917327e66660c6e92 # v2.0.0 with: args: > -Dsonar.go.tests.reportPaths=${{ steps.sonarqube_report_paths.outputs.sonarqube_tests_report_paths }} @@ -312,7 +329,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -344,7 +361,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 365c9b518e7..37eaa557927 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -48,7 +48,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} diff --git a/.github/workflows/dependency-check.yml b/.github/workflows/dependency-check.yml index 5a2acbac496..e4cb1081429 100644 --- a/.github/workflows/dependency-check.yml +++ b/.github/workflows/dependency-check.yml @@ -47,7 +47,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} diff --git a/.github/workflows/generic-test-runner.yml b/.github/workflows/generic-test-runner.yml index a739d705f88..727b091ac41 100644 --- a/.github/workflows/generic-test-runner.yml +++ b/.github/workflows/generic-test-runner.yml @@ -53,7 +53,7 @@ jobs: uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Check if image exists id: check-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@ad22fbd6f4d108b82aaf49b527bcf40f32babea8 #v2.2.1 + uses: smartcontractkit/chainlink-github-actions/docker/image-exists@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 with: repository: chainlink tag: ${{ github.sha }}${{ matrix.image.tag-suffix }} @@ -61,7 +61,7 @@ jobs: AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - name: Build Image if: steps.check-image.outputs.exists == 'false' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@ad22fbd6f4d108b82aaf49b527bcf40f32babea8 # v2.2.1 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 with: cl_repo: smartcontractkit/chainlink cl_ref: ${{ github.sha }} @@ -126,7 +126,7 @@ jobs: - name: Checkout the repo uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@ad22fbd6f4d108b82aaf49b527bcf40f32babea8 # v2.2.1 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 with: test_command_to_run: make test_need_operator_assets && cd ./integration-tests && go test -timeout 1h -count=1 ./${{ github.event.inputs.directory }} -run ${{ github.event.inputs.test }} -v -args ${{ github.event.inputs.test-inputs }} test_download_vendor_packages_command: cd ./integration-tests && go mod download diff --git a/.github/workflows/goreleaser-build-publish-develop.yml b/.github/workflows/goreleaser-build-publish-develop.yml index 0ba17533610..56fcff14f94 100644 --- a/.github/workflows/goreleaser-build-publish-develop.yml +++ b/.github/workflows/goreleaser-build-publish-develop.yml @@ -39,7 +39,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} diff --git a/.github/workflows/integration-chaos-tests.yml b/.github/workflows/integration-chaos-tests.yml index ecc4a1e9216..0191c3f4615 100644 --- a/.github/workflows/integration-chaos-tests.yml +++ b/.github/workflows/integration-chaos-tests.yml @@ -30,7 +30,7 @@ jobs: uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Check if image exists id: check-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@ad22fbd6f4d108b82aaf49b527bcf40f32babea8 # v2.2.1 + uses: smartcontractkit/chainlink-github-actions/docker/image-exists@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 with: repository: chainlink tag: ${{ github.sha }} @@ -38,7 +38,7 @@ jobs: AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - name: Build Image if: steps.check-image.outputs.exists == 'false' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@ad22fbd6f4d108b82aaf49b527bcf40f32babea8 # v2.2.1 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 with: cl_repo: smartcontractkit/chainlink cl_ref: ${{ github.sha }} @@ -53,7 +53,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -79,7 +79,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -99,7 +99,7 @@ jobs: steps: - name: Collect Metrics id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -109,7 +109,7 @@ jobs: - name: Checkout the repo uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@ad22fbd6f4d108b82aaf49b527bcf40f32babea8 # v2.2.1 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 with: test_command_to_run: make test_need_operator_assets && cd integration-tests && go test -timeout 1h -count=1 -json -test.parallel 11 ./chaos 2>&1 | tee /tmp/gotest.log | gotestfmt test_download_vendor_packages_command: cd ./integration-tests && go mod download diff --git a/.github/workflows/integration-tests-publish.yml b/.github/workflows/integration-tests-publish.yml index 9f9f6ca092a..9581a2af510 100644 --- a/.github/workflows/integration-tests-publish.yml +++ b/.github/workflows/integration-tests-publish.yml @@ -20,7 +20,7 @@ jobs: steps: - name: Collect Metrics id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 4214c936b50..a47530e4d04 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -3,7 +3,8 @@ on: merge_group: pull_request: schedule: - - cron: "0 0 * * *" + # - cron: "0 0 * * *" + - cron: "0 * * * *" # every hour while we debug for flakes push: tags: - "*" @@ -20,6 +21,7 @@ env: TEST_SUITE: smoke TEST_ARGS: -test.timeout 12m INTERNAL_DOCKER_REPO: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com + MOD_CACHE_VERSION: 2 jobs: changes: @@ -42,7 +44,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -72,7 +74,7 @@ jobs: - name: Collect Metrics if: needs.changes.outputs.src == 'true' id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -85,7 +87,7 @@ jobs: - name: Check if image exists if: needs.changes.outputs.src == 'true' id: check-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@ad22fbd6f4d108b82aaf49b527bcf40f32babea8 # v2.2.1 + uses: smartcontractkit/chainlink-github-actions/docker/image-exists@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 with: repository: chainlink tag: ${{ github.sha }}${{ matrix.image.tag-suffix }} @@ -93,7 +95,7 @@ jobs: AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - name: Build Image if: steps.check-image.outputs.exists == 'false' && needs.changes.outputs.src == 'true' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@ad22fbd6f4d108b82aaf49b527bcf40f32babea8 # v2.2.1 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 with: cl_repo: smartcontractkit/chainlink cl_ref: ${{ github.sha }} @@ -119,7 +121,7 @@ jobs: - name: Collect Metrics if: needs.changes.outputs.src == 'true' id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -155,9 +157,95 @@ jobs: matrix: product: - name: automation - nodes: 9 + nodes: 11 os: ubuntu-latest pyroscope_env: ci-smoke-automation-evm-simulated + # temporarily disabled + # - name: ocr2vrf + # nodes: 2 + # os: ubuntu-latest + # pyroscope_env: ci-smoke-ocr2vrf-evm-simulated + runs-on: ${{ matrix.product.os }} + name: ETH Smoke Tests ${{ matrix.product.name }} + steps: + - name: Checkout the repo + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + with: + ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }} + ## Run this step when changes that require tests to be run are made + - name: Run Tests + if: needs.changes.outputs.src == 'true' + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 + env: + TESTCONTAINERS_RYUK_DISABLED: true + PYROSCOPE_SERVER: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 + PYROSCOPE_ENVIRONMENT: ${{ matrix.product.pyroscope_env }} + PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + with: + test_command_to_run: make test_need_operator_assets && cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ./smoke/${{ matrix.product.name }}_test.go 2>&1 | tee /tmp/gotest.log | gotestfmt + test_download_vendor_packages_command: cd ./integration-tests && go mod download + cl_repo: ${{ env.CHAINLINK_IMAGE }} + cl_image_tag: ${{ github.sha }} + aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + artifacts_location: ./integration-tests/smoke/logs + publish_check_name: EVM Smoke Test Results ${{ matrix.product.name }} + token: ${{ secrets.GITHUB_TOKEN }} + go_mod_path: ./integration-tests/go.mod + cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} + cache_restore_only: 'true' + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + + ## Run this step when changes that do not need the test to run are made + - name: Run Setup + if: needs.changes.outputs.src == 'false' + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-run-tests-environment@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 + with: + test_download_vendor_packages_command: cd ./integration-tests && go mod download + go_mod_path: ./integration-tests/go.mod + cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} + cache_restore_only: 'true' + 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@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + 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 + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec + with: + basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} + this-job-name: ETH Smoke Tests ${{ matrix.product.name }} + test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' + continue-on-error: true + + eth-smoke-tests-matrix-docker: + environment: integration + permissions: + checks: write + pull-requests: write + id-token: write + contents: read + needs: [build-chainlink, changes] + env: + SELECTED_NETWORKS: SIMULATED,SIMULATED_1,SIMULATED_2 + CHAINLINK_COMMIT_SHA: ${{ github.sha }} + CHAINLINK_ENV_USER: ${{ github.actor }} + TEST_LOG_LEVEL: debug + strategy: + fail-fast: false + matrix: + product: - name: cron nodes: 1 os: ubuntu-latest @@ -166,21 +254,13 @@ jobs: nodes: 1 os: ubuntu-latest pyroscope_env: "" - - name: keeper - nodes: 30 - os: ubuntu20.04-4cores-16GB - pyroscope_env: ci-smoke-keeper-evm-simulated - - name: forwarder_ocr - nodes: 1 - os: ubuntu-latest - pyroscope_env: ci-smoke-forwarder-ocr-evm-simulated - name: ocr nodes: 1 - os: ubuntu-latest + os: ubuntu20.04-8cores-32GB pyroscope_env: ci-smoke-ocr-evm-simulated - name: ocr2 nodes: 1 - os: ubuntu-latest + os: ubuntu20.04-8cores-32GB pyroscope_env: ci-smoke-ocr2-evm-simulated - name: runlog nodes: 1 @@ -188,16 +268,112 @@ jobs: pyroscope_env: "" - name: vrf nodes: 1 - os: ubuntu-latest + os: ubuntu20.04-8cores-32GB pyroscope_env: ci-smoke-vrf-evm-simulated - name: vrfv2 nodes: 1 - os: ubuntu-latest + os: ubuntu20.04-8cores-32GB pyroscope_env: ci-smoke-vrf2-evm-simulated - - name: ocr2vrf - nodes: 2 - os: ubuntu-latest - pyroscope_env: ci-smoke-ocr2vrf-evm-simulated + - name: forwarder_ocr + nodes: 1 + os: ubuntu20.04-8cores-32GB + pyroscope_env: ci-smoke-forwarder-ocr-evm-simulated + - name: forwarders_ocr2 + nodes: 1 + os: ubuntu20.04-8cores-32GB + pyroscope_env: ci-smoke-forwarder-ocr-evm-simulated + + # Keeper tests split out to use minimal environments + - name: keeper-1 + nodes: 1 + os: ubuntu20.04-8cores-32GB + pyroscope_env: ci-smoke-keeper-evm-simulated + file: keeper + run: -run ^TestKeeperBasicSmoke$ + - name: keeper-2 + nodes: 1 + os: ubuntu20.04-8cores-32GB + pyroscope_env: ci-smoke-keeper-evm-simulated + file: keeper + run: -run ^TestKeeperBlockCountPerTurn/registry_1_1$ + - name: keeper-3 + nodes: 1 + os: ubuntu20.04-8cores-32GB + pyroscope_env: ci-smoke-keeper-evm-simulated + file: keeper + run: -run ^TestKeeperBlockCountPerTurn/registry_1_2$ + - name: keeper-4 + nodes: 1 + os: ubuntu20.04-8cores-32GB + pyroscope_env: ci-smoke-keeper-evm-simulated + file: keeper + run: -run ^TestKeeperBlockCountPerTurn/registry_1_3$ + - name: keeper-5 + nodes: 1 + os: ubuntu20.04-8cores-32GB + pyroscope_env: ci-smoke-keeper-evm-simulated + file: keeper + run: -run ^TestKeeperSimulation$ + - name: keeper-6 + nodes: 1 + os: ubuntu20.04-8cores-32GB + pyroscope_env: ci-smoke-keeper-evm-simulated + file: keeper + run: -run ^TestKeeperCheckPerformGasLimit/registry_1_2$ + - name: keeper-7 + nodes: 1 + os: ubuntu20.04-8cores-32GB + pyroscope_env: ci-smoke-keeper-evm-simulated + file: keeper + run: -run ^TestKeeperCheckPerformGasLimit/registry_1_3$ + - name: keeper-8 + nodes: 1 + os: ubuntu20.04-8cores-32GB + pyroscope_env: ci-smoke-keeper-evm-simulated + file: keeper + run: -run ^TestKeeperRegisterUpkeep$ + - name: keeper-9 + nodes: 1 + os: ubuntu20.04-8cores-32GB + pyroscope_env: ci-smoke-keeper-evm-simulated + file: keeper + run: -run ^TestKeeperAddFunds$ + - name: keeper-10 + nodes: 1 + os: ubuntu20.04-8cores-32GB + pyroscope_env: ci-smoke-keeper-evm-simulated + file: keeper + run: -run ^TestKeeperRemove$ + - name: keeper-11 + nodes: 1 + os: ubuntu20.04-8cores-32GB + pyroscope_env: ci-smoke-keeper-evm-simulated + file: keeper + run: -run ^TestKeeperPauseRegistry$ + - name: keeper-12 + nodes: 1 + os: ubuntu20.04-8cores-32GB + pyroscope_env: ci-smoke-keeper-evm-simulated + file: keeper + run: -run ^TestKeeperMigrateRegistry$ + - name: keeper-13 + nodes: 1 + os: ubuntu20.04-8cores-32GB + pyroscope_env: ci-smoke-keeper-evm-simulated + file: keeper + run: -run ^TestKeeperNodeDown/registry_1_1$ + - name: keeper-14 + nodes: 1 + os: ubuntu20.04-8cores-32GB + pyroscope_env: ci-smoke-keeper-evm-simulated + file: keeper + run: -run ^TestKeeperNodeDown/registry_1_2$ + - name: keeper-15 + nodes: 1 + os: ubuntu20.04-8cores-32GB + pyroscope_env: ci-smoke-keeper-evm-simulated + file: keeper + run: -run ^TestKeeperNodeDown/registry_1_3$ runs-on: ${{ matrix.product.os }} name: ETH Smoke Tests ${{ matrix.product.name }} steps: @@ -205,34 +381,47 @@ jobs: uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 with: ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }} + - name: Build Go Test Command + id: build-go-test-command + run: | + # if the matrix.product.run is set, use it for a different command + if [ "${{ matrix.product.run }}" != "" ]; then + echo "run_command=${{ matrix.product.run }} ./smoke/${{ matrix.product.file }}_test.go" >> "$GITHUB_OUTPUT" + else + echo "run_command=./smoke/${{ matrix.product.name }}_test.go" >> "$GITHUB_OUTPUT" + fi ## Run this step when changes that require tests to be run are made - name: Run Tests if: needs.changes.outputs.src == 'true' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@ad22fbd6f4d108b82aaf49b527bcf40f32babea8 # v2.2.1 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 env: PYROSCOPE_SERVER: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 PYROSCOPE_ENVIRONMENT: ${{ matrix.product.pyroscope_env }} PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} with: - test_command_to_run: make test_need_operator_assets && cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ./smoke/${{ matrix.product.name }}_test.go 2>&1 | tee /tmp/gotest.log | gotestfmt + test_command_to_run: make test_need_operator_assets && cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestfmt test_download_vendor_packages_command: cd ./integration-tests && go mod download cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ github.sha }} + aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} artifacts_location: ./integration-tests/smoke/logs publish_check_name: EVM Smoke Test Results ${{ matrix.product.name }} token: ${{ secrets.GITHUB_TOKEN }} go_mod_path: ./integration-tests/go.mod + cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} + cache_restore_only: 'true' QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - ## Run this step when changes that do not need the test to run are made - name: Run Setup if: needs.changes.outputs.src == 'false' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-run-tests-environment@ad22fbd6f4d108b82aaf49b527bcf40f32babea8 # v2.2.1 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-run-tests-environment@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 with: test_download_vendor_packages_command: cd ./integration-tests && go mod download go_mod_path: ./integration-tests/go.mod + cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} + cache_restore_only: 'true' QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} @@ -248,7 +437,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -261,20 +450,44 @@ jobs: if: always() runs-on: ubuntu-latest name: ETH Smoke Tests - needs: eth-smoke-tests-matrix + needs: [eth-smoke-tests-matrix,eth-smoke-tests-matrix-docker] steps: - name: Check smoke test matrix status - if: needs.eth-smoke-tests-matrix.result != 'success' + if: needs.eth-smoke-tests-matrix.result != 'success' || needs.eth-smoke-tests-matrix-docker.result != 'success' run: exit 1 - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@8163dcea2f01a0a8fec84b284406ff7af1d2e1c0 + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} this-job-name: ETH Smoke Tests continue-on-error: true + + # Run the setup if the matrix finishes but this time save the cache if we have a cache hit miss + # this will also only run if both of the matrix jobs pass + eth-smoke-go-mod-cache: + environment: integration + needs: [eth-smoke-tests] + runs-on: ubuntu20.04-16cores-64GB + name: ETH Smoke Tests Go Mod Cache + steps: + - name: Checkout the repo + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + with: + ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }} + - name: Run Setup + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-go@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 + with: + test_download_vendor_packages_command: | + cd ./integration-tests + go mod download + # force download of test dependencies + go test -run=NonExistentTest ./smoke/... || echo "ignore expected test failure" + go_mod_path: ./integration-tests/go.mod + cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} + cache_restore_only: 'false' ### Migration tests node-migration-tests: @@ -288,7 +501,7 @@ jobs: runs-on: ubuntu-latest needs: [build-chainlink, changes, build-test-image] # Only run migration tests on new tags - if: startsWith(github.ref, 'refs/tags/') + if: startsWith(github.ref, 'refs/tags/') env: SELECTED_NETWORKS: SIMULATED,SIMULATED_1,SIMULATED_2 CHAINLINK_COMMIT_SHA: ${{ github.sha }} @@ -313,7 +526,7 @@ jobs: run: | echo "Running migration tests from version '${{ steps.get_latest_version.outputs.latest_version }}' to: '${{ github.sha }}'" - name: Run Migration Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@ad22fbd6f4d108b82aaf49b527bcf40f32babea8 # v2.2.1 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 with: test_command_to_run: make test_need_operator_assets && cd ./integration-tests && go test -timeout 30m -count=1 -json ./migration 2>&1 | tee /tmp/gotest.log | gotestfmt test_download_vendor_packages_command: cd ./integration-tests && go mod download @@ -323,6 +536,8 @@ jobs: publish_check_name: Node Migration Test Results token: ${{ secrets.GITHUB_TOKEN }} go_mod_path: ./integration-tests/go.mod + cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} + cache_restore_only: 'true' QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} @@ -337,7 +552,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -411,7 +626,7 @@ jobs: steps: - name: Check if image exists id: check-image - uses: smartcontractkit/chainlink-github-actions/docker/image-exists@ad22fbd6f4d108b82aaf49b527bcf40f32babea8 # v2.2.1 + uses: smartcontractkit/chainlink-github-actions/docker/image-exists@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 with: repository: chainlink-solana-tests tag: ${{ needs.get_solana_sha.outputs.sha }} @@ -443,7 +658,7 @@ jobs: - name: Collect Metrics if: needs.changes.outputs.src == 'true' id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -482,7 +697,7 @@ jobs: - name: Collect Metrics if: needs.changes.outputs.src == 'true' id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -536,7 +751,7 @@ jobs: - name: Collect Metrics if: needs.changes.outputs.src == 'true' id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -550,7 +765,7 @@ jobs: ref: ${{ needs.get_solana_sha.outputs.sha }} - name: Run Tests if: needs.changes.outputs.src == 'true' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@ad22fbd6f4d108b82aaf49b527bcf40f32babea8 # v2.2.1 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 with: 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 }} @@ -558,6 +773,7 @@ jobs: 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 }} QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} @@ -591,24 +807,18 @@ jobs: EVM_KEYS: ${{ secrets.QA_EVM_KEYS }} TEST_EVM_KEYS: ${{ secrets.QA_EVM_KEYS }} - GOERLI_URLS: ${{ secrets.QA_GOERLI_URLS }} - TEST_GOERLI_URLS: ${{ secrets.QA_GOERLI_URLS }} - GOERLI_HTTP_URLS: ${{ secrets.QA_GOERLI_HTTP_URLS }} - TEST_GOERLI_HTTP_URLS: ${{ secrets.QA_GOERLI_HTTP_URLS }} - - OPTIMISM_GOERLI_URLS: ${{ secrets.QA_OPTIMISM_GOERLI_URLS }} TEST_OPTIMISM_GOERLI_URLS: ${{ secrets.QA_OPTIMISM_GOERLI_URLS }} - OPTIMISM_GOERLI_HTTP_URLS: ${{ secrets.QA_OPTIMISM_GOERLI_HTTP_URLS }} TEST_OPTIMISM_GOERLI_HTTP_URLS: ${{ secrets.QA_OPTIMISM_GOERLI_HTTP_URLS }} - ARBITRUM_GOERLI_URLS: ${{ secrets.QA_ARBITRUM_GOERLI_URLS }} TEST_ARBITRUM_GOERLI_URLS: ${{ secrets.QA_ARBITRUM_GOERLI_URLS }} - ARBITRUM_GOERLI_HTTP_URLS: ${{ secrets.QA_ARBITRUM_GOERLI_HTTP_URLS }} TEST_ARBITRUM_GOERLI_HTTP_URLS: ${{ secrets.QA_ARBITRUM_GOERLI_HTTP_URLS }} strategy: fail-fast: false matrix: - testnet: [GOERLI, OPTIMISM_GOERLI, ARBITRUM_GOERLI] + # NOTE: If changing this matrix, make sure to update the matrix in the testnet-smoke-tests-notify job to be the same + # otherwise reporting will be broken. Getting a single matrix for multiple jobs is a pain + # https://github.com/orgs/community/discussions/26284#discussioncomment-3251198 + testnet: [OPTIMISM_GOERLI, ARBITRUM_GOERLI] name: Live Testnet Smoke Tests ${{ matrix.testnet }} runs-on: ubuntu-latest steps: @@ -618,75 +828,158 @@ jobs: ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }} ## Only run OCR smoke test for now - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@ad22fbd6f4d108b82aaf49b527bcf40f32babea8 # v2.2.1 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 env: PYROSCOPE_SERVER: ${{ secrets.QA_PYROSCOPE_INSTANCE }} PYROSCOPE_ENVIRONMENT: ci-smoke-ocr-evm-${{ matrix.testnet }} # TODO: Only for OCR for now PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} with: test_command_to_run: make test_need_operator_assets && cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=1 ./smoke/ocr_test.go 2>&1 | tee /tmp/gotest.log | gotestfmt - test_download_vendor_packages_command: make gomod + test_download_vendor_packages_command: cd ./integration-tests && go mod download cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ github.sha }} + aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} artifacts_location: ./integration-tests/smoke/logs publish_check_name: ${{ matrix.testnet }} OCR Smoke Test Results token: ${{ secrets.GITHUB_TOKEN }} go_mod_path: ./integration-tests/go.mod + cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} + cache_restore_only: 'true' QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} - - name: Notify Slack - if: false ## TODO: This is currently noisy and needs to be more compact. - id: slack + + - name: Collect Metrics + if: always() + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec + with: + basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} + this-job-name: Live Testnet Smoke Tests ${{ matrix.testnet }} + test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' + continue-on-error: true + + testnet-smoke-tests-notify: + name: Live Testnet Start Slack Thread + if: ${{ github.event_name == 'schedule' || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) }} ## Only run live tests on new tags and nightly + environment: integration + outputs: + thread_ts: ${{ steps.slack.outputs.thread_ts }} + permissions: + checks: write + pull-requests: write + id-token: write + contents: read + runs-on: ubuntu-latest + needs: testnet-smoke-tests-matrix + steps: + - name: Debug Result + run: echo ${{needs.testnet-smoke-tests-matrix.result}} + - name: Main Slack Notification uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + id: slack with: - channel-id: ${{ secrets.QA_RELEASE_SLACK_CHANNEL }} + channel-id: ${{ secrets.QA_SLACK_CHANNEL }} payload: | { - "text": "", - "blocks": [ - { - "type": "header", - "text": { - "type": "plain_text", - "text": "Live Smoke Test Results for ${{ matrix.testnet }} ${{ job.status == 'success' && ':white_check_mark:' || ':x:'}}", - "emoji": true - } - }, + "attachments": [ { - "type": "divider" - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "Tag: <${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.ref_name }}|${{ github.ref_name }}>\nCommit: <${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}>\n<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Run>" - } - }, - { - "type": "divider" - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "OCR ${{ job.status == 'success' && ':white_check_mark:' || ':x:'}}" - } + "color": "${{ needs.testnet-smoke-tests-matrix.result == 'success' && '#2E7D32' || '#C62828' }}", + "blocks": [ + { + "type": "header", + "text": { + "type": "plain_text", + "text": "Live Smoke Test Results ${{ needs.testnet-smoke-tests-matrix.result == 'success' && ':white_check_mark:' || ':x:'}}", + "emoji": true + } + }, + { + "type": "divider" + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "<${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.ref_name }}|${{ github.ref_name }}> | <${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}> | <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Run>" + } + } + ] } ] } env: SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + testnet-smoke-tests-results: + name: Post Live Testnet Smoke Test Results + environment: integration + permissions: + checks: write + pull-requests: write + id-token: write + contents: read + runs-on: ubuntu-latest + needs: testnet-smoke-tests-notify + strategy: + fail-fast: false + matrix: + # NOTE: If changing this matrix, make sure to update the matrix in the testnet-smoke-tests-matrix job to be the same + # otherwise reporting will be broken. Getting a single matrix for multiple jobs is a pain + # https://github.com/orgs/community/discussions/26284#discussioncomment-3251198 + testnet: [OPTIMISM_GOERLI, ARBITRUM_GOERLI] + steps: + - name: Get Results + id: test-results + run: | + echo "Querying test results" + + echo "status=$(curl \ + -H "Authorization: Bearer ${{ github.token }}" \ + 'https://api.github.com/repos/${{github.repository}}/actions/runs/${{ github.run_id }}/jobs' \ + | jq -r '.jobs[] | select(.name == "Live Testnet Smoke Tests ${{ matrix.testnet}}").steps[] | select(.name == "Run Tests").conclusion')" >> $GITHUB_OUTPUT + + echo "status=$(curl \ + -H "Authorization: Bearer ${{ github.token }}" \ + 'https://api.github.com/repos/${{github.repository}}/actions/runs/${{ github.run_id }}/jobs' \ + | jq -r '.jobs[] | select(.name == "Live Testnet Smoke Tests ${{ matrix.testnet}}").steps[] | select(.name == "Run Tests").conclusion')" + echo "thread_ts=${{ needs.testnet-smoke-tests-notify.outputs.thread_ts }}" + + - name: Test Details + uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 with: - basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} - this-job-name: Live Testnet Smoke Tests ${{ matrix.testnet }} - test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' - continue-on-error: true + channel-id: ${{ secrets.QA_SLACK_CHANNEL }} + payload: | + { + "thread_ts": "${{ needs.testnet-smoke-tests-notify.outputs.thread_ts }}", + "attachments": [ + { + "color": "${{ steps.test-results.outputs.status == 'success' && '#2E7D32' || '#C62828' }}", + "blocks": [ + { + "type": "header", + "text": { + "type": "plain_text", + "text": "${{ matrix.testnet }} Smoke Test Results ${{ steps.test-results.outputs.status == 'success' && ':white_check_mark:' || ':x:'}}", + "emoji": true + } + }, + { + "type": "divider" + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "OCR ${{ steps.test-results.outputs.status == 'success' && ':white_check_mark:' || ':x:'}}" + } + } + ] + } + ] + } + env: + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} - ### End Live Testnet Section + ### End Live Testnet Section \ No newline at end of file diff --git a/.github/workflows/lint-gh-workflows.yml b/.github/workflows/lint-gh-workflows.yml index 60c1648d3ed..95c80f3d5da 100644 --- a/.github/workflows/lint-gh-workflows.yml +++ b/.github/workflows/lint-gh-workflows.yml @@ -13,7 +13,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} diff --git a/.github/workflows/on-demand-ocr-soak-test.yml b/.github/workflows/on-demand-ocr-soak-test.yml index bc41757b8ff..284464a4d09 100644 --- a/.github/workflows/on-demand-ocr-soak-test.yml +++ b/.github/workflows/on-demand-ocr-soak-test.yml @@ -14,6 +14,10 @@ on: - "CELO_MAINNET" - "BASE_GOERLI" - "BASE_MAINNET" + - "BSC_MAINNET" + - "BSC_TESTNET" + - "SCROLL_SEPOLIA" + - "SCROLL_MAINNET" fundingPrivateKey: description: Private funding key (Skip for Simulated) required: false @@ -77,7 +81,7 @@ jobs: steps: - name: Collect Metrics id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -117,7 +121,7 @@ jobs: QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@ad22fbd6f4d108b82aaf49b527bcf40f32babea8 # v2.2.1 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 env: DETACH_RUNNER: true TEST_SUITE: soak diff --git a/.github/workflows/operator-ui.yml b/.github/workflows/operator-ui.yml index 68039f27686..8aac69c04dd 100644 --- a/.github/workflows/operator-ui.yml +++ b/.github/workflows/operator-ui.yml @@ -33,7 +33,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} diff --git a/.github/workflows/performance-tests.yml b/.github/workflows/performance-tests.yml index b277b9f1b3b..3c104892407 100644 --- a/.github/workflows/performance-tests.yml +++ b/.github/workflows/performance-tests.yml @@ -42,7 +42,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -57,7 +57,7 @@ jobs: - name: Checkout the repo uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@ad22fbd6f4d108b82aaf49b527bcf40f32babea8 # v2.2.1 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 with: test_command_to_run: cd integration-tests && go test -timeout 1h -count=1 -json -test.parallel 10 ./performance 2>&1 | tee /tmp/gotest.log | gotestfmt test_download_vendor_packages_command: make gomod @@ -79,7 +79,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} diff --git a/.github/workflows/readme.yml b/.github/workflows/readme.yml index 194938eede3..d3788674d6d 100644 --- a/.github/workflows/readme.yml +++ b/.github/workflows/readme.yml @@ -31,7 +31,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} diff --git a/.github/workflows/sigscanner.yml b/.github/workflows/sigscanner.yml index 6d376e28af0..390af228f06 100644 --- a/.github/workflows/sigscanner.yml +++ b/.github/workflows/sigscanner.yml @@ -26,7 +26,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@8163dcea2f01a0a8fec84b284406ff7af1d2e1c0 + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} diff --git a/.github/workflows/solidity-foundry.yml b/.github/workflows/solidity-foundry.yml index f81aa1d12e8..5c114c6e0ad 100644 --- a/.github/workflows/solidity-foundry.yml +++ b/.github/workflows/solidity-foundry.yml @@ -16,13 +16,20 @@ jobs: - uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1 id: changes with: + # Foundry is only used for Solidity v0.8 contracts, therefore we can ignore + # changes to older contracts. filters: | src: - - 'contracts/**/*' + - 'contracts/src/v0.8/**/*' - '.github/workflows/solidity-foundry.yml' + - 'contracts/foundry.toml' tests: + strategy: + matrix: + product: [ vrf, automation, llo-feeds, functions, automation-dev, shared ] needs: [changes] + if: needs.changes.outputs.changes == 'true' name: Tests # See https://github.com/foundry-rs/foundry/issues/3827 runs-on: ubuntu-22.04 @@ -37,42 +44,44 @@ jobs: # and not native Foundry. This is to make sure the dependencies # stay in sync. - name: Setup NodeJS - if: ${{ needs.changes.outputs.changes == 'true' }} uses: ./.github/actions/setup-nodejs - name: Install Foundry - if: ${{ needs.changes.outputs.changes == 'true' }} uses: foundry-rs/foundry-toolchain@v1 with: version: nightly - name: Run Forge build - if: ${{ needs.changes.outputs.changes == 'true' }} run: | forge --version forge build id: build working-directory: contracts + env: + FOUNDRY_PROFILE: ${{ matrix.product }} - name: Run Forge tests - if: ${{ needs.changes.outputs.changes == 'true' }} run: | forge test -vvv id: test working-directory: contracts + env: + FOUNDRY_PROFILE: ${{ matrix.product }} - name: Run Forge snapshot - if: ${{ needs.changes.outputs.changes == 'true' }} run: | - forge snapshot --match-test _gas --check + forge snapshot --check gas-snapshots/${{ matrix.product }}.gas-snapshot id: snapshot working-directory: contracts + env: + FOUNDRY_PROFILE: ${{ matrix.product }} + - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} - this-job-name: Foundry Tests + this-job-name: Foundry Tests ${{ matrix.product }} continue-on-error: true diff --git a/.github/workflows/solidity-hardhat.yml b/.github/workflows/solidity-hardhat.yml new file mode 100644 index 00000000000..1c630b48bb8 --- /dev/null +++ b/.github/workflows/solidity-hardhat.yml @@ -0,0 +1,177 @@ +name: Solidity-Hardhat + +on: + merge_group: + push: + +env: + NODE_OPTIONS: --max_old_space_size=8192 + +defaults: + run: + shell: bash + +jobs: + changes: + name: Detect changes + runs-on: ubuntu-latest + outputs: + changes: ${{ steps.changes.outputs.src }} + steps: + - name: Checkout the repo + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1 + id: changes + with: + filters: | + src: + - 'contracts/src/!(v0.8/(llo-feeds|ccip)/**)/**/*' + - 'contracts/test/**/*' + - 'contracts/package.json' + - 'contracts/hardhat.config.ts' + - 'contracts/ci.json' + - '.github/workflows/solidity-hardhat.yml' + + split-tests: + name: Split Solidity Tests + runs-on: ubuntu-latest + outputs: + splits: ${{ steps.split.outputs.splits }} + steps: + - name: Checkout the repo + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - name: Generate splits + id: split + uses: ./.github/actions/split-tests + with: + config: ./contracts/ci.json + - name: Collect Metrics + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec + with: + basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} + this-job-name: Split Solidity Tests + continue-on-error: true + + solidity-coverage-splits: + needs: [changes, split-tests] + if: needs.changes.outputs.changes == 'true' + name: Solidity Coverage ${{ matrix.split.id }} ${{ fromJSON('["(skipped)", ""]')[needs.changes.outputs.changes == 'true'] }} + strategy: + fail-fast: false + matrix: + split: ${{ fromJson(needs.split-tests.outputs.splits) }} + runs-on: ubuntu20.04-4cores-16GB + steps: + - name: Checkout the repo + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - name: Setup NodeJS + uses: ./.github/actions/setup-nodejs + - name: Setup Hardhat + uses: ./.github/actions/setup-hardhat + with: + namespace: coverage + - name: Run coverage + env: + SPLIT: ${{ matrix.split.coverageTests }} + shell: bash + run: pnpm coverage --testfiles "$SPLIT" + working-directory: contracts + - name: Push coverage + run: ./tools/bin/codecov -f ./contracts/coverage.json + - name: Rename coverage + run: mv ./contracts/coverage.json ./contracts/coverage-${{ matrix.split.idx }}.json + - name: Upload coverage + uses: actions/upload-artifact@v3 + with: + name: solidity-coverage-${{ matrix.split.idx }} + path: ./contracts/coverage-${{ matrix.split.idx }}.json + - name: Collect Metrics + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec + with: + basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} + this-job-name: Solidity Coverage ${{ matrix.split.id }} + continue-on-error: true + + solidity-coverage: + needs: [changes, solidity-coverage-splits] + if: needs.changes.outputs.changes == 'true' + name: Solidity Coverage ${{ fromJSON('["(skipped)", ""]')[needs.changes.outputs.changes == 'true'] }} + runs-on: ubuntu-latest + steps: + - name: Checkout the repo + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - name: Setup NodeJS + uses: ./.github/actions/setup-nodejs + - name: Make coverage directory + run: mkdir ./contracts/coverage-reports + - name: Download coverage + uses: actions/download-artifact@v3 + with: + path: ./contracts/coverage-reports + - name: Display structure of downloaded files + run: ls -R coverage-reports + working-directory: contracts + - name: Generate merged report + run: pnpm istanbul report text text-summary + working-directory: contracts + + solidity-splits: + needs: [changes, split-tests] + if: needs.changes.outputs.changes == 'true' + name: Solidity ${{ matrix.split.id }} ${{ fromJSON('["(skipped)", ""]')[needs.changes.outputs.changes == 'true'] }} + strategy: + fail-fast: false + matrix: + split: ${{ fromJson(needs.split-tests.outputs.splits) }} + runs-on: ubuntu20.04-4cores-16GB + steps: + - name: Checkout the repo + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - name: Setup NodeJS + uses: ./.github/actions/setup-nodejs + - name: Setup Hardhat + uses: ./.github/actions/setup-hardhat + with: + namespace: coverage + - name: Run tests + env: + SPLIT: ${{ matrix.split.tests }} + working-directory: contracts + run: pnpm test -- $SPLIT + - name: Collect Metrics + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec + with: + basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} + this-job-name: Solidity ${{ matrix.split.id }} + continue-on-error: true + + solidity: + needs: [changes, solidity-splits] + name: Solidity + runs-on: ubuntu-latest + if: always() + steps: + - run: echo 'Solidity tests finished!' + - name: Check test results + run: | + if [[ "${{ needs.changes.result }}" = "failure" || "${{ needs.solidity-splits.result }}" = "failure" ]]; then + echo "One or more changes / solidity-splits jobs failed" + exit 1 + else + echo "All test jobs passed successfully" + fi + - name: Collect Metrics + if: always() + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec + with: + basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} + this-job-name: Solidity + continue-on-error: true \ No newline at end of file diff --git a/.github/workflows/solidity.yml b/.github/workflows/solidity.yml index 614679c284a..b024782ed42 100644 --- a/.github/workflows/solidity.yml +++ b/.github/workflows/solidity.yml @@ -4,9 +4,6 @@ on: merge_group: push: -env: - NODE_OPTIONS: --max_old_space_size=8192 - defaults: run: shell: bash @@ -28,181 +25,22 @@ jobs: - 'contracts/**/*' - '.github/workflows/solidity.yml' - split-tests: - name: Split Solidity Tests - runs-on: ubuntu-latest - outputs: - splits: ${{ steps.split.outputs.splits }} - steps: - - name: Checkout the repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - - name: Generate splits - id: split - uses: ./.github/actions/split-tests - with: - config: ./contracts/ci.json - - name: Collect Metrics - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b - with: - basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} - this-job-name: Split Solidity Tests - continue-on-error: true - - solidity-coverage-splits: - needs: [changes, split-tests] - name: Solidity Coverage ${{ matrix.split.id }} ${{ fromJSON('["(skipped)", ""]')[needs.changes.outputs.changes == 'true'] }} - strategy: - fail-fast: false - matrix: - split: ${{ fromJson(needs.split-tests.outputs.splits) }} - runs-on: ubuntu20.04-4cores-16GB - steps: - - name: Checkout the repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - - name: Setup NodeJS - if: ${{ needs.changes.outputs.changes == 'true' }} - uses: ./.github/actions/setup-nodejs - - name: Setup Hardhat - if: ${{ needs.changes.outputs.changes == 'true' }} - uses: ./.github/actions/setup-hardhat - with: - namespace: coverage - - name: Run coverage - if: ${{ needs.changes.outputs.changes == 'true' }} - env: - SPLIT: ${{ matrix.split.coverageTests }} - shell: bash - run: pnpm coverage --testfiles "$SPLIT" - working-directory: contracts - - name: Push coverage - if: ${{ needs.changes.outputs.changes == 'true' }} - run: ./tools/bin/codecov -f ./contracts/coverage.json - - name: Rename coverage - if: ${{ needs.changes.outputs.changes == 'true' }} - run: mv ./contracts/coverage.json ./contracts/coverage-${{ matrix.split.idx }}.json - - name: Upload coverage - if: ${{ needs.changes.outputs.changes == 'true' }} - uses: actions/upload-artifact@v3 - with: - name: solidity-coverage-${{ matrix.split.idx }} - path: ./contracts/coverage-${{ matrix.split.idx }}.json - - name: Collect Metrics - if: ${{ needs.changes.outputs.changes == 'true' }} - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b - with: - basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} - this-job-name: Solidity Coverage ${{ matrix.split.id }} - continue-on-error: true - - solidity-coverage: - needs: [changes, solidity-coverage-splits] - name: Solidity Coverage ${{ fromJSON('["(skipped)", ""]')[needs.changes.outputs.changes == 'true'] }} - runs-on: ubuntu-latest - steps: - - name: Checkout the repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - - name: Setup NodeJS - if: ${{ needs.changes.outputs.changes == 'true' }} - uses: ./.github/actions/setup-nodejs - - name: Make coverage directory - if: ${{ needs.changes.outputs.changes == 'true' }} - run: mkdir ./contracts/coverage-reports - - name: Download coverage - if: ${{ needs.changes.outputs.changes == 'true' }} - uses: actions/download-artifact@v3 - with: - path: ./contracts/coverage-reports - - name: Display structure of downloaded files - if: ${{ needs.changes.outputs.changes == 'true' }} - run: ls -R coverage-reports - working-directory: contracts - - name: Generate merged report - if: ${{ needs.changes.outputs.changes == 'true' }} - run: pnpm istanbul report text text-summary - working-directory: contracts - - solidity-splits: - needs: [changes, split-tests] - name: Solidity ${{ matrix.split.id }} ${{ fromJSON('["(skipped)", ""]')[needs.changes.outputs.changes == 'true'] }} - strategy: - fail-fast: false - matrix: - split: ${{ fromJson(needs.split-tests.outputs.splits) }} - runs-on: ubuntu20.04-4cores-16GB - steps: - - name: Checkout the repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - - name: Setup NodeJS - if: ${{ needs.changes.outputs.changes == 'true' }} - uses: ./.github/actions/setup-nodejs - - name: Setup Hardhat - if: ${{ needs.changes.outputs.changes == 'true' }} - uses: ./.github/actions/setup-hardhat - with: - namespace: coverage - - name: Run tests - if: ${{ needs.changes.outputs.changes == 'true' }} - env: - SPLIT: ${{ matrix.split.tests }} - working-directory: contracts - run: pnpm test -- $SPLIT - - name: Collect Metrics - if: ${{ needs.changes.outputs.changes == 'true' }} - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b - with: - basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} - this-job-name: Solidity ${{ matrix.split.id }} - continue-on-error: true - - solidity: - needs: [changes, solidity-splits] - name: Solidity - runs-on: ubuntu-latest - if: always() - steps: - - run: echo 'Solidity tests finished!' - - name: Check test results - run: | - if [[ "${{ needs.changes.result }}" = "failure" || "${{ needs.solidity-splits.result }}" = "failure" ]]; then - echo "One or more changes / solidity-splits jobs failed" - exit 1 - else - echo "All test jobs passed successfully" - fi - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@8163dcea2f01a0a8fec84b284406ff7af1d2e1c0 - with: - basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} - this-job-name: Solidity - continue-on-error: true - prepublish-test: needs: [changes] + if: needs.changes.outputs.changes == 'true' name: Prepublish Test ${{ fromJSON('["(skipped)", ""]')[needs.changes.outputs.changes == 'true'] }} runs-on: ubuntu-latest steps: - name: Checkout the repo uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Setup NodeJS - if: ${{ needs.changes.outputs.changes == 'true' }} uses: ./.github/actions/setup-nodejs - name: Run Prepublish test - if: ${{ needs.changes.outputs.changes == 'true' }} working-directory: contracts run: pnpm prepublishOnly - name: Collect Metrics - if: ${{ needs.changes.outputs.changes == 'true' }} id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -211,6 +49,7 @@ jobs: native-compile: needs: [changes] + if: needs.changes.outputs.changes == 'true' name: Native Compilation ${{ fromJSON('["(skipped)", ""]')[needs.changes.outputs.changes == 'true'] }} runs-on: ubuntu-latest steps: @@ -225,18 +64,15 @@ jobs: - name: Install diff-so-fancy run: echo "$GITHUB_WORKSPACE/diff-so-fancy" >> $GITHUB_PATH - name: Setup NodeJS - if: ${{ needs.changes.outputs.changes == 'true' }} uses: ./.github/actions/setup-nodejs with: prod: "true" - name: Setup Go - if: ${{ needs.changes.outputs.changes == 'true' }} uses: ./.github/actions/setup-go - name: Run native compile and generate wrappers - if: ${{ needs.changes.outputs.changes == 'true' }} - run: make go-solidity-wrappers + run: make wrappers-all + working-directory: ./contracts - name: Verify local solc binaries - if: ${{ needs.changes.outputs.changes == 'true' }} run: ./tools/ci/check_solc_hashes - name: Check if Go solidity wrappers are updated if: ${{ needs.changes.outputs.changes == 'true' }} @@ -245,11 +81,10 @@ jobs: env: GITHUB_TOKEN: ${{ github.token }} if: ${{ failure() }} - run: gh pr comment -b 'Go solidity wrappers are out-of-date, regenerate them via the `make go-solidity-wrappers` command' + run: gh pr comment -b 'Go solidity wrappers are out-of-date, regenerate them via the `make wrappers-all` command' - name: Collect Metrics - if: ${{ needs.changes.outputs.changes == 'true' }} id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -261,21 +96,19 @@ jobs: run: working-directory: contracts needs: [changes] + if: needs.changes.outputs.changes == 'true' name: Lint ${{ fromJSON('["(skipped)", ""]')[needs.changes.outputs.changes == 'true'] }} runs-on: ubuntu-latest steps: - name: Checkout the repo uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Setup NodeJS - if: ${{ needs.changes.outputs.changes == 'true' }} uses: ./.github/actions/setup-nodejs - name: Run pnpm lint - if: ${{ needs.changes.outputs.changes == 'true' }} run: pnpm lint - name: Collect Metrics - if: ${{ needs.changes.outputs.changes == 'true' }} id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -287,21 +120,19 @@ jobs: run: working-directory: contracts needs: [changes] + if: needs.changes.outputs.changes == 'true' name: Prettier Formatting runs-on: ubuntu-latest steps: - name: Checkout the repo uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Setup NodeJS - if: ${{ needs.changes.outputs.changes == 'true' }} uses: ./.github/actions/setup-nodejs - name: Run prettier check - if: ${{ needs.changes.outputs.changes == 'true' }} run: pnpm prettier:check - name: Collect Metrics - if: ${{ needs.changes.outputs.changes == 'true' }} id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} diff --git a/.github/workflows/sync-develop-from-smartcontractkit-chainlink.yml b/.github/workflows/sync-develop-from-smartcontractkit-chainlink.yml index d4d6fa3f79e..314095a5012 100644 --- a/.github/workflows/sync-develop-from-smartcontractkit-chainlink.yml +++ b/.github/workflows/sync-develop-from-smartcontractkit-chainlink.yml @@ -30,7 +30,7 @@ jobs: - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@90fcbaac8ebf86da9c4d55dba24f6fe3029f0e0b + uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} diff --git a/.gitignore b/.gitignore index b763b582487..4d65eb32a1e 100644 --- a/.gitignore +++ b/.gitignore @@ -45,6 +45,7 @@ core/cmd/TestClient_ImportExportP2PKeyBundle_test_key.json output.txt race.* golangci-lint-output.txt +golangci-lint/ # DB state ./db/ diff --git a/.nvmrc b/.nvmrc index 53a42214a46..f274881e5fd 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v16.13.2 +v16.16.0 diff --git a/.tool-versions b/.tool-versions index 33d3adb2849..c7deac35bf5 100644 --- a/.tool-versions +++ b/.tool-versions @@ -4,5 +4,5 @@ nodejs 16.16.0 postgres 13.3 helm 3.10.3 zig 0.10.1 -golangci-lint 1.53.2 +golangci-lint 1.53.3 shellspec 0.28.1 diff --git a/CODEOWNERS b/CODEOWNERS index 10d1284e0ba..2b2fb18443a 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -9,6 +9,7 @@ /core/internal @samsondav @jmank88 # Chains +/common @smartcontractkit/integrations /core/chains/evm @samsondav @prashantkumar1982 /core/chains/evm/headtracker @pinebit @samsondav @prashantkumar1982 /core/chains/evm/client @samsondav @prashantkumar1982 @@ -45,8 +46,16 @@ /core/services/webhook @samsondav -# Chainlink Functions related services -core/services/ocr2/plugins/functions @bolekk @justinkaseman @KuphJr @pinebit +# Chainlink Functions +core/services/functions @smartcontractkit/functions +core/services/ocr2/plugins/functions @smartcontractkit/functions +core/services/s4 @pinebit @bolekk +core/service/ocr2/plugins/s4 @pinebit @bolekk +core/services/ocr2/plugins/threshold @KuphJr @bolekk +core/services/relay/evm/functions.go @bolekk @justinkaseman @KuphJr +core/services/relay/evm/functions @bolekk @justinkaseman @KuphJr +core/scripts/functions @smartcontractkit/functions +core/scripts/gateway @bolekk @pinebit # API /core/web @jkongie @@ -61,8 +70,10 @@ core/services/ocr2/plugins/functions @bolekk @justinkaseman @KuphJr @pinebit /contracts/ @se3000 @connorwstein /contracts/**/*Keeper* @smartcontractkit/keepers /contracts/**/*Upkeep* @smartcontractkit/keepers -/contracts/**/*Functions* @bolekk @justinkaseman @KuphJr @pinebit -/contracts/src/v0.8/functions @bolekk @justinkaseman @KuphJr @pinebit +/contracts/**/*Functions* @smartcontractkit/functions +/contracts/src/v0.8/functions @smartcontractkit/functions +contracts/test/v0.8/functions @smartcontractkit/functions +/contracts/src/v0.8/llo-feeds @austinborn @Fletch153 # Tests /integration-tests/ @smartcontractkit/test-tooling-team @@ -95,3 +106,6 @@ flake.lock @smartcontractkit/prodsec-public ./core/config @samsondav @jmank88 ./docs/CONFIG.md @samsondav @jmank88 @dwightjl ./internal/config/docs.toml @samsondav @jmank88 @dwightjl + +# LOOP Plugins +/plugins @jmank88 @krehermann diff --git a/GNUmakefile b/GNUmakefile index cf0f7aba9e4..6ee81eb5036 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -89,37 +89,6 @@ operator-ui: ## Fetch the frontend abigen: ## Build & install abigen. ./tools/bin/build_abigen -.PHONY: go-solidity-wrappers -go-solidity-wrappers: pnpmdep abigen ## Recompiles solidity contracts and their go wrappers. - ./contracts/scripts/native_solc_compile_all - go generate ./core/gethwrappers - -.PHONY: go-solidity-wrappers-transmission -go-solidity-wrappers-transmission: pnpmdep abigen ## Recompiles solidity contracts and their go wrappers. - ./contracts/scripts/transmission/native_solc_compile_all_transmission - go generate ./core/gethwrappers/transmission - -.PHONY: go-solidity-wrappers-ocr2vrf -go-solidity-wrappers-ocr2vrf: pnpmdep abigen ## Recompiles solidity contracts and their go wrappers. - ./contracts/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 - - -.PHONY: go-solidity-wrappers-functions -go-solidity-wrappers-functions: pnpmdep abigen ## Recompiles solidity contracts and their go wrappers. - ./contracts/scripts/native_solc_compile_all_functions - go generate ./core/gethwrappers/functions/go_generate.go - -.PHONY: go-solidity-wrappers-llo -go-solidity-wrappers-llo: pnpmdep abigen ## Recompiles solidity contracts and their go wrappers. - ./contracts/scripts/native_solc_compile_all_llo - go generate ./core/gethwrappers/go_generate_llo.go - .PHONY: generate generate: abigen codecgen mockery ## Execute all go:generate commands. go generate -x ./... @@ -176,11 +145,9 @@ config-docs: ## Generate core node configuration documentation .PHONY: golangci-lint golangci-lint: ## Run golangci-lint for all issues. - docker run --rm -v $(shell pwd):/app -w /app golangci/golangci-lint:v1.53.2 golangci-lint run --max-issues-per-linter 0 --max-same-issues 0 > golangci-lint-output.txt + [ -d "./golangci-lint" ] || mkdir ./golangci-lint && \ + docker run --rm -v $(shell pwd):/app -w /app golangci/golangci-lint:v1.53.2 golangci-lint run --max-issues-per-linter 0 --max-same-issues 0 > ./golangci-lint/$(shell date --iso=seconds).txt -.PHONY: snapshot -snapshot: - cd ./contracts && forge snapshot --match-test _gas GORELEASER_CONFIG ?= .goreleaser.yaml diff --git a/VERSION b/VERSION index 197c4d5c2d7..437459cd94c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.4.0 +2.5.0 diff --git a/charts/chainlink-cluster/devspace.yaml b/charts/chainlink-cluster/devspace.yaml index 26998ab4f71..63b6f112fec 100644 --- a/charts/chainlink-cluster/devspace.yaml +++ b/charts/chainlink-cluster/devspace.yaml @@ -19,7 +19,7 @@ pipelines: run: |- run_dependencies --all # 1. Deploy any projects this project needs (see "dependencies") ensure_pull_secrets --all # 2. Ensure pull secrets - build_images --all -t $(git describe --always) # 3. Build, tag (git commit hash) and push all images (see "images") + build_images --all -t $(git rev-parse --short HEAD) # 3. Build, tag (git commit hash) and push all images (see "images") create_deployments --all # 4. Deploy Helm charts and manifests specfied as "deployments" images: diff --git a/common/chains/label/label.go b/common/chains/label/label.go new file mode 100644 index 00000000000..2498fde0ee9 --- /dev/null +++ b/common/chains/label/label.go @@ -0,0 +1,8 @@ +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 new file mode 100644 index 00000000000..f980c73fc1b --- /dev/null +++ b/common/fee/models.go @@ -0,0 +1,85 @@ +package fee + +import ( + "math/big" + + "github.com/pkg/errors" + + "github.com/smartcontractkit/chainlink/v2/common/chains/label" + "github.com/smartcontractkit/chainlink/v2/core/logger" + bigmath "github.com/smartcontractkit/chainlink/v2/core/utils/big_math" +) + +var ( + ErrBumpFeeExceedsLimit = errors.New("fee bump exceeds limit") + ErrBump = errors.New("fee bump failed") + ErrConnectivity = errors.New("transaction propagation issue: transactions are not being mined") +) + +func IsBumpErr(err error) bool { + return err != nil && (errors.Is(err, ErrBumpFeeExceedsLimit) || errors.Is(err, ErrBump) || errors.Is(err, ErrConnectivity)) +} + +// CalculateFee computes the fee price for a transaction. +// The fee price is the minimum of: +// - max fee price specified, default fee price and max fee price for the node. +func CalculateFee( + maxFeePrice, defaultPrice, maxFeePriceConfigured *big.Int, +) *big.Int { + maxFeePriceAllowed := bigmath.Min(maxFeePrice, maxFeePriceConfigured) + return bigmath.Min(defaultPrice, maxFeePriceAllowed) +} + +// CalculateBumpedFee computes the next fee price to attempt as the largest of: +// - A configured percentage bump (bumpPercent) on top of the baseline price. +// - A configured fixed amount of Unit (bumpMin) on top of the baseline price. +// The baseline price is the maximum of the previous fee price attempt and the node's current fee price. +func CalculateBumpedFee( + lggr logger.SugaredLogger, + currentfeePrice, originalfeePrice, maxFeePriceInput, maxBumpPrice, bumpMin *big.Int, + bumpPercent uint16, + toChainUnit feeUnitToChainUnit, +) (*big.Int, error) { + maxFeePrice := bigmath.Min(maxFeePriceInput, maxBumpPrice) + bumpedFeePrice := maxBumpedFee(originalfeePrice, bumpPercent, bumpMin) + + // Update bumpedFeePrice if currentfeePrice is higher than bumpedFeePrice and within maxFeePrice + bumpedFeePrice = maxFee(lggr, currentfeePrice, bumpedFeePrice, maxFeePrice, "fee price", toChainUnit) + + if bumpedFeePrice.Cmp(maxFeePrice) > 0 { + return maxFeePrice, errors.Wrapf(ErrBumpFeeExceedsLimit, "bumped fee price of %s would exceed configured max fee price of %s (original price was %s). %s", + toChainUnit(bumpedFeePrice), toChainUnit(maxFeePrice), toChainUnit(originalfeePrice), label.NodeConnectivityProblemWarning) + } else if bumpedFeePrice.Cmp(originalfeePrice) == 0 { + // NOTE: This really shouldn't happen since we enforce minimums for + // FeeEstimator.BumpPercent and FeeEstimator.BumpMin in the config validation, + // but it's here anyway for a "belts and braces" approach + return bumpedFeePrice, errors.Wrapf(ErrBump, "bumped fee price of %s is equal to original fee price of %s."+ + " ACTION REQUIRED: This is a configuration error, you must increase either "+ + "FeeEstimator.BumpPercent or FeeEstimator.BumpMin", toChainUnit(bumpedFeePrice), toChainUnit(bumpedFeePrice)) + } + return bumpedFeePrice, nil +} + +// Returns highest bumped fee price of originalFeePrice bumped by fixed units or percentage. +func maxBumpedFee(originalFeePrice *big.Int, feeBumpPercent uint16, feeBumpUnits *big.Int) *big.Int { + return bigmath.Max( + addPercentage(originalFeePrice, feeBumpPercent), + new(big.Int).Add(originalFeePrice, feeBumpUnits), + ) +} + +// Returns the max of currentFeePrice, bumpedFeePrice, and maxFeePrice +func maxFee(lggr logger.SugaredLogger, currentFeePrice, bumpedFeePrice, maxFeePrice *big.Int, feeType string, toChainUnit feeUnitToChainUnit) *big.Int { + if currentFeePrice == nil { + return bumpedFeePrice + } + if currentFeePrice.Cmp(maxFeePrice) > 0 { + // Shouldn't happen because the estimator should not be allowed to + // estimate a higher fee than the maximum allowed + lggr.AssumptionViolationf("Ignoring current %s of %s that would exceed max %s of %s", feeType, toChainUnit(currentFeePrice), feeType, toChainUnit(maxFeePrice)) + } else if bumpedFeePrice.Cmp(currentFeePrice) < 0 { + // If the current fee price is higher than the old price bumped, use that instead + return currentFeePrice + } + return bumpedFeePrice +} diff --git a/common/fee/utils.go b/common/fee/utils.go index 838ee23daa9..71ababddbe3 100644 --- a/common/fee/utils.go +++ b/common/fee/utils.go @@ -1,23 +1,29 @@ package fee import ( + "math" "math/big" - bigmath "github.com/smartcontractkit/chainlink/v2/core/utils/big_math" - + "github.com/pkg/errors" "github.com/shopspring/decimal" ) -func GetMaxFeePrice(userSpecifiedMax, maxFee *big.Int) *big.Int { - return bigmath.Min(userSpecifiedMax, maxFee) -} +func ApplyMultiplier(feeLimit uint32, multiplier float32) (uint32, error) { + result := decimal.NewFromBigInt(big.NewInt(0).SetUint64(uint64(feeLimit)), 0).Mul(decimal.NewFromFloat32(multiplier)).IntPart() -func CapFeePrice(calculatedFeePrice, userSpecifiedMax, maxFeePriceWei *big.Int, feeLimit uint32, multiplier float32) (maxFeePrice *big.Int, chainSpecificFeeLimit uint32) { - chainSpecificFeeLimit = ApplyMultiplier(feeLimit, multiplier) - maxFeePrice = GetMaxFeePrice(userSpecifiedMax, maxFeePriceWei) - return bigmath.Min(calculatedFeePrice, maxFeePrice), chainSpecificFeeLimit + if result > math.MaxUint32 { + return 0, errors.Errorf("integer overflow when applying multiplier of %f to fee limit of %d", multiplier, feeLimit) + } + return uint32(result), nil } -func ApplyMultiplier(feeLimit uint32, multiplier float32) uint32 { - return uint32(decimal.NewFromBigInt(big.NewInt(0).SetUint64(uint64(feeLimit)), 0).Mul(decimal.NewFromFloat32(multiplier)).IntPart()) +// Returns the input value increased by the given percentage. +func addPercentage(value *big.Int, percentage uint16) *big.Int { + bumped := new(big.Int) + bumped.Mul(value, big.NewInt(int64(100+percentage))) + bumped.Div(bumped, big.NewInt(100)) + return bumped } + +// Returns the fee in its chain specific unit. +type feeUnitToChainUnit func(fee *big.Int) string diff --git a/common/headtracker/head_tracker.go b/common/headtracker/head_tracker.go index 4de7d93134e..91813d89a2d 100644 --- a/common/headtracker/head_tracker.go +++ b/common/headtracker/head_tracker.go @@ -3,7 +3,6 @@ package headtracker import ( "context" "fmt" - "math/big" "sync" "time" @@ -334,7 +333,7 @@ func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) backfill(ctx context.Context, hea head = existingHead continue } - head, err = ht.fetchAndSaveHead(ctx, i) + head, err = ht.fetchAndSaveHead(ctx, i, head.GetParentHash()) fetched++ if ctx.Err() != nil { ht.log.Debugw("context canceled, aborting backfill", "err", err, "ctx.Err", ctx.Err()) @@ -346,9 +345,9 @@ 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) (HTH, error) { - ht.log.Debugw("Fetching head", "blockHeight", n) - head, err := ht.client.HeadByNumber(ctx, big.NewInt(n)) +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 { return ht.getNilHead(), err } else if !head.IsValid() { diff --git a/common/headtracker/types/client.go b/common/headtracker/types/client.go index 53962954377..906f95bbe54 100644 --- a/common/headtracker/types/client.go +++ b/common/headtracker/types/client.go @@ -9,6 +9,7 @@ import ( type Client[H types.Head[BLOCK_HASH], S types.Subscription, ID types.ID, BLOCK_HASH types.Hashable] interface { HeadByNumber(ctx context.Context, number *big.Int) (head H, err error) + HeadByHash(ctx context.Context, hash BLOCK_HASH) (head H, err error) // ConfiguredChainID returns the chain ID that the node is configured to connect to ConfiguredChainID() (id ID) // SubscribeNewHead is the method in which the client receives new Head. diff --git a/common/txmgr/confirmer.go b/common/txmgr/confirmer.go index 4d3fd2fdc37..07ed2d29f02 100644 --- a/common/txmgr/confirmer.go +++ b/common/txmgr/confirmer.go @@ -15,10 +15,10 @@ import ( "go.uber.org/multierr" clienttypes "github.com/smartcontractkit/chainlink/v2/common/chains/client" + commonfee "github.com/smartcontractkit/chainlink/v2/common/fee" feetypes "github.com/smartcontractkit/chainlink/v2/common/fee/types" txmgrtypes "github.com/smartcontractkit/chainlink/v2/common/txmgr/types" "github.com/smartcontractkit/chainlink/v2/common/types" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/label" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/pg" @@ -758,7 +758,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) att } attempt, err = ec.bumpGas(ctx, etx, etx.TxAttempts) - if gas.IsBumpErr(err) { + if commonfee.IsBumpErr(err) { lggr.Errorw("Failed to bump gas", append(logFields, "err", err)...) // Do not create a new attempt if bumping gas would put us over the limit or cause some other problem // Instead try to resubmit the previous attempt, and keep resubmitting until its accepted @@ -801,7 +801,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) bum return bumpedAttempt, err } - if errors.Is(errors.Cause(err), gas.ErrBumpGasExceedsLimit) { + if errors.Is(errors.Cause(err), commonfee.ErrBumpFeeExceedsLimit) { promGasBumpExceedsLimit.WithLabelValues(ec.chainID.String()).Inc() } diff --git a/common/types/client.go b/common/types/client.go deleted file mode 100644 index a3f89a3155b..00000000000 --- a/common/types/client.go +++ /dev/null @@ -1,56 +0,0 @@ -package types - -import ( - "context" - "math/big" -) - -// A generic client interface for communication with the RPC node -// Every native chain must implement independently -type Client[ - CHAINID ID, - SEQ Sequence, - ADDR Hashable, - BLOCK any, - BLOCKHASH Hashable, - TX any, - TXHASH Hashable, - TXRECEIPT any, - EVENT any, - EVENTOPS any, // event filter query options -] interface { - // ChainID stored for quick access - ConfiguredChainID() CHAINID - // ChainID RPC call - ChainID() (CHAINID, error) - - Accounts[ADDR, SEQ] - Transactions[TX, TXHASH, TXRECEIPT] - Events[EVENT, EVENTOPS] - Blocks[BLOCK, BLOCKHASH] - - CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error -} - -type Accounts[ADDR Hashable, SEQ Sequence] interface { - BalanceAt(ctx context.Context, accountAddress ADDR, blockNumber *big.Int) (*big.Int, error) - TokenBalance(ctx context.Context, accountAddress ADDR, tokenAddress ADDR) (*big.Int, error) - SequenceAt(ctx context.Context, accountAddress ADDR, blockNumber *big.Int) (SEQ, error) -} - -type Transactions[TX any, TXHASH Hashable, TXRECEIPT any] interface { - SendTransaction(ctx context.Context, tx *TX) error - SimulateTransaction(ctx context.Context, tx *TX) error - TransactionByHash(ctx context.Context, txHash TXHASH) (*TX, error) - TransactionReceipt(ctx context.Context, txHash TXHASH) (*TXRECEIPT, error) -} - -type Blocks[BLOCK any, BLOCKHASH Hashable] interface { - BlockByNumber(ctx context.Context, number *big.Int) (*BLOCK, error) - BlockByHash(ctx context.Context, hash BLOCKHASH) (*BLOCK, error) - LatestBlockHeight(context.Context) (*big.Int, error) -} - -type Events[EVENT any, EVENTOPS any] interface { - FilterEvents(ctx context.Context, query EVENTOPS) ([]EVENT, error) -} diff --git a/common/types/head_tracker.go b/common/types/head_tracker.go index 0d69a2ccaa5..811298f8956 100644 --- a/common/types/head_tracker.go +++ b/common/types/head_tracker.go @@ -24,6 +24,10 @@ type HeadTracker[H Head[BLOCK_HASH], BLOCK_HASH Hashable] 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) } diff --git a/contracts/.gas-snapshot b/contracts/.gas-snapshot deleted file mode 100644 index fee527e4686..00000000000 --- a/contracts/.gas-snapshot +++ /dev/null @@ -1,85 +0,0 @@ -EIP_712_1014_4337:testEIP712EIP4337AndCreateSmartContractAccount() (gas: 910680) -EIP_712_1014_4337:testEIP712EIP4337AndCreateSmartContractAccountWithPaymaster() (gas: 2299908) -EIP_712_1014_4337:testEIP712EIP4337AndCreateSmartContractAccountWithPaymasterForVRFRequest() (gas: 2893568) -EIP_712_1014_4337:testEIP712EIP4337WithExistingSmartContractAccount() (gas: 875294) -FunctionsOracle_sendRequest:testEmptyRequestDataReverts() (gas: 13408) -FunctionsOracle_setDONPublicKey:testEmptyPublicKeyReverts() (gas: 10974) -FunctionsOracle_setDONPublicKey:testOnlyOwnerReverts() (gas: 11255) -FunctionsOracle_setDONPublicKey:testSetDONPublicKeySuccess() (gas: 126409) -FunctionsOracle_setDONPublicKey:testSetDONPublicKey_gas() (gas: 97558) -FunctionsOracle_setRegistry:testEmptyPublicKeyReverts() (gas: 10613) -FunctionsOracle_setRegistry:testOnlyOwnerReverts() (gas: 10905) -FunctionsOracle_setRegistry:testSetRegistrySuccess() (gas: 35769) -FunctionsOracle_setRegistry:testSetRegistry_gas() (gas: 31987) -FunctionsOracle_typeAndVersion:testTypeAndVersionSuccess() (gas: 6950) -VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_correctlyRemovesAMiddleDigest() (gas: 24243) -VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_correctlyRemovesTheFirstDigest() (gas: 24210) -VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_correctlyUnsetsDigestsInSequence() (gas: 44307) -VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_revertsIfCalledByNonOwner() (gas: 11322) -VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_revertsIfRemovingAnEmptyDigest() (gas: 10951) -VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_revertsIfRemovingAnNonExistentDigest() (gas: 13425) -VerifierActivateConfigTest:test_revertsIfDigestIsEmpty() (gas: 10939) -VerifierActivateConfigTest:test_revertsIfDigestNotSet() (gas: 13371) -VerifierActivateConfigTest:test_revertsIfNotOwner() (gas: 13410) -VerifierActivateConfigWithDeactivatedConfigTest:test_allowsVerification() (gas: 93382) -VerifierActivateFeedTest:test_revertsIfNoFeedExistsActivate() (gas: 13179) -VerifierActivateFeedTest:test_revertsIfNoFeedExistsDeactivate() (gas: 13179) -VerifierActivateFeedTest:test_revertsIfNotOwnerActivateFeed() (gas: 13360) -VerifierActivateFeedTest:test_revertsIfNotOwnerDeactivateFeed() (gas: 13437) -VerifierConstructorTest:test_revertsIfInitializedWithEmptyVerifierProxy() (gas: 59748) -VerifierConstructorTest:test_setsTheCorrectProperties() (gas: 1613888) -VerifierDeactivateFeedWithVerifyTest:test_currentReportAllowsVerification() (gas: 188235) -VerifierDeactivateFeedWithVerifyTest:test_currentReportFailsVerification() (gas: 108080) -VerifierDeactivateFeedWithVerifyTest:test_previousReportAllowsVerification() (gas: 95709) -VerifierDeactivateFeedWithVerifyTest:test_previousReportFailsVerification() (gas: 64662) -VerifierProxyAccessControlledVerificationTest:test_proxiesToTheVerifierIfHasAccess() (gas: 193000) -VerifierProxyAccessControlledVerificationTest:test_revertsIfNoAccess() (gas: 104244) -VerifierProxyConstructorTest:test_correctlySetsTheCorrectAccessControllerInterface() (gas: 868185) -VerifierProxyConstructorTest:test_correctlySetsTheOwner() (gas: 848303) -VerifierProxyConstructorTest:test_correctlySetsVersion() (gas: 6961) -VerifierProxyInitializeVerifierTest:test_revertsIfDigestAlreadySet() (gas: 49842) -VerifierProxyInitializeVerifierTest:test_revertsIfNotCorrectVerifier() (gas: 13103) -VerifierProxyInitializeVerifierTest:test_revertsIfNotOwner() (gas: 13375) -VerifierProxyInitializeVerifierTest:test_revertsIfVerifierAlreadyInitialized() (gas: 41915) -VerifierProxyInitializeVerifierTest:test_revertsIfZeroAddress() (gas: 10904) -VerifierProxyInitializeVerifierTest:test_updatesVerifierIfVerifier() (gas: 49086) -VerifierProxySetAccessControllerTest:test_emitsTheCorrectEvent() (gas: 35362) -VerifierProxySetAccessControllerTest:test_revertsIfCalledByNonOwner() (gas: 11345) -VerifierProxySetAccessControllerTest:test_successfullySetsNewAccessController() (gas: 32027) -VerifierProxySetAccessControllerTest:test_successfullySetsNewAccessControllerIsEmpty() (gas: 12126) -VerifierProxyUnsetVerifierTest:test_revertsIfDigestDoesNotExist() (gas: 13174) -VerifierProxyUnsetVerifierTest:test_revertsIfNotAdmin() (gas: 11249) -VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest:test_correctlyUnsetsVerifier() (gas: 12686) -VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest:test_emitsAnEventAfterUnsettingVerifier() (gas: 17965) -VerifierProxyVerifyTest:test_proxiesToTheCorrectVerifier() (gas: 190392) -VerifierProxyVerifyTest:test_revertsIfNoVerifierConfigured() (gas: 106909) -VerifierSetConfigTest:test_correctlyUpdatesTheConfig() (gas: 1056693) -VerifierSetConfigTest:test_revertsIfCalledByNonOwner() (gas: 178549) -VerifierSetConfigTest:test_revertsIfDuplicateSigners() (gas: 250802) -VerifierSetConfigTest:test_revertsIfFaultToleranceIsZero() (gas: 175843) -VerifierSetConfigTest:test_revertsIfNotEnoughSigners() (gas: 15106) -VerifierSetConfigTest:test_revertsIfSetWithTooManySigners() (gas: 21461) -VerifierSetConfigTest:test_revertsIfSignerContainsZeroAddress() (gas: 227232) -VerifierSetConfigWhenThereAreMultipleDigestsTest:test_correctlySetsConfigWhenDigestsAreRemoved() (gas: 537498) -VerifierSetConfigWhenThereAreMultipleDigestsTest:test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() (gas: 961835) -VerifierSetConfigWhenThereAreMultipleDigestsTest:test_correctlyUpdatesTheDigestInTheProxy() (gas: 518984) -VerifierSupportsInterfaceTest:test_falseIfIsNotCorrectInterface() (gas: 5590) -VerifierSupportsInterfaceTest:test_trueIfIsCorrectInterface() (gas: 5611) -VerifierVerifyMultipleConfigDigestTest:test_canVerifyNewerReportsWithNewerConfigs() (gas: 127391) -VerifierVerifyMultipleConfigDigestTest:test_canVerifyOlderReportsWithOlderConfigs() (gas: 183273) -VerifierVerifyMultipleConfigDigestTest:test_revertsIfAReportIsVerifiedWithAnExistingButIncorrectDigest() (gas: 82823) -VerifierVerifyMultipleConfigDigestTest:test_revertsIfVerifyingWithAnUnsetDigest() (gas: 122803) -VerifierVerifySingleConfigDigestTest:test_emitsAnEventIfReportVerified() (gas: 183146) -VerifierVerifySingleConfigDigestTest:test_returnsThePriceAndBlockNumIfReportVerified() (gas: 183283) -VerifierVerifySingleConfigDigestTest:test_revertsIfConfigDigestNotSet() (gas: 110853) -VerifierVerifySingleConfigDigestTest:test_revertsIfDuplicateSignersHaveSigned() (gas: 177012) -VerifierVerifySingleConfigDigestTest:test_revertsIfMismatchedSignatureLength() (gas: 47600) -VerifierVerifySingleConfigDigestTest:test_revertsIfReportHasUnconfiguredFeedID() (gas: 98652) -VerifierVerifySingleConfigDigestTest:test_revertsIfVerifiedByNonProxy() (gas: 99453) -VerifierVerifySingleConfigDigestTest:test_revertsIfVerifiedWithIncorrectAddresses() (gas: 178753) -VerifierVerifySingleConfigDigestTest:test_revertsIfWrongNumberOfSigners() (gas: 104735) -VerifierVerifySingleConfigDigestTest:test_setsTheCorrectEpoch() (gas: 190459) -Verifier_accessControlledVerify:testVerifyWithAccessControl_gas() (gas: 194809) -Verifier_setConfig:testSetConfigSuccess_gas() (gas: 921474) -Verifier_verify:testVerifyProxySuccess_gas() (gas: 185263) -Verifier_verify:testVerifySuccess_gas() (gas: 180648) \ No newline at end of file diff --git a/contracts/GNUmakefile b/contracts/GNUmakefile new file mode 100644 index 00000000000..ea70ae43f93 --- /dev/null +++ b/contracts/GNUmakefile @@ -0,0 +1,80 @@ +# ALL_FOUNDRY_PRODUCTS contains a list of all products that have a foundry +# profile defined. Adding a product to this list will make it available for +# snapshotting. +ALL_FOUNDRY_PRODUCTS = vrf automation llo-feeds functions automation-dev shared + +# To make a snapshot for a specific product, either set the `FOUNDRY_PROFILE` env var +# or call the target with `FOUNDRY_PROFILE=product` +# When developing with Foundry, you'll most likely already have the env var set +# to run the tests for the product you're working on. In that case, you can just +# call `make snapshot` and it will use the env var. +# env var example +# export FOUNDRY_PROFILE=llo-feeds +# make snapshot +# make call example +# make FOUNDRY_PROFILE=llo-feeds snapshot +.PHONY: snapshot +snapshot: ## Make a snapshot for a specific product. + export FOUNDRY_PROFILE=$(FOUNDRY_PROFILE) && forge snapshot --snap gas-snapshots/$(FOUNDRY_PROFILE).gas-snapshot + +.PHONY: snapshot-all +snapshot-all: ## Make a snapshot for all products. + for foundry_profile in $(ALL_FOUNDRY_PRODUCTS) ; do \ + make snapshot FOUNDRY_PROFILE=$$foundry_profile ; \ + done + +.PHONY: pnpmdep +pnpmdep: ## Install solidity contract dependencies through pnpm + pnpm i + +.PHONY: abigen +abigen: ## Build & install abigen. + ../tools/bin/build_abigen + + +# To generate gethwrappers for a specific product, either set the `FOUNDRY_PROFILE` +# env var or call the target with `FOUNDRY_PROFILE=product` +# This uses FOUNDRY_PROFILE, even though it does support non-foundry products. This +# is to improve the workflow for developers working with Foundry, which is the +# recommended way to develop Solidity for CL products. +# env var example +# export FOUNDRY_PROFILE=llo-feeds +# make wrappers +# make call example +# make FOUNDRY_PROFILE=llo-feeds wrappers +.PHONY: wrappers +wrappers: pnpmdep abigen ## Recompiles solidity contracts and their go wrappers. + ./scripts/native_solc_compile_all_$(FOUNDRY_PROFILE) + go generate ../core/gethwrappers/$(FOUNDRY_PROFILE) + +# This call generates all gethwrappers for all products. It does so based on the +# assumption that native_solc_compile_all contains sub-calls to each product, and +# go_generate does the same. +.PHONY: wrappers-all +wrappers-all: pnpmdep abigen ## Recompiles solidity contracts and their go wrappers. + # 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 " .__ .__ .__ .__ __" + @echo " ____ | |__ _____ |__| ____ | | |__| ____ | | __" + @echo " _/ ___\| | \\\\\\__ \ | |/ \| | | |/ \| |/ /" + @echo " \ \___| Y \/ __ \| | | \ |_| | | \ <" + @echo " \___ >___| (____ /__|___| /____/__|___| /__|_ \\" + @echo " \/ \/ \/ \/ \/ \/" + @echo "" + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | \ + awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/contracts/foundry.toml b/contracts/foundry.toml index b8e157b69c8..c1da24ad814 100644 --- a/contracts/foundry.toml +++ b/contracts/foundry.toml @@ -17,7 +17,7 @@ block_timestamp = 1234567890 block_number = 12345 [profile.functions] -solc_version = '0.8.6' +solc_version = '0.8.19' src = 'src/v0.8/functions' test = 'src/v0.8/functions/tests' @@ -33,4 +33,23 @@ src = 'src/v0.8/automation' test = 'src/v0.8/automation/test' solc_version = '0.8.6' +[profile.automation-dev] +optimizer_runs = 10000 +src = 'src/v0.8/dev/automation' +test = 'src/v0.8/dev/automation/test' + +[profile.llo-feeds] +optimizer_runs = 1000000 +src = 'src/v0.8/llo-feeds' +test = 'src/v0.8/llo-feeds/test' +solc_version = '0.8.16' + +[profile.shared] +optimizer_runs = 1000000 +src = 'src/v0.8/shared' +test = 'src/v0.8/shared/test' +solc_version = '0.8.19' +deny_warnings = true + + # See more config options https://github.com/foundry-rs/foundry/tree/master/config diff --git a/contracts/gas-snapshots/automation-dev.gas-snapshot b/contracts/gas-snapshots/automation-dev.gas-snapshot new file mode 100644 index 00000000000..1a939d69e19 --- /dev/null +++ b/contracts/gas-snapshots/automation-dev.gas-snapshot @@ -0,0 +1,5 @@ +AutomationForwarder_forward:testBasicSuccess() (gas: 87630) +AutomationForwarder_forward:testNotAuthorizedReverts() (gas: 21681) +AutomationForwarder_forward:testWrongFunctionSelectorSuccess() (gas: 17958) +AutomationForwarder_updateRegistry:testBasicSuccess() (gas: 14577) +AutomationForwarder_updateRegistry:testNotFromRegistryNotAuthorizedReverts() (gas: 13893) \ No newline at end of file diff --git a/contracts/gas-snapshots/automation.gas-snapshot b/contracts/gas-snapshots/automation.gas-snapshot new file mode 100644 index 00000000000..934aebf982d --- /dev/null +++ b/contracts/gas-snapshots/automation.gas-snapshot @@ -0,0 +1,8 @@ +HeartbeatRequester_getAggregatorRequestHeartbeat:testBasicSuccess() (gas: 75412) +HeartbeatRequester_getAggregatorRequestHeartbeat:testHeartbeatNotPermittedReverts() (gas: 21730) +HeartbeatRequester_permitHeartbeat:testBasicDeployerSuccess() (gas: 48280) +HeartbeatRequester_permitHeartbeat:testBasicSuccess() (gas: 45856) +HeartbeatRequester_permitHeartbeat:testOnlyCallableByOwnerReverts() (gas: 13796) +HeartbeatRequester_removeHeartbeat:testBasicSuccess() (gas: 30192) +HeartbeatRequester_removeHeartbeat:testOnlyCallableByOwnerReverts() (gas: 11629) +HeartbeatRequester_removeHeartbeat:testRemoveNoPermitsSuccess() (gas: 15660) \ No newline at end of file diff --git a/contracts/gas-snapshots/functions.gas-snapshot b/contracts/gas-snapshots/functions.gas-snapshot new file mode 100644 index 00000000000..b0a733f39c8 --- /dev/null +++ b/contracts/gas-snapshots/functions.gas-snapshot @@ -0,0 +1,17 @@ +FunctionsOracle_sendRequest:testEmptyRequestDataReverts() (gas: 13430) +FunctionsOracle_setDONPublicKey:testEmptyPublicKeyReverts() (gas: 10974) +FunctionsOracle_setDONPublicKey:testOnlyOwnerReverts() (gas: 11255) +FunctionsOracle_setDONPublicKey:testSetDONPublicKeySuccess() (gas: 126453) +FunctionsOracle_setDONPublicKey:testSetDONPublicKey_gas() (gas: 97558) +FunctionsOracle_setRegistry:testEmptyPublicKeyReverts() (gas: 10635) +FunctionsOracle_setRegistry:testOnlyOwnerReverts() (gas: 10927) +FunctionsOracle_setRegistry:testSetRegistrySuccess() (gas: 35791) +FunctionsOracle_setRegistry:testSetRegistry_gas() (gas: 31987) +FunctionsOracle_typeAndVersion:testTypeAndVersionSuccess() (gas: 6905) +FunctionsRouter_Pause:test_Pause_RevertIfNotOwner() (gas: 13293) +FunctionsRouter_Pause:test_Pause_Success() (gas: 20205) +FunctionsRouter_Unpause:test_Unpause_RevertIfNotOwner() (gas: 13338) +FunctionsRouter_Unpause:test_Unpause_Success() (gas: 77279) +FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26347) +FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfPaused() (gas: 15699) +FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas: 152436) diff --git a/contracts/gas-snapshots/llo-feeds.gas-snapshot b/contracts/gas-snapshots/llo-feeds.gas-snapshot new file mode 100644 index 00000000000..c5d28f2e6eb --- /dev/null +++ b/contracts/gas-snapshots/llo-feeds.gas-snapshot @@ -0,0 +1,227 @@ +FeeManagerProcessFeeTest:test_DiscountIsAppliedForNative() (gas: 47380) +FeeManagerProcessFeeTest:test_V1PayloadVerifies() (gas: 17377) +FeeManagerProcessFeeTest:test_V2PayloadVerifies() (gas: 105616) +FeeManagerProcessFeeTest:test_V2PayloadWithoutQuoteFails() (gas: 19971) +FeeManagerProcessFeeTest:test_V2PayloadWithoutZeroFee() (gas: 63248) +FeeManagerProcessFeeTest:test_WithdrawERC20() (gas: 63905) +FeeManagerProcessFeeTest:test_WithdrawNonAdminAddr() (gas: 48635) +FeeManagerProcessFeeTest:test_WithdrawUnwrappedNative() (gas: 20266) +FeeManagerProcessFeeTest:test_baseFeeIsAppliedForLink() (gas: 14770) +FeeManagerProcessFeeTest:test_baseFeeIsAppliedForNative() (gas: 17266) +FeeManagerProcessFeeTest:test_correctDiscountIsAppliedWhenBothTokensAreDiscounted() (gas: 83368) +FeeManagerProcessFeeTest:test_discountAIsNotAppliedWhenSetForOtherUsers() (gas: 51028) +FeeManagerProcessFeeTest:test_discountFeeRoundsDownWhenUneven() (gas: 47526) +FeeManagerProcessFeeTest:test_discountIsAppliedForLink() (gas: 44813) +FeeManagerProcessFeeTest:test_discountIsAppliedWith100PercentSurcharge() (gas: 70986) +FeeManagerProcessFeeTest:test_discountIsNoLongerAppliedAfterRemoving() (gas: 40625) +FeeManagerProcessFeeTest:test_discountIsNotAppliedForInvalidTokenAddress() (gas: 12439) +FeeManagerProcessFeeTest:test_discountIsNotAppliedToOtherFeeds() (gas: 49052) +FeeManagerProcessFeeTest:test_emptyQuoteRevertsWithError() (gas: 12305) +FeeManagerProcessFeeTest:test_eventIsEmittedAfterSurchargeIsSet() (gas: 36250) +FeeManagerProcessFeeTest:test_eventIsEmittedUponWithdraw() (gas: 60995) +FeeManagerProcessFeeTest:test_feeIsUpdatedAfterDiscountIsRemoved() (gas: 43112) +FeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewDiscountIsApplied() (gas: 59576) +FeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewSurchargeIsApplied() (gas: 55837) +FeeManagerProcessFeeTest:test_feeIsZeroWith100PercentDiscount() (gas: 47236) +FeeManagerProcessFeeTest:test_getBaseRewardWithLinkQuote() (gas: 14790) +FeeManagerProcessFeeTest:test_getLinkFeeIsRoundedUp() (gas: 45004) +FeeManagerProcessFeeTest:test_getLinkRewardIsRoundedDown() (gas: 44928) +FeeManagerProcessFeeTest:test_getLinkRewardWithNativeQuoteAndSurchargeWithLinkDiscount() (gas: 74660) +FeeManagerProcessFeeTest:test_getRewardWithLinkDiscount() (gas: 44856) +FeeManagerProcessFeeTest:test_getRewardWithLinkQuoteAndLinkDiscount() (gas: 44836) +FeeManagerProcessFeeTest:test_getRewardWithNativeQuote() (gas: 17266) +FeeManagerProcessFeeTest:test_getRewardWithNativeQuoteAndSurcharge() (gas: 45334) +FeeManagerProcessFeeTest:test_linkAvailableForPaymentReturnsLinkBalance() (gas: 47449) +FeeManagerProcessFeeTest:test_nativeSurcharge0Percent() (gas: 25401) +FeeManagerProcessFeeTest:test_nativeSurcharge100Percent() (gas: 45370) +FeeManagerProcessFeeTest:test_nativeSurchargeCannotExceed100Percent() (gas: 12085) +FeeManagerProcessFeeTest:test_nativeSurchargeEventIsEmittedOnUpdate() (gas: 36252) +FeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFee() (gas: 46898) +FeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFeeAndDiscountAndSurchargeIsSet() (gas: 70466) +FeeManagerProcessFeeTest:test_nonAdminProxyUserCannotProcessFee() (gas: 19083) +FeeManagerProcessFeeTest:test_nonAdminUserCanNotSetDiscount() (gas: 14729) +FeeManagerProcessFeeTest:test_payLinkDeficit() (gas: 176744) +FeeManagerProcessFeeTest:test_payLinkDeficitOnlyCallableByAdmin() (gas: 12412) +FeeManagerProcessFeeTest:test_payLinkDeficitPaysAllFeesProcessed() (gas: 193372) +FeeManagerProcessFeeTest:test_payLinkDeficitTwice() (gas: 179113) +FeeManagerProcessFeeTest:test_processFeeAsProxy() (gas: 105905) +FeeManagerProcessFeeTest:test_processFeeDefaultReportsStillVerifiesWithEmptyQuote() (gas: 18191) +FeeManagerProcessFeeTest:test_processFeeEmitsEventIfNotEnoughLink() (gas: 144715) +FeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 19196) +FeeManagerProcessFeeTest:test_processFeeNative() (gas: 156773) +FeeManagerProcessFeeTest:test_processFeeUsesCorrectDigest() (gas: 106864) +FeeManagerProcessFeeTest:test_processFeeWithDefaultReportPayloadAndQuoteStillVerifies() (gas: 20530) +FeeManagerProcessFeeTest:test_processFeeWithInvalidReportVersionFailsToDecode() (gas: 22030) +FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNative() (gas: 160148) +FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddress() (gas: 68000) +FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeShortFunds() (gas: 72531) +FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeWithExcessiveFee() (gas: 167132) +FeeManagerProcessFeeTest:test_processFeeWithWithCorruptQuotePayload() (gas: 19808) +FeeManagerProcessFeeTest:test_processFeeWithWithEmptyQuotePayload() (gas: 20285) +FeeManagerProcessFeeTest:test_processFeeWithWithZeroQuotePayload() (gas: 21225) +FeeManagerProcessFeeTest:test_reportWithNoExpiryOrFeeReturnsZero() (gas: 10966) +FeeManagerProcessFeeTest:test_setDiscountOver100Percent() (gas: 14453) +FeeManagerProcessFeeTest:test_subscriberDiscountEventIsEmittedOnUpdate() (gas: 41096) +FeeManagerProcessFeeTest:test_surchargeFeeRoundsUpWhenUneven() (gas: 45663) +FeeManagerProcessFeeTest:test_surchargeIsApplied() (gas: 45631) +FeeManagerProcessFeeTest:test_surchargeIsAppliedForNativeFeeWithDiscount() (gas: 71344) +FeeManagerProcessFeeTest:test_surchargeIsNoLongerAppliedAfterRemoving() (gas: 40305) +FeeManagerProcessFeeTest:test_surchargeIsNotAppliedForLinkFee() (gas: 44851) +FeeManagerProcessFeeTest:test_surchargeIsNotAppliedWith100PercentDiscount() (gas: 70842) +FeeManagerProcessFeeTest:test_testRevertIfReportHasExpired() (gas: 15287) +RewardManagerClaimTest:test_claimAllRecipients() (gas: 261746) +RewardManagerClaimTest:test_claimMultipleRecipients() (gas: 145152) +RewardManagerClaimTest:test_claimRewardsWithDuplicatPoolIdsDoesNotPayoutTwice() (gas: 311112) +RewardManagerClaimTest:test_claimSingleRecipient() (gas: 83152) +RewardManagerClaimTest:test_claimUnevenAmountRoundsDown() (gas: 296514) +RewardManagerClaimTest:test_claimUnregisteredPoolId() (gas: 33836) +RewardManagerClaimTest:test_claimUnregisteredRecipient() (gas: 35153) +RewardManagerClaimTest:test_eventIsEmittedUponClaim() (gas: 80827) +RewardManagerClaimTest:test_eventIsNotEmittedUponUnsuccessfulClaim() (gas: 24119) +RewardManagerClaimTest:test_recipientsClaimMultipleDeposits() (gas: 354497) +RewardManagerClaimTest:test_singleRecipientClaimMultipleDeposits() (gas: 125594) +RewardManagerNoRecipientSet:test_claimAllRecipientsAfterRecipientsSet() (gas: 460065) +RewardManagerPayRecipientsTest:test_addFundsToPoolAsNonOwnerOrFeeManager() (gas: 12746) +RewardManagerPayRecipientsTest:test_addFundsToPoolAsOwner() (gas: 49476) +RewardManagerPayRecipientsTest:test_payAllRecipients() (gas: 243950) +RewardManagerPayRecipientsTest:test_payAllRecipientsFromNonAdminUser() (gas: 15490) +RewardManagerPayRecipientsTest:test_payAllRecipientsFromRecipientInPool() (gas: 244240) +RewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalInvalidRecipient() (gas: 255332) +RewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalUnregisteredRecipient() (gas: 258494) +RewardManagerPayRecipientsTest:test_payRecipientWithInvalidPool() (gas: 28014) +RewardManagerPayRecipientsTest:test_payRecipientsEmptyRecipientList() (gas: 19996) +RewardManagerPayRecipientsTest:test_payRecipientsWithInvalidPoolId() (gas: 43841) +RewardManagerPayRecipientsTest:test_paySingleRecipient() (gas: 79278) +RewardManagerPayRecipientsTest:test_paySubsetOfRecipientsInPool() (gas: 192105) +RewardManagerRecipientClaimDifferentWeightsTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 264807) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsMultiplePools() (gas: 484691) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsSinglePool() (gas: 267815) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimEmptyPoolWhenSecondPoolContainsFunds() (gas: 274756) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsMultiplePools() (gas: 247842) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsSinglePool() (gas: 145214) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleRecipientMultiplePools() (gas: 124215) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleUniqueRecipient() (gas: 97656) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimUnevenAmountRoundsDown() (gas: 542551) +RewardManagerRecipientClaimMultiplePoolsTest:test_claimUnregisteredRecipient() (gas: 55393) +RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInBothPools() (gas: 24031) +RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInNoPools() (gas: 18192) +RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInSinglePool() (gas: 21793) +RewardManagerRecipientClaimMultiplePoolsTest:test_recipientsClaimMultipleDeposits() (gas: 358947) +RewardManagerRecipientClaimMultiplePoolsTest:test_singleRecipientClaimMultipleDeposits() (gas: 125610) +RewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 187397) +RewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmountWithSmallDeposit() (gas: 207289) +RewardManagerSetRecipientsTest:test_eventIsEmittedUponSetRecipients() (gas: 185494) +RewardManagerSetRecipientsTest:test_setRecipientContainsDuplicateRecipients() (gas: 117290) +RewardManagerSetRecipientsTest:test_setRewardRecipientFromManagerAddress() (gas: 185271) +RewardManagerSetRecipientsTest:test_setRewardRecipientFromNonOwnerOrFeeManagerAddress() (gas: 16348) +RewardManagerSetRecipientsTest:test_setRewardRecipientTwice() (gas: 184667) +RewardManagerSetRecipientsTest:test_setRewardRecipientWeights() (gas: 174935) +RewardManagerSetRecipientsTest:test_setRewardRecipientWithZeroAddress() (gas: 84821) +RewardManagerSetRecipientsTest:test_setRewardRecipientWithZeroWeight() (gas: 177469) +RewardManagerSetRecipientsTest:test_setRewardRecipients() (gas: 179469) +RewardManagerSetRecipientsTest:test_setRewardRecipientsIsEmpty() (gas: 82005) +RewardManagerSetRecipientsTest:test_setSingleRewardRecipient() (gas: 105112) +RewardManagerSetupTest:test_eventEmittedUponFeeManagerUpdate() (gas: 16365) +RewardManagerSetupTest:test_eventEmittedUponFeePaid() (gas: 251334) +RewardManagerSetupTest:test_rejectsZeroLinkAddressOnConstruction() (gas: 59237) +RewardManagerSetupTest:test_setFeeManagerZeroAddress() (gas: 12015) +RewardManagerUpdateRewardRecipientsMultiplePoolsTest:test_updatePrimaryRecipientWeights() (gas: 351585) +RewardManagerUpdateRewardRecipientsTest:test_eventIsEmittedUponUpdateRecipients() (gas: 271069) +RewardManagerUpdateRewardRecipientsTest:test_onlyAdminCanUpdateRecipients() (gas: 14622) +RewardManagerUpdateRewardRecipientsTest:test_partialUpdateRecipientWeights() (gas: 202980) +RewardManagerUpdateRewardRecipientsTest:test_updateAllRecipientsWithSameAddressAndWeight() (gas: 265007) +RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsToSubset() (gas: 239393) +RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithExcessiveWeight() (gas: 252954) +RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithSameAddressAndWeight() (gas: 143091) +RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithUnderWeightSet() (gas: 253019) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientWeights() (gas: 347067) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientWithNewZeroAddress() (gas: 251680) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsContainsDuplicateRecipients() (gas: 278976) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentLargerSet() (gas: 254184) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentPartialSet() (gas: 252404) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSet() (gas: 253625) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSetWithInvalidWeights() (gas: 252514) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForLargerSet() (gas: 245636) +RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForSmallerSet() (gas: 243962) +VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_correctlyRemovesAMiddleDigest() (gas: 24221) +VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_correctlyRemovesTheFirstDigest() (gas: 24188) +VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_correctlyUnsetsDigestsInSequence() (gas: 44250) +VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_revertsIfCalledByNonOwner() (gas: 11300) +VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_revertsIfRemovingAnEmptyDigest() (gas: 10929) +VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_revertsIfRemovingAnNonExistentDigest() (gas: 13403) +VerifierActivateConfigTest:test_revertsIfDigestIsEmpty() (gas: 10939) +VerifierActivateConfigTest:test_revertsIfDigestNotSet() (gas: 13371) +VerifierActivateConfigTest:test_revertsIfNotOwner() (gas: 13410) +VerifierActivateConfigWithDeactivatedConfigTest:test_allowsVerification() (gas: 93459) +VerifierActivateFeedTest:test_revertsIfNoFeedExistsActivate() (gas: 13179) +VerifierActivateFeedTest:test_revertsIfNoFeedExistsDeactivate() (gas: 13179) +VerifierActivateFeedTest:test_revertsIfNotOwnerActivateFeed() (gas: 13360) +VerifierActivateFeedTest:test_revertsIfNotOwnerDeactivateFeed() (gas: 13437) +VerifierConstructorTest:test_revertsIfInitializedWithEmptyVerifierProxy() (gas: 59939) +VerifierConstructorTest:test_setsTheCorrectProperties() (gas: 1785046) +VerifierDeactivateFeedWithVerifyTest:test_currentReportAllowsVerification() (gas: 188309) +VerifierDeactivateFeedWithVerifyTest:test_currentReportFailsVerification() (gas: 109640) +VerifierDeactivateFeedWithVerifyTest:test_previousReportAllowsVerification() (gas: 95886) +VerifierDeactivateFeedWithVerifyTest:test_previousReportFailsVerification() (gas: 66198) +VerifierProxyAccessControlledVerificationTest:test_proxiesToTheVerifierIfHasAccess() (gas: 203049) +VerifierProxyAccessControlledVerificationTest:test_revertsIfNoAccess() (gas: 105809) +VerifierProxyConstructorTest:test_correctlySetsTheCorrectAccessControllerInterface() (gas: 1073832) +VerifierProxyConstructorTest:test_correctlySetsTheOwner() (gas: 1053935) +VerifierProxyConstructorTest:test_correctlySetsVersion() (gas: 6939) +VerifierProxyInitializeVerifierTest:test_revertsIfDigestAlreadySet() (gas: 50301) +VerifierProxyInitializeVerifierTest:test_revertsIfNotCorrectVerifier() (gas: 13573) +VerifierProxyInitializeVerifierTest:test_revertsIfNotOwner() (gas: 13375) +VerifierProxyInitializeVerifierTest:test_revertsIfVerifierAlreadyInitialized() (gas: 41915) +VerifierProxyInitializeVerifierTest:test_revertsIfZeroAddress() (gas: 10904) +VerifierProxyInitializeVerifierTest:test_setFeeManagerZeroAddress() (gas: 10913) +VerifierProxyInitializeVerifierTest:test_updatesVerifierIfVerifier() (gas: 49628) +VerifierProxySetAccessControllerTest:test_emitsTheCorrectEvent() (gas: 35384) +VerifierProxySetAccessControllerTest:test_revertsIfCalledByNonOwner() (gas: 11367) +VerifierProxySetAccessControllerTest:test_successfullySetsNewAccessController() (gas: 32075) +VerifierProxySetAccessControllerTest:test_successfullySetsNewAccessControllerIsEmpty() (gas: 12174) +VerifierProxyUnsetVerifierTest:test_revertsIfDigestDoesNotExist() (gas: 13174) +VerifierProxyUnsetVerifierTest:test_revertsIfNotAdmin() (gas: 11249) +VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest:test_correctlyUnsetsVerifier() (gas: 12719) +VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest:test_emitsAnEventAfterUnsettingVerifier() (gas: 17965) +VerifierProxyVerifyTest:test_proxiesToTheCorrectVerifier() (gas: 200395) +VerifierProxyVerifyTest:test_revertsIfNoVerifierConfigured() (gas: 108443) +VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlySetsConfigWhenDigestsAreRemoved() (gas: 538606) +VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() (gas: 964141) +VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlyUpdatesTheDigestInTheProxy() (gas: 520142) +VerifierSetConfigFromSourceTest:test_revertsIfCalledByNonOwner() (gas: 179332) +VerifierSetConfigTest:test_correctlyUpdatesTheConfig() (gas: 1057626) +VerifierSetConfigTest:test_revertsIfCalledByNonOwner() (gas: 179223) +VerifierSetConfigTest:test_revertsIfDuplicateSigners() (gas: 251573) +VerifierSetConfigTest:test_revertsIfFaultToleranceIsZero() (gas: 176522) +VerifierSetConfigTest:test_revertsIfNotEnoughSigners() (gas: 15814) +VerifierSetConfigTest:test_revertsIfSetWithTooManySigners() (gas: 22170) +VerifierSetConfigTest:test_revertsIfSignerContainsZeroAddress() (gas: 228003) +VerifierSetConfigWhenThereAreMultipleDigestsTest:test_correctlySetsConfigWhenDigestsAreRemoved() (gas: 538415) +VerifierSetConfigWhenThereAreMultipleDigestsTest:test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() (gas: 963754) +VerifierSetConfigWhenThereAreMultipleDigestsTest:test_correctlyUpdatesTheDigestInTheProxy() (gas: 519945) +VerifierSupportsInterfaceTest:test_falseIfIsNotCorrectInterface() (gas: 5590) +VerifierSupportsInterfaceTest:test_trueIfIsCorrectInterface() (gas: 5611) +VerifierTestBillingReport:test_verifyWithLink() (gas: 274848) +VerifierTestBillingReport:test_verifyWithNative() (gas: 275476) +VerifierTestBillingReport:test_verifyWithNativeUnwrapped() (gas: 285450) +VerifierTestBillingReport:test_verifyWithNativeUnwrappedReturnsChange() (gas: 292517) +VerifierVerifyMultipleConfigDigestTest:test_canVerifyNewerReportsWithNewerConfigs() (gas: 127500) +VerifierVerifyMultipleConfigDigestTest:test_canVerifyOlderReportsWithOlderConfigs() (gas: 183379) +VerifierVerifyMultipleConfigDigestTest:test_revertsIfAReportIsVerifiedWithAnExistingButIncorrectDigest() (gas: 84470) +VerifierVerifyMultipleConfigDigestTest:test_revertsIfVerifyingWithAnUnsetDigest() (gas: 124347) +VerifierVerifySingleConfigDigestTest:test_emitsAnEventIfReportVerified() (gas: 183237) +VerifierVerifySingleConfigDigestTest:test_returnsThePriceAndBlockNumIfReportVerified() (gas: 183406) +VerifierVerifySingleConfigDigestTest:test_revertsIfConfigDigestNotSet() (gas: 112459) +VerifierVerifySingleConfigDigestTest:test_revertsIfDuplicateSignersHaveSigned() (gas: 178601) +VerifierVerifySingleConfigDigestTest:test_revertsIfMismatchedSignatureLength() (gas: 49278) +VerifierVerifySingleConfigDigestTest:test_revertsIfReportHasUnconfiguredFeedID() (gas: 100262) +VerifierVerifySingleConfigDigestTest:test_revertsIfVerifiedByNonProxy() (gas: 101024) +VerifierVerifySingleConfigDigestTest:test_revertsIfVerifiedWithIncorrectAddresses() (gas: 180352) +VerifierVerifySingleConfigDigestTest:test_revertsIfWrongNumberOfSigners() (gas: 106317) +VerifierVerifySingleConfigDigestTest:test_setsTheCorrectEpoch() (gas: 190539) +Verifier_accessControlledVerify:testVerifyWithAccessControl_gas() (gas: 207063) +Verifier_setConfig:testSetConfigSuccess_gas() (gas: 922408) +Verifier_verify:testVerifyProxySuccess_gas() (gas: 197508) +Verifier_verify:testVerifySuccess_gas() (gas: 182991) +Verifier_verifyWithFee:testVerifyProxyWithLinkFeeSuccess_gas() (gas: 246271) +Verifier_verifyWithFee:testVerifyProxyWithNativeFeeSuccess_gas() (gas: 263976) \ No newline at end of file diff --git a/contracts/gas-snapshots/shared.gas-snapshot b/contracts/gas-snapshots/shared.gas-snapshot new file mode 100644 index 00000000000..cb2e8defe4a --- /dev/null +++ b/contracts/gas-snapshots/shared.gas-snapshot @@ -0,0 +1,32 @@ +BurnMintERC677_approve:testApproveSuccess() (gas: 52254) +BurnMintERC677_approve:testInvalidAddressReverts() (gas: 10641) +BurnMintERC677_burn:testBasicBurnSuccess() (gas: 164344) +BurnMintERC677_burn:testBurnFromZeroAddressReverts() (gas: 43462) +BurnMintERC677_burn:testExceedsBalanceReverts() (gas: 18035) +BurnMintERC677_burn:testSenderNotBurnerReverts() (gas: 13359) +BurnMintERC677_burnFrom:testBurnFromSuccess() (gas: 54662) +BurnMintERC677_burnFrom:testExceedsBalanceReverts() (gas: 32873) +BurnMintERC677_burnFrom:testInsufficientAllowanceReverts() (gas: 18107) +BurnMintERC677_burnFrom:testSenderNotBurnerReverts() (gas: 13359) +BurnMintERC677_burnFromAlias:testBurnFromSuccess() (gas: 54688) +BurnMintERC677_burnFromAlias:testExceedsBalanceReverts() (gas: 32889) +BurnMintERC677_burnFromAlias:testInsufficientAllowanceReverts() (gas: 18127) +BurnMintERC677_burnFromAlias:testSenderNotBurnerReverts() (gas: 13379) +BurnMintERC677_constructor:testConstructorSuccess() (gas: 1669109) +BurnMintERC677_decreaseApproval:testDecreaseApprovalSuccess() (gas: 28520) +BurnMintERC677_grantMintAndBurnRoles:testGrantMintAndBurnRolesSuccess() (gas: 120049) +BurnMintERC677_grantRole:testGrantBurnAccessSuccess() (gas: 52707) +BurnMintERC677_grantRole:testGrantManySuccess() (gas: 935521) +BurnMintERC677_grantRole:testGrantMintAccessSuccess() (gas: 93588) +BurnMintERC677_increaseApproval:testIncreaseApprovalSuccess() (gas: 40911) +BurnMintERC677_mint:testBasicMintSuccess() (gas: 149365) +BurnMintERC677_mint:testMaxSupplyExceededReverts() (gas: 46627) +BurnMintERC677_mint:testSenderNotMinterReverts() (gas: 11195) +BurnMintERC677_supportsInterface:testConstructorSuccess() (gas: 8685) +BurnMintERC677_transfer:testInvalidAddressReverts() (gas: 10617) +BurnMintERC677_transfer:testTransferSuccess() (gas: 39462) +OpStackBurnMintERC677_constructor:testConstructorSuccess() (gas: 1739317) +OpStackBurnMintERC677_interfaceCompatibility:testBurnCompatibility() (gas: 259440) +OpStackBurnMintERC677_interfaceCompatibility:testMintCompatibility() (gas: 137935) +OpStackBurnMintERC677_interfaceCompatibility:testStaticFunctionsCompatibility() (gas: 10622) +OpStackBurnMintERC677_supportsInterface:testConstructorSuccess() (gas: 8961) \ No newline at end of file diff --git a/contracts/gas-snapshots/vrf.gas-snapshot b/contracts/gas-snapshots/vrf.gas-snapshot new file mode 100644 index 00000000000..637a0edf963 --- /dev/null +++ b/contracts/gas-snapshots/vrf.gas-snapshot @@ -0,0 +1,15 @@ +TrustedBlockhashStoreTest:testGenericBHSFunctions() (gas: 53507) +TrustedBlockhashStoreTest:testTrustedBHSFunctions() (gas: 49536) +VRFCoordinatorV2Plus_Migration:testDeregister() (gas: 99368) +VRFCoordinatorV2Plus_Migration:testMigrateRevertsWhenInvalidCaller() (gas: 27234) +VRFCoordinatorV2Plus_Migration:testMigrateRevertsWhenInvalidCoordinator() (gas: 17734) +VRFCoordinatorV2Plus_Migration:testMigrateRevertsWhenPendingFulfillment() (gas: 237536) +VRFCoordinatorV2Plus_Migration:testMigration() (gas: 468424) +VRFV2Plus:testCreateSubscription() (gas: 181121) +VRFV2Plus:testGetActiveSubscriptionIds() (gas: 3465607) +VRFV2Plus:testRegisterProvingKey() (gas: 101019) +VRFV2Plus:testRequestAndFulfillRandomWordsLINK() (gas: 755125) +VRFV2Plus:testRequestAndFulfillRandomWordsNative() (gas: 705549) +VRFV2Plus:testSetConfig() (gas: 73057) +VRFV2PlusWrapperTest:testRequestAndFulfillRandomWordsLINKWrapper() (gas: 390063) +VRFV2PlusWrapperTest:testRequestAndFulfillRandomWordsNativeWrapper() (gas: 290612) \ No newline at end of file diff --git a/contracts/pnpm-lock.yaml b/contracts/pnpm-lock.yaml index 2d3185ed893..da673532152 100644 --- a/contracts/pnpm-lock.yaml +++ b/contracts/pnpm-lock.yaml @@ -1,133 +1,187 @@ -lockfileVersion: 5.4 +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false overrides: '@ethersproject/logger': 5.0.6 -specifiers: - '@eth-optimism/contracts': ^0.5.21 - '@ethereum-waffle/mock-contract': ^3.3.0 - '@ethersproject/abi': ~5.6.0 - '@ethersproject/bignumber': ~5.6.0 - '@ethersproject/contracts': ~5.6.0 - '@ethersproject/providers': ~5.6.1 - '@ethersproject/random': ~5.6.0 - '@nomicfoundation/hardhat-network-helpers': ^1.0.8 - '@nomiclabs/hardhat-ethers': ^2.0.2 - '@nomiclabs/hardhat-etherscan': ^3.1.0 - '@nomiclabs/hardhat-waffle': ^2.0.1 - '@openzeppelin/contracts': ~4.3.3 - '@openzeppelin/contracts-upgradeable-4.7.3': npm:@openzeppelin/contracts-upgradeable@v4.7.3 - '@openzeppelin/contracts-v0.7': npm:@openzeppelin/contracts@v3.4.2 - '@openzeppelin/hardhat-upgrades': 1.22.1 - '@openzeppelin/test-helpers': ^0.5.11 - '@typechain/ethers-v5': ^7.0.1 - '@typechain/hardhat': ^3.0.0 - '@types/cbor': 5.0.1 - '@types/chai': ^4.2.18 - '@types/debug': ^4.1.7 - '@types/deep-equal-in-any-order': ^1.0.1 - '@types/mocha': ^8.2.2 - '@types/node': ^15.12.2 - '@typescript-eslint/eslint-plugin': ^5.59.5 - '@typescript-eslint/parser': ^5.59.5 - abi-to-sol: ^0.6.6 - chai: ^4.3.4 - debug: ^4.3.2 - deep-equal-in-any-order: ^2.0.6 - eslint: ^8.40.0 - eslint-config-prettier: ^8.8.0 - eslint-plugin-prettier: ^4.2.1 - ethereum-waffle: ^3.3.0 - ethers: ~5.6.0 - hardhat: ~2.12.7 - hardhat-abi-exporter: ^2.2.1 - hardhat-contract-sizer: ^2.5.1 - hardhat-gas-reporter: ^1.0.9 - hardhat-ignore-warnings: ^0.2.6 - istanbul: ^0.4.5 - moment: ^2.29.4 - prettier: ^2.8.8 - prettier-plugin-solidity: 1.1.3 - rlp: ^2.0.0 - solhint: ^3.4.1 - solhint-plugin-prettier: ^0.0.5 - solidity-coverage: ^0.8.4 - ts-node: ^10.0.0 - tslib: ^2.4.0 - typechain: ^8.0.0 - typescript: ^4.3.2 - dependencies: - '@eth-optimism/contracts': 0.5.37_ethers@5.6.1 - '@openzeppelin/contracts': 4.3.3 - '@openzeppelin/contracts-upgradeable-4.7.3': /@openzeppelin/contracts-upgradeable/4.7.3 - '@openzeppelin/contracts-v0.7': /@openzeppelin/contracts/3.4.2 + '@eth-optimism/contracts': + specifier: ^0.5.21 + version: 0.5.37(ethers@5.6.1) + '@openzeppelin/contracts': + specifier: ~4.3.3 + version: 4.3.3 + '@openzeppelin/contracts-upgradeable-4.7.3': + specifier: npm:@openzeppelin/contracts-upgradeable@v4.7.3 + version: /@openzeppelin/contracts-upgradeable@4.7.3 + '@openzeppelin/contracts-v0.7': + specifier: npm:@openzeppelin/contracts@v3.4.2 + version: /@openzeppelin/contracts@3.4.2 devDependencies: - '@ethereum-waffle/mock-contract': 3.4.4 - '@ethersproject/abi': 5.6.1 - '@ethersproject/bignumber': 5.6.1 - '@ethersproject/contracts': 5.6.1 - '@ethersproject/providers': 5.6.1 - '@ethersproject/random': 5.6.1 - '@nomicfoundation/hardhat-network-helpers': 1.0.8_hardhat@2.12.7 - '@nomiclabs/hardhat-ethers': 2.0.2_z6fcyyhc2nf3iwqkyspxr4tlaq - '@nomiclabs/hardhat-etherscan': 3.1.0_hardhat@2.12.7 - '@nomiclabs/hardhat-waffle': 2.0.1_d7ejcwiim3eoh3awwn3s5bqjfe - '@openzeppelin/hardhat-upgrades': 1.22.1_t427xxny5pzfvmqb7mxuxbqor4 - '@openzeppelin/test-helpers': 0.5.11_bn.js@4.12.0 - '@typechain/ethers-v5': 7.2.0_pwtfr6mt5pw2hiixtkqheirqmq - '@typechain/hardhat': 3.1.0_gx5th54lc6trgzrpj7pwublyoa - '@types/cbor': 5.0.1 - '@types/chai': 4.3.3 - '@types/debug': 4.1.7 - '@types/deep-equal-in-any-order': 1.0.1 - '@types/mocha': 8.2.2 - '@types/node': 15.14.9 - '@typescript-eslint/eslint-plugin': 5.59.8_loqfnwogukjtmydbmg57mzzpb4 - '@typescript-eslint/parser': 5.59.8_kigkzfftsmftz3xok324pyvzui - abi-to-sol: 0.6.6 - chai: 4.3.6 - debug: 4.3.4 - deep-equal-in-any-order: 2.0.6 - eslint: 8.42.0 - eslint-config-prettier: 8.8.0_eslint@8.42.0 - eslint-plugin-prettier: 4.2.1_vnriwwub2rhvoyn4ckagrc4lpi - ethereum-waffle: 3.3.0_typescript@4.9.5 - ethers: 5.6.1 - hardhat: 2.12.7_goz53koj4ourpjwgrks4nqbe6i - hardhat-abi-exporter: 2.2.1_hardhat@2.12.7 - hardhat-contract-sizer: 2.5.1_hardhat@2.12.7 - hardhat-gas-reporter: 1.0.9_hardhat@2.12.7 - hardhat-ignore-warnings: 0.2.9 - istanbul: 0.4.5 - moment: 2.29.4 - prettier: 2.8.8 - prettier-plugin-solidity: 1.1.3_prettier@2.8.8 - rlp: 2.2.7 - solhint: 3.4.1 - solhint-plugin-prettier: 0.0.5_x46sgpbsioqs6smmgnper2ntba - solidity-coverage: 0.8.4_hardhat@2.12.7 - ts-node: 10.0.0_zlol4fzmmjgb3bdeviopae4asm - tslib: 2.4.0 - typechain: 8.2.0_typescript@4.9.5 - typescript: 4.9.5 + '@ethereum-waffle/mock-contract': + specifier: ^3.3.0 + version: 3.4.4 + '@ethersproject/abi': + specifier: ~5.6.0 + version: 5.6.1 + '@ethersproject/bignumber': + specifier: ~5.6.0 + version: 5.6.1 + '@ethersproject/contracts': + specifier: ~5.6.0 + version: 5.6.1 + '@ethersproject/providers': + specifier: ~5.6.1 + version: 5.6.1 + '@ethersproject/random': + specifier: ~5.6.0 + version: 5.6.1 + '@nomicfoundation/hardhat-network-helpers': + specifier: ^1.0.8 + version: 1.0.8(hardhat@2.12.7) + '@nomiclabs/hardhat-ethers': + specifier: ^2.0.2 + version: 2.0.2(ethers@5.6.1)(hardhat@2.12.7) + '@nomiclabs/hardhat-etherscan': + specifier: ^3.1.0 + version: 3.1.0(hardhat@2.12.7) + '@nomiclabs/hardhat-waffle': + specifier: ^2.0.1 + version: 2.0.1(@nomiclabs/hardhat-ethers@2.0.2)(ethereum-waffle@3.3.0)(ethers@5.6.1)(hardhat@2.12.7) + '@openzeppelin/hardhat-upgrades': + specifier: 1.22.1 + version: 1.22.1(@nomiclabs/hardhat-ethers@2.0.2)(@nomiclabs/hardhat-etherscan@3.1.0)(ethers@5.6.1)(hardhat@2.12.7) + '@openzeppelin/test-helpers': + specifier: ^0.5.11 + version: 0.5.11(bn.js@4.12.0) + '@typechain/ethers-v5': + specifier: ^7.0.1 + version: 7.2.0(@ethersproject/abi@5.6.1)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.6.1)(ethers@5.6.1)(typechain@8.2.0)(typescript@4.9.5) + '@typechain/hardhat': + specifier: ^3.0.0 + version: 3.1.0(hardhat@2.12.7)(lodash@4.17.21)(typechain@8.2.0) + '@types/cbor': + specifier: 5.0.1 + version: 5.0.1 + '@types/chai': + specifier: ^4.2.18 + version: 4.3.3 + '@types/debug': + specifier: ^4.1.7 + version: 4.1.7 + '@types/deep-equal-in-any-order': + specifier: ^1.0.1 + version: 1.0.1 + '@types/mocha': + specifier: ^8.2.2 + version: 8.2.2 + '@types/node': + specifier: ^15.12.2 + version: 15.14.9 + '@typescript-eslint/eslint-plugin': + specifier: ^5.59.5 + version: 5.59.8(@typescript-eslint/parser@5.59.8)(eslint@8.42.0)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: ^5.59.5 + version: 5.59.8(eslint@8.42.0)(typescript@4.9.5) + abi-to-sol: + specifier: ^0.6.6 + version: 0.6.6 + chai: + specifier: ^4.3.4 + version: 4.3.6 + debug: + specifier: ^4.3.2 + version: 4.3.4(supports-color@8.1.1) + deep-equal-in-any-order: + specifier: ^2.0.6 + version: 2.0.6 + eslint: + specifier: ^8.40.0 + version: 8.42.0 + eslint-config-prettier: + specifier: ^8.8.0 + version: 8.8.0(eslint@8.42.0) + eslint-plugin-prettier: + specifier: ^4.2.1 + version: 4.2.1(eslint-config-prettier@8.8.0)(eslint@8.42.0)(prettier@2.8.8) + ethereum-waffle: + specifier: ^3.3.0 + version: 3.3.0(typescript@4.9.5) + ethers: + specifier: ~5.6.0 + version: 5.6.1 + hardhat: + specifier: ~2.12.7 + version: 2.12.7(ts-node@10.0.0)(typescript@4.9.5) + hardhat-abi-exporter: + specifier: ^2.2.1 + version: 2.2.1(hardhat@2.12.7) + hardhat-contract-sizer: + specifier: ^2.5.1 + version: 2.5.1(hardhat@2.12.7) + hardhat-gas-reporter: + specifier: ^1.0.9 + version: 1.0.9(hardhat@2.12.7) + hardhat-ignore-warnings: + specifier: ^0.2.6 + version: 0.2.9 + istanbul: + specifier: ^0.4.5 + version: 0.4.5 + moment: + specifier: ^2.29.4 + version: 2.29.4 + prettier: + specifier: ^2.8.8 + version: 2.8.8 + prettier-plugin-solidity: + specifier: 1.1.3 + version: 1.1.3(prettier@2.8.8) + rlp: + specifier: ^2.0.0 + version: 2.2.7 + solhint: + specifier: ^3.4.1 + version: 3.4.1 + solhint-plugin-prettier: + specifier: ^0.0.5 + version: 0.0.5(prettier-plugin-solidity@1.1.3)(prettier@2.8.8) + solidity-coverage: + specifier: ^0.8.4 + version: 0.8.4(hardhat@2.12.7) + ts-node: + specifier: ^10.0.0 + version: 10.0.0(@types/node@15.14.9)(typescript@4.9.5) + tslib: + specifier: ^2.4.0 + version: 2.4.0 + typechain: + specifier: ^8.0.0 + version: 8.2.0(typescript@4.9.5) + typescript: + specifier: ^4.3.2 + version: 4.9.5 packages: - /@babel/code-frame/7.18.6: + /@babel/code-frame@7.18.6: resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} engines: {node: '>=6.9.0'} dependencies: '@babel/highlight': 7.18.6 dev: true - /@babel/helper-validator-identifier/7.19.1: + /@babel/helper-validator-identifier@7.19.1: resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} engines: {node: '>=6.9.0'} dev: true - /@babel/highlight/7.18.6: + /@babel/highlight@7.18.6: resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} engines: {node: '>=6.9.0'} dependencies: @@ -136,21 +190,21 @@ packages: js-tokens: 4.0.0 dev: true - /@babel/runtime/7.19.0: + /@babel/runtime@7.19.0: resolution: {integrity: sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==} engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.13.9 dev: true - /@colors/colors/1.5.0: + /@colors/colors@1.5.0: resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} requiresBuild: true dev: true optional: true - /@ensdomains/address-encoder/0.1.9: + /@ensdomains/address-encoder@0.1.9: resolution: {integrity: sha512-E2d2gP4uxJQnDu2Kfg1tHNspefzbLT8Tyjrm5sEuim32UkU2sm5xL4VXtgc2X33fmPEw9+jUMpGs4veMbf+PYg==} dependencies: bech32: 1.1.4 @@ -162,7 +216,7 @@ packages: ripemd160: 2.0.2 dev: true - /@ensdomains/ens/0.4.5: + /@ensdomains/ens@0.4.5: resolution: {integrity: sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==} deprecated: Please use @ensdomains/ens-contracts dependencies: @@ -173,7 +227,7 @@ packages: web3-utils: 1.8.0 dev: true - /@ensdomains/ensjs/2.1.0: + /@ensdomains/ensjs@2.1.0: resolution: {integrity: sha512-GRbGPT8Z/OJMDuxs75U/jUNEC0tbL0aj7/L/QQznGYKm/tiasp+ndLOaoULy9kKJFC0TBByqfFliEHDgoLhyog==} dependencies: '@babel/runtime': 7.19.0 @@ -189,12 +243,12 @@ packages: - utf-8-validate dev: true - /@ensdomains/resolver/0.2.4: + /@ensdomains/resolver@0.2.4: resolution: {integrity: sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==} deprecated: Please use @ensdomains/ens-contracts dev: true - /@eslint-community/eslint-utils/4.4.0_eslint@8.42.0: + /@eslint-community/eslint-utils@4.4.0(eslint@8.42.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -204,17 +258,17 @@ packages: eslint-visitor-keys: 3.4.1 dev: true - /@eslint-community/regexpp/4.5.1: + /@eslint-community/regexpp@4.5.1: resolution: {integrity: sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true - /@eslint/eslintrc/2.0.3: + /@eslint/eslintrc@2.0.3: resolution: {integrity: sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) espree: 9.5.2 globals: 13.20.0 ignore: 5.2.4 @@ -226,12 +280,12 @@ packages: - supports-color dev: true - /@eslint/js/8.42.0: + /@eslint/js@8.42.0: resolution: {integrity: sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@eth-optimism/contracts/0.5.37_ethers@5.6.1: + /@eth-optimism/contracts@0.5.37(ethers@5.6.1): resolution: {integrity: sha512-HbNUUDIM1dUAM0hWPfGp3l9/Zte40zi8QhVbUSIwdYRA7jG7cZgbteqavrjW8wwFqxkWX9IrtA0KAR7pNlSAIQ==} peerDependencies: ethers: ^5 @@ -245,7 +299,7 @@ packages: - utf-8-validate dev: false - /@eth-optimism/core-utils/0.10.1: + /@eth-optimism/core-utils@0.10.1: resolution: {integrity: sha512-IJvG5UtYvyz6An9QdohlCLoeB3NBFxx2lRJKlPzvYYlfugUNNCHsajRIWIwJTcPRRma0WPd46JUsKACLJDdNrA==} dependencies: '@ethersproject/abi': 5.7.0 @@ -269,7 +323,7 @@ packages: - utf-8-validate dev: false - /@ethereum-waffle/chai/3.4.4: + /@ethereum-waffle/chai@3.4.4: resolution: {integrity: sha512-/K8czydBtXXkcM9X6q29EqEkc5dN3oYenyH2a9hF7rGAApAJUpH8QBtojxOY/xQ2up5W332jqgxwp0yPiYug1g==} engines: {node: '>=10.0'} dependencies: @@ -282,13 +336,13 @@ packages: - utf-8-validate dev: true - /@ethereum-waffle/compiler/3.4.4_typescript@4.9.5: + /@ethereum-waffle/compiler@3.4.4(typescript@4.9.5): resolution: {integrity: sha512-RUK3axJ8IkD5xpWjWoJgyHclOeEzDLQFga6gKpeGxiS/zBu+HB0W2FvsrrLalTFIaPw/CGYACRBSIxqiCqwqTQ==} engines: {node: '>=10.0'} dependencies: '@resolver-engine/imports': 0.3.3 '@resolver-engine/imports-fs': 0.3.3 - '@typechain/ethers-v5': 2.0.0_mwhxf3vrorrl5yk6tbvkb5vxk4 + '@typechain/ethers-v5': 2.0.0(ethers@5.6.1)(typechain@3.0.0) '@types/mkdirp': 0.5.2 '@types/node-fetch': 2.6.2 ethers: 5.6.1 @@ -296,7 +350,7 @@ packages: node-fetch: 2.6.7 solc: 0.6.12 ts-generator: 0.1.1 - typechain: 3.0.0_typescript@4.9.5 + typechain: 3.0.0(typescript@4.9.5) transitivePeerDependencies: - bufferutil - encoding @@ -305,7 +359,7 @@ packages: - utf-8-validate dev: true - /@ethereum-waffle/ens/3.4.4: + /@ethereum-waffle/ens@3.4.4: resolution: {integrity: sha512-0m4NdwWxliy3heBYva1Wr4WbJKLnwXizmy5FfSSr5PMbjI7SIGCdCB59U7/ZzY773/hY3bLnzLwvG5mggVjJWg==} engines: {node: '>=10.0'} dependencies: @@ -317,7 +371,7 @@ packages: - utf-8-validate dev: true - /@ethereum-waffle/mock-contract/3.4.4: + /@ethereum-waffle/mock-contract@3.4.4: resolution: {integrity: sha512-Mp0iB2YNWYGUV+VMl5tjPsaXKbKo8MDH9wSJ702l9EBjdxFf/vBvnMBAC1Fub1lLtmD0JHtp1pq+mWzg/xlLnA==} engines: {node: '>=10.0'} dependencies: @@ -328,7 +382,7 @@ packages: - utf-8-validate dev: true - /@ethereum-waffle/provider/3.4.4: + /@ethereum-waffle/provider@3.4.4: resolution: {integrity: sha512-GK8oKJAM8+PKy2nK08yDgl4A80mFuI8zBkE0C9GqTRYQqvuxIyXoLmJ5NZU9lIwyWVv5/KsoA11BgAv2jXE82g==} engines: {node: '>=10.0'} dependencies: @@ -344,22 +398,23 @@ packages: - utf-8-validate dev: true - /@ethereumjs/common/2.6.5: + /@ethereumjs/common@2.6.5: resolution: {integrity: sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==} dependencies: crc-32: 1.2.2 ethereumjs-util: 7.1.5 dev: true - /@ethereumjs/tx/3.5.2: + /@ethereumjs/tx@3.5.2: resolution: {integrity: sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==} dependencies: '@ethereumjs/common': 2.6.5 ethereumjs-util: 7.1.5 dev: true - /@ethersproject/abi/5.0.0-beta.153: + /@ethersproject/abi@5.0.0-beta.153: resolution: {integrity: sha512-aXweZ1Z7vMNzJdLpR1CZUAIgnwjrZeUSvN9syCwlBaEBUFJmFY+HHnfuTI5vIhVs/mRkfJVrbEyl51JZQqyjAg==} + requiresBuild: true dependencies: '@ethersproject/address': 5.7.0 '@ethersproject/bignumber': 5.7.0 @@ -373,7 +428,7 @@ packages: dev: true optional: true - /@ethersproject/abi/5.6.0: + /@ethersproject/abi@5.6.0: resolution: {integrity: sha512-AhVByTwdXCc2YQ20v300w6KVHle9g2OFc28ZAFCPnJyEpkv1xKXjZcSTgWOlv1i+0dqlgF8RCF2Rn2KC1t+1Vg==} dependencies: '@ethersproject/address': 5.7.0 @@ -386,7 +441,7 @@ packages: '@ethersproject/properties': 5.7.0 '@ethersproject/strings': 5.7.0 - /@ethersproject/abi/5.6.1: + /@ethersproject/abi@5.6.1: resolution: {integrity: sha512-0cqssYh6FXjlwKWBmLm3+zH2BNARoS5u/hxbz+LpQmcDB3w0W553h2btWui1/uZp2GBM/SI3KniTuMcYyHpA5w==} dependencies: '@ethersproject/address': 5.7.0 @@ -400,7 +455,7 @@ packages: '@ethersproject/strings': 5.7.0 dev: true - /@ethersproject/abi/5.7.0: + /@ethersproject/abi@5.7.0: resolution: {integrity: sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==} dependencies: '@ethersproject/address': 5.7.0 @@ -413,7 +468,7 @@ packages: '@ethersproject/properties': 5.7.0 '@ethersproject/strings': 5.7.0 - /@ethersproject/abstract-provider/5.6.0: + /@ethersproject/abstract-provider@5.6.0: resolution: {integrity: sha512-oPMFlKLN+g+y7a79cLK3WiLcjWFnZQtXWgnLAbHZcN3s7L4v90UHpTOrLk+m3yr0gt+/h9STTM6zrr7PM8uoRw==} dependencies: '@ethersproject/bignumber': 5.6.1 @@ -424,7 +479,7 @@ packages: '@ethersproject/transactions': 5.7.0 '@ethersproject/web': 5.7.1 - /@ethersproject/abstract-provider/5.7.0: + /@ethersproject/abstract-provider@5.7.0: resolution: {integrity: sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==} dependencies: '@ethersproject/bignumber': 5.7.0 @@ -435,7 +490,7 @@ packages: '@ethersproject/transactions': 5.7.0 '@ethersproject/web': 5.7.1 - /@ethersproject/abstract-signer/5.6.0: + /@ethersproject/abstract-signer@5.6.0: resolution: {integrity: sha512-WOqnG0NJKtI8n0wWZPReHtaLkDByPL67tn4nBaDAhmVq8sjHTPbCdz4DRhVu/cfTOvfy9w3iq5QZ7BX7zw56BQ==} dependencies: '@ethersproject/abstract-provider': 5.7.0 @@ -444,7 +499,7 @@ packages: '@ethersproject/logger': 5.0.6 '@ethersproject/properties': 5.7.0 - /@ethersproject/abstract-signer/5.7.0: + /@ethersproject/abstract-signer@5.7.0: resolution: {integrity: sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==} dependencies: '@ethersproject/abstract-provider': 5.7.0 @@ -453,7 +508,7 @@ packages: '@ethersproject/logger': 5.0.6 '@ethersproject/properties': 5.7.0 - /@ethersproject/address/5.6.0: + /@ethersproject/address@5.6.0: resolution: {integrity: sha512-6nvhYXjbXsHPS+30sHZ+U4VMagFC/9zAk6Gd/h3S21YW4+yfb0WfRtaAIZ4kfM4rrVwqiy284LP0GtL5HXGLxQ==} dependencies: '@ethersproject/bignumber': 5.6.1 @@ -462,7 +517,7 @@ packages: '@ethersproject/logger': 5.0.6 '@ethersproject/rlp': 5.7.0 - /@ethersproject/address/5.7.0: + /@ethersproject/address@5.7.0: resolution: {integrity: sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==} dependencies: '@ethersproject/bignumber': 5.7.0 @@ -471,70 +526,70 @@ packages: '@ethersproject/logger': 5.0.6 '@ethersproject/rlp': 5.7.0 - /@ethersproject/base64/5.6.0: + /@ethersproject/base64@5.6.0: resolution: {integrity: sha512-2Neq8wxJ9xHxCF9TUgmKeSh9BXJ6OAxWfeGWvbauPh8FuHEjamgHilllx8KkSd5ErxyHIX7Xv3Fkcud2kY9ezw==} dependencies: '@ethersproject/bytes': 5.7.0 - /@ethersproject/base64/5.7.0: + /@ethersproject/base64@5.7.0: resolution: {integrity: sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==} dependencies: '@ethersproject/bytes': 5.7.0 - /@ethersproject/basex/5.6.0: + /@ethersproject/basex@5.6.0: resolution: {integrity: sha512-qN4T+hQd/Md32MoJpc69rOwLYRUXwjTlhHDIeUkUmiN/JyWkkLLMoG0TqvSQKNqZOMgN5stbUYN6ILC+eD7MEQ==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/properties': 5.7.0 - /@ethersproject/basex/5.7.0: + /@ethersproject/basex@5.7.0: resolution: {integrity: sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/properties': 5.7.0 - /@ethersproject/bignumber/5.6.0: + /@ethersproject/bignumber@5.6.0: resolution: {integrity: sha512-VziMaXIUHQlHJmkv1dlcd6GY2PmT0khtAqaMctCIDogxkrarMzA9L94KN1NeXqqOfFD6r0sJT3vCTOFSmZ07DA==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/logger': 5.0.6 bn.js: 4.12.0 - /@ethersproject/bignumber/5.6.1: + /@ethersproject/bignumber@5.6.1: resolution: {integrity: sha512-UtMeZ3GaUuF9sx2u9nPZiPP3ULcAFmXyvynR7oHl/tPrM+vldZh7ocMsoa1PqKYGnQnqUZJoqxZnGN6J0qdipA==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/logger': 5.0.6 bn.js: 4.12.0 - /@ethersproject/bignumber/5.7.0: + /@ethersproject/bignumber@5.7.0: resolution: {integrity: sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/logger': 5.0.6 bn.js: 5.2.1 - /@ethersproject/bytes/5.6.0: + /@ethersproject/bytes@5.6.0: resolution: {integrity: sha512-3hJPlYemb9V4VLfJF5BfN0+55vltPZSHU3QKUyP9M3Y2TcajbiRrz65UG+xVHOzBereB1b9mn7r12o177xgN7w==} dependencies: '@ethersproject/logger': 5.0.6 - /@ethersproject/bytes/5.7.0: + /@ethersproject/bytes@5.7.0: resolution: {integrity: sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==} dependencies: '@ethersproject/logger': 5.0.6 - /@ethersproject/constants/5.6.0: + /@ethersproject/constants@5.6.0: resolution: {integrity: sha512-SrdaJx2bK0WQl23nSpV/b1aq293Lh0sUaZT/yYKPDKn4tlAbkH96SPJwIhwSwTsoQQZxuh1jnqsKwyymoiBdWA==} dependencies: '@ethersproject/bignumber': 5.6.1 - /@ethersproject/constants/5.7.0: + /@ethersproject/constants@5.7.0: resolution: {integrity: sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==} dependencies: '@ethersproject/bignumber': 5.7.0 - /@ethersproject/contracts/5.6.0: + /@ethersproject/contracts@5.6.0: resolution: {integrity: sha512-74Ge7iqTDom0NX+mux8KbRUeJgu1eHZ3iv6utv++sLJG80FVuU9HnHeKVPfjd9s3woFhaFoQGf3B3iH/FrQmgw==} dependencies: '@ethersproject/abi': 5.7.0 @@ -548,7 +603,7 @@ packages: '@ethersproject/properties': 5.7.0 '@ethersproject/transactions': 5.7.0 - /@ethersproject/contracts/5.6.1: + /@ethersproject/contracts@5.6.1: resolution: {integrity: sha512-0fpBBDoPqJMsutE6sNjg6pvCJaIcl7tliMQTMRcoUWDACfjO68CpKOJBlsEhEhmzdnu/41KbrfAeg+sB3y35MQ==} dependencies: '@ethersproject/abi': 5.6.1 @@ -563,7 +618,7 @@ packages: '@ethersproject/transactions': 5.7.0 dev: true - /@ethersproject/contracts/5.7.0: + /@ethersproject/contracts@5.7.0: resolution: {integrity: sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==} dependencies: '@ethersproject/abi': 5.7.0 @@ -578,7 +633,7 @@ packages: '@ethersproject/transactions': 5.7.0 dev: false - /@ethersproject/hash/5.6.0: + /@ethersproject/hash@5.6.0: resolution: {integrity: sha512-fFd+k9gtczqlr0/BruWLAu7UAOas1uRRJvOR84uDf4lNZ+bTkGl366qvniUZHKtlqxBRU65MkOobkmvmpHU+jA==} dependencies: '@ethersproject/abstract-signer': 5.7.0 @@ -590,7 +645,7 @@ packages: '@ethersproject/properties': 5.7.0 '@ethersproject/strings': 5.7.0 - /@ethersproject/hash/5.7.0: + /@ethersproject/hash@5.7.0: resolution: {integrity: sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==} dependencies: '@ethersproject/abstract-signer': 5.7.0 @@ -603,7 +658,7 @@ packages: '@ethersproject/properties': 5.7.0 '@ethersproject/strings': 5.7.0 - /@ethersproject/hdnode/5.6.0: + /@ethersproject/hdnode@5.6.0: resolution: {integrity: sha512-61g3Jp3nwDqJcL/p4nugSyLrpl/+ChXIOtCEM8UDmWeB3JCAt5FoLdOMXQc3WWkc0oM2C0aAn6GFqqMcS/mHTw==} dependencies: '@ethersproject/abstract-signer': 5.7.0 @@ -619,7 +674,7 @@ packages: '@ethersproject/transactions': 5.7.0 '@ethersproject/wordlists': 5.7.0 - /@ethersproject/hdnode/5.7.0: + /@ethersproject/hdnode@5.7.0: resolution: {integrity: sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==} dependencies: '@ethersproject/abstract-signer': 5.7.0 @@ -635,7 +690,7 @@ packages: '@ethersproject/transactions': 5.7.0 '@ethersproject/wordlists': 5.7.0 - /@ethersproject/json-wallets/5.6.0: + /@ethersproject/json-wallets@5.6.0: resolution: {integrity: sha512-fmh86jViB9r0ibWXTQipxpAGMiuxoqUf78oqJDlCAJXgnJF024hOOX7qVgqsjtbeoxmcLwpPsXNU0WEe/16qPQ==} dependencies: '@ethersproject/abstract-signer': 5.7.0 @@ -652,7 +707,7 @@ packages: aes-js: 3.0.0 scrypt-js: 3.0.1 - /@ethersproject/json-wallets/5.7.0: + /@ethersproject/json-wallets@5.7.0: resolution: {integrity: sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==} dependencies: '@ethersproject/abstract-signer': 5.7.0 @@ -669,54 +724,54 @@ packages: aes-js: 3.0.0 scrypt-js: 3.0.1 - /@ethersproject/keccak256/5.6.0: + /@ethersproject/keccak256@5.6.0: resolution: {integrity: sha512-tk56BJ96mdj/ksi7HWZVWGjCq0WVl/QvfhFQNeL8fxhBlGoP+L80uDCiQcpJPd+2XxkivS3lwRm3E0CXTfol0w==} dependencies: '@ethersproject/bytes': 5.7.0 js-sha3: 0.8.0 - /@ethersproject/keccak256/5.7.0: + /@ethersproject/keccak256@5.7.0: resolution: {integrity: sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==} dependencies: '@ethersproject/bytes': 5.7.0 js-sha3: 0.8.0 - /@ethersproject/logger/5.0.6: + /@ethersproject/logger@5.0.6: resolution: {integrity: sha512-FrX0Vnb3JZ1md/7GIZfmJ06XOAA8r3q9Uqt9O5orr4ZiksnbpXKlyDzQtlZ5Yv18RS8CAUbiKH9vwidJg1BPmQ==} - /@ethersproject/networks/5.6.0: + /@ethersproject/networks@5.6.0: resolution: {integrity: sha512-DaVzgyThzHgSDLuURhvkp4oviGoGe9iTZW4jMEORHDRCgSZ9K9THGFKqL+qGXqPAYLEgZTf5z2w56mRrPR1MjQ==} dependencies: '@ethersproject/logger': 5.0.6 - /@ethersproject/networks/5.7.1: + /@ethersproject/networks@5.7.1: resolution: {integrity: sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==} dependencies: '@ethersproject/logger': 5.0.6 - /@ethersproject/pbkdf2/5.6.0: + /@ethersproject/pbkdf2@5.6.0: resolution: {integrity: sha512-Wu1AxTgJo3T3H6MIu/eejLFok9TYoSdgwRr5oGY1LTLfmGesDoSx05pemsbrPT2gG4cQME+baTSCp5sEo2erZQ==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/sha2': 5.7.0 - /@ethersproject/pbkdf2/5.7.0: + /@ethersproject/pbkdf2@5.7.0: resolution: {integrity: sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/sha2': 5.7.0 - /@ethersproject/properties/5.6.0: + /@ethersproject/properties@5.6.0: resolution: {integrity: sha512-szoOkHskajKePTJSZ46uHUWWkbv7TzP2ypdEK6jGMqJaEt2sb0jCgfBo0gH0m2HBpRixMuJ6TBRaQCF7a9DoCg==} dependencies: '@ethersproject/logger': 5.0.6 - /@ethersproject/properties/5.7.0: + /@ethersproject/properties@5.7.0: resolution: {integrity: sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==} dependencies: '@ethersproject/logger': 5.0.6 - /@ethersproject/providers/5.6.1: + /@ethersproject/providers@5.6.1: resolution: {integrity: sha512-w8Wx15nH+aVDvnoKCyI1f3x0B5idmk/bDJXMEUqCfdO8Eadd0QpDx9lDMTMmenhOmf9vufLJXjpSm24D3ZnVpg==} dependencies: '@ethersproject/abstract-provider': 5.7.0 @@ -742,7 +797,7 @@ packages: - bufferutil - utf-8-validate - /@ethersproject/providers/5.7.1: + /@ethersproject/providers@5.7.1: resolution: {integrity: sha512-vZveG/DLyo+wk4Ga1yx6jSEHrLPgmTt+dFv0dv8URpVCRf0jVhalps1jq/emN/oXnMRsC7cQgAF32DcXLL7BPQ==} dependencies: '@ethersproject/abstract-provider': 5.7.0 @@ -770,51 +825,51 @@ packages: - utf-8-validate dev: false - /@ethersproject/random/5.6.0: + /@ethersproject/random@5.6.0: resolution: {integrity: sha512-si0PLcLjq+NG/XHSZz90asNf+YfKEqJGVdxoEkSukzbnBgC8rydbgbUgBbBGLeHN4kAJwUFEKsu3sCXT93YMsw==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/logger': 5.0.6 - /@ethersproject/random/5.6.1: + /@ethersproject/random@5.6.1: resolution: {integrity: sha512-/wtPNHwbmng+5yi3fkipA8YBT59DdkGRoC2vWk09Dci/q5DlgnMkhIycjHlavrvrjJBkFjO/ueLyT+aUDfc4lA==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/logger': 5.0.6 - /@ethersproject/random/5.7.0: + /@ethersproject/random@5.7.0: resolution: {integrity: sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/logger': 5.0.6 - /@ethersproject/rlp/5.6.0: + /@ethersproject/rlp@5.6.0: resolution: {integrity: sha512-dz9WR1xpcTL+9DtOT/aDO+YyxSSdO8YIS0jyZwHHSlAmnxA6cKU3TrTd4Xc/bHayctxTgGLYNuVVoiXE4tTq1g==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/logger': 5.0.6 - /@ethersproject/rlp/5.7.0: + /@ethersproject/rlp@5.7.0: resolution: {integrity: sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/logger': 5.0.6 - /@ethersproject/sha2/5.6.0: + /@ethersproject/sha2@5.6.0: resolution: {integrity: sha512-1tNWCPFLu1n3JM9t4/kytz35DkuF9MxqkGGEHNauEbaARdm2fafnOyw1s0tIQDPKF/7bkP1u3dbrmjpn5CelyA==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/logger': 5.0.6 hash.js: 1.1.7 - /@ethersproject/sha2/5.7.0: + /@ethersproject/sha2@5.7.0: resolution: {integrity: sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/logger': 5.0.6 hash.js: 1.1.7 - /@ethersproject/signing-key/5.6.0: + /@ethersproject/signing-key@5.6.0: resolution: {integrity: sha512-S+njkhowmLeUu/r7ir8n78OUKx63kBdMCPssePS89So1TH4hZqnWFsThEd/GiXYp9qMxVrydf7KdM9MTGPFukA==} dependencies: '@ethersproject/bytes': 5.7.0 @@ -824,7 +879,7 @@ packages: elliptic: 6.5.4 hash.js: 1.1.7 - /@ethersproject/signing-key/5.7.0: + /@ethersproject/signing-key@5.7.0: resolution: {integrity: sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==} dependencies: '@ethersproject/bytes': 5.7.0 @@ -834,7 +889,7 @@ packages: elliptic: 6.5.4 hash.js: 1.1.7 - /@ethersproject/solidity/5.6.0: + /@ethersproject/solidity@5.6.0: resolution: {integrity: sha512-YwF52vTNd50kjDzqKaoNNbC/r9kMDPq3YzDWmsjFTRBcIF1y4JCQJ8gB30wsTfHbaxgxelI5BfxQSxD/PbJOww==} dependencies: '@ethersproject/bignumber': 5.7.0 @@ -844,21 +899,21 @@ packages: '@ethersproject/sha2': 5.7.0 '@ethersproject/strings': 5.7.0 - /@ethersproject/strings/5.6.0: + /@ethersproject/strings@5.6.0: resolution: {integrity: sha512-uv10vTtLTZqrJuqBZR862ZQjTIa724wGPWQqZrofaPI/kUsf53TBG0I0D+hQ1qyNtllbNzaW+PDPHHUI6/65Mg==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/constants': 5.7.0 '@ethersproject/logger': 5.0.6 - /@ethersproject/strings/5.7.0: + /@ethersproject/strings@5.7.0: resolution: {integrity: sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==} dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/constants': 5.7.0 '@ethersproject/logger': 5.0.6 - /@ethersproject/transactions/5.6.0: + /@ethersproject/transactions@5.6.0: resolution: {integrity: sha512-4HX+VOhNjXHZyGzER6E/LVI2i6lf9ejYeWD6l4g50AdmimyuStKc39kvKf1bXWQMg7QNVh+uC7dYwtaZ02IXeg==} dependencies: '@ethersproject/address': 5.7.0 @@ -871,7 +926,7 @@ packages: '@ethersproject/rlp': 5.7.0 '@ethersproject/signing-key': 5.7.0 - /@ethersproject/transactions/5.7.0: + /@ethersproject/transactions@5.7.0: resolution: {integrity: sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==} dependencies: '@ethersproject/address': 5.7.0 @@ -884,14 +939,14 @@ packages: '@ethersproject/rlp': 5.7.0 '@ethersproject/signing-key': 5.7.0 - /@ethersproject/units/5.6.0: + /@ethersproject/units@5.6.0: resolution: {integrity: sha512-tig9x0Qmh8qbo1w8/6tmtyrm/QQRviBh389EQ+d8fP4wDsBrJBf08oZfoiz1/uenKK9M78yAP4PoR7SsVoTjsw==} dependencies: '@ethersproject/bignumber': 5.7.0 '@ethersproject/constants': 5.7.0 '@ethersproject/logger': 5.0.6 - /@ethersproject/wallet/5.6.0: + /@ethersproject/wallet@5.6.0: resolution: {integrity: sha512-qMlSdOSTyp0MBeE+r7SUhr1jjDlC1zAXB8VD84hCnpijPQiSNbxr6GdiLXxpUs8UKzkDiNYYC5DRI3MZr+n+tg==} dependencies: '@ethersproject/abstract-provider': 5.7.0 @@ -910,7 +965,7 @@ packages: '@ethersproject/transactions': 5.7.0 '@ethersproject/wordlists': 5.7.0 - /@ethersproject/web/5.6.0: + /@ethersproject/web@5.6.0: resolution: {integrity: sha512-G/XHj0hV1FxI2teHRfCGvfBUHFmU+YOSbCxlAMqJklxSa7QMiHFQfAxvwY2PFqgvdkxEKwRNr/eCjfAPEm2Ctg==} dependencies: '@ethersproject/base64': 5.7.0 @@ -919,7 +974,7 @@ packages: '@ethersproject/properties': 5.7.0 '@ethersproject/strings': 5.7.0 - /@ethersproject/web/5.7.1: + /@ethersproject/web@5.7.1: resolution: {integrity: sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==} dependencies: '@ethersproject/base64': 5.7.0 @@ -928,7 +983,7 @@ packages: '@ethersproject/properties': 5.7.0 '@ethersproject/strings': 5.7.0 - /@ethersproject/wordlists/5.6.0: + /@ethersproject/wordlists@5.6.0: resolution: {integrity: sha512-q0bxNBfIX3fUuAo9OmjlEYxP40IB8ABgb7HjEZCL5IKubzV3j30CWi2rqQbjTS2HfoyQbfINoKcTVWP4ejwR7Q==} dependencies: '@ethersproject/bytes': 5.7.0 @@ -937,7 +992,7 @@ packages: '@ethersproject/properties': 5.7.0 '@ethersproject/strings': 5.7.0 - /@ethersproject/wordlists/5.7.0: + /@ethersproject/wordlists@5.7.0: resolution: {integrity: sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==} dependencies: '@ethersproject/bytes': 5.7.0 @@ -946,27 +1001,27 @@ packages: '@ethersproject/properties': 5.7.0 '@ethersproject/strings': 5.7.0 - /@humanwhocodes/config-array/0.11.10: + /@humanwhocodes/config-array@0.11.10: resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==} engines: {node: '>=10.10.0'} dependencies: '@humanwhocodes/object-schema': 1.2.1 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) minimatch: 3.1.2 transitivePeerDependencies: - supports-color dev: true - /@humanwhocodes/module-importer/1.0.1: + /@humanwhocodes/module-importer@1.0.1: resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} dev: true - /@humanwhocodes/object-schema/1.2.1: + /@humanwhocodes/object-schema@1.2.1: resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} dev: true - /@metamask/eth-sig-util/4.0.1: + /@metamask/eth-sig-util@4.0.1: resolution: {integrity: sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==} engines: {node: '>=12.0.0'} dependencies: @@ -977,15 +1032,15 @@ packages: tweetnacl-util: 0.15.1 dev: true - /@noble/hashes/1.1.2: + /@noble/hashes@1.1.2: resolution: {integrity: sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==} dev: true - /@noble/secp256k1/1.6.3: + /@noble/secp256k1@1.6.3: resolution: {integrity: sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==} dev: true - /@nodelib/fs.scandir/2.1.5: + /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} dependencies: @@ -993,12 +1048,12 @@ packages: run-parallel: 1.1.9 dev: true - /@nodelib/fs.stat/2.0.5: + /@nodelib/fs.stat@2.0.5: resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} dev: true - /@nodelib/fs.walk/1.2.8: + /@nodelib/fs.walk@1.2.8: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} dependencies: @@ -1006,7 +1061,7 @@ packages: fastq: 1.6.0 dev: true - /@nomicfoundation/ethereumjs-block/4.0.0: + /@nomicfoundation/ethereumjs-block@4.0.0: resolution: {integrity: sha512-bk8uP8VuexLgyIZAHExH1QEovqx0Lzhc9Ntm63nCRKLHXIZkobaFaeCVwTESV7YkPKUk7NiK11s8ryed4CS9yA==} engines: {node: '>=14'} dependencies: @@ -1018,7 +1073,7 @@ packages: ethereum-cryptography: 0.1.3 dev: true - /@nomicfoundation/ethereumjs-blockchain/6.0.0: + /@nomicfoundation/ethereumjs-blockchain@6.0.0: resolution: {integrity: sha512-pLFEoea6MWd81QQYSReLlLfH7N9v7lH66JC/NMPN848ySPPQA5renWnE7wPByfQFzNrPBuDDRFFULMDmj1C0xw==} engines: {node: '>=14'} dependencies: @@ -1029,7 +1084,7 @@ packages: '@nomicfoundation/ethereumjs-trie': 5.0.0 '@nomicfoundation/ethereumjs-util': 8.0.0 abstract-level: 1.0.3 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) ethereum-cryptography: 0.1.3 level: 8.0.0 lru-cache: 5.1.1 @@ -1038,14 +1093,14 @@ packages: - supports-color dev: true - /@nomicfoundation/ethereumjs-common/3.0.0: + /@nomicfoundation/ethereumjs-common@3.0.0: resolution: {integrity: sha512-WS7qSshQfxoZOpHG/XqlHEGRG1zmyjYrvmATvc4c62+gZXgre1ymYP8ZNgx/3FyZY0TWe9OjFlKOfLqmgOeYwA==} dependencies: '@nomicfoundation/ethereumjs-util': 8.0.0 crc-32: 1.2.2 dev: true - /@nomicfoundation/ethereumjs-ethash/2.0.0: + /@nomicfoundation/ethereumjs-ethash@2.0.0: resolution: {integrity: sha512-WpDvnRncfDUuXdsAXlI4lXbqUDOA+adYRQaEezIkxqDkc+LDyYDbd/xairmY98GnQzo1zIqsIL6GB5MoMSJDew==} engines: {node: '>=14'} dependencies: @@ -1057,7 +1112,7 @@ packages: ethereum-cryptography: 0.1.3 dev: true - /@nomicfoundation/ethereumjs-evm/1.0.0: + /@nomicfoundation/ethereumjs-evm@1.0.0: resolution: {integrity: sha512-hVS6qRo3V1PLKCO210UfcEQHvlG7GqR8iFzp0yyjTg2TmJQizcChKgWo8KFsdMw6AyoLgLhHGHw4HdlP8a4i+Q==} engines: {node: '>=14'} dependencies: @@ -1065,7 +1120,7 @@ packages: '@nomicfoundation/ethereumjs-util': 8.0.0 '@types/async-eventemitter': 0.2.1 async-eventemitter: 0.2.4 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) ethereum-cryptography: 0.1.3 mcl-wasm: 0.7.9 rustbn.js: 0.2.0 @@ -1073,27 +1128,27 @@ packages: - supports-color dev: true - /@nomicfoundation/ethereumjs-rlp/4.0.0: + /@nomicfoundation/ethereumjs-rlp@4.0.0: resolution: {integrity: sha512-GaSOGk5QbUk4eBP5qFbpXoZoZUj/NrW7MRa0tKY4Ew4c2HAS0GXArEMAamtFrkazp0BO4K5p2ZCG3b2FmbShmw==} engines: {node: '>=14'} hasBin: true dev: true - /@nomicfoundation/ethereumjs-statemanager/1.0.0: + /@nomicfoundation/ethereumjs-statemanager@1.0.0: resolution: {integrity: sha512-jCtqFjcd2QejtuAMjQzbil/4NHf5aAWxUc+CvS0JclQpl+7M0bxMofR2AJdtz+P3u0ke2euhYREDiE7iSO31vQ==} dependencies: '@nomicfoundation/ethereumjs-common': 3.0.0 '@nomicfoundation/ethereumjs-rlp': 4.0.0 '@nomicfoundation/ethereumjs-trie': 5.0.0 '@nomicfoundation/ethereumjs-util': 8.0.0 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) ethereum-cryptography: 0.1.3 functional-red-black-tree: 1.0.1 transitivePeerDependencies: - supports-color dev: true - /@nomicfoundation/ethereumjs-trie/5.0.0: + /@nomicfoundation/ethereumjs-trie@5.0.0: resolution: {integrity: sha512-LIj5XdE+s+t6WSuq/ttegJzZ1vliwg6wlb+Y9f4RlBpuK35B9K02bO7xU+E6Rgg9RGptkWd6TVLdedTI4eNc2A==} engines: {node: '>=14'} dependencies: @@ -1103,7 +1158,7 @@ packages: readable-stream: 3.6.0 dev: true - /@nomicfoundation/ethereumjs-tx/4.0.0: + /@nomicfoundation/ethereumjs-tx@4.0.0: resolution: {integrity: sha512-Gg3Lir2lNUck43Kp/3x6TfBNwcWC9Z1wYue9Nz3v4xjdcv6oDW9QSMJxqsKw9QEGoBBZ+gqwpW7+F05/rs/g1w==} engines: {node: '>=14'} dependencies: @@ -1113,7 +1168,7 @@ packages: ethereum-cryptography: 0.1.3 dev: true - /@nomicfoundation/ethereumjs-util/8.0.0: + /@nomicfoundation/ethereumjs-util@8.0.0: resolution: {integrity: sha512-2emi0NJ/HmTG+CGY58fa+DQuAoroFeSH9gKu9O6JnwTtlzJtgfTixuoOqLEgyyzZVvwfIpRueuePb8TonL1y+A==} engines: {node: '>=14'} dependencies: @@ -1121,7 +1176,7 @@ packages: ethereum-cryptography: 0.1.3 dev: true - /@nomicfoundation/ethereumjs-vm/6.0.0: + /@nomicfoundation/ethereumjs-vm@6.0.0: resolution: {integrity: sha512-JMPxvPQ3fzD063Sg3Tp+UdwUkVxMoo1uML6KSzFhMH3hoQi/LMuXBoEHAoW83/vyNS9BxEe6jm6LmT5xdeEJ6w==} engines: {node: '>=14'} dependencies: @@ -1136,7 +1191,7 @@ packages: '@nomicfoundation/ethereumjs-util': 8.0.0 '@types/async-eventemitter': 0.2.1 async-eventemitter: 0.2.4 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) ethereum-cryptography: 0.1.3 functional-red-black-tree: 1.0.1 mcl-wasm: 0.7.9 @@ -1145,16 +1200,16 @@ packages: - supports-color dev: true - /@nomicfoundation/hardhat-network-helpers/1.0.8_hardhat@2.12.7: + /@nomicfoundation/hardhat-network-helpers@1.0.8(hardhat@2.12.7): resolution: {integrity: sha512-MNqQbzUJZnCMIYvlniC3U+kcavz/PhhQSsY90tbEtUyMj/IQqsLwIRZa4ctjABh3Bz0KCh9OXUZ7Yk/d9hr45Q==} peerDependencies: hardhat: ^2.9.5 dependencies: ethereumjs-util: 7.1.5 - hardhat: 2.12.7_goz53koj4ourpjwgrks4nqbe6i + hardhat: 2.12.7(ts-node@10.0.0)(typescript@4.9.5) dev: true - /@nomicfoundation/solidity-analyzer-darwin-arm64/0.1.0: + /@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.0: resolution: {integrity: sha512-vEF3yKuuzfMHsZecHQcnkUrqm8mnTWfJeEVFHpg+cO+le96xQA4lAJYdUan8pXZohQxv1fSReQsn4QGNuBNuCw==} engines: {node: '>= 10'} cpu: [arm64] @@ -1163,7 +1218,7 @@ packages: dev: true optional: true - /@nomicfoundation/solidity-analyzer-darwin-x64/0.1.0: + /@nomicfoundation/solidity-analyzer-darwin-x64@0.1.0: resolution: {integrity: sha512-dlHeIg0pTL4dB1l9JDwbi/JG6dHQaU1xpDK+ugYO8eJ1kxx9Dh2isEUtA4d02cQAl22cjOHTvifAk96A+ItEHA==} engines: {node: '>= 10'} cpu: [x64] @@ -1172,7 +1227,7 @@ packages: dev: true optional: true - /@nomicfoundation/solidity-analyzer-freebsd-x64/0.1.0: + /@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.0: resolution: {integrity: sha512-WFCZYMv86WowDA4GiJKnebMQRt3kCcFqHeIomW6NMyqiKqhK1kIZCxSLDYsxqlx396kKLPN1713Q1S8tu68GKg==} engines: {node: '>= 10'} cpu: [x64] @@ -1181,7 +1236,7 @@ packages: dev: true optional: true - /@nomicfoundation/solidity-analyzer-linux-arm64-gnu/0.1.0: + /@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.0: resolution: {integrity: sha512-DTw6MNQWWlCgc71Pq7CEhEqkb7fZnS7oly13pujs4cMH1sR0JzNk90Mp1zpSCsCs4oKan2ClhMlLKtNat/XRKQ==} engines: {node: '>= 10'} cpu: [arm64] @@ -1190,7 +1245,7 @@ packages: dev: true optional: true - /@nomicfoundation/solidity-analyzer-linux-arm64-musl/0.1.0: + /@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.0: resolution: {integrity: sha512-wUpUnR/3GV5Da88MhrxXh/lhb9kxh9V3Jya2NpBEhKDIRCDmtXMSqPMXHZmOR9DfCwCvG6vLFPr/+YrPCnUN0w==} engines: {node: '>= 10'} cpu: [arm64] @@ -1199,7 +1254,7 @@ packages: dev: true optional: true - /@nomicfoundation/solidity-analyzer-linux-x64-gnu/0.1.0: + /@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.0: resolution: {integrity: sha512-lR0AxK1x/MeKQ/3Pt923kPvwigmGX3OxeU5qNtQ9pj9iucgk4PzhbS3ruUeSpYhUxG50jN4RkIGwUMoev5lguw==} engines: {node: '>= 10'} cpu: [x64] @@ -1208,7 +1263,7 @@ packages: dev: true optional: true - /@nomicfoundation/solidity-analyzer-linux-x64-musl/0.1.0: + /@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.0: resolution: {integrity: sha512-A1he/8gy/JeBD3FKvmI6WUJrGrI5uWJNr5Xb9WdV+DK0F8msuOqpEByLlnTdLkXMwW7nSl3awvLezOs9xBHJEg==} engines: {node: '>= 10'} cpu: [x64] @@ -1217,7 +1272,7 @@ packages: dev: true optional: true - /@nomicfoundation/solidity-analyzer-win32-arm64-msvc/0.1.0: + /@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.0: resolution: {integrity: sha512-7x5SXZ9R9H4SluJZZP8XPN+ju7Mx+XeUMWZw7ZAqkdhP5mK19I4vz3x0zIWygmfE8RT7uQ5xMap0/9NPsO+ykw==} engines: {node: '>= 10'} cpu: [arm64] @@ -1226,7 +1281,7 @@ packages: dev: true optional: true - /@nomicfoundation/solidity-analyzer-win32-ia32-msvc/0.1.0: + /@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.0: resolution: {integrity: sha512-m7w3xf+hnE774YRXu+2mGV7RiF3QJtUoiYU61FascCkQhX3QMQavh7saH/vzb2jN5D24nT/jwvaHYX/MAM9zUw==} engines: {node: '>= 10'} cpu: [ia32] @@ -1235,7 +1290,7 @@ packages: dev: true optional: true - /@nomicfoundation/solidity-analyzer-win32-x64-msvc/0.1.0: + /@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.0: resolution: {integrity: sha512-xCuybjY0sLJQnJhupiFAXaek2EqF0AP0eBjgzaalPXSNvCEN6ZYHvUzdA50ENDVeSYFXcUsYf3+FsD3XKaeptA==} engines: {node: '>= 10'} cpu: [x64] @@ -1244,7 +1299,7 @@ packages: dev: true optional: true - /@nomicfoundation/solidity-analyzer/0.1.0: + /@nomicfoundation/solidity-analyzer@0.1.0: resolution: {integrity: sha512-xGWAiVCGOycvGiP/qrlf9f9eOn7fpNbyJygcB0P21a1MDuVPlKt0Srp7rvtBEutYQ48ouYnRXm33zlRnlTOPHg==} engines: {node: '>= 12'} optionalDependencies: @@ -1260,17 +1315,17 @@ packages: '@nomicfoundation/solidity-analyzer-win32-x64-msvc': 0.1.0 dev: true - /@nomiclabs/hardhat-ethers/2.0.2_z6fcyyhc2nf3iwqkyspxr4tlaq: + /@nomiclabs/hardhat-ethers@2.0.2(ethers@5.6.1)(hardhat@2.12.7): resolution: {integrity: sha512-6quxWe8wwS4X5v3Au8q1jOvXYEPkS1Fh+cME5u6AwNdnI4uERvPlVjlgRWzpnb+Rrt1l/cEqiNRH9GlsBMSDQg==} peerDependencies: ethers: ^5.0.0 hardhat: ^2.0.0 dependencies: ethers: 5.6.1 - hardhat: 2.12.7_goz53koj4ourpjwgrks4nqbe6i + hardhat: 2.12.7(ts-node@10.0.0)(typescript@4.9.5) dev: true - /@nomiclabs/hardhat-etherscan/3.1.0_hardhat@2.12.7: + /@nomiclabs/hardhat-etherscan@3.1.0(hardhat@2.12.7): resolution: {integrity: sha512-JroYgfN1AlYFkQTQ3nRwFi4o8NtZF7K/qFR2dxDUgHbCtIagkUseca9L4E/D2ScUm4XT40+8PbCdqZi+XmHyQA==} peerDependencies: hardhat: ^2.0.4 @@ -1279,9 +1334,9 @@ packages: '@ethersproject/address': 5.7.0 cbor: 5.2.0 chalk: 2.4.2 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) fs-extra: 7.0.1 - hardhat: 2.12.7_goz53koj4ourpjwgrks4nqbe6i + hardhat: 2.12.7(ts-node@10.0.0)(typescript@4.9.5) lodash: 4.17.21 semver: 6.3.0 table: 6.8.0 @@ -1290,7 +1345,7 @@ packages: - supports-color dev: true - /@nomiclabs/hardhat-waffle/2.0.1_d7ejcwiim3eoh3awwn3s5bqjfe: + /@nomiclabs/hardhat-waffle@2.0.1(@nomiclabs/hardhat-ethers@2.0.2)(ethereum-waffle@3.3.0)(ethers@5.6.1)(hardhat@2.12.7): resolution: {integrity: sha512-2YR2V5zTiztSH9n8BYWgtv3Q+EL0N5Ltm1PAr5z20uAY4SkkfylJ98CIqt18XFvxTD5x4K2wKBzddjV9ViDAZQ==} peerDependencies: '@nomiclabs/hardhat-ethers': ^2.0.0 @@ -1298,34 +1353,34 @@ packages: ethers: ^5.0.0 hardhat: ^2.0.0 dependencies: - '@nomiclabs/hardhat-ethers': 2.0.2_z6fcyyhc2nf3iwqkyspxr4tlaq + '@nomiclabs/hardhat-ethers': 2.0.2(ethers@5.6.1)(hardhat@2.12.7) '@types/sinon-chai': 3.2.8 '@types/web3': 1.0.19 - ethereum-waffle: 3.3.0_typescript@4.9.5 + ethereum-waffle: 3.3.0(typescript@4.9.5) ethers: 5.6.1 - hardhat: 2.12.7_goz53koj4ourpjwgrks4nqbe6i + hardhat: 2.12.7(ts-node@10.0.0)(typescript@4.9.5) dev: true - /@openzeppelin/contract-loader/0.6.3: + /@openzeppelin/contract-loader@0.6.3: resolution: {integrity: sha512-cOFIjBjwbGgZhDZsitNgJl0Ye1rd5yu/Yx5LMgeq3u0ZYzldm4uObzHDFq4gjDdoypvyORjjJa3BlFA7eAnVIg==} dependencies: find-up: 4.1.0 fs-extra: 8.1.0 dev: true - /@openzeppelin/contracts-upgradeable/4.7.3: + /@openzeppelin/contracts-upgradeable@4.7.3: resolution: {integrity: sha512-+wuegAMaLcZnLCJIvrVUDzA9z/Wp93f0Dla/4jJvIhijRrPabjQbZe6fWiECLaJyfn5ci9fqf9vTw3xpQOad2A==} dev: false - /@openzeppelin/contracts/3.4.2: + /@openzeppelin/contracts@3.4.2: resolution: {integrity: sha512-z0zMCjyhhp4y7XKAcDAi3Vgms4T2PstwBdahiO0+9NaGICQKjynK3wduSRplTgk4LXmoO1yfDGO5RbjKYxtuxA==} dev: false - /@openzeppelin/contracts/4.3.3: + /@openzeppelin/contracts@4.3.3: resolution: {integrity: sha512-tDBopO1c98Yk7Cv/PZlHqrvtVjlgK5R4J6jxLwoO7qxK4xqOiZG+zSkIvGFpPZ0ikc3QOED3plgdqjgNTnBc7g==} dev: false - /@openzeppelin/hardhat-upgrades/1.22.1_t427xxny5pzfvmqb7mxuxbqor4: + /@openzeppelin/hardhat-upgrades@1.22.1(@nomiclabs/hardhat-ethers@2.0.2)(@nomiclabs/hardhat-etherscan@3.1.0)(ethers@5.6.1)(hardhat@2.12.7): resolution: {integrity: sha512-MdoitCTLl4zwMU8MeE/bCj+7JMWBEvd38XqJkw36PkJrXlbv6FedDVCPoumMAhpmtymm0nTwTYYklYG+L6WiiQ==} hasBin: true peerDependencies: @@ -1338,26 +1393,26 @@ packages: '@nomiclabs/harhdat-etherscan': optional: true dependencies: - '@nomiclabs/hardhat-ethers': 2.0.2_z6fcyyhc2nf3iwqkyspxr4tlaq - '@nomiclabs/hardhat-etherscan': 3.1.0_hardhat@2.12.7 + '@nomiclabs/hardhat-ethers': 2.0.2(ethers@5.6.1)(hardhat@2.12.7) + '@nomiclabs/hardhat-etherscan': 3.1.0(hardhat@2.12.7) '@openzeppelin/upgrades-core': 1.22.0 chalk: 4.1.2 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) ethers: 5.6.1 - hardhat: 2.12.7_goz53koj4ourpjwgrks4nqbe6i + hardhat: 2.12.7(ts-node@10.0.0)(typescript@4.9.5) proper-lockfile: 4.1.2 transitivePeerDependencies: - supports-color dev: true - /@openzeppelin/test-helpers/0.5.11_bn.js@4.12.0: + /@openzeppelin/test-helpers@0.5.11(bn.js@4.12.0): resolution: {integrity: sha512-HkFpCjtTD8dk+wdYhsT07YbMGCE+Z4Wp5sBKXvPDF3Lynoc0H2KqZgCWV+qr2YZ0WW1oX/sXkKFrrKJ0caBTjw==} dependencies: '@openzeppelin/contract-loader': 0.6.3 '@truffle/contract': 4.6.2 ansi-colors: 3.2.4 chai: 4.3.6 - chai-bn: 0.2.2_bn.js@4.12.0+chai@4.3.6 + chai-bn: 0.2.2(bn.js@4.12.0)(chai@4.3.6) ethjs-abi: 0.2.1 lodash.flatten: 4.4.0 semver: 5.7.1 @@ -1371,13 +1426,13 @@ packages: - utf-8-validate dev: true - /@openzeppelin/upgrades-core/1.22.0: + /@openzeppelin/upgrades-core@1.22.0: resolution: {integrity: sha512-TcTabzRbYOzWJnwiToj0LRzje25d9QbDPe2dOT9eHlLDRhOMiep39FDibJjkYd5IdF3s8M9IcK+YSnf49renEg==} dependencies: cbor: 8.1.0 chalk: 4.1.2 compare-versions: 5.0.3 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) ethereumjs-util: 7.1.5 proper-lockfile: 4.1.2 solidity-ast: 0.4.45 @@ -1385,7 +1440,7 @@ packages: - supports-color dev: true - /@resolver-engine/core/0.3.3: + /@resolver-engine/core@0.3.3: resolution: {integrity: sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ==} dependencies: debug: 3.2.7 @@ -1395,7 +1450,7 @@ packages: - supports-color dev: true - /@resolver-engine/fs/0.3.3: + /@resolver-engine/fs@0.3.3: resolution: {integrity: sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ==} dependencies: '@resolver-engine/core': 0.3.3 @@ -1404,7 +1459,7 @@ packages: - supports-color dev: true - /@resolver-engine/imports-fs/0.3.3: + /@resolver-engine/imports-fs@0.3.3: resolution: {integrity: sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA==} dependencies: '@resolver-engine/fs': 0.3.3 @@ -1414,7 +1469,7 @@ packages: - supports-color dev: true - /@resolver-engine/imports/0.3.3: + /@resolver-engine/imports@0.3.3: resolution: {integrity: sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q==} dependencies: '@resolver-engine/core': 0.3.3 @@ -1426,11 +1481,11 @@ packages: - supports-color dev: true - /@scure/base/1.1.1: + /@scure/base@1.1.1: resolution: {integrity: sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==} dev: true - /@scure/bip32/1.1.0: + /@scure/bip32@1.1.0: resolution: {integrity: sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==} dependencies: '@noble/hashes': 1.1.2 @@ -1438,14 +1493,14 @@ packages: '@scure/base': 1.1.1 dev: true - /@scure/bip39/1.1.0: + /@scure/bip39@1.1.0: resolution: {integrity: sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==} dependencies: '@noble/hashes': 1.1.2 '@scure/base': 1.1.1 dev: true - /@sentry/core/5.30.0: + /@sentry/core@5.30.0: resolution: {integrity: sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==} engines: {node: '>=6'} dependencies: @@ -1456,7 +1511,7 @@ packages: tslib: 1.14.1 dev: true - /@sentry/hub/5.30.0: + /@sentry/hub@5.30.0: resolution: {integrity: sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==} engines: {node: '>=6'} dependencies: @@ -1465,7 +1520,7 @@ packages: tslib: 1.14.1 dev: true - /@sentry/minimal/5.30.0: + /@sentry/minimal@5.30.0: resolution: {integrity: sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==} engines: {node: '>=6'} dependencies: @@ -1474,7 +1529,7 @@ packages: tslib: 1.14.1 dev: true - /@sentry/node/5.30.0: + /@sentry/node@5.30.0: resolution: {integrity: sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==} engines: {node: '>=6'} dependencies: @@ -1491,7 +1546,7 @@ packages: - supports-color dev: true - /@sentry/tracing/5.30.0: + /@sentry/tracing@5.30.0: resolution: {integrity: sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==} engines: {node: '>=6'} dependencies: @@ -1502,12 +1557,12 @@ packages: tslib: 1.14.1 dev: true - /@sentry/types/5.30.0: + /@sentry/types@5.30.0: resolution: {integrity: sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==} engines: {node: '>=6'} dev: true - /@sentry/utils/5.30.0: + /@sentry/utils@5.30.0: resolution: {integrity: sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==} engines: {node: '>=6'} dependencies: @@ -1515,43 +1570,45 @@ packages: tslib: 1.14.1 dev: true - /@sindresorhus/is/0.14.0: + /@sindresorhus/is@0.14.0: resolution: {integrity: sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==} engines: {node: '>=6'} + requiresBuild: true dev: true - /@sindresorhus/is/4.6.0: + /@sindresorhus/is@4.6.0: resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} engines: {node: '>=10'} dev: true - /@solidity-parser/parser/0.14.3: + /@solidity-parser/parser@0.14.3: resolution: {integrity: sha512-29g2SZ29HtsqA58pLCtopI1P/cPy5/UAzlcAXO6T/CNJimG6yA8kx4NaseMyJULiC+TEs02Y9/yeHzClqoA0hw==} dependencies: antlr4ts: 0.5.0-alpha.4 dev: true - /@solidity-parser/parser/0.16.0: + /@solidity-parser/parser@0.16.0: resolution: {integrity: sha512-ESipEcHyRHg4Np4SqBCfcXwyxxna1DgFVz69bgpLV8vzl/NP1DtcKsJ4dJZXWQhY/Z4J2LeKBiOkOVZn9ct33Q==} dependencies: antlr4ts: 0.5.0-alpha.4 dev: true - /@szmarczak/http-timer/1.1.2: + /@szmarczak/http-timer@1.1.2: resolution: {integrity: sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==} engines: {node: '>=6'} + requiresBuild: true dependencies: defer-to-connect: 1.1.1 dev: true - /@szmarczak/http-timer/5.0.1: + /@szmarczak/http-timer@5.0.1: resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} engines: {node: '>=14.16'} dependencies: defer-to-connect: 2.0.1 dev: true - /@truffle/abi-utils/0.3.2: + /@truffle/abi-utils@0.3.2: resolution: {integrity: sha512-32queMD64YKL/tmQgSV4Xs073dIaZ9tp7NP1icjwvFSA3Q9yeu7ApYbSbYMsx9H9zWkkVOsfcoJ2kJEieOCzsA==} dependencies: change-case: 3.0.2 @@ -1559,11 +1616,11 @@ packages: web3-utils: 1.7.4 dev: true - /@truffle/blockchain-utils/0.1.4: + /@truffle/blockchain-utils@0.1.4: resolution: {integrity: sha512-HegAo5A8UX9vE8dtceBRgCY207gOb9wj54c8mNOOWHcFpkyJz7kZYGo44As6Imh10/0hD2j7vHQ56Jf+uszJ3A==} dev: true - /@truffle/codec/0.14.5: + /@truffle/codec@0.14.5: resolution: {integrity: sha512-3FCpTJe6o7LGWUfrSdguMpdpH1PTn3u7bIfbj6Cfdzym2OAVSgxTgdlqC1poepbk0xcOVcUW+EsqNwLMqmBiPA==} dependencies: '@truffle/abi-utils': 0.3.2 @@ -1571,7 +1628,7 @@ packages: big.js: 6.2.1 bn.js: 5.2.1 cbor: 5.2.0 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) lodash: 4.17.21 semver: 7.3.7 utf8: 3.0.0 @@ -1580,23 +1637,23 @@ packages: - supports-color dev: true - /@truffle/compile-common/0.8.1: + /@truffle/compile-common@0.8.1: resolution: {integrity: sha512-7mzzG9Cfrn+fDT5Sqi7B6pccvIIV5w/GM8/56YgnjysbDzy5aZ6mv0fe37ZbcznEVQ35NJjBy+lEr/ozOGXwQA==} dependencies: '@truffle/error': 0.1.1 colors: 1.4.0 dev: true - /@truffle/contract-schema/3.4.10: + /@truffle/contract-schema@3.4.10: resolution: {integrity: sha512-BhRNRoRvlj2th6E5RNS0BnS0ZxQe01JJz8I7MjkGqdeXSvrn6qDCAnbmvhNgUv0l5h8w5+gBOQhAJhILf1shdQ==} dependencies: ajv: 6.12.6 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true - /@truffle/contract/4.6.2: + /@truffle/contract@4.6.2: resolution: {integrity: sha512-OZZIDmKtHgZS2Q6sCczNe8OfTuMWpRaAo3vwY49LGGs0VXLiwc7nIcCFh+bMg14IRK6vBN4pWE9W9eWSBFy31Q==} dependencies: '@ensdomains/ensjs': 2.1.0 @@ -1606,7 +1663,7 @@ packages: '@truffle/error': 0.1.1 '@truffle/interface-adapter': 0.5.22 bignumber.js: 7.2.1 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) ethers: 4.0.49 web3: 1.7.4 web3-core-helpers: 1.7.4 @@ -1619,24 +1676,24 @@ packages: - utf-8-validate dev: true - /@truffle/debug-utils/6.0.35: + /@truffle/debug-utils@6.0.35: resolution: {integrity: sha512-GuLsc+GFEYiUM683GWh4/ol3jkBts5a601detVWu1Xo5/bSL5gxooOjgOTovjA8dimCjkyi/DnK2yHHC+q+g0g==} dependencies: '@truffle/codec': 0.14.5 '@trufflesuite/chromafi': 3.0.0 bn.js: 5.2.1 chalk: 2.4.2 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) highlightjs-solidity: 2.0.5 transitivePeerDependencies: - supports-color dev: true - /@truffle/error/0.1.1: + /@truffle/error@0.1.1: resolution: {integrity: sha512-sE7c9IHIGdbK4YayH4BC8i8qMjoAOeg6nUXUDZZp8wlU21/EMpaG+CLx+KqcIPyR+GSWIW3Dm0PXkr2nlggFDA==} dev: true - /@truffle/interface-adapter/0.5.22: + /@truffle/interface-adapter@0.5.22: resolution: {integrity: sha512-Bgl5Afb1mPVNedI8CJzZQzVIdrZWSXISTBrXPZmppD4Q+6V1RUzlLxiaGGB4gYHOA+U0pBzD8MCcSycPAD9RsA==} dependencies: bn.js: 5.2.1 @@ -1648,7 +1705,7 @@ packages: - utf-8-validate dev: true - /@trufflesuite/chromafi/3.0.0: + /@trufflesuite/chromafi@3.0.0: resolution: {integrity: sha512-oqWcOqn8nT1bwlPPfidfzS55vqcIDdpfzo3HbU9EnUmcSTX+I8z0UyUFI3tZQjByVJulbzxHxUGS3ZJPwK/GPQ==} dependencies: camelcase: 4.1.0 @@ -1661,33 +1718,33 @@ packages: strip-indent: 2.0.0 dev: true - /@tsconfig/node10/1.0.9: + /@tsconfig/node10@1.0.9: resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} dev: true - /@tsconfig/node12/1.0.11: + /@tsconfig/node12@1.0.11: resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} dev: true - /@tsconfig/node14/1.0.3: + /@tsconfig/node14@1.0.3: resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} dev: true - /@tsconfig/node16/1.0.3: + /@tsconfig/node16@1.0.3: resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==} dev: true - /@typechain/ethers-v5/2.0.0_mwhxf3vrorrl5yk6tbvkb5vxk4: + /@typechain/ethers-v5@2.0.0(ethers@5.6.1)(typechain@3.0.0): resolution: {integrity: sha512-0xdCkyGOzdqh4h5JSf+zoWx85IusEjDcPIwNEHP8mrWSnCae4rvrqB+/gtpdNfX7zjlFlZiMeePn2r63EI3Lrw==} peerDependencies: ethers: ^5.0.0 typechain: ^3.0.0 dependencies: ethers: 5.6.1 - typechain: 3.0.0_typescript@4.9.5 + typechain: 3.0.0(typescript@4.9.5) dev: true - /@typechain/ethers-v5/7.2.0_pwtfr6mt5pw2hiixtkqheirqmq: + /@typechain/ethers-v5@7.2.0(@ethersproject/abi@5.6.1)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.6.1)(ethers@5.6.1)(typechain@8.2.0)(typescript@4.9.5): resolution: {integrity: sha512-jfcmlTvaaJjng63QsT49MT6R1HFhtO/TBMWbyzPFSzMmVIqb2tL6prnKBs4ZJrSvmgIXWy+ttSjpaxCTq8D/Tw==} peerDependencies: '@ethersproject/abi': ^5.0.0 @@ -1702,12 +1759,12 @@ packages: '@ethersproject/providers': 5.6.1 ethers: 5.6.1 lodash: 4.17.21 - ts-essentials: 7.0.3_typescript@4.9.5 - typechain: 8.2.0_typescript@4.9.5 + ts-essentials: 7.0.3(typescript@4.9.5) + typechain: 8.2.0(typescript@4.9.5) typescript: 4.9.5 dev: true - /@typechain/hardhat/3.1.0_gx5th54lc6trgzrpj7pwublyoa: + /@typechain/hardhat@3.1.0(hardhat@2.12.7)(lodash@4.17.21)(typechain@8.2.0): resolution: {integrity: sha512-C6Be6l+vTpao19PvMH2CB/lhL1TRLkhdPkvQCF/zqkY1e+0iqY2Bb9Jd3PTt6I8QvMm89ZDerrCJC9927ZHmlg==} peerDependencies: hardhat: ^2.0.10 @@ -1715,28 +1772,28 @@ packages: typechain: ^6.0.0 dependencies: fs-extra: 9.1.0 - hardhat: 2.12.7_goz53koj4ourpjwgrks4nqbe6i + hardhat: 2.12.7(ts-node@10.0.0)(typescript@4.9.5) lodash: 4.17.21 - typechain: 8.2.0_typescript@4.9.5 + typechain: 8.2.0(typescript@4.9.5) dev: true - /@types/async-eventemitter/0.2.1: + /@types/async-eventemitter@0.2.1: resolution: {integrity: sha512-M2P4Ng26QbAeITiH7w1d7OxtldgfAe0wobpyJzVK/XOb0cUGKU2R4pfAhqcJBXAe2ife5ZOhSv4wk7p+ffURtg==} dev: true - /@types/bn.js/4.11.6: + /@types/bn.js@4.11.6: resolution: {integrity: sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==} dependencies: '@types/node': 15.14.9 dev: true - /@types/bn.js/5.1.1: + /@types/bn.js@5.1.1: resolution: {integrity: sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==} dependencies: '@types/node': 15.14.9 dev: true - /@types/cacheable-request/6.0.2: + /@types/cacheable-request@6.0.2: resolution: {integrity: sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==} dependencies: '@types/http-cache-semantics': 4.0.1 @@ -1745,43 +1802,43 @@ packages: '@types/responselike': 1.0.0 dev: true - /@types/cbor/5.0.1: + /@types/cbor@5.0.1: resolution: {integrity: sha512-zVqJy2KzusZPLOgyGJDnOIbu3DxIGGqxYbEwtEEe4Z+la8jwIhOyb+GMrlHafs5tvKruwf8f8qOYP6zTvse/pw==} dependencies: '@types/node': 15.14.9 dev: true - /@types/chai/4.3.3: + /@types/chai@4.3.3: resolution: {integrity: sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==} dev: true - /@types/concat-stream/1.6.1: + /@types/concat-stream@1.6.1: resolution: {integrity: sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==} dependencies: '@types/node': 15.14.9 dev: true - /@types/debug/4.1.7: + /@types/debug@4.1.7: resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==} dependencies: '@types/ms': 0.7.31 dev: true - /@types/deep-equal-in-any-order/1.0.1: + /@types/deep-equal-in-any-order@1.0.1: resolution: {integrity: sha512-hUWUUE53WjKfcCncSmWmNXVNNT+0Iz7gYFnov3zdCXrX3Thxp1Cnmfd5LwWOeCVUV5LhpiFgS05vaAG72doo9w==} dev: true - /@types/events/3.0.0: + /@types/events@3.0.0: resolution: {integrity: sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==} dev: true - /@types/form-data/0.0.33: + /@types/form-data@0.0.33: resolution: {integrity: sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==} dependencies: '@types/node': 15.14.9 dev: true - /@types/glob/7.1.1: + /@types/glob@7.1.1: resolution: {integrity: sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==} dependencies: '@types/events': 3.0.0 @@ -1789,130 +1846,130 @@ packages: '@types/node': 15.14.9 dev: true - /@types/http-cache-semantics/4.0.1: + /@types/http-cache-semantics@4.0.1: resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==} dev: true - /@types/json-schema/7.0.11: + /@types/json-schema@7.0.11: resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} dev: true - /@types/keyv/3.1.4: + /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: '@types/node': 15.14.9 dev: true - /@types/lru-cache/5.1.1: + /@types/lru-cache@5.1.1: resolution: {integrity: sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==} dev: true - /@types/minimatch/3.0.3: + /@types/minimatch@3.0.3: resolution: {integrity: sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==} dev: true - /@types/mkdirp/0.5.2: + /@types/mkdirp@0.5.2: resolution: {integrity: sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==} dependencies: '@types/node': 15.14.9 dev: true - /@types/mocha/8.2.2: + /@types/mocha@8.2.2: resolution: {integrity: sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==} dev: true - /@types/ms/0.7.31: + /@types/ms@0.7.31: resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} dev: true - /@types/node-fetch/2.6.2: + /@types/node-fetch@2.6.2: resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==} dependencies: '@types/node': 15.14.9 form-data: 3.0.1 dev: true - /@types/node/10.17.60: + /@types/node@10.17.60: resolution: {integrity: sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==} dev: true - /@types/node/12.19.16: + /@types/node@12.19.16: resolution: {integrity: sha512-7xHmXm/QJ7cbK2laF+YYD7gb5MggHIIQwqyjin3bpEGiSuvScMQ5JZZXPvRipi1MwckTQbJZROMns/JxdnIL1Q==} dev: true - /@types/node/15.14.9: + /@types/node@15.14.9: resolution: {integrity: sha512-qjd88DrCxupx/kJD5yQgZdcYKZKSIGBVDIBE1/LTGcNm3d2Np/jxojkdePDdfnBHJc5W7vSMpbJ1aB7p/Py69A==} dev: true - /@types/node/8.10.66: + /@types/node@8.10.66: resolution: {integrity: sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==} dev: true - /@types/pbkdf2/3.1.0: + /@types/pbkdf2@3.1.0: resolution: {integrity: sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==} dependencies: '@types/node': 15.14.9 dev: true - /@types/prettier/2.7.1: + /@types/prettier@2.7.1: resolution: {integrity: sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==} dev: true - /@types/qs/6.9.7: + /@types/qs@6.9.7: resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} dev: true - /@types/resolve/0.0.8: + /@types/resolve@0.0.8: resolution: {integrity: sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==} dependencies: '@types/node': 15.14.9 dev: true - /@types/responselike/1.0.0: + /@types/responselike@1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} dependencies: '@types/node': 15.14.9 dev: true - /@types/secp256k1/4.0.3: + /@types/secp256k1@4.0.3: resolution: {integrity: sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==} dependencies: '@types/node': 15.14.9 dev: true - /@types/semver/7.5.0: + /@types/semver@7.5.0: resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} dev: true - /@types/sinon-chai/3.2.8: + /@types/sinon-chai@3.2.8: resolution: {integrity: sha512-d4ImIQbT/rKMG8+AXpmcan5T2/PNeSjrYhvkwet6z0p8kzYtfgA32xzOBlbU0yqJfq+/0Ml805iFoODO0LP5/g==} dependencies: '@types/chai': 4.3.3 '@types/sinon': 10.0.13 dev: true - /@types/sinon/10.0.13: + /@types/sinon@10.0.13: resolution: {integrity: sha512-UVjDqJblVNQYvVNUsj0PuYYw0ELRmgt1Nt5Vk0pT5f16ROGfcKJY8o1HVuMOJOpD727RrGB9EGvoaTQE5tgxZQ==} dependencies: '@types/sinonjs__fake-timers': 8.1.2 dev: true - /@types/sinonjs__fake-timers/8.1.2: + /@types/sinonjs__fake-timers@8.1.2: resolution: {integrity: sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==} dev: true - /@types/underscore/1.11.4: + /@types/underscore@1.11.4: resolution: {integrity: sha512-uO4CD2ELOjw8tasUrAhvnn2W4A0ZECOvMjCivJr4gA9pGgjv+qxKWY9GLTMVEK8ej85BxQOocUyE7hImmSQYcg==} dev: true - /@types/web3/1.0.19: + /@types/web3@1.0.19: resolution: {integrity: sha512-fhZ9DyvDYDwHZUp5/STa9XW2re0E8GxoioYJ4pEUZ13YHpApSagixj7IAdoYH5uAK+UalGq6Ml8LYzmgRA/q+A==} dependencies: '@types/bn.js': 5.1.1 '@types/underscore': 1.11.4 dev: true - /@typescript-eslint/eslint-plugin/5.59.8_loqfnwogukjtmydbmg57mzzpb4: + /@typescript-eslint/eslint-plugin@5.59.8(@typescript-eslint/parser@5.59.8)(eslint@8.42.0)(typescript@4.9.5): resolution: {integrity: sha512-JDMOmhXteJ4WVKOiHXGCoB96ADWg9q7efPWHRViT/f09bA8XOMLAVHHju3l0MkZnG1izaWXYmgvQcUjTRcpShQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -1924,23 +1981,23 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.5.1 - '@typescript-eslint/parser': 5.59.8_kigkzfftsmftz3xok324pyvzui + '@typescript-eslint/parser': 5.59.8(eslint@8.42.0)(typescript@4.9.5) '@typescript-eslint/scope-manager': 5.59.8 - '@typescript-eslint/type-utils': 5.59.8_kigkzfftsmftz3xok324pyvzui - '@typescript-eslint/utils': 5.59.8_kigkzfftsmftz3xok324pyvzui - debug: 4.3.4 + '@typescript-eslint/type-utils': 5.59.8(eslint@8.42.0)(typescript@4.9.5) + '@typescript-eslint/utils': 5.59.8(eslint@8.42.0)(typescript@4.9.5) + debug: 4.3.4(supports-color@8.1.1) eslint: 8.42.0 grapheme-splitter: 1.0.4 ignore: 5.2.4 natural-compare-lite: 1.4.0 semver: 7.5.0 - tsutils: 3.21.0_typescript@4.9.5 + tsutils: 3.21.0(typescript@4.9.5) typescript: 4.9.5 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser/5.59.8_kigkzfftsmftz3xok324pyvzui: + /@typescript-eslint/parser@5.59.8(eslint@8.42.0)(typescript@4.9.5): resolution: {integrity: sha512-AnR19RjJcpjoeGojmwZtCwBX/RidqDZtzcbG3xHrmz0aHHoOcbWnpDllenRDmDvsV0RQ6+tbb09/kyc+UT9Orw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -1952,15 +2009,15 @@ packages: dependencies: '@typescript-eslint/scope-manager': 5.59.8 '@typescript-eslint/types': 5.59.8 - '@typescript-eslint/typescript-estree': 5.59.8_typescript@4.9.5 - debug: 4.3.4 + '@typescript-eslint/typescript-estree': 5.59.8(typescript@4.9.5) + debug: 4.3.4(supports-color@8.1.1) eslint: 8.42.0 typescript: 4.9.5 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager/5.59.8: + /@typescript-eslint/scope-manager@5.59.8: resolution: {integrity: sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: @@ -1968,7 +2025,7 @@ packages: '@typescript-eslint/visitor-keys': 5.59.8 dev: true - /@typescript-eslint/type-utils/5.59.8_kigkzfftsmftz3xok324pyvzui: + /@typescript-eslint/type-utils@5.59.8(eslint@8.42.0)(typescript@4.9.5): resolution: {integrity: sha512-+5M518uEIHFBy3FnyqZUF3BMP+AXnYn4oyH8RF012+e7/msMY98FhGL5SrN29NQ9xDgvqCgYnsOiKp1VjZ/fpA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -1978,22 +2035,22 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.59.8_typescript@4.9.5 - '@typescript-eslint/utils': 5.59.8_kigkzfftsmftz3xok324pyvzui - debug: 4.3.4 + '@typescript-eslint/typescript-estree': 5.59.8(typescript@4.9.5) + '@typescript-eslint/utils': 5.59.8(eslint@8.42.0)(typescript@4.9.5) + debug: 4.3.4(supports-color@8.1.1) eslint: 8.42.0 - tsutils: 3.21.0_typescript@4.9.5 + tsutils: 3.21.0(typescript@4.9.5) typescript: 4.9.5 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types/5.59.8: + /@typescript-eslint/types@5.59.8: resolution: {integrity: sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree/5.59.8_typescript@4.9.5: + /@typescript-eslint/typescript-estree@5.59.8(typescript@4.9.5): resolution: {integrity: sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -2004,28 +2061,28 @@ packages: dependencies: '@typescript-eslint/types': 5.59.8 '@typescript-eslint/visitor-keys': 5.59.8 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.0 - tsutils: 3.21.0_typescript@4.9.5 + tsutils: 3.21.0(typescript@4.9.5) typescript: 4.9.5 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils/5.59.8_kigkzfftsmftz3xok324pyvzui: + /@typescript-eslint/utils@5.59.8(eslint@8.42.0)(typescript@4.9.5): resolution: {integrity: sha512-Tr65630KysnNn9f9G7ROF3w1b5/7f6QVCJ+WK9nhIocWmx9F+TmCAcglF26Vm7z8KCTwoKcNEBZrhlklla3CKg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0_eslint@8.42.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.42.0) '@types/json-schema': 7.0.11 '@types/semver': 7.5.0 '@typescript-eslint/scope-manager': 5.59.8 '@typescript-eslint/types': 5.59.8 - '@typescript-eslint/typescript-estree': 5.59.8_typescript@4.9.5 + '@typescript-eslint/typescript-estree': 5.59.8(typescript@4.9.5) eslint: 8.42.0 eslint-scope: 5.1.1 semver: 7.5.0 @@ -2034,7 +2091,7 @@ packages: - typescript dev: true - /@typescript-eslint/visitor-keys/5.59.8: + /@typescript-eslint/visitor-keys@5.59.8: resolution: {integrity: sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: @@ -2042,48 +2099,48 @@ packages: eslint-visitor-keys: 3.4.1 dev: true - /@yarnpkg/lockfile/1.1.0: + /@yarnpkg/lockfile@1.1.0: resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} dev: true - /abbrev/1.0.9: + /abbrev@1.0.9: resolution: {integrity: sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==} dev: true - /abbrev/1.1.1: + /abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} dev: true - /abi-to-sol/0.6.6: + /abi-to-sol@0.6.6: resolution: {integrity: sha512-PRn81rSpv6NXFPYQSw7ujruqIP6UkwZ/XoFldtiqCX8+2kHVc73xVaUVvdbro06vvBVZiwnxhEIGdI4BRMwGHw==} hasBin: true dependencies: '@truffle/abi-utils': 0.3.2 '@truffle/contract-schema': 3.4.10 ajv: 6.12.6 - better-ajv-errors: 0.8.2_ajv@6.12.6 + better-ajv-errors: 0.8.2(ajv@6.12.6) neodoc: 2.0.2 semver: 7.3.7 source-map-support: 0.5.21 optionalDependencies: prettier: 2.8.8 - prettier-plugin-solidity: 1.1.3_prettier@2.8.8 + prettier-plugin-solidity: 1.1.3(prettier@2.8.8) transitivePeerDependencies: - supports-color dev: true - /abort-controller/3.0.0: + /abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} dependencies: event-target-shim: 5.0.1 dev: true - /abortcontroller-polyfill/1.7.3: + /abortcontroller-polyfill@1.7.3: resolution: {integrity: sha512-zetDJxd89y3X99Kvo4qFx8GKlt6GsvN3UcRZHwU6iFA/0KiOmhkTVhe8oRoTBiTVPZu09x3vCra47+w8Yz1+2Q==} dev: true - /abstract-level/1.0.3: + /abstract-level@1.0.3: resolution: {integrity: sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==} engines: {node: '>=12'} dependencies: @@ -2096,33 +2153,33 @@ packages: queue-microtask: 1.2.3 dev: true - /abstract-leveldown/2.6.3: + /abstract-leveldown@2.6.3: resolution: {integrity: sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==} dependencies: xtend: 4.0.2 dev: true - /abstract-leveldown/2.7.2: + /abstract-leveldown@2.7.2: resolution: {integrity: sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==} dependencies: xtend: 4.0.2 dev: true - /abstract-leveldown/3.0.0: + /abstract-leveldown@3.0.0: resolution: {integrity: sha512-KUWx9UWGQD12zsmLNj64/pndaz4iJh/Pj7nopgkfDG6RlCcbMZvT6+9l7dchK4idog2Is8VdC/PvNbFuFmalIQ==} engines: {node: '>=4'} dependencies: xtend: 4.0.2 dev: true - /abstract-leveldown/5.0.0: + /abstract-leveldown@5.0.0: resolution: {integrity: sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A==} engines: {node: '>=6'} dependencies: xtend: 4.0.2 dev: true - /accepts/1.3.7: + /accepts@1.3.7: resolution: {integrity: sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==} engines: {node: '>= 0.6'} dependencies: @@ -2130,7 +2187,7 @@ packages: negotiator: 0.6.2 dev: true - /acorn-jsx/5.3.2_acorn@8.8.0: + /acorn-jsx@5.3.2(acorn@8.8.0): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -2138,40 +2195,41 @@ packages: acorn: 8.8.0 dev: true - /acorn/8.8.0: + /acorn@8.8.0: resolution: {integrity: sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==} engines: {node: '>=0.4.0'} hasBin: true dev: true - /address/1.1.2: + /address@1.1.2: resolution: {integrity: sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==} engines: {node: '>= 0.12.0'} dev: true - /adm-zip/0.4.16: + /adm-zip@0.4.16: resolution: {integrity: sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==} engines: {node: '>=0.3.0'} dev: true - /aes-js/3.0.0: + /aes-js@3.0.0: resolution: {integrity: sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==} - /aes-js/3.1.2: + /aes-js@3.1.2: resolution: {integrity: sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==} + requiresBuild: true dev: true optional: true - /agent-base/6.0.2: + /agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} dependencies: - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true - /aggregate-error/3.1.0: + /aggregate-error@3.1.0: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} dependencies: @@ -2179,7 +2237,7 @@ packages: indent-string: 4.0.0 dev: true - /ajv/6.12.6: + /ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} dependencies: fast-deep-equal: 3.1.3 @@ -2188,7 +2246,7 @@ packages: uri-js: 4.4.1 dev: true - /ajv/8.11.0: + /ajv@8.11.0: resolution: {integrity: sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==} dependencies: fast-deep-equal: 3.1.3 @@ -2197,88 +2255,89 @@ packages: uri-js: 4.4.1 dev: true - /amdefine/1.0.1: + /amdefine@1.0.1: resolution: {integrity: sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==} engines: {node: '>=0.4.2'} + requiresBuild: true dev: true optional: true - /ansi-colors/3.2.3: + /ansi-colors@3.2.3: resolution: {integrity: sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==} engines: {node: '>=6'} dev: true - /ansi-colors/3.2.4: + /ansi-colors@3.2.4: resolution: {integrity: sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==} engines: {node: '>=6'} dev: true - /ansi-colors/4.1.1: + /ansi-colors@4.1.1: resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} engines: {node: '>=6'} dev: true - /ansi-colors/4.1.3: + /ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} dev: true - /ansi-escapes/4.3.2: + /ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} dependencies: type-fest: 0.21.3 dev: true - /ansi-regex/2.1.1: + /ansi-regex@2.1.1: resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} engines: {node: '>=0.10.0'} dev: true - /ansi-regex/3.0.1: + /ansi-regex@3.0.1: resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==} engines: {node: '>=4'} dev: true - /ansi-regex/4.1.1: + /ansi-regex@4.1.1: resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} engines: {node: '>=6'} dev: true - /ansi-regex/5.0.1: + /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} dev: true - /ansi-styles/2.2.1: + /ansi-styles@2.2.1: resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==} engines: {node: '>=0.10.0'} dev: true - /ansi-styles/3.2.1: + /ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} dependencies: color-convert: 1.9.3 dev: true - /ansi-styles/4.3.0: + /ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} dependencies: color-convert: 2.0.1 dev: true - /antlr4/4.13.0: + /antlr4@4.13.0: resolution: {integrity: sha512-zooUbt+UscjnWyOrsuY/tVFL4rwrAGwOivpQmvmUDE22hy/lUA467Rc1rcixyRwcRUIXFYBwv7+dClDSHdmmew==} engines: {node: '>=16'} dev: true - /antlr4ts/0.5.0-alpha.4: + /antlr4ts@0.5.0-alpha.4: resolution: {integrity: sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==} dev: true - /anymatch/3.1.2: + /anymatch@3.1.2: resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} engines: {node: '>= 8'} dependencies: @@ -2286,83 +2345,83 @@ packages: picomatch: 2.3.1 dev: true - /arg/4.1.3: + /arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} dev: true - /argparse/1.0.10: + /argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} dependencies: sprintf-js: 1.0.3 dev: true - /argparse/2.0.1: + /argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true - /arr-diff/4.0.0: + /arr-diff@4.0.0: resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} engines: {node: '>=0.10.0'} dev: true - /arr-flatten/1.1.0: + /arr-flatten@1.1.0: resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} engines: {node: '>=0.10.0'} dev: true - /arr-union/3.1.0: + /arr-union@3.1.0: resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} engines: {node: '>=0.10.0'} dev: true - /array-back/1.0.4: + /array-back@1.0.4: resolution: {integrity: sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==} engines: {node: '>=0.12.0'} dependencies: typical: 2.6.1 dev: true - /array-back/2.0.0: + /array-back@2.0.0: resolution: {integrity: sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==} engines: {node: '>=4'} dependencies: typical: 2.6.1 dev: true - /array-back/3.1.0: + /array-back@3.1.0: resolution: {integrity: sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==} engines: {node: '>=6'} dev: true - /array-back/4.0.2: + /array-back@4.0.2: resolution: {integrity: sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==} engines: {node: '>=8'} dev: true - /array-filter/1.0.0: + /array-filter@1.0.0: resolution: {integrity: sha512-Ene1hbrinPZ1qPoZp7NSx4jQnh4nr7MtY78pHNb+yr8yHbxmTS7ChGW0a55JKA7TkRDeoQxK4GcJaCvBYplSKA==} dev: true - /array-flatten/1.1.1: + /array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} dev: true - /array-union/2.1.0: + /array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} dev: true - /array-uniq/1.0.3: + /array-uniq@1.0.3: resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} engines: {node: '>=0.10.0'} dev: true - /array-unique/0.3.2: + /array-unique@0.3.2: resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} engines: {node: '>=0.10.0'} dev: true - /array.prototype.reduce/1.0.4: + /array.prototype.reduce@1.0.4: resolution: {integrity: sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==} engines: {node: '>= 0.4'} dependencies: @@ -2373,11 +2432,11 @@ packages: is-string: 1.0.7 dev: true - /asap/2.0.6: + /asap@2.0.6: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} dev: true - /asn1.js/4.10.1: + /asn1.js@4.10.1: resolution: {integrity: sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==} dependencies: bn.js: 4.12.0 @@ -2385,91 +2444,91 @@ packages: minimalistic-assert: 1.0.1 dev: true - /asn1/0.2.4: + /asn1@0.2.4: resolution: {integrity: sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==} dependencies: safer-buffer: 2.1.2 dev: true - /assert-plus/1.0.0: + /assert-plus@1.0.0: resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} engines: {node: '>=0.8'} dev: true - /assertion-error/1.1.0: + /assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} - /assign-symbols/1.0.0: + /assign-symbols@1.0.0: resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} engines: {node: '>=0.10.0'} dev: true - /ast-parents/0.0.1: + /ast-parents@0.0.1: resolution: {integrity: sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA==} dev: true - /astral-regex/2.0.0: + /astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} dev: true - /async-eventemitter/0.2.4: + /async-eventemitter@0.2.4: resolution: {integrity: sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==} dependencies: async: 2.6.3 dev: true - /async-limiter/1.0.1: + /async-limiter@1.0.1: resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==} dev: true - /async/1.5.2: + /async@1.5.2: resolution: {integrity: sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==} dev: true - /async/2.6.2: + /async@2.6.2: resolution: {integrity: sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==} dependencies: lodash: 4.17.21 dev: true - /async/2.6.3: + /async@2.6.3: resolution: {integrity: sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==} dependencies: lodash: 4.17.21 dev: true - /asynckit/0.4.0: + /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: true - /at-least-node/1.0.0: + /at-least-node@1.0.0: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} dev: true - /atob/2.1.2: + /atob@2.1.2: resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} engines: {node: '>= 4.5.0'} hasBin: true dev: true - /available-typed-arrays/1.0.2: + /available-typed-arrays@1.0.2: resolution: {integrity: sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==} engines: {node: '>= 0.4'} dependencies: array-filter: 1.0.0 dev: true - /aws-sign2/0.7.0: + /aws-sign2@0.7.0: resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} dev: true - /aws4/1.11.0: + /aws4@1.11.0: resolution: {integrity: sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==} dev: true - /babel-code-frame/6.26.0: + /babel-code-frame@6.26.0: resolution: {integrity: sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==} dependencies: chalk: 1.1.3 @@ -2477,7 +2536,7 @@ packages: js-tokens: 3.0.2 dev: true - /babel-core/6.26.3: + /babel-core@6.26.3: resolution: {integrity: sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==} dependencies: babel-code-frame: 6.26.0 @@ -2503,7 +2562,7 @@ packages: - supports-color dev: true - /babel-generator/6.26.1: + /babel-generator@6.26.1: resolution: {integrity: sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==} dependencies: babel-messages: 6.23.0 @@ -2516,7 +2575,7 @@ packages: trim-right: 1.0.1 dev: true - /babel-helper-builder-binary-assignment-operator-visitor/6.24.1: + /babel-helper-builder-binary-assignment-operator-visitor@6.24.1: resolution: {integrity: sha512-gCtfYORSG1fUMX4kKraymq607FWgMWg+j42IFPc18kFQEsmtaibP4UrqsXt8FlEJle25HUd4tsoDR7H2wDhe9Q==} dependencies: babel-helper-explode-assignable-expression: 6.24.1 @@ -2526,7 +2585,7 @@ packages: - supports-color dev: true - /babel-helper-call-delegate/6.24.1: + /babel-helper-call-delegate@6.24.1: resolution: {integrity: sha512-RL8n2NiEj+kKztlrVJM9JT1cXzzAdvWFh76xh/H1I4nKwunzE4INBXn8ieCZ+wh4zWszZk7NBS1s/8HR5jDkzQ==} dependencies: babel-helper-hoist-variables: 6.24.1 @@ -2537,7 +2596,7 @@ packages: - supports-color dev: true - /babel-helper-define-map/6.26.0: + /babel-helper-define-map@6.26.0: resolution: {integrity: sha512-bHkmjcC9lM1kmZcVpA5t2om2nzT/xiZpo6TJq7UlZ3wqKfzia4veeXbIhKvJXAMzhhEBd3cR1IElL5AenWEUpA==} dependencies: babel-helper-function-name: 6.24.1 @@ -2548,7 +2607,7 @@ packages: - supports-color dev: true - /babel-helper-explode-assignable-expression/6.24.1: + /babel-helper-explode-assignable-expression@6.24.1: resolution: {integrity: sha512-qe5csbhbvq6ccry9G7tkXbzNtcDiH4r51rrPUbwwoTzZ18AqxWYRZT6AOmxrpxKnQBW0pYlBI/8vh73Z//78nQ==} dependencies: babel-runtime: 6.26.0 @@ -2558,7 +2617,7 @@ packages: - supports-color dev: true - /babel-helper-function-name/6.24.1: + /babel-helper-function-name@6.24.1: resolution: {integrity: sha512-Oo6+e2iX+o9eVvJ9Y5eKL5iryeRdsIkwRYheCuhYdVHsdEQysbc2z2QkqCLIYnNxkT5Ss3ggrHdXiDI7Dhrn4Q==} dependencies: babel-helper-get-function-arity: 6.24.1 @@ -2570,28 +2629,28 @@ packages: - supports-color dev: true - /babel-helper-get-function-arity/6.24.1: + /babel-helper-get-function-arity@6.24.1: resolution: {integrity: sha512-WfgKFX6swFB1jS2vo+DwivRN4NB8XUdM3ij0Y1gnC21y1tdBoe6xjVnd7NSI6alv+gZXCtJqvrTeMW3fR/c0ng==} dependencies: babel-runtime: 6.26.0 babel-types: 6.26.0 dev: true - /babel-helper-hoist-variables/6.24.1: + /babel-helper-hoist-variables@6.24.1: resolution: {integrity: sha512-zAYl3tqerLItvG5cKYw7f1SpvIxS9zi7ohyGHaI9cgDUjAT6YcY9jIEH5CstetP5wHIVSceXwNS7Z5BpJg+rOw==} dependencies: babel-runtime: 6.26.0 babel-types: 6.26.0 dev: true - /babel-helper-optimise-call-expression/6.24.1: + /babel-helper-optimise-call-expression@6.24.1: resolution: {integrity: sha512-Op9IhEaxhbRT8MDXx2iNuMgciu2V8lDvYCNQbDGjdBNCjaMvyLf4wl4A3b8IgndCyQF8TwfgsQ8T3VD8aX1/pA==} dependencies: babel-runtime: 6.26.0 babel-types: 6.26.0 dev: true - /babel-helper-regex/6.26.0: + /babel-helper-regex@6.26.0: resolution: {integrity: sha512-VlPiWmqmGJp0x0oK27Out1D+71nVVCTSdlbhIVoaBAj2lUgrNjBCRR9+llO4lTSb2O4r7PJg+RobRkhBrf6ofg==} dependencies: babel-runtime: 6.26.0 @@ -2599,7 +2658,7 @@ packages: lodash: 4.17.21 dev: true - /babel-helper-remap-async-to-generator/6.24.1: + /babel-helper-remap-async-to-generator@6.24.1: resolution: {integrity: sha512-RYqaPD0mQyQIFRu7Ho5wE2yvA/5jxqCIj/Lv4BXNq23mHYu/vxikOy2JueLiBxQknwapwrJeNCesvY0ZcfnlHg==} dependencies: babel-helper-function-name: 6.24.1 @@ -2611,7 +2670,7 @@ packages: - supports-color dev: true - /babel-helper-replace-supers/6.24.1: + /babel-helper-replace-supers@6.24.1: resolution: {integrity: sha512-sLI+u7sXJh6+ToqDr57Bv973kCepItDhMou0xCP2YPVmR1jkHSCY+p1no8xErbV1Siz5QE8qKT1WIwybSWlqjw==} dependencies: babel-helper-optimise-call-expression: 6.24.1 @@ -2624,7 +2683,7 @@ packages: - supports-color dev: true - /babel-helpers/6.24.1: + /babel-helpers@6.24.1: resolution: {integrity: sha512-n7pFrqQm44TCYvrCDb0MqabAF+JUBq+ijBvNMUxpkLjJaAu32faIexewMumrH5KLLJ1HDyT0PTEqRyAe/GwwuQ==} dependencies: babel-runtime: 6.26.0 @@ -2633,31 +2692,31 @@ packages: - supports-color dev: true - /babel-messages/6.23.0: + /babel-messages@6.23.0: resolution: {integrity: sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==} dependencies: babel-runtime: 6.26.0 dev: true - /babel-plugin-check-es2015-constants/6.22.0: + /babel-plugin-check-es2015-constants@6.22.0: resolution: {integrity: sha512-B1M5KBP29248dViEo1owyY32lk1ZSH2DaNNrXLGt8lyjjHm7pBqAdQ7VKUPR6EEDO323+OvT3MQXbCin8ooWdA==} dependencies: babel-runtime: 6.26.0 dev: true - /babel-plugin-syntax-async-functions/6.13.0: + /babel-plugin-syntax-async-functions@6.13.0: resolution: {integrity: sha512-4Zp4unmHgw30A1eWI5EpACji2qMocisdXhAftfhXoSV9j0Tvj6nRFE3tOmRY912E0FMRm/L5xWE7MGVT2FoLnw==} dev: true - /babel-plugin-syntax-exponentiation-operator/6.13.0: + /babel-plugin-syntax-exponentiation-operator@6.13.0: resolution: {integrity: sha512-Z/flU+T9ta0aIEKl1tGEmN/pZiI1uXmCiGFRegKacQfEJzp7iNsKloZmyJlQr+75FCJtiFfGIK03SiCvCt9cPQ==} dev: true - /babel-plugin-syntax-trailing-function-commas/6.22.0: + /babel-plugin-syntax-trailing-function-commas@6.22.0: resolution: {integrity: sha512-Gx9CH3Q/3GKbhs07Bszw5fPTlU+ygrOGfAhEt7W2JICwufpC4SuO0mG0+4NykPBSYPMJhqvVlDBU17qB1D+hMQ==} dev: true - /babel-plugin-transform-async-to-generator/6.24.1: + /babel-plugin-transform-async-to-generator@6.24.1: resolution: {integrity: sha512-7BgYJujNCg0Ti3x0c/DL3tStvnKS6ktIYOmo9wginv/dfZOrbSZ+qG4IRRHMBOzZ5Awb1skTiAsQXg/+IWkZYw==} dependencies: babel-helper-remap-async-to-generator: 6.24.1 @@ -2667,19 +2726,19 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-arrow-functions/6.22.0: + /babel-plugin-transform-es2015-arrow-functions@6.22.0: resolution: {integrity: sha512-PCqwwzODXW7JMrzu+yZIaYbPQSKjDTAsNNlK2l5Gg9g4rz2VzLnZsStvp/3c46GfXpwkyufb3NCyG9+50FF1Vg==} dependencies: babel-runtime: 6.26.0 dev: true - /babel-plugin-transform-es2015-block-scoped-functions/6.22.0: + /babel-plugin-transform-es2015-block-scoped-functions@6.22.0: resolution: {integrity: sha512-2+ujAT2UMBzYFm7tidUsYh+ZoIutxJ3pN9IYrF1/H6dCKtECfhmB8UkHVpyxDwkj0CYbQG35ykoz925TUnBc3A==} dependencies: babel-runtime: 6.26.0 dev: true - /babel-plugin-transform-es2015-block-scoping/6.26.0: + /babel-plugin-transform-es2015-block-scoping@6.26.0: resolution: {integrity: sha512-YiN6sFAQ5lML8JjCmr7uerS5Yc/EMbgg9G8ZNmk2E3nYX4ckHR01wrkeeMijEf5WHNK5TW0Sl0Uu3pv3EdOJWw==} dependencies: babel-runtime: 6.26.0 @@ -2691,7 +2750,7 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-classes/6.24.1: + /babel-plugin-transform-es2015-classes@6.24.1: resolution: {integrity: sha512-5Dy7ZbRinGrNtmWpquZKZ3EGY8sDgIVB4CU8Om8q8tnMLrD/m94cKglVcHps0BCTdZ0TJeeAWOq2TK9MIY6cag==} dependencies: babel-helper-define-map: 6.26.0 @@ -2707,7 +2766,7 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-computed-properties/6.24.1: + /babel-plugin-transform-es2015-computed-properties@6.24.1: resolution: {integrity: sha512-C/uAv4ktFP/Hmh01gMTvYvICrKze0XVX9f2PdIXuriCSvUmV9j+u+BB9f5fJK3+878yMK6dkdcq+Ymr9mrcLzw==} dependencies: babel-runtime: 6.26.0 @@ -2716,26 +2775,26 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-destructuring/6.23.0: + /babel-plugin-transform-es2015-destructuring@6.23.0: resolution: {integrity: sha512-aNv/GDAW0j/f4Uy1OEPZn1mqD+Nfy9viFGBfQ5bZyT35YqOiqx7/tXdyfZkJ1sC21NyEsBdfDY6PYmLHF4r5iA==} dependencies: babel-runtime: 6.26.0 dev: true - /babel-plugin-transform-es2015-duplicate-keys/6.24.1: + /babel-plugin-transform-es2015-duplicate-keys@6.24.1: resolution: {integrity: sha512-ossocTuPOssfxO2h+Z3/Ea1Vo1wWx31Uqy9vIiJusOP4TbF7tPs9U0sJ9pX9OJPf4lXRGj5+6Gkl/HHKiAP5ug==} dependencies: babel-runtime: 6.26.0 babel-types: 6.26.0 dev: true - /babel-plugin-transform-es2015-for-of/6.23.0: + /babel-plugin-transform-es2015-for-of@6.23.0: resolution: {integrity: sha512-DLuRwoygCoXx+YfxHLkVx5/NpeSbVwfoTeBykpJK7JhYWlL/O8hgAK/reforUnZDlxasOrVPPJVI/guE3dCwkw==} dependencies: babel-runtime: 6.26.0 dev: true - /babel-plugin-transform-es2015-function-name/6.24.1: + /babel-plugin-transform-es2015-function-name@6.24.1: resolution: {integrity: sha512-iFp5KIcorf11iBqu/y/a7DK3MN5di3pNCzto61FqCNnUX4qeBwcV1SLqe10oXNnCaxBUImX3SckX2/o1nsrTcg==} dependencies: babel-helper-function-name: 6.24.1 @@ -2745,13 +2804,13 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-literals/6.22.0: + /babel-plugin-transform-es2015-literals@6.22.0: resolution: {integrity: sha512-tjFl0cwMPpDYyoqYA9li1/7mGFit39XiNX5DKC/uCNjBctMxyL1/PT/l4rSlbvBG1pOKI88STRdUsWXB3/Q9hQ==} dependencies: babel-runtime: 6.26.0 dev: true - /babel-plugin-transform-es2015-modules-amd/6.24.1: + /babel-plugin-transform-es2015-modules-amd@6.24.1: resolution: {integrity: sha512-LnIIdGWIKdw7zwckqx+eGjcS8/cl8D74A3BpJbGjKTFFNJSMrjN4bIh22HY1AlkUbeLG6X6OZj56BDvWD+OeFA==} dependencies: babel-plugin-transform-es2015-modules-commonjs: 6.26.2 @@ -2761,7 +2820,7 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-modules-commonjs/6.26.2: + /babel-plugin-transform-es2015-modules-commonjs@6.26.2: resolution: {integrity: sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==} dependencies: babel-plugin-transform-strict-mode: 6.24.1 @@ -2772,7 +2831,7 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-modules-systemjs/6.24.1: + /babel-plugin-transform-es2015-modules-systemjs@6.24.1: resolution: {integrity: sha512-ONFIPsq8y4bls5PPsAWYXH/21Hqv64TBxdje0FvU3MhIV6QM2j5YS7KvAzg/nTIVLot2D2fmFQrFWCbgHlFEjg==} dependencies: babel-helper-hoist-variables: 6.24.1 @@ -2782,7 +2841,7 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-modules-umd/6.24.1: + /babel-plugin-transform-es2015-modules-umd@6.24.1: resolution: {integrity: sha512-LpVbiT9CLsuAIp3IG0tfbVo81QIhn6pE8xBJ7XSeCtFlMltuar5VuBV6y6Q45tpui9QWcy5i0vLQfCfrnF7Kiw==} dependencies: babel-plugin-transform-es2015-modules-amd: 6.24.1 @@ -2792,7 +2851,7 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-object-super/6.24.1: + /babel-plugin-transform-es2015-object-super@6.24.1: resolution: {integrity: sha512-8G5hpZMecb53vpD3mjs64NhI1au24TAmokQ4B+TBFBjN9cVoGoOvotdrMMRmHvVZUEvqGUPWL514woru1ChZMA==} dependencies: babel-helper-replace-supers: 6.24.1 @@ -2801,7 +2860,7 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-parameters/6.24.1: + /babel-plugin-transform-es2015-parameters@6.24.1: resolution: {integrity: sha512-8HxlW+BB5HqniD+nLkQ4xSAVq3bR/pcYW9IigY+2y0dI+Y7INFeTbfAQr+63T3E4UDsZGjyb+l9txUnABWxlOQ==} dependencies: babel-helper-call-delegate: 6.24.1 @@ -2814,20 +2873,20 @@ packages: - supports-color dev: true - /babel-plugin-transform-es2015-shorthand-properties/6.24.1: + /babel-plugin-transform-es2015-shorthand-properties@6.24.1: resolution: {integrity: sha512-mDdocSfUVm1/7Jw/FIRNw9vPrBQNePy6wZJlR8HAUBLybNp1w/6lr6zZ2pjMShee65t/ybR5pT8ulkLzD1xwiw==} dependencies: babel-runtime: 6.26.0 babel-types: 6.26.0 dev: true - /babel-plugin-transform-es2015-spread/6.22.0: + /babel-plugin-transform-es2015-spread@6.22.0: resolution: {integrity: sha512-3Ghhi26r4l3d0Js933E5+IhHwk0A1yiutj9gwvzmFbVV0sPMYk2lekhOufHBswX7NCoSeF4Xrl3sCIuSIa+zOg==} dependencies: babel-runtime: 6.26.0 dev: true - /babel-plugin-transform-es2015-sticky-regex/6.24.1: + /babel-plugin-transform-es2015-sticky-regex@6.24.1: resolution: {integrity: sha512-CYP359ADryTo3pCsH0oxRo/0yn6UsEZLqYohHmvLQdfS9xkf+MbCzE3/Kolw9OYIY4ZMilH25z/5CbQbwDD+lQ==} dependencies: babel-helper-regex: 6.26.0 @@ -2835,19 +2894,19 @@ packages: babel-types: 6.26.0 dev: true - /babel-plugin-transform-es2015-template-literals/6.22.0: + /babel-plugin-transform-es2015-template-literals@6.22.0: resolution: {integrity: sha512-x8b9W0ngnKzDMHimVtTfn5ryimars1ByTqsfBDwAqLibmuuQY6pgBQi5z1ErIsUOWBdw1bW9FSz5RZUojM4apg==} dependencies: babel-runtime: 6.26.0 dev: true - /babel-plugin-transform-es2015-typeof-symbol/6.23.0: + /babel-plugin-transform-es2015-typeof-symbol@6.23.0: resolution: {integrity: sha512-fz6J2Sf4gYN6gWgRZaoFXmq93X+Li/8vf+fb0sGDVtdeWvxC9y5/bTD7bvfWMEq6zetGEHpWjtzRGSugt5kNqw==} dependencies: babel-runtime: 6.26.0 dev: true - /babel-plugin-transform-es2015-unicode-regex/6.24.1: + /babel-plugin-transform-es2015-unicode-regex@6.24.1: resolution: {integrity: sha512-v61Dbbihf5XxnYjtBN04B/JBvsScY37R1cZT5r9permN1cp+b70DY3Ib3fIkgn1DI9U3tGgBJZVD8p/mE/4JbQ==} dependencies: babel-helper-regex: 6.26.0 @@ -2855,7 +2914,7 @@ packages: regexpu-core: 2.0.0 dev: true - /babel-plugin-transform-exponentiation-operator/6.24.1: + /babel-plugin-transform-exponentiation-operator@6.24.1: resolution: {integrity: sha512-LzXDmbMkklvNhprr20//RStKVcT8Cu+SQtX18eMHLhjHf2yFzwtQ0S2f0jQ+89rokoNdmwoSqYzAhq86FxlLSQ==} dependencies: babel-helper-builder-binary-assignment-operator-visitor: 6.24.1 @@ -2865,20 +2924,20 @@ packages: - supports-color dev: true - /babel-plugin-transform-regenerator/6.26.0: + /babel-plugin-transform-regenerator@6.26.0: resolution: {integrity: sha512-LS+dBkUGlNR15/5WHKe/8Neawx663qttS6AGqoOUhICc9d1KciBvtrQSuc0PI+CxQ2Q/S1aKuJ+u64GtLdcEZg==} dependencies: regenerator-transform: 0.10.1 dev: true - /babel-plugin-transform-strict-mode/6.24.1: + /babel-plugin-transform-strict-mode@6.24.1: resolution: {integrity: sha512-j3KtSpjyLSJxNoCDrhwiJad8kw0gJ9REGj8/CqL0HeRyLnvUNYV9zcqluL6QJSXh3nfsLEmSLvwRfGzrgR96Pw==} dependencies: babel-runtime: 6.26.0 babel-types: 6.26.0 dev: true - /babel-preset-env/1.7.0: + /babel-preset-env@1.7.0: resolution: {integrity: sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==} dependencies: babel-plugin-check-es2015-constants: 6.22.0 @@ -2915,7 +2974,7 @@ packages: - supports-color dev: true - /babel-register/6.26.0: + /babel-register@6.26.0: resolution: {integrity: sha512-veliHlHX06wjaeY8xNITbveXSiI+ASFnOqvne/LaIJIqOWi2Ogmj91KOugEz/hoh/fwMhXNBJPCv8Xaz5CyM4A==} dependencies: babel-core: 6.26.3 @@ -2929,14 +2988,14 @@ packages: - supports-color dev: true - /babel-runtime/6.26.0: + /babel-runtime@6.26.0: resolution: {integrity: sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==} dependencies: core-js: 2.6.12 regenerator-runtime: 0.11.1 dev: true - /babel-template/6.26.0: + /babel-template@6.26.0: resolution: {integrity: sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==} dependencies: babel-runtime: 6.26.0 @@ -2948,7 +3007,7 @@ packages: - supports-color dev: true - /babel-traverse/6.26.0: + /babel-traverse@6.26.0: resolution: {integrity: sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==} dependencies: babel-code-frame: 6.26.0 @@ -2964,7 +3023,7 @@ packages: - supports-color dev: true - /babel-types/6.26.0: + /babel-types@6.26.0: resolution: {integrity: sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==} dependencies: babel-runtime: 6.26.0 @@ -2973,7 +3032,7 @@ packages: to-fast-properties: 1.0.3 dev: true - /babelify/7.3.0: + /babelify@7.3.0: resolution: {integrity: sha512-vID8Fz6pPN5pJMdlUnNFSfrlcx5MUule4k9aKs/zbZPyXxMTcRrB0M4Tarw22L8afr8eYSWxDPYCob3TdrqtlA==} dependencies: babel-core: 6.26.3 @@ -2982,29 +3041,33 @@ packages: - supports-color dev: true - /babylon/6.18.0: + /babylon@6.18.0: resolution: {integrity: sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==} hasBin: true dev: true - /backoff/2.5.0: + /backoff@2.5.0: resolution: {integrity: sha512-wC5ihrnUXmR2douXmXLCe5O3zg3GKIyvRi/hi58a/XyRxVI+3/yM0PYueQOZXPXQ9pxBislYkw+sF9b7C/RuMA==} engines: {node: '>= 0.6'} dependencies: precond: 0.2.3 dev: true - /balanced-match/1.0.0: + /balanced-match@1.0.0: resolution: {integrity: sha512-9Y0g0Q8rmSt+H33DfKv7FOc3v+iRI+o1lbzt8jGcIosYW37IIW/2XVYq5NPdmaD5NQ59Nk26Kl/vZbwW9Fr8vg==} dev: true - /base-x/3.0.9: + /base-x@3.0.9: resolution: {integrity: sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==} dependencies: safe-buffer: 5.2.1 dev: true - /base/0.11.2: + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: true + + /base@0.11.2: resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} engines: {node: '>=0.10.0'} dependencies: @@ -3017,20 +3080,16 @@ packages: pascalcase: 0.1.1 dev: true - /base64-js/1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - dev: true - - /bcrypt-pbkdf/1.0.2: + /bcrypt-pbkdf@1.0.2: resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} dependencies: tweetnacl: 0.14.5 dev: true - /bech32/1.1.4: + /bech32@1.1.4: resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==} - /better-ajv-errors/0.8.2_ajv@6.12.6: + /better-ajv-errors@0.8.2(ajv@6.12.6): resolution: {integrity: sha512-FnODTBJSQSHmJXDLPiC7ca0dC4S1HSTPv1+Hg2sm/C71i3Dj0l1jcUEaq/3OQ6MmnUveshTsUvUj65pDSr3Qow==} peerDependencies: ajv: 4.11.8 - 8 @@ -3045,47 +3104,47 @@ packages: leven: 3.1.0 dev: true - /big-integer/1.6.36: + /big-integer@1.6.36: resolution: {integrity: sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==} engines: {node: '>=0.6'} dev: true - /big.js/6.2.1: + /big.js@6.2.1: resolution: {integrity: sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==} dev: true - /bigint-crypto-utils/3.1.8: + /bigint-crypto-utils@3.1.8: resolution: {integrity: sha512-+VMV9Laq8pXLBKKKK49nOoq9bfR3j7NNQAtbA617a4nw9bVLo8rsqkKMBgM2AJWlNX9fEIyYaYX+d0laqYV4tw==} engines: {node: '>=10.4.0'} dependencies: bigint-mod-arith: 3.1.2 dev: true - /bigint-mod-arith/3.1.2: + /bigint-mod-arith@3.1.2: resolution: {integrity: sha512-nx8J8bBeiRR+NlsROFH9jHswW5HO8mgfOSqW0AmjicMMvaONDa8AO+5ViKDUUNytBPWiwfvZP4/Bj4Y3lUfvgQ==} engines: {node: '>=10.4.0'} dev: true - /bignumber.js/7.2.1: + /bignumber.js@7.2.1: resolution: {integrity: sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==} dev: true - /bignumber.js/9.1.0: + /bignumber.js@9.1.0: resolution: {integrity: sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==} dev: true - /binary-extensions/2.2.0: + /binary-extensions@2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} dev: true - /bindings/1.5.0: + /bindings@1.5.0: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} dependencies: file-uri-to-path: 1.0.0 dev: true - /bip39/2.5.0: + /bip39@2.5.0: resolution: {integrity: sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA==} dependencies: create-hash: 1.2.0 @@ -3095,31 +3154,31 @@ packages: unorm: 1.6.0 dev: true - /bip66/1.1.5: + /bip66@1.1.5: resolution: {integrity: sha512-nemMHz95EmS38a26XbbdxIYj5csHd3RMP3H5bwQknX0WYHF01qhpufP42mLOwVICuH2JmhIhXiWs89MfUGL7Xw==} dependencies: safe-buffer: 5.2.1 dev: true - /blakejs/1.2.1: + /blakejs@1.2.1: resolution: {integrity: sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==} dev: true - /bluebird/3.7.2: + /bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} dev: true - /bn.js/4.11.6: + /bn.js@4.11.6: resolution: {integrity: sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==} dev: true - /bn.js/4.12.0: + /bn.js@4.12.0: resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} - /bn.js/5.2.1: + /bn.js@5.2.1: resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} - /body-parser/1.19.0: + /body-parser@1.19.0: resolution: {integrity: sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==} engines: {node: '>= 0.8'} dependencies: @@ -3137,24 +3196,24 @@ packages: - supports-color dev: true - /boolbase/1.0.0: + /boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} dev: true - /brace-expansion/1.1.11: + /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: balanced-match: 1.0.0 concat-map: 0.0.1 dev: true - /brace-expansion/2.0.1: + /brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} dependencies: balanced-match: 1.0.0 dev: true - /braces/2.3.2: + /braces@2.3.2: resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==} engines: {node: '>=0.10.0'} dependencies: @@ -3172,17 +3231,17 @@ packages: - supports-color dev: true - /braces/3.0.2: + /braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} dependencies: fill-range: 7.0.1 dev: true - /brorand/1.1.0: + /brorand@1.1.0: resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} - /browser-level/1.0.1: + /browser-level@1.0.1: resolution: {integrity: sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==} dependencies: abstract-level: 1.0.3 @@ -3191,11 +3250,11 @@ packages: run-parallel-limit: 1.1.0 dev: true - /browser-stdout/1.3.1: + /browser-stdout@1.3.1: resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} dev: true - /browserify-aes/1.2.0: + /browserify-aes@1.2.0: resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} dependencies: buffer-xor: 1.0.3 @@ -3206,7 +3265,7 @@ packages: safe-buffer: 5.2.1 dev: true - /browserify-cipher/1.0.1: + /browserify-cipher@1.0.1: resolution: {integrity: sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==} dependencies: browserify-aes: 1.2.0 @@ -3214,7 +3273,7 @@ packages: evp_bytestokey: 1.0.3 dev: true - /browserify-des/1.0.2: + /browserify-des@1.0.2: resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==} dependencies: cipher-base: 1.0.4 @@ -3223,21 +3282,21 @@ packages: safe-buffer: 5.2.1 dev: true - /browserify-rsa/4.0.1: + /browserify-rsa@4.0.1: resolution: {integrity: sha512-+YpEyaLDDvvdzIxQ+cCx73r5YEhS3ANGOkiHdyWqW4t3gdeoNEYjSiQwntbU4Uo2/9yRkpYX3SRFeH+7jc2Duw==} dependencies: bn.js: 4.12.0 randombytes: 2.1.0 dev: true - /browserify-sha3/0.0.4: + /browserify-sha3@0.0.4: resolution: {integrity: sha512-WmXX4M8lltqzMnBiPbP9KQdITknmxe4Wp3rhGfpYJst5yOeGwKkHpC0t+Ty22laH4Ltg9YO+p14p93wiipqjxA==} dependencies: js-sha3: 0.6.1 safe-buffer: 5.2.1 dev: true - /browserify-sign/4.0.4: + /browserify-sign@4.0.4: resolution: {integrity: sha512-D2ItxCwNtLcHRrOCuEDZQlIezlFyUV/N5IYz6TY1svu1noyThFuthoEjzT8ChZe3UEctqnwmykcPhet3Eiz58A==} dependencies: bn.js: 4.12.0 @@ -3249,7 +3308,7 @@ packages: parse-asn1: 5.1.5 dev: true - /browserslist/3.2.8: + /browserslist@3.2.8: resolution: {integrity: sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==} hasBin: true dependencies: @@ -3257,13 +3316,13 @@ packages: electron-to-chromium: 1.4.270 dev: true - /bs58/4.0.1: + /bs58@4.0.1: resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} dependencies: base-x: 3.0.9 dev: true - /bs58check/2.1.2: + /bs58check@2.1.2: resolution: {integrity: sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==} dependencies: bs58: 4.0.1 @@ -3271,39 +3330,39 @@ packages: safe-buffer: 5.2.1 dev: true - /buffer-from/1.1.2: + /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} dev: true - /buffer-to-arraybuffer/0.0.5: + /buffer-to-arraybuffer@0.0.5: resolution: {integrity: sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==} dev: true - /buffer-xor/1.0.3: + /buffer-xor@1.0.3: resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} dev: true - /buffer-xor/2.0.2: + /buffer-xor@2.0.2: resolution: {integrity: sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==} dependencies: safe-buffer: 5.2.1 dev: true - /buffer/5.7.1: + /buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} dependencies: base64-js: 1.5.1 ieee754: 1.2.1 dev: true - /buffer/6.0.3: + /buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} dependencies: base64-js: 1.5.1 ieee754: 1.2.1 dev: true - /bufferutil/4.0.6: + /bufferutil@4.0.6: resolution: {integrity: sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==} engines: {node: '>=6.14.2'} requiresBuild: true @@ -3311,42 +3370,42 @@ packages: node-gyp-build: 4.5.0 dev: true - /bufio/1.0.7: + /bufio@1.0.7: resolution: {integrity: sha512-bd1dDQhiC+bEbEfg56IdBv7faWa6OipMs/AFFFvtFnB3wAYjlwQpQRZ0pm6ZkgtfL0pILRXhKxOiQj6UzoMR7A==} engines: {node: '>=8.0.0'} dev: false - /busboy/1.6.0: + /busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} dependencies: streamsearch: 1.1.0 dev: true - /bytes/3.1.0: + /bytes@3.1.0: resolution: {integrity: sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==} engines: {node: '>= 0.8'} dev: true - /bytes/3.1.2: + /bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} dev: true - /bytewise-core/1.2.3: + /bytewise-core@1.2.3: resolution: {integrity: sha512-nZD//kc78OOxeYtRlVk8/zXqTB4gf/nlguL1ggWA8FuchMyOxcyHR4QPQZMUmA7czC+YnaBrPUCubqAWe50DaA==} dependencies: typewise-core: 1.2.0 dev: true - /bytewise/1.1.0: + /bytewise@1.1.0: resolution: {integrity: sha512-rHuuseJ9iQ0na6UDhnrRVDh8YnWVlU6xM3VH6q/+yHDeUH2zIhUzP+2/h3LIrhLDBtTqzWpE3p3tP/boefskKQ==} dependencies: bytewise-core: 1.2.3 typewise: 1.0.3 dev: true - /cache-base/1.0.1: + /cache-base@1.0.1: resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} engines: {node: '>=0.10.0'} dependencies: @@ -3361,14 +3420,15 @@ packages: unset-value: 1.0.0 dev: true - /cacheable-lookup/6.1.0: + /cacheable-lookup@6.1.0: resolution: {integrity: sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==} engines: {node: '>=10.6.0'} dev: true - /cacheable-request/6.1.0: + /cacheable-request@6.1.0: resolution: {integrity: sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==} engines: {node: '>=8'} + requiresBuild: true dependencies: clone-response: 1.0.2 get-stream: 5.1.0 @@ -3379,7 +3439,7 @@ packages: responselike: 1.0.2 dev: true - /cacheable-request/7.0.2: + /cacheable-request@7.0.2: resolution: {integrity: sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==} engines: {node: '>=8'} dependencies: @@ -3392,66 +3452,66 @@ packages: responselike: 2.0.1 dev: true - /cachedown/1.0.0: + /cachedown@1.0.0: resolution: {integrity: sha512-t+yVk82vQWCJF3PsWHMld+jhhjkkWjcAzz8NbFx1iULOXWl8Tm/FdM4smZNVw3MRr0X+lVTx9PKzvEn4Ng19RQ==} dependencies: abstract-leveldown: 2.7.2 lru-cache: 3.2.0 dev: true - /call-bind/1.0.2: + /call-bind@1.0.2: resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} dependencies: function-bind: 1.1.1 get-intrinsic: 1.1.3 dev: true - /callsites/3.1.0: + /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} dev: true - /camel-case/3.0.0: + /camel-case@3.0.0: resolution: {integrity: sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==} dependencies: no-case: 2.3.2 upper-case: 1.1.3 dev: true - /camelcase/3.0.0: + /camelcase@3.0.0: resolution: {integrity: sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==} engines: {node: '>=0.10.0'} dev: true - /camelcase/4.1.0: + /camelcase@4.1.0: resolution: {integrity: sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==} engines: {node: '>=4'} dev: true - /camelcase/5.3.1: + /camelcase@5.3.1: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} engines: {node: '>=6'} dev: true - /camelcase/6.3.0: + /camelcase@6.3.0: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} dev: true - /caniuse-lite/1.0.30001414: + /caniuse-lite@1.0.30001414: resolution: {integrity: sha512-t55jfSaWjCdocnFdKQoO+d2ct9C59UZg4dY3OnUlSZ447r8pUtIKdp0hpAzrGFultmTC+Us+KpKi4GZl/LXlFg==} dev: true - /caseless/0.12.0: + /caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} dev: true - /catering/2.1.1: + /catering@2.1.1: resolution: {integrity: sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==} engines: {node: '>=6'} dev: true - /cbor/5.2.0: + /cbor@5.2.0: resolution: {integrity: sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==} engines: {node: '>=6.0.0'} dependencies: @@ -3459,14 +3519,14 @@ packages: nofilter: 1.0.4 dev: true - /cbor/8.1.0: + /cbor@8.1.0: resolution: {integrity: sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==} engines: {node: '>=12.19'} dependencies: nofilter: 3.1.0 dev: true - /chai-bn/0.2.2_bn.js@4.12.0+chai@4.3.6: + /chai-bn@0.2.2(bn.js@4.12.0)(chai@4.3.6): resolution: {integrity: sha512-MzjelH0p8vWn65QKmEq/DLBG1Hle4WeyqT79ANhXZhn/UxRWO0OogkAxi5oGGtfzwU9bZR8mvbvYdoqNVWQwFg==} peerDependencies: bn.js: ^4.11.0 @@ -3476,7 +3536,7 @@ packages: chai: 4.3.6 dev: true - /chai/4.3.6: + /chai@4.3.6: resolution: {integrity: sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==} engines: {node: '>=4'} dependencies: @@ -3488,7 +3548,7 @@ packages: pathval: 1.1.1 type-detect: 4.0.8 - /chalk/1.1.3: + /chalk@1.1.3: resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==} engines: {node: '>=0.10.0'} dependencies: @@ -3499,7 +3559,7 @@ packages: supports-color: 2.0.0 dev: true - /chalk/2.4.2: + /chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} dependencies: @@ -3508,7 +3568,7 @@ packages: supports-color: 5.5.0 dev: true - /chalk/4.1.2: + /chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} dependencies: @@ -3516,7 +3576,7 @@ packages: supports-color: 7.2.0 dev: true - /change-case/3.0.2: + /change-case@3.0.2: resolution: {integrity: sha512-Mww+SLF6MZ0U6kdg11algyKd5BARbyM4TbFBepwowYSR5ClfQGCGtxNXgykpN0uF/bstWeaGDT4JWaDh8zWAHA==} dependencies: camel-case: 3.0.0 @@ -3539,20 +3599,20 @@ packages: upper-case-first: 1.1.2 dev: true - /charenc/0.0.2: + /charenc@0.0.2: resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} dev: true - /check-error/1.0.2: + /check-error@1.0.2: resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==} - /checkpoint-store/1.1.0: + /checkpoint-store@1.1.0: resolution: {integrity: sha512-J/NdY2WvIx654cc6LWSq/IYFFCUf75fFTgwzFnmbqyORH4MwgiQCgswLLKBGzmsyTI5V7i5bp/So6sMbDWhedg==} dependencies: functional-red-black-tree: 1.0.1 dev: true - /cheerio-select/2.1.0: + /cheerio-select@2.1.0: resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} dependencies: boolbase: 1.0.0 @@ -3563,7 +3623,7 @@ packages: domutils: 3.0.1 dev: true - /cheerio/1.0.0-rc.12: + /cheerio@1.0.0-rc.12: resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} engines: {node: '>= 6'} dependencies: @@ -3576,7 +3636,7 @@ packages: parse5-htmlparser2-tree-adapter: 7.0.0 dev: true - /chokidar/3.3.0: + /chokidar@3.3.0: resolution: {integrity: sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==} engines: {node: '>= 8.10.0'} dependencies: @@ -3591,7 +3651,7 @@ packages: fsevents: 2.1.3 dev: true - /chokidar/3.5.3: + /chokidar@3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} dependencies: @@ -3606,15 +3666,15 @@ packages: fsevents: 2.3.2 dev: true - /chownr/1.1.4: + /chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} dev: true - /ci-info/2.0.0: + /ci-info@2.0.0: resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} dev: true - /cids/0.7.5: + /cids@0.7.5: resolution: {integrity: sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==} engines: {node: '>=4.0.0', npm: '>=3.0.0'} deprecated: This module has been superseded by the multiformats module @@ -3626,18 +3686,18 @@ packages: multihashes: 0.4.21 dev: true - /cipher-base/1.0.4: + /cipher-base@1.0.4: resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==} dependencies: inherits: 2.0.4 safe-buffer: 5.2.1 dev: true - /class-is/1.1.0: + /class-is@1.1.0: resolution: {integrity: sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==} dev: true - /class-utils/0.3.6: + /class-utils@0.3.6: resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} engines: {node: '>=0.10.0'} dependencies: @@ -3647,7 +3707,7 @@ packages: static-extend: 0.1.2 dev: true - /classic-level/1.2.0: + /classic-level@1.2.0: resolution: {integrity: sha512-qw5B31ANxSluWz9xBzklRWTUAJ1SXIdaVKTVS7HcTGKOAmExx65Wo5BUICW+YGORe2FOUaDghoI9ZDxj82QcFg==} engines: {node: '>=12'} requiresBuild: true @@ -3659,12 +3719,12 @@ packages: node-gyp-build: 4.5.0 dev: true - /clean-stack/2.2.0: + /clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} dev: true - /cli-table3/0.5.1: + /cli-table3@0.5.1: resolution: {integrity: sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==} engines: {node: '>=6'} dependencies: @@ -3674,7 +3734,7 @@ packages: colors: 1.4.0 dev: true - /cli-table3/0.6.3: + /cli-table3@0.6.3: resolution: {integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==} engines: {node: 10.* || >= 12.*} dependencies: @@ -3683,7 +3743,7 @@ packages: '@colors/colors': 1.5.0 dev: true - /cliui/3.2.0: + /cliui@3.2.0: resolution: {integrity: sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==} dependencies: string-width: 1.0.2 @@ -3691,7 +3751,7 @@ packages: wrap-ansi: 2.1.0 dev: true - /cliui/5.0.0: + /cliui@5.0.0: resolution: {integrity: sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==} dependencies: string-width: 3.1.0 @@ -3699,7 +3759,7 @@ packages: wrap-ansi: 5.1.0 dev: true - /cliui/7.0.4: + /cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} dependencies: string-width: 4.2.3 @@ -3707,28 +3767,28 @@ packages: wrap-ansi: 7.0.0 dev: true - /clone-response/1.0.2: + /clone-response@1.0.2: resolution: {integrity: sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==} dependencies: mimic-response: 1.0.1 dev: true - /clone/2.1.2: + /clone@2.1.2: resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} engines: {node: '>=0.8'} dev: true - /code-error-fragment/0.0.230: + /code-error-fragment@0.0.230: resolution: {integrity: sha512-cadkfKp6932H8UkhzE/gcUqhRMNf8jHzkAN7+5Myabswaghu4xABTgPHDCjW+dBAJxj/SpkTYokpzDqY4pCzQw==} engines: {node: '>= 4'} dev: true - /code-point-at/1.1.0: + /code-point-at@1.1.0: resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==} engines: {node: '>=0.10.0'} dev: true - /collection-visit/1.0.0: + /collection-visit@1.0.0: resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} engines: {node: '>=0.10.0'} dependencies: @@ -3736,44 +3796,44 @@ packages: object-visit: 1.0.1 dev: true - /color-convert/1.9.3: + /color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: color-name: 1.1.3 dev: true - /color-convert/2.0.1: + /color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} dependencies: color-name: 1.1.4 dev: true - /color-name/1.1.3: + /color-name@1.1.3: resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} dev: true - /color-name/1.1.4: + /color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} dev: true - /colors/1.4.0: + /colors@1.4.0: resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} engines: {node: '>=0.1.90'} dev: true - /combined-stream/1.0.8: + /combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} dependencies: delayed-stream: 1.0.0 dev: true - /command-exists/1.2.9: + /command-exists@1.2.9: resolution: {integrity: sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==} dev: true - /command-line-args/4.0.7: + /command-line-args@4.0.7: resolution: {integrity: sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA==} hasBin: true dependencies: @@ -3782,7 +3842,7 @@ packages: typical: 2.6.1 dev: true - /command-line-args/5.2.1: + /command-line-args@5.2.1: resolution: {integrity: sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==} engines: {node: '>=4.0.0'} dependencies: @@ -3792,7 +3852,7 @@ packages: typical: 4.0.0 dev: true - /command-line-usage/6.1.3: + /command-line-usage@6.1.3: resolution: {integrity: sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==} engines: {node: '>=8.0.0'} dependencies: @@ -3802,28 +3862,28 @@ packages: typical: 5.2.0 dev: true - /commander/10.0.1: + /commander@10.0.1: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} dev: true - /commander/3.0.2: + /commander@3.0.2: resolution: {integrity: sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==} dev: true - /compare-versions/5.0.3: + /compare-versions@5.0.3: resolution: {integrity: sha512-4UZlZP8Z99MGEY+Ovg/uJxJuvoXuN4M6B3hKaiackiHrgzQFEe3diJi1mf1PNHbFujM7FvLrK2bpgIaImbtZ1A==} dev: true - /component-emitter/1.3.0: + /component-emitter@1.3.0: resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} dev: true - /concat-map/0.0.1: + /concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} dev: true - /concat-stream/1.6.2: + /concat-stream@1.6.2: resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} engines: {'0': node >= 0.8} dependencies: @@ -3833,21 +3893,21 @@ packages: typedarray: 0.0.6 dev: true - /constant-case/2.0.0: + /constant-case@2.0.0: resolution: {integrity: sha512-eS0N9WwmjTqrOmR3o83F5vW8Z+9R1HnVz3xmzT2PMFug9ly+Au/fxRWlEBSb6LcZwspSsEn9Xs1uw9YgzAg1EQ==} dependencies: snake-case: 2.1.0 upper-case: 1.1.3 dev: true - /content-disposition/0.5.3: + /content-disposition@0.5.3: resolution: {integrity: sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==} engines: {node: '>= 0.6'} dependencies: safe-buffer: 5.1.2 dev: true - /content-hash/2.5.2: + /content-hash@2.5.2: resolution: {integrity: sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==} dependencies: cids: 0.7.5 @@ -3855,65 +3915,66 @@ packages: multihashes: 0.4.21 dev: true - /content-type/1.0.4: + /content-type@1.0.4: resolution: {integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==} engines: {node: '>= 0.6'} dev: true - /convert-source-map/1.8.0: + /convert-source-map@1.8.0: resolution: {integrity: sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==} dependencies: safe-buffer: 5.1.2 dev: true - /cookie-signature/1.0.6: + /cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} dev: true - /cookie/0.4.0: + /cookie@0.4.0: resolution: {integrity: sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==} engines: {node: '>= 0.6'} dev: true - /cookie/0.4.2: + /cookie@0.4.2: resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} engines: {node: '>= 0.6'} dev: true - /cookiejar/2.1.2: + /cookiejar@2.1.2: resolution: {integrity: sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==} + requiresBuild: true dev: true - /copy-descriptor/0.1.1: + /copy-descriptor@0.1.1: resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} engines: {node: '>=0.10.0'} dev: true - /core-js-pure/3.25.3: + /core-js-pure@3.25.3: resolution: {integrity: sha512-T/7qvgv70MEvRkZ8p6BasLZmOVYKzOaWNBEHAU8FmveCJkl4nko2quqPQOmy6AJIp5MBanhz9no3A94NoRb0XA==} requiresBuild: true dev: true - /core-js/2.6.12: + /core-js@2.6.12: resolution: {integrity: sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==} deprecated: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. requiresBuild: true dev: true - /core-js/3.30.1: + /core-js@3.30.1: resolution: {integrity: sha512-ZNS5nbiSwDTq4hFosEDqm65izl2CWmLz0hARJMyNQBgkUZMIF51cQiMvIQKA6hvuaeWxQDP3hEedM1JZIgTldQ==} requiresBuild: true dev: true - /core-util-is/1.0.2: + /core-util-is@1.0.2: resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} dev: true - /core-util-is/1.0.3: + /core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} dev: true - /cors/2.8.5: + /cors@2.8.5: resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} engines: {node: '>= 0.10'} dependencies: @@ -3921,7 +3982,7 @@ packages: vary: 1.1.2 dev: true - /cosmiconfig/8.2.0: + /cosmiconfig@8.2.0: resolution: {integrity: sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==} engines: {node: '>=14'} dependencies: @@ -3931,20 +3992,20 @@ packages: path-type: 4.0.0 dev: true - /crc-32/1.2.2: + /crc-32@1.2.2: resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} engines: {node: '>=0.8'} hasBin: true dev: true - /create-ecdh/4.0.3: + /create-ecdh@4.0.3: resolution: {integrity: sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==} dependencies: bn.js: 4.12.0 elliptic: 6.5.4 dev: true - /create-hash/1.2.0: + /create-hash@1.2.0: resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} dependencies: cipher-base: 1.0.4 @@ -3954,7 +4015,7 @@ packages: sha.js: 2.4.11 dev: true - /create-hmac/1.1.7: + /create-hmac@1.1.7: resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} dependencies: cipher-base: 1.0.4 @@ -3965,11 +4026,11 @@ packages: sha.js: 2.4.11 dev: true - /create-require/1.1.1: + /create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} dev: true - /cross-fetch/2.2.6: + /cross-fetch@2.2.6: resolution: {integrity: sha512-9JZz+vXCmfKUZ68zAptS7k4Nu8e2qcibe7WVZYps7sAgk5R8GYTc+T1WR0v1rlP9HxgARmOX1UTIJZFytajpNA==} dependencies: node-fetch: 2.6.7 @@ -3978,7 +4039,7 @@ packages: - encoding dev: true - /cross-fetch/3.1.5: + /cross-fetch@3.1.5: resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==} dependencies: node-fetch: 2.6.7 @@ -3986,7 +4047,7 @@ packages: - encoding dev: true - /cross-spawn/6.0.5: + /cross-spawn@6.0.5: resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} engines: {node: '>=4.8'} dependencies: @@ -3997,7 +4058,7 @@ packages: which: 1.3.1 dev: true - /cross-spawn/7.0.3: + /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} dependencies: @@ -4006,11 +4067,11 @@ packages: which: 2.0.2 dev: true - /crypt/0.0.2: + /crypt@0.0.2: resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} dev: true - /crypto-addr-codec/0.1.7: + /crypto-addr-codec@0.1.7: resolution: {integrity: sha512-X4hzfBzNhy4mAc3UpiXEC/L0jo5E8wAa9unsnA8nNXYzXjCcGk83hfC5avJWCSGT8V91xMnAS9AKMHmjw5+XCg==} dependencies: base-x: 3.0.9 @@ -4022,7 +4083,7 @@ packages: sha3: 2.1.4 dev: true - /crypto-browserify/3.12.0: + /crypto-browserify@3.12.0: resolution: {integrity: sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==} dependencies: browserify-cipher: 1.0.1 @@ -4038,7 +4099,7 @@ packages: randomfill: 1.0.4 dev: true - /css-select/5.1.0: + /css-select@5.1.0: resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} dependencies: boolbase: 1.0.0 @@ -4048,30 +4109,30 @@ packages: nth-check: 2.1.1 dev: true - /css-what/6.1.0: + /css-what@6.1.0: resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} engines: {node: '>= 6'} dev: true - /d/1.0.1: + /d@1.0.1: resolution: {integrity: sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==} dependencies: es5-ext: 0.10.62 type: 1.2.0 dev: true - /dashdash/1.14.1: + /dashdash@1.14.1: resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} engines: {node: '>=0.10'} dependencies: assert-plus: 1.0.0 dev: true - /death/1.1.0: + /death@1.1.0: resolution: {integrity: sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==} dev: true - /debug/2.6.9: + /debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: supports-color: '*' @@ -4082,19 +4143,7 @@ packages: ms: 2.0.0 dev: true - /debug/3.2.6: - resolution: {integrity: sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==} - deprecated: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797) - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.3 - dev: true - - /debug/3.2.6_supports-color@6.0.0: + /debug@3.2.6(supports-color@6.0.0): resolution: {integrity: sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==} deprecated: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797) peerDependencies: @@ -4107,7 +4156,7 @@ packages: supports-color: 6.0.0 dev: true - /debug/3.2.7: + /debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: supports-color: '*' @@ -4118,19 +4167,7 @@ packages: ms: 2.1.3 dev: true - /debug/4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 - dev: true - - /debug/4.3.4_supports-color@8.1.1: + /debug@4.3.4(supports-color@8.1.1): resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} peerDependencies: @@ -4143,49 +4180,49 @@ packages: supports-color: 8.1.1 dev: true - /decamelize/1.2.0: + /decamelize@1.2.0: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} dev: true - /decamelize/4.0.0: + /decamelize@4.0.0: resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} engines: {node: '>=10'} dev: true - /decode-uri-component/0.2.0: + /decode-uri-component@0.2.0: resolution: {integrity: sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==} engines: {node: '>=0.10'} dev: true - /decompress-response/3.3.0: + /decompress-response@3.3.0: resolution: {integrity: sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==} engines: {node: '>=4'} dependencies: mimic-response: 1.0.1 dev: true - /decompress-response/6.0.0: + /decompress-response@6.0.0: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} dependencies: mimic-response: 3.1.0 dev: true - /deep-eql/3.0.1: + /deep-eql@3.0.1: resolution: {integrity: sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==} engines: {node: '>=0.12'} dependencies: type-detect: 4.0.8 - /deep-equal-in-any-order/2.0.6: + /deep-equal-in-any-order@2.0.6: resolution: {integrity: sha512-RfnWHQzph10YrUjvWwhd15Dne8ciSJcZ3U6OD7owPwiVwsdE5IFSoZGg8rlwJD11ES+9H5y8j3fCofviRHOqLQ==} dependencies: lodash.mapvalues: 4.6.0 sort-any: 2.0.0 dev: true - /deep-equal/1.1.1: + /deep-equal@1.1.1: resolution: {integrity: sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==} dependencies: is-arguments: 1.0.4 @@ -4196,31 +4233,32 @@ packages: regexp.prototype.flags: 1.4.3 dev: true - /deep-extend/0.6.0: + /deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} dev: true - /deep-is/0.1.4: + /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true - /defer-to-connect/1.1.1: + /defer-to-connect@1.1.1: resolution: {integrity: sha512-J7thop4u3mRTkYRQ+Vpfwy2G5Ehoy82I14+14W4YMDLKdWloI9gSzRbV30s/NckQGVJtPkWNcW4oMAUigTdqiQ==} + requiresBuild: true dev: true - /defer-to-connect/2.0.1: + /defer-to-connect@2.0.1: resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} engines: {node: '>=10'} dev: true - /deferred-leveldown/1.2.2: + /deferred-leveldown@1.2.2: resolution: {integrity: sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==} dependencies: abstract-leveldown: 2.6.3 dev: true - /deferred-leveldown/4.0.2: + /deferred-leveldown@4.0.2: resolution: {integrity: sha512-5fMC8ek8alH16QiV0lTCis610D1Zt1+LA4MS4d63JgS32lrCjTFDUFz2ao09/j2I4Bqb5jL4FZYwu7Jz0XO1ww==} engines: {node: '>=6'} dependencies: @@ -4228,7 +4266,7 @@ packages: inherits: 2.0.4 dev: true - /define-properties/1.1.4: + /define-properties@1.1.4: resolution: {integrity: sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==} engines: {node: '>= 0.4'} dependencies: @@ -4236,21 +4274,21 @@ packages: object-keys: 1.1.1 dev: true - /define-property/0.2.5: + /define-property@0.2.5: resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==} engines: {node: '>=0.10.0'} dependencies: is-descriptor: 0.1.6 dev: true - /define-property/1.0.0: + /define-property@1.0.0: resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} engines: {node: '>=0.10.0'} dependencies: is-descriptor: 1.0.2 dev: true - /define-property/2.0.2: + /define-property@2.0.2: resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} engines: {node: '>=0.10.0'} dependencies: @@ -4258,49 +4296,49 @@ packages: isobject: 3.0.1 dev: true - /defined/1.0.0: + /defined@1.0.0: resolution: {integrity: sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ==} dev: true - /delayed-stream/1.0.0: + /delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} dev: true - /depd/1.1.2: + /depd@1.1.2: resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} engines: {node: '>= 0.6'} dev: true - /depd/2.0.0: + /depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} dev: true - /des.js/1.0.1: + /des.js@1.0.1: resolution: {integrity: sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==} dependencies: inherits: 2.0.4 minimalistic-assert: 1.0.1 dev: true - /destroy/1.0.4: + /destroy@1.0.4: resolution: {integrity: sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==} dev: true - /detect-indent/4.0.0: + /detect-indent@4.0.0: resolution: {integrity: sha512-BDKtmHlOzwI7iRuEkhzsnPoi5ypEhWAJB5RvHWe1kMr06js3uK5B3734i3ui5Yd+wOJV1cpE4JnivPD283GU/A==} engines: {node: '>=0.10.0'} dependencies: repeating: 2.0.1 dev: true - /detect-indent/5.0.0: + /detect-indent@5.0.0: resolution: {integrity: sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==} engines: {node: '>=4'} dev: true - /detect-port/1.3.0: + /detect-port@1.3.0: resolution: {integrity: sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==} engines: {node: '>= 4.2.1'} hasBin: true @@ -4311,22 +4349,22 @@ packages: - supports-color dev: true - /diff/3.5.0: + /diff@3.5.0: resolution: {integrity: sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==} engines: {node: '>=0.3.1'} dev: true - /diff/4.0.2: + /diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} dev: true - /diff/5.0.0: + /diff@5.0.0: resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} engines: {node: '>=0.3.1'} dev: true - /diffie-hellman/5.0.3: + /diffie-hellman@5.0.3: resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==} dependencies: bn.js: 4.12.0 @@ -4334,27 +4372,27 @@ packages: randombytes: 2.1.0 dev: true - /difflib/0.2.4: + /difflib@0.2.4: resolution: {integrity: sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==} dependencies: heap: 0.2.6 dev: true - /dir-glob/3.0.1: + /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} dependencies: path-type: 4.0.0 dev: true - /doctrine/3.0.0: + /doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} dependencies: esutils: 2.0.3 dev: true - /dom-serializer/2.0.0: + /dom-serializer@2.0.0: resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} dependencies: domelementtype: 2.3.0 @@ -4362,22 +4400,22 @@ packages: entities: 4.4.0 dev: true - /dom-walk/0.1.1: + /dom-walk@0.1.1: resolution: {integrity: sha512-8CGZnLAdYN/o0SHjlP3nLvliHpi2f/prVU63/Hc4DTDpBgsNVAJekegjFtxfZ7NTUEDzHUByjX1gT3eYakIKqg==} dev: true - /domelementtype/2.3.0: + /domelementtype@2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} dev: true - /domhandler/5.0.3: + /domhandler@5.0.3: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} dependencies: domelementtype: 2.3.0 dev: true - /domutils/3.0.1: + /domutils@3.0.1: resolution: {integrity: sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==} dependencies: dom-serializer: 2.0.0 @@ -4385,20 +4423,20 @@ packages: domhandler: 5.0.3 dev: true - /dot-case/2.1.1: + /dot-case@2.1.1: resolution: {integrity: sha512-HnM6ZlFqcajLsyudHq7LeeLDr2rFAVYtDv/hV5qchQEidSck8j9OPUsXY9KwJv/lHMtYlX4DjRQqwFYa+0r8Ug==} dependencies: no-case: 2.3.2 dev: true - /dotignore/0.1.2: + /dotignore@0.1.2: resolution: {integrity: sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==} hasBin: true dependencies: minimatch: 3.1.2 dev: true - /drbg.js/1.0.1: + /drbg.js@1.0.1: resolution: {integrity: sha512-F4wZ06PvqxYLFEZKkFxTDcns9oFNk34hvmJSEwdzsxVQ8YI5YaxtACgQatkYgv2VI2CFkUd2Y+xosPQnHv809g==} engines: {node: '>=0.10'} dependencies: @@ -4407,26 +4445,26 @@ packages: create-hmac: 1.1.7 dev: true - /duplexer3/0.1.4: + /duplexer3@0.1.4: resolution: {integrity: sha512-CEj8FwwNA4cVH2uFCoHUrmojhYh1vmCdOaneKJXwkeY1i9jnlslVo9dx+hQ5Hl9GnH/Bwy/IjxAyOePyPKYnzA==} dev: true - /ecc-jsbn/0.1.2: + /ecc-jsbn@0.1.2: resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} dependencies: jsbn: 0.1.1 safer-buffer: 2.1.2 dev: true - /ee-first/1.1.1: + /ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} dev: true - /electron-to-chromium/1.4.270: + /electron-to-chromium@1.4.270: resolution: {integrity: sha512-KNhIzgLiJmDDC444dj9vEOpZEgsV96ult9Iff98Vanumn+ShJHd5se8aX6KeVxdc0YQeqdrezBZv89rleDbvSg==} dev: true - /elliptic/6.5.4: + /elliptic@6.5.4: resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} dependencies: bn.js: 4.12.0 @@ -4437,20 +4475,20 @@ packages: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 - /emoji-regex/7.0.3: + /emoji-regex@7.0.3: resolution: {integrity: sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==} dev: true - /emoji-regex/8.0.0: + /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} dev: true - /encodeurl/1.0.2: + /encodeurl@1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} dev: true - /encoding-down/5.0.4: + /encoding-down@5.0.4: resolution: {integrity: sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw==} engines: {node: '>=6'} dependencies: @@ -4461,49 +4499,49 @@ packages: xtend: 4.0.2 dev: true - /encoding/0.1.13: + /encoding@0.1.13: resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} dependencies: iconv-lite: 0.6.3 dev: true - /end-of-stream/1.4.4: + /end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} dependencies: once: 1.4.0 dev: true - /enquirer/2.3.6: + /enquirer@2.3.6: resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} engines: {node: '>=8.6'} dependencies: ansi-colors: 4.1.3 dev: true - /entities/4.4.0: + /entities@4.4.0: resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==} engines: {node: '>=0.12'} dev: true - /env-paths/2.2.1: + /env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} dev: true - /errno/0.1.8: + /errno@0.1.8: resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} hasBin: true dependencies: prr: 1.0.1 dev: true - /error-ex/1.3.2: + /error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} dependencies: is-arrayish: 0.2.1 dev: true - /es-abstract/1.20.3: + /es-abstract@1.20.3: resolution: {integrity: sha512-AyrnaKVpMzljIdwjzrj+LxGmj8ik2LckwXacHqrJJ/jxz6dDDBcZ7I7nlHM0FvEW8MfbWJwOd+yT2XzYW49Frw==} engines: {node: '>= 0.4'} dependencies: @@ -4533,11 +4571,11 @@ packages: unbox-primitive: 1.0.2 dev: true - /es-array-method-boxes-properly/1.0.0: + /es-array-method-boxes-properly@1.0.0: resolution: {integrity: sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==} dev: true - /es-to-primitive/1.2.1: + /es-to-primitive@1.2.1: resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} engines: {node: '>= 0.4'} dependencies: @@ -4546,7 +4584,7 @@ packages: is-symbol: 1.0.3 dev: true - /es5-ext/0.10.62: + /es5-ext@0.10.62: resolution: {integrity: sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==} engines: {node: '>=0.10'} requiresBuild: true @@ -4556,7 +4594,7 @@ packages: next-tick: 1.1.0 dev: true - /es6-iterator/2.0.3: + /es6-iterator@2.0.3: resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} dependencies: d: 1.0.1 @@ -4564,37 +4602,37 @@ packages: es6-symbol: 3.1.3 dev: true - /es6-promise/4.2.8: + /es6-promise@4.2.8: resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} dev: true - /es6-symbol/3.1.3: + /es6-symbol@3.1.3: resolution: {integrity: sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==} dependencies: d: 1.0.1 ext: 1.4.0 dev: true - /escalade/3.1.1: + /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} dev: true - /escape-html/1.0.3: + /escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} dev: true - /escape-string-regexp/1.0.5: + /escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} dev: true - /escape-string-regexp/4.0.0: + /escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} dev: true - /escodegen/1.8.1: + /escodegen@1.8.1: resolution: {integrity: sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==} engines: {node: '>=0.12.0'} hasBin: true @@ -4607,7 +4645,7 @@ packages: source-map: 0.2.0 dev: true - /eslint-config-prettier/8.8.0_eslint@8.42.0: + /eslint-config-prettier@8.8.0(eslint@8.42.0): resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==} hasBin: true peerDependencies: @@ -4616,7 +4654,7 @@ packages: eslint: 8.42.0 dev: true - /eslint-plugin-prettier/4.2.1_vnriwwub2rhvoyn4ckagrc4lpi: + /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.8.0)(eslint@8.42.0)(prettier@2.8.8): resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -4628,12 +4666,12 @@ packages: optional: true dependencies: eslint: 8.42.0 - eslint-config-prettier: 8.8.0_eslint@8.42.0 + eslint-config-prettier: 8.8.0(eslint@8.42.0) prettier: 2.8.8 prettier-linter-helpers: 1.0.0 dev: true - /eslint-scope/5.1.1: + /eslint-scope@5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} dependencies: @@ -4641,7 +4679,7 @@ packages: estraverse: 4.3.0 dev: true - /eslint-scope/7.2.0: + /eslint-scope@7.2.0: resolution: {integrity: sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: @@ -4649,17 +4687,17 @@ packages: estraverse: 5.3.0 dev: true - /eslint-visitor-keys/3.4.1: + /eslint-visitor-keys@3.4.1: resolution: {integrity: sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint/8.42.0: + /eslint@8.42.0: resolution: {integrity: sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0_eslint@8.42.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.42.0) '@eslint-community/regexpp': 4.5.1 '@eslint/eslintrc': 2.0.3 '@eslint/js': 8.42.0 @@ -4669,7 +4707,7 @@ packages: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.0 @@ -4702,67 +4740,67 @@ packages: - supports-color dev: true - /espree/9.5.2: + /espree@9.5.2: resolution: {integrity: sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: acorn: 8.8.0 - acorn-jsx: 5.3.2_acorn@8.8.0 + acorn-jsx: 5.3.2(acorn@8.8.0) eslint-visitor-keys: 3.4.1 dev: true - /esprima/2.7.3: + /esprima@2.7.3: resolution: {integrity: sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==} engines: {node: '>=0.10.0'} hasBin: true dev: true - /esprima/4.0.1: + /esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} hasBin: true dev: true - /esquery/1.5.0: + /esquery@1.5.0: resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} engines: {node: '>=0.10'} dependencies: estraverse: 5.3.0 dev: true - /esrecurse/4.3.0: + /esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} dependencies: estraverse: 5.3.0 dev: true - /estraverse/1.9.3: + /estraverse@1.9.3: resolution: {integrity: sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==} engines: {node: '>=0.10.0'} dev: true - /estraverse/4.3.0: + /estraverse@4.3.0: resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} engines: {node: '>=4.0'} dev: true - /estraverse/5.3.0: + /estraverse@5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} dev: true - /esutils/2.0.3: + /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} dev: true - /etag/1.8.1: + /etag@1.8.1: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} dev: true - /eth-block-tracker/3.0.1: + /eth-block-tracker@3.0.1: resolution: {integrity: sha512-WUVxWLuhMmsfenfZvFO5sbl1qFY2IqUlw/FPVmjjdElpqLsZtSG+wPe9Dz7W/sB6e80HgFKknOmKk2eNlznHug==} dependencies: eth-query: 2.1.2 @@ -4776,14 +4814,14 @@ packages: - supports-color dev: true - /eth-ens-namehash/2.0.8: + /eth-ens-namehash@2.0.8: resolution: {integrity: sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==} dependencies: idna-uts46-hx: 2.3.1 js-sha3: 0.5.7 dev: true - /eth-gas-reporter/0.2.25: + /eth-gas-reporter@0.2.25: resolution: {integrity: sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ==} peerDependencies: '@codechecks/client': ^0.1.0 @@ -4803,12 +4841,12 @@ packages: mocha: 7.2.0 req-cwd: 2.0.0 request: 2.88.2 - request-promise-native: 1.0.9_request@2.88.2 + request-promise-native: 1.0.9(request@2.88.2) sha1: 1.1.1 sync-request: 6.1.0 dev: true - /eth-json-rpc-infura/3.2.1: + /eth-json-rpc-infura@3.2.1: resolution: {integrity: sha512-W7zR4DZvyTn23Bxc0EWsq4XGDdD63+XPUCEhV2zQvQGavDVC4ZpFDK4k99qN7bd7/fjj37+rxmuBOBeIqCA5Mw==} dependencies: cross-fetch: 2.2.6 @@ -4820,7 +4858,7 @@ packages: - supports-color dev: true - /eth-json-rpc-middleware/1.6.0: + /eth-json-rpc-middleware@1.6.0: resolution: {integrity: sha512-tDVCTlrUvdqHKqivYMjtFZsdD7TtpNLBCfKAcOpaVs7orBMS/A8HWro6dIzNtTZIR05FAbJ3bioFOnZpuCew9Q==} dependencies: async: 2.6.3 @@ -4840,7 +4878,7 @@ packages: - supports-color dev: true - /eth-lib/0.1.29: + /eth-lib@0.1.29: resolution: {integrity: sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==} dependencies: bn.js: 4.12.0 @@ -4855,7 +4893,7 @@ packages: - utf-8-validate dev: true - /eth-lib/0.2.8: + /eth-lib@0.2.8: resolution: {integrity: sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==} dependencies: bn.js: 4.12.0 @@ -4863,14 +4901,14 @@ packages: xhr-request-promise: 0.1.2 dev: true - /eth-query/2.1.2: + /eth-query@2.1.2: resolution: {integrity: sha512-srES0ZcvwkR/wd5OQBRA1bIJMww1skfGS0s8wlwK3/oNP4+wnds60krvu5R1QbpRQjMmpG5OMIWro5s7gvDPsA==} dependencies: json-rpc-random-id: 1.0.1 xtend: 4.0.2 dev: true - /eth-sig-util/1.4.2: + /eth-sig-util@1.4.2: resolution: {integrity: sha512-iNZ576iTOGcfllftB73cPB5AN+XUQAT/T8xzsILsghXC1o8gJUqe3RHlcDqagu+biFpYQ61KQrZZJza8eRSYqw==} deprecated: Deprecated in favor of '@metamask/eth-sig-util' dependencies: @@ -4878,7 +4916,7 @@ packages: ethereumjs-util: 5.2.1 dev: true - /eth-sig-util/3.0.0: + /eth-sig-util@3.0.0: resolution: {integrity: sha512-4eFkMOhpGbTxBQ3AMzVf0haUX2uTur7DpWiHzWyTURa28BVJJtOkcb9Ok5TV0YvEPG61DODPW7ZUATbJTslioQ==} deprecated: Deprecated in favor of '@metamask/eth-sig-util' dependencies: @@ -4890,7 +4928,7 @@ packages: tweetnacl-util: 0.15.1 dev: true - /eth-tx-summary/3.2.4: + /eth-tx-summary@3.2.4: resolution: {integrity: sha512-NtlDnaVZah146Rm8HMRUNMgIwG/ED4jiqk0TME9zFheMl1jOp6jL1m0NKGjJwehXQ6ZKCPr16MTr+qspKpEXNg==} dependencies: async: 2.6.3 @@ -4905,7 +4943,7 @@ packages: through2: 2.0.5 dev: true - /ethashjs/0.0.8: + /ethashjs@0.0.8: resolution: {integrity: sha512-/MSbf/r2/Ld8o0l15AymjOTlPqpN8Cr4ByUEA9GtR4x0yAh3TdtDzEg29zMjXCNPI7u6E5fOQdj/Cf9Tc7oVNw==} deprecated: 'New package name format for new versions: @ethereumjs/ethash. Please update.' dependencies: @@ -4915,21 +4953,21 @@ packages: miller-rabin: 4.0.1 dev: true - /ethereum-bloom-filters/1.0.10: + /ethereum-bloom-filters@1.0.10: resolution: {integrity: sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==} dependencies: js-sha3: 0.8.0 dev: true - /ethereum-common/0.0.18: + /ethereum-common@0.0.18: resolution: {integrity: sha512-EoltVQTRNg2Uy4o84qpa2aXymXDJhxm7eos/ACOg0DG4baAbMjhbdAEsx9GeE8sC3XCxnYvrrzZDH8D8MtA2iQ==} dev: true - /ethereum-common/0.2.0: + /ethereum-common@0.2.0: resolution: {integrity: sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==} dev: true - /ethereum-cryptography/0.1.3: + /ethereum-cryptography@0.1.3: resolution: {integrity: sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==} dependencies: '@types/pbkdf2': 3.1.0 @@ -4949,7 +4987,7 @@ packages: setimmediate: 1.0.5 dev: true - /ethereum-cryptography/1.1.2: + /ethereum-cryptography@1.1.2: resolution: {integrity: sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==} dependencies: '@noble/hashes': 1.1.2 @@ -4958,13 +4996,13 @@ packages: '@scure/bip39': 1.1.0 dev: true - /ethereum-waffle/3.3.0_typescript@4.9.5: + /ethereum-waffle@3.3.0(typescript@4.9.5): resolution: {integrity: sha512-4xm3RWAPCu5LlaVxYEg0tG3L7g5ovBw1GY/UebrzZ+OTx22vcPjI+bvelFlGBpkdnO5yOIFXjH2eK59tNAe9IA==} engines: {node: '>=10.0'} hasBin: true dependencies: '@ethereum-waffle/chai': 3.4.4 - '@ethereum-waffle/compiler': 3.4.4_typescript@4.9.5 + '@ethereum-waffle/compiler': 3.4.4(typescript@4.9.5) '@ethereum-waffle/mock-contract': 3.4.4 '@ethereum-waffle/provider': 3.4.4 ethers: 5.6.1 @@ -4976,21 +5014,21 @@ packages: - utf-8-validate dev: true - /ethereumjs-abi/0.6.5: + /ethereumjs-abi@0.6.5: resolution: {integrity: sha512-rCjJZ/AE96c/AAZc6O3kaog4FhOsAViaysBxqJNy2+LHP0ttH0zkZ7nXdVHOAyt6lFwLO0nlCwWszysG/ao1+g==} dependencies: bn.js: 4.12.0 ethereumjs-util: 4.5.0 dev: true - /ethereumjs-abi/0.6.8: + /ethereumjs-abi@0.6.8: resolution: {integrity: sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==} dependencies: bn.js: 4.12.0 ethereumjs-util: 6.2.1 dev: true - /ethereumjs-account/2.0.5: + /ethereumjs-account@2.0.5: resolution: {integrity: sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA==} dependencies: ethereumjs-util: 5.2.1 @@ -4998,7 +5036,7 @@ packages: safe-buffer: 5.2.1 dev: true - /ethereumjs-account/3.0.0: + /ethereumjs-account@3.0.0: resolution: {integrity: sha512-WP6BdscjiiPkQfF9PVfMcwx/rDvfZTjFKY0Uwc09zSQr9JfIVH87dYIJu0gNhBhpmovV4yq295fdllS925fnBA==} deprecated: Please use Util.Account class found on package ethereumjs-util@^7.0.6 https://github.com/ethereumjs/ethereumjs-util/releases/tag/v7.0.6 dependencies: @@ -5007,7 +5045,7 @@ packages: safe-buffer: 5.2.1 dev: true - /ethereumjs-block/1.7.1: + /ethereumjs-block@1.7.1: resolution: {integrity: sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==} deprecated: 'New package name format for new versions: @ethereumjs/block. Please update.' dependencies: @@ -5018,7 +5056,7 @@ packages: merkle-patricia-tree: 2.3.2 dev: true - /ethereumjs-block/2.2.2: + /ethereumjs-block@2.2.2: resolution: {integrity: sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==} deprecated: 'New package name format for new versions: @ethereumjs/block. Please update.' dependencies: @@ -5029,7 +5067,7 @@ packages: merkle-patricia-tree: 2.3.2 dev: true - /ethereumjs-blockchain/4.0.4: + /ethereumjs-blockchain@4.0.4: resolution: {integrity: sha512-zCxaRMUOzzjvX78DTGiKjA+4h2/sF0OYL1QuPux0DHpyq8XiNoF5GYHtb++GUxVlMsMfZV7AVyzbtgcRdIcEPQ==} deprecated: 'New package name format for new versions: @ethereumjs/blockchain. Please update.' dependencies: @@ -5045,12 +5083,12 @@ packages: semaphore: 1.1.0 dev: true - /ethereumjs-common/1.5.0: + /ethereumjs-common@1.5.0: resolution: {integrity: sha512-SZOjgK1356hIY7MRj3/ma5qtfr/4B5BL+G4rP/XSMYr2z1H5el4RX5GReYCKmQmYI/nSBmRnwrZ17IfHuG0viQ==} deprecated: 'New package name format for new versions: @ethereumjs/common. Please update.' dev: true - /ethereumjs-tx/1.3.7: + /ethereumjs-tx@1.3.7: resolution: {integrity: sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==} deprecated: 'New package name format for new versions: @ethereumjs/tx. Please update.' dependencies: @@ -5058,7 +5096,7 @@ packages: ethereumjs-util: 5.2.1 dev: true - /ethereumjs-tx/2.1.2: + /ethereumjs-tx@2.1.2: resolution: {integrity: sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==} deprecated: 'New package name format for new versions: @ethereumjs/tx. Please update.' dependencies: @@ -5066,7 +5104,7 @@ packages: ethereumjs-util: 6.2.1 dev: true - /ethereumjs-util/4.5.0: + /ethereumjs-util@4.5.0: resolution: {integrity: sha512-gT1zBY8aQKkexYu7XNeBZBnJsRLo+sWD1XWRLJOaDSz49/9kCOs6ERP52Bw/TA4uaVFKpM+O8ebWy44Ib5B6xw==} dependencies: bn.js: 4.12.0 @@ -5076,7 +5114,7 @@ packages: secp256k1: 3.7.1 dev: true - /ethereumjs-util/5.2.1: + /ethereumjs-util@5.2.1: resolution: {integrity: sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==} dependencies: bn.js: 4.12.0 @@ -5088,7 +5126,7 @@ packages: safe-buffer: 5.2.1 dev: true - /ethereumjs-util/6.2.1: + /ethereumjs-util@6.2.1: resolution: {integrity: sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==} dependencies: '@types/bn.js': 4.11.6 @@ -5100,7 +5138,7 @@ packages: rlp: 2.2.7 dev: true - /ethereumjs-util/7.1.5: + /ethereumjs-util@7.1.5: resolution: {integrity: sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==} engines: {node: '>=10.0.0'} dependencies: @@ -5111,7 +5149,7 @@ packages: rlp: 2.2.7 dev: true - /ethereumjs-vm/2.6.0: + /ethereumjs-vm@2.6.0: resolution: {integrity: sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw==} deprecated: 'New package name format for new versions: @ethereumjs/vm. Please update.' dependencies: @@ -5128,7 +5166,7 @@ packages: safe-buffer: 5.2.1 dev: true - /ethereumjs-vm/4.2.0: + /ethereumjs-vm@4.2.0: resolution: {integrity: sha512-X6qqZbsY33p5FTuZqCnQ4+lo957iUJMM6Mpa6bL4UW0dxM6WmDSHuI4j/zOp1E2TDKImBGCJA9QPfc08PaNubA==} deprecated: 'New package name format for new versions: @ethereumjs/vm. Please update.' dependencies: @@ -5149,7 +5187,7 @@ packages: util.promisify: 1.1.1 dev: true - /ethereumjs-wallet/0.6.5: + /ethereumjs-wallet@0.6.5: resolution: {integrity: sha512-MDwjwB9VQVnpp/Dc1XzA6J1a3wgHQ4hSvA1uWNatdpOrtCbPVuQSKSyRnjLvS0a+KKMw2pvQ9Ybqpb3+eW8oNA==} requiresBuild: true dependencies: @@ -5165,7 +5203,7 @@ packages: dev: true optional: true - /ethers/4.0.49: + /ethers@4.0.49: resolution: {integrity: sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==} dependencies: aes-js: 3.0.0 @@ -5179,7 +5217,7 @@ packages: xmlhttprequest: 1.8.0 dev: true - /ethers/5.6.1: + /ethers@5.6.1: resolution: {integrity: sha512-qtl/2W+dwmUa5Z3JqwsbV3JEBZZHNARe5K/A2ePcNAuhJYnEKIgGOT/O9ouPwBijSqVoQnmQMzi5D48LFNOY2A==} dependencies: '@ethersproject/abi': 5.6.0 @@ -5216,7 +5254,7 @@ packages: - bufferutil - utf-8-validate - /ethjs-abi/0.2.1: + /ethjs-abi@0.2.1: resolution: {integrity: sha512-g2AULSDYI6nEJyJaEVEXtTimRY2aPC2fi7ddSy0W+LXvEVL8Fe1y76o43ecbgdUKwZD+xsmEgX1yJr1Ia3r1IA==} engines: {node: '>=6.5.0', npm: '>=3'} dependencies: @@ -5225,7 +5263,7 @@ packages: number-to-bn: 1.7.0 dev: true - /ethjs-unit/0.1.6: + /ethjs-unit@0.1.6: resolution: {integrity: sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==} engines: {node: '>=6.5.0', npm: '>=3'} dependencies: @@ -5233,7 +5271,7 @@ packages: number-to-bn: 1.7.0 dev: true - /ethjs-util/0.1.6: + /ethjs-util@0.1.6: resolution: {integrity: sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==} engines: {node: '>=6.5.0', npm: '>=3'} dependencies: @@ -5241,28 +5279,28 @@ packages: strip-hex-prefix: 1.0.0 dev: true - /event-target-shim/5.0.1: + /event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} dev: true - /eventemitter3/4.0.4: + /eventemitter3@4.0.4: resolution: {integrity: sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==} dev: true - /events/3.3.0: + /events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} dev: true - /evp_bytestokey/1.0.3: + /evp_bytestokey@1.0.3: resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} dependencies: md5.js: 1.3.5 safe-buffer: 5.2.1 dev: true - /expand-brackets/2.1.4: + /expand-brackets@2.1.4: resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==} engines: {node: '>=0.10.0'} dependencies: @@ -5277,7 +5315,7 @@ packages: - supports-color dev: true - /express/4.17.1: + /express@4.17.1: resolution: {integrity: sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==} engines: {node: '>= 0.10.0'} dependencies: @@ -5315,20 +5353,20 @@ packages: - supports-color dev: true - /ext/1.4.0: + /ext@1.4.0: resolution: {integrity: sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==} dependencies: type: 2.0.0 dev: true - /extend-shallow/2.0.1: + /extend-shallow@2.0.1: resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} engines: {node: '>=0.10.0'} dependencies: is-extendable: 0.1.1 dev: true - /extend-shallow/3.0.2: + /extend-shallow@3.0.2: resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} engines: {node: '>=0.10.0'} dependencies: @@ -5336,11 +5374,11 @@ packages: is-extendable: 1.0.1 dev: true - /extend/3.0.2: + /extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} dev: true - /extglob/2.0.4: + /extglob@2.0.4: resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} engines: {node: '>=0.10.0'} dependencies: @@ -5356,38 +5394,38 @@ packages: - supports-color dev: true - /extsprintf/1.3.0: + /extsprintf@1.3.0: resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} engines: {'0': node >=0.6.0} dev: true - /extsprintf/1.4.0: + /extsprintf@1.4.0: resolution: {integrity: sha512-6NW8DZ8pWBc5NbGYUiqqccj9dXnuSzilZYqprdKJBZsQodGH9IyUoFOGxIWVDcBzHMb8ET24aqx9p66tZEWZkA==} engines: {'0': node >=0.6.0} dev: true - /fake-merkle-patricia-tree/1.0.1: + /fake-merkle-patricia-tree@1.0.1: resolution: {integrity: sha512-Tgq37lkc9pUIgIKw5uitNUKcgcYL3R6JvXtKQbOf/ZSavXbidsksgp/pAY6p//uhw0I4yoMsvTSovvVIsk/qxA==} dependencies: checkpoint-store: 1.1.0 dev: true - /fast-check/3.1.1: + /fast-check@3.1.1: resolution: {integrity: sha512-3vtXinVyuUKCKFKYcwXhGE6NtGWkqF8Yh3rvMZNzmwz8EPrgoc/v4pDdLHyLnCyCI5MZpZZkDEwFyXyEONOxpA==} engines: {node: '>=8.0.0'} dependencies: pure-rand: 5.0.3 dev: true - /fast-deep-equal/3.1.3: + /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true - /fast-diff/1.2.0: + /fast-diff@1.2.0: resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==} dev: true - /fast-glob/3.2.12: + /fast-glob@3.2.12: resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} engines: {node: '>=8.6.0'} dependencies: @@ -5398,38 +5436,38 @@ packages: micromatch: 4.0.5 dev: true - /fast-json-stable-stringify/2.1.0: + /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} dev: true - /fast-levenshtein/2.0.6: + /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} dev: true - /fastq/1.6.0: + /fastq@1.6.0: resolution: {integrity: sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==} dependencies: reusify: 1.0.4 dev: true - /fetch-ponyfill/4.1.0: + /fetch-ponyfill@4.1.0: resolution: {integrity: sha512-knK9sGskIg2T7OnYLdZ2hZXn0CtDrAIBxYQLpmEf0BqfdWnwmM1weccUl5+4EdA44tzNSFAuxITPbXtPehUB3g==} dependencies: node-fetch: 1.7.3 dev: true - /file-entry-cache/6.0.1: + /file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: flat-cache: 3.0.4 dev: true - /file-uri-to-path/1.0.0: + /file-uri-to-path@1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} dev: true - /fill-range/4.0.0: + /fill-range@4.0.0: resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==} engines: {node: '>=0.10.0'} dependencies: @@ -5439,14 +5477,14 @@ packages: to-regex-range: 2.1.1 dev: true - /fill-range/7.0.1: + /fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} dependencies: to-regex-range: 5.0.1 dev: true - /finalhandler/1.1.2: + /finalhandler@1.1.2: resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==} engines: {node: '>= 0.8'} dependencies: @@ -5461,7 +5499,7 @@ packages: - supports-color dev: true - /find-replace/1.0.3: + /find-replace@1.0.3: resolution: {integrity: sha512-KrUnjzDCD9426YnCP56zGYy/eieTnhtK6Vn++j+JJzmlsWWwEkDnsyVF575spT6HJ6Ow9tlbT3TQTDsa+O4UWA==} engines: {node: '>=4.0.0'} dependencies: @@ -5469,14 +5507,14 @@ packages: test-value: 2.1.0 dev: true - /find-replace/3.0.0: + /find-replace@3.0.0: resolution: {integrity: sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==} engines: {node: '>=4.0.0'} dependencies: array-back: 3.1.0 dev: true - /find-up/1.1.2: + /find-up@1.1.2: resolution: {integrity: sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==} engines: {node: '>=0.10.0'} dependencies: @@ -5484,21 +5522,21 @@ packages: pinkie-promise: 2.0.1 dev: true - /find-up/2.1.0: + /find-up@2.1.0: resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} engines: {node: '>=4'} dependencies: locate-path: 2.0.0 dev: true - /find-up/3.0.0: + /find-up@3.0.0: resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} engines: {node: '>=6'} dependencies: locate-path: 3.0.0 dev: true - /find-up/4.1.0: + /find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} dependencies: @@ -5506,7 +5544,7 @@ packages: path-exists: 4.0.0 dev: true - /find-up/5.0.0: + /find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} dependencies: @@ -5514,7 +5552,7 @@ packages: path-exists: 4.0.0 dev: true - /find-yarn-workspace-root/1.2.1: + /find-yarn-workspace-root@1.2.1: resolution: {integrity: sha512-dVtfb0WuQG+8Ag2uWkbG79hOUzEsRrhBzgfn86g2sJPkzmcpGdghbNTfUKGTxymFrY/tLIodDzLoW9nOJ4FY8Q==} dependencies: fs-extra: 4.0.3 @@ -5523,13 +5561,13 @@ packages: - supports-color dev: true - /find-yarn-workspace-root/2.0.0: + /find-yarn-workspace-root@2.0.0: resolution: {integrity: sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==} dependencies: micromatch: 4.0.5 dev: true - /flat-cache/3.0.4: + /flat-cache@3.0.4: resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: @@ -5537,27 +5575,27 @@ packages: rimraf: 3.0.2 dev: true - /flat/4.1.1: + /flat@4.1.1: resolution: {integrity: sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==} hasBin: true dependencies: is-buffer: 2.0.5 dev: true - /flat/5.0.2: + /flat@5.0.2: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true dev: true - /flatted/3.2.7: + /flatted@3.2.7: resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} dev: true - /flow-stoplight/1.0.0: + /flow-stoplight@1.0.0: resolution: {integrity: sha512-rDjbZUKpN8OYhB0IE/vY/I8UWO/602IIJEU/76Tv4LvYnwHCk0BCsvz4eRr9n+FQcri7L5cyaXOo0+/Kh4HisA==} dev: true - /follow-redirects/1.15.2_debug@4.3.4: + /follow-redirects@1.15.2(debug@4.3.4): resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} engines: {node: '>=4.0'} peerDependencies: @@ -5566,33 +5604,33 @@ packages: debug: optional: true dependencies: - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) dev: true - /for-each/0.3.3: + /for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} dependencies: is-callable: 1.2.7 dev: true - /for-in/1.0.2: + /for-in@1.0.2: resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} engines: {node: '>=0.10.0'} dev: true - /foreach/2.0.5: + /foreach@2.0.5: resolution: {integrity: sha512-ZBbtRiapkZYLsqoPyZOR+uPfto0GRMNQN1GwzZtZt7iZvPPbDDQV0JF5Hx4o/QFQ5c0vyuoZ98T8RSBbopzWtA==} dev: true - /forever-agent/0.6.1: + /forever-agent@0.6.1: resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} dev: true - /form-data-encoder/1.7.1: + /form-data-encoder@1.7.1: resolution: {integrity: sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==} dev: true - /form-data/2.3.3: + /form-data@2.3.3: resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} engines: {node: '>= 0.12'} dependencies: @@ -5601,7 +5639,7 @@ packages: mime-types: 2.1.27 dev: true - /form-data/3.0.1: + /form-data@3.0.1: resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} engines: {node: '>= 6'} dependencies: @@ -5610,28 +5648,28 @@ packages: mime-types: 2.1.27 dev: true - /forwarded/0.1.2: + /forwarded@0.1.2: resolution: {integrity: sha512-Ua9xNhH0b8pwE3yRbFfXJvfdWF0UHNCdeyb2sbi9Ul/M+r3PTdrz7Cv4SCfZRMjmzEM9PhraqfZFbGTIg3OMyA==} engines: {node: '>= 0.6'} dev: true - /fp-ts/1.19.3: + /fp-ts@1.19.3: resolution: {integrity: sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==} dev: true - /fragment-cache/0.2.1: + /fragment-cache@0.2.1: resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} engines: {node: '>=0.10.0'} dependencies: map-cache: 0.2.2 dev: true - /fresh/0.5.2: + /fresh@0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} dev: true - /fs-extra/0.30.0: + /fs-extra@0.30.0: resolution: {integrity: sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==} dependencies: graceful-fs: 4.2.10 @@ -5641,7 +5679,7 @@ packages: rimraf: 2.7.1 dev: true - /fs-extra/4.0.3: + /fs-extra@4.0.3: resolution: {integrity: sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==} dependencies: graceful-fs: 4.2.10 @@ -5649,7 +5687,7 @@ packages: universalify: 0.1.2 dev: true - /fs-extra/7.0.1: + /fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} dependencies: @@ -5658,7 +5696,7 @@ packages: universalify: 0.1.2 dev: true - /fs-extra/8.1.0: + /fs-extra@8.1.0: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} dependencies: @@ -5667,7 +5705,7 @@ packages: universalify: 0.1.2 dev: true - /fs-extra/9.1.0: + /fs-extra@9.1.0: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} dependencies: @@ -5677,21 +5715,21 @@ packages: universalify: 2.0.0 dev: true - /fs-minipass/1.2.7: + /fs-minipass@1.2.7: resolution: {integrity: sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==} dependencies: minipass: 2.9.0 dev: true - /fs-readdir-recursive/1.1.0: + /fs-readdir-recursive@1.1.0: resolution: {integrity: sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==} dev: true - /fs.realpath/1.0.0: + /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} dev: true - /fsevents/2.1.3: + /fsevents@2.1.3: resolution: {integrity: sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] @@ -5700,7 +5738,7 @@ packages: dev: true optional: true - /fsevents/2.3.2: + /fsevents@2.3.2: resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] @@ -5708,11 +5746,11 @@ packages: dev: true optional: true - /function-bind/1.1.1: + /function-bind@1.1.1: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} dev: true - /function.prototype.name/1.1.5: + /function.prototype.name@1.1.5: resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} engines: {node: '>= 0.4'} dependencies: @@ -5722,15 +5760,15 @@ packages: functions-have-names: 1.2.3 dev: true - /functional-red-black-tree/1.0.1: + /functional-red-black-tree@1.0.1: resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} dev: true - /functions-have-names/1.2.3: + /functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} dev: true - /ganache-core/2.13.2: + /ganache-core@2.13.2: resolution: {integrity: sha512-tIF5cR+ANQz0+3pHWxHjIwHqFXcVo0Mb+kcsNhglNFALcYo49aQpnS9dqHartqPfMFjiHh/qFoD3mYK0d/qGgw==} engines: {node: '>=8.9.0'} deprecated: ganache-core is now ganache; visit https://trfl.io/g7 for details @@ -5740,7 +5778,7 @@ packages: bip39: 2.5.0 cachedown: 1.0.0 clone: 2.1.2 - debug: 3.2.6 + debug: 3.2.6(supports-color@6.0.0) encoding-down: 5.0.4 eth-sig-util: 3.0.0 ethereumjs-abi: 0.6.8 @@ -5774,19 +5812,19 @@ packages: bundledDependencies: - keccak - /get-caller-file/1.0.3: + /get-caller-file@1.0.3: resolution: {integrity: sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==} dev: true - /get-caller-file/2.0.5: + /get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} dev: true - /get-func-name/2.0.0: + /get-func-name@2.0.0: resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} - /get-intrinsic/1.1.3: + /get-intrinsic@1.1.3: resolution: {integrity: sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==} dependencies: function-bind: 1.1.1 @@ -5794,36 +5832,37 @@ packages: has-symbols: 1.0.3 dev: true - /get-port/3.2.0: + /get-port@3.2.0: resolution: {integrity: sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==} engines: {node: '>=4'} dev: true - /get-stream/3.0.0: + /get-stream@3.0.0: resolution: {integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==} engines: {node: '>=4'} dev: true - /get-stream/4.1.0: + /get-stream@4.1.0: resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} engines: {node: '>=6'} + requiresBuild: true dependencies: pump: 3.0.0 dev: true - /get-stream/5.1.0: + /get-stream@5.1.0: resolution: {integrity: sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==} engines: {node: '>=8'} dependencies: pump: 3.0.0 dev: true - /get-stream/6.0.1: + /get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} dev: true - /get-symbol-description/1.0.0: + /get-symbol-description@1.0.0: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} engines: {node: '>= 0.4'} dependencies: @@ -5831,18 +5870,18 @@ packages: get-intrinsic: 1.1.3 dev: true - /get-value/2.0.6: + /get-value@2.0.6: resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} engines: {node: '>=0.10.0'} dev: true - /getpass/0.1.7: + /getpass@0.1.7: resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} dependencies: assert-plus: 1.0.0 dev: true - /ghost-testrpc/0.0.2: + /ghost-testrpc@0.0.2: resolution: {integrity: sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==} hasBin: true dependencies: @@ -5850,21 +5889,21 @@ packages: node-emoji: 1.11.0 dev: true - /glob-parent/5.1.2: + /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} dependencies: is-glob: 4.0.3 dev: true - /glob-parent/6.0.2: + /glob-parent@6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} dependencies: is-glob: 4.0.3 dev: true - /glob/5.0.15: + /glob@5.0.15: resolution: {integrity: sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==} dependencies: inflight: 1.0.6 @@ -5874,7 +5913,7 @@ packages: path-is-absolute: 1.0.1 dev: true - /glob/7.1.3: + /glob@7.1.3: resolution: {integrity: sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==} dependencies: fs.realpath: 1.0.0 @@ -5885,7 +5924,7 @@ packages: path-is-absolute: 1.0.1 dev: true - /glob/7.1.7: + /glob@7.1.7: resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} dependencies: fs.realpath: 1.0.0 @@ -5896,7 +5935,7 @@ packages: path-is-absolute: 1.0.1 dev: true - /glob/7.2.0: + /glob@7.2.0: resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} dependencies: fs.realpath: 1.0.0 @@ -5907,7 +5946,7 @@ packages: path-is-absolute: 1.0.1 dev: true - /glob/7.2.3: + /glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} dependencies: fs.realpath: 1.0.0 @@ -5918,7 +5957,7 @@ packages: path-is-absolute: 1.0.1 dev: true - /glob/8.1.0: + /glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} engines: {node: '>=12'} dependencies: @@ -5929,14 +5968,14 @@ packages: once: 1.4.0 dev: true - /global-modules/2.0.0: + /global-modules@2.0.0: resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==} engines: {node: '>=6'} dependencies: global-prefix: 3.0.0 dev: true - /global-prefix/3.0.0: + /global-prefix@3.0.0: resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==} engines: {node: '>=6'} dependencies: @@ -5945,26 +5984,26 @@ packages: which: 1.3.1 dev: true - /global/4.3.2: + /global@4.3.2: resolution: {integrity: sha512-/4AybdwIDU4HkCUbJkZdWpe4P6vuw/CUtu+0I1YlLIPe7OlUO7KNJ+q/rO70CW2/NW6Jc6I62++Hzsf5Alu6rQ==} dependencies: min-document: 2.19.0 process: 0.5.2 dev: true - /globals/13.20.0: + /globals@13.20.0: resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} engines: {node: '>=8'} dependencies: type-fest: 0.20.2 dev: true - /globals/9.18.0: + /globals@9.18.0: resolution: {integrity: sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==} engines: {node: '>=0.10.0'} dev: true - /globby/10.0.2: + /globby@10.0.2: resolution: {integrity: sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==} engines: {node: '>=8'} dependencies: @@ -5978,7 +6017,7 @@ packages: slash: 3.0.0 dev: true - /globby/11.1.0: + /globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} dependencies: @@ -5990,7 +6029,7 @@ packages: slash: 3.0.0 dev: true - /got/12.1.0: + /got@12.1.0: resolution: {integrity: sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig==} engines: {node: '>=14.16'} dependencies: @@ -6009,7 +6048,7 @@ packages: responselike: 2.0.1 dev: true - /got/7.1.0: + /got@7.1.0: resolution: {integrity: sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==} engines: {node: '>=4'} dependencies: @@ -6031,7 +6070,7 @@ packages: url-to-options: 1.0.1 dev: true - /got/9.6.0: + /got@9.6.0: resolution: {integrity: sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==} engines: {node: '>=8.6'} dependencies: @@ -6050,24 +6089,24 @@ packages: url-parse-lax: 3.0.0 dev: true - /graceful-fs/4.2.10: + /graceful-fs@4.2.10: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} dev: true - /grapheme-splitter/1.0.4: + /grapheme-splitter@1.0.4: resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} dev: true - /graphemer/1.4.0: + /graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} dev: true - /growl/1.10.5: + /growl@1.10.5: resolution: {integrity: sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==} engines: {node: '>=4.x'} dev: true - /handlebars/4.7.7: + /handlebars@4.7.7: resolution: {integrity: sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==} engines: {node: '>=0.4.7'} hasBin: true @@ -6080,12 +6119,12 @@ packages: uglify-js: 3.17.3 dev: true - /har-schema/2.0.0: + /har-schema@2.0.0: resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} engines: {node: '>=4'} dev: true - /har-validator/5.1.5: + /har-validator@5.1.5: resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} engines: {node: '>=6'} deprecated: this library is no longer supported @@ -6094,39 +6133,39 @@ packages: har-schema: 2.0.0 dev: true - /hardhat-abi-exporter/2.2.1_hardhat@2.12.7: + /hardhat-abi-exporter@2.2.1(hardhat@2.12.7): resolution: {integrity: sha512-Um7+RPvJEj+OqWjPoPKlTTkO1Akr10pqpgMk8Pw2jz2wrGv5XQBGNW5aQgGVDUosYktUIWDaEhcwwFKbFsir9A==} engines: {node: '>=12.10.0'} peerDependencies: hardhat: ^2.0.0 dependencies: - hardhat: 2.12.7_goz53koj4ourpjwgrks4nqbe6i + hardhat: 2.12.7(ts-node@10.0.0)(typescript@4.9.5) dev: true - /hardhat-contract-sizer/2.5.1_hardhat@2.12.7: + /hardhat-contract-sizer@2.5.1(hardhat@2.12.7): resolution: {integrity: sha512-28yRb73e30aBVaZOOHTlHZFIdIasA/iFunIehrUviIJTubvdQjtSiQUo2wexHFtt71mQeMPP8qjw2sdbgatDnQ==} peerDependencies: hardhat: ^2.0.0 dependencies: chalk: 4.1.2 cli-table3: 0.6.3 - hardhat: 2.12.7_goz53koj4ourpjwgrks4nqbe6i + hardhat: 2.12.7(ts-node@10.0.0)(typescript@4.9.5) dev: true - /hardhat-gas-reporter/1.0.9_hardhat@2.12.7: + /hardhat-gas-reporter@1.0.9(hardhat@2.12.7): resolution: {integrity: sha512-INN26G3EW43adGKBNzYWOlI3+rlLnasXTwW79YNnUhXPDa+yHESgt639dJEs37gCjhkbNKcRRJnomXEuMFBXJg==} peerDependencies: hardhat: ^2.0.2 dependencies: array-uniq: 1.0.3 eth-gas-reporter: 0.2.25 - hardhat: 2.12.7_goz53koj4ourpjwgrks4nqbe6i + hardhat: 2.12.7(ts-node@10.0.0)(typescript@4.9.5) sha1: 1.1.1 transitivePeerDependencies: - '@codechecks/client' dev: true - /hardhat-ignore-warnings/0.2.9: + /hardhat-ignore-warnings@0.2.9: resolution: {integrity: sha512-q1oj6/ixiAx+lgIyGLBajVCSC7qUtAoK7LS9Nr8UVHYo8Iuh5naBiVGo4RDJ6wxbDGYBkeSukUGZrMqzC2DWwA==} dependencies: minimatch: 5.1.6 @@ -6134,7 +6173,7 @@ packages: solidity-comments: 0.0.2 dev: true - /hardhat/2.12.7_goz53koj4ourpjwgrks4nqbe6i: + /hardhat@2.12.7(ts-node@10.0.0)(typescript@4.9.5): resolution: {integrity: sha512-voWoN6zn5d8BOEaczSyK/1PyfdeOeI3SbGCFb36yCHTJUt6OIqLb+ZDX30VhA1UsYKzLqG7UnWl3fKJUuANc6A==} engines: {node: ^14.0.0 || ^16.0.0 || ^18.0.0} hasBin: true @@ -6170,7 +6209,7 @@ packages: chalk: 2.4.2 chokidar: 3.5.3 ci-info: 2.0.0 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) enquirer: 2.3.6 env-paths: 2.2.1 ethereum-cryptography: 1.1.2 @@ -6190,10 +6229,10 @@ packages: raw-body: 2.5.1 resolve: 1.17.0 semver: 6.3.0 - solc: 0.7.3_debug@4.3.4 + solc: 0.7.3(debug@4.3.4) source-map-support: 0.5.21 stacktrace-parser: 0.1.10 - ts-node: 10.0.0_zlol4fzmmjgb3bdeviopae4asm + ts-node: 10.0.0(@types/node@15.14.9)(typescript@4.9.5) tsort: 0.0.1 typescript: 4.9.5 undici: 5.19.1 @@ -6205,61 +6244,61 @@ packages: - utf-8-validate dev: true - /has-ansi/2.0.0: + /has-ansi@2.0.0: resolution: {integrity: sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==} engines: {node: '>=0.10.0'} dependencies: ansi-regex: 2.1.1 dev: true - /has-bigints/1.0.2: + /has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} dev: true - /has-flag/1.0.0: + /has-flag@1.0.0: resolution: {integrity: sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==} engines: {node: '>=0.10.0'} dev: true - /has-flag/3.0.0: + /has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} dev: true - /has-flag/4.0.0: + /has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} dev: true - /has-property-descriptors/1.0.0: + /has-property-descriptors@1.0.0: resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} dependencies: get-intrinsic: 1.1.3 dev: true - /has-symbol-support-x/1.4.2: + /has-symbol-support-x@1.4.2: resolution: {integrity: sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==} dev: true - /has-symbols/1.0.3: + /has-symbols@1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} engines: {node: '>= 0.4'} dev: true - /has-to-string-tag-x/1.4.1: + /has-to-string-tag-x@1.4.1: resolution: {integrity: sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==} dependencies: has-symbol-support-x: 1.4.2 dev: true - /has-tostringtag/1.0.0: + /has-tostringtag@1.0.0: resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} engines: {node: '>= 0.4'} dependencies: has-symbols: 1.0.3 dev: true - /has-value/0.3.1: + /has-value@0.3.1: resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==} engines: {node: '>=0.10.0'} dependencies: @@ -6268,7 +6307,7 @@ packages: isobject: 2.1.0 dev: true - /has-value/1.0.0: + /has-value@1.0.0: resolution: {integrity: sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==} engines: {node: '>=0.10.0'} dependencies: @@ -6277,12 +6316,12 @@ packages: isobject: 3.0.1 dev: true - /has-values/0.1.4: + /has-values@0.1.4: resolution: {integrity: sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==} engines: {node: '>=0.10.0'} dev: true - /has-values/1.0.0: + /has-values@1.0.0: resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} engines: {node: '>=0.10.0'} dependencies: @@ -6290,14 +6329,14 @@ packages: kind-of: 4.0.0 dev: true - /has/1.0.3: + /has@1.0.3: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} engines: {node: '>= 0.4.0'} dependencies: function-bind: 1.1.1 dev: true - /hash-base/3.1.0: + /hash-base@3.1.0: resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} engines: {node: '>=4'} dependencies: @@ -6306,51 +6345,51 @@ packages: safe-buffer: 5.2.1 dev: true - /hash.js/1.1.3: + /hash.js@1.1.3: resolution: {integrity: sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==} dependencies: inherits: 2.0.4 minimalistic-assert: 1.0.1 dev: true - /hash.js/1.1.7: + /hash.js@1.1.7: resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} dependencies: inherits: 2.0.4 minimalistic-assert: 1.0.1 - /he/1.2.0: + /he@1.2.0: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true dev: true - /header-case/1.0.1: + /header-case@1.0.1: resolution: {integrity: sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ==} dependencies: no-case: 2.3.2 upper-case: 1.1.3 dev: true - /heap/0.2.6: + /heap@0.2.6: resolution: {integrity: sha512-MzzWcnfB1e4EG2vHi3dXHoBupmuXNZzx6pY6HldVS55JKKBoq3xOyzfSaZRkJp37HIhEYC78knabHff3zc4dQQ==} dev: true - /highlight.js/10.7.3: + /highlight.js@10.7.3: resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} dev: true - /highlightjs-solidity/2.0.5: + /highlightjs-solidity@2.0.5: resolution: {integrity: sha512-ReXxQSGQkODMUgHcWzVSnfDCDrL2HshOYgw3OlIYmfHeRzUPkfJTUIp95pK4CmbiNG2eMTOmNLpfCz9Zq7Cwmg==} dev: true - /hmac-drbg/1.0.1: + /hmac-drbg@1.0.1: resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} dependencies: hash.js: 1.1.7 minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 - /home-or-tmp/2.0.0: + /home-or-tmp@2.0.0: resolution: {integrity: sha512-ycURW7oUxE2sNiPVw1HVEFsW+ecOpJ5zaj7eC0RlwhibhRBod20muUN8qu/gzx956YrLolVvs1MTXwKgC2rVEg==} engines: {node: '>=0.10.0'} dependencies: @@ -6358,11 +6397,11 @@ packages: os-tmpdir: 1.0.2 dev: true - /hosted-git-info/2.8.9: + /hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} dev: true - /htmlparser2/8.0.1: + /htmlparser2@8.0.1: resolution: {integrity: sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==} dependencies: domelementtype: 2.3.0 @@ -6371,7 +6410,7 @@ packages: entities: 4.4.0 dev: true - /http-basic/8.1.3: + /http-basic@8.1.3: resolution: {integrity: sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==} engines: {node: '>=6.0.0'} dependencies: @@ -6381,11 +6420,11 @@ packages: parse-cache-control: 1.0.1 dev: true - /http-cache-semantics/4.0.3: + /http-cache-semantics@4.0.3: resolution: {integrity: sha512-TcIMG3qeVLgDr1TEd2XvHaTnMPwYQUQMIBLy+5pLSDKYFc7UIqj39w8EGzZkaxoLv/l2K8HaI0t5AVA+YYgUew==} dev: true - /http-errors/1.7.2: + /http-errors@1.7.2: resolution: {integrity: sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==} engines: {node: '>= 0.6'} dependencies: @@ -6396,7 +6435,7 @@ packages: toidentifier: 1.0.0 dev: true - /http-errors/1.7.3: + /http-errors@1.7.3: resolution: {integrity: sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==} engines: {node: '>= 0.6'} dependencies: @@ -6407,7 +6446,7 @@ packages: toidentifier: 1.0.0 dev: true - /http-errors/2.0.0: + /http-errors@2.0.0: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} dependencies: @@ -6418,17 +6457,17 @@ packages: toidentifier: 1.0.1 dev: true - /http-https/1.0.0: + /http-https@1.0.0: resolution: {integrity: sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg==} dev: true - /http-response-object/3.0.2: + /http-response-object@3.0.2: resolution: {integrity: sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==} dependencies: '@types/node': 10.17.60 dev: true - /http-signature/1.2.0: + /http-signature@1.2.0: resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} engines: {node: '>=0.8', npm: '>=1.3.7'} dependencies: @@ -6437,7 +6476,7 @@ packages: sshpk: 1.16.1 dev: true - /http2-wrapper/2.1.11: + /http2-wrapper@2.1.11: resolution: {integrity: sha512-aNAk5JzLturWEUiuhAN73Jcbq96R7rTitAoXV54FYMatvihnpD2+6PUgU4ce3D/m5VDbw+F5CsyKSF176ptitQ==} engines: {node: '>=10.19.0'} dependencies: @@ -6445,64 +6484,64 @@ packages: resolve-alpn: 1.2.1 dev: true - /https-proxy-agent/5.0.1: + /https-proxy-agent@5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} dependencies: agent-base: 6.0.2 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true - /iconv-lite/0.4.24: + /iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} dependencies: safer-buffer: 2.1.2 dev: true - /iconv-lite/0.6.3: + /iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} dependencies: safer-buffer: 2.1.2 dev: true - /idna-uts46-hx/2.3.1: + /idna-uts46-hx@2.3.1: resolution: {integrity: sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==} engines: {node: '>=4.0.0'} dependencies: punycode: 2.1.0 dev: true - /ieee754/1.2.1: + /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} dev: true - /ignore/5.2.0: + /ignore@5.2.0: resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==} engines: {node: '>= 4'} dev: true - /ignore/5.2.4: + /ignore@5.2.4: resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} engines: {node: '>= 4'} dev: true - /immediate/3.2.3: + /immediate@3.2.3: resolution: {integrity: sha512-RrGCXRm/fRVqMIhqXrGEX9rRADavPiDFSoMb/k64i9XMk8uH4r/Omi5Ctierj6XzNecwDbO4WuFbDD1zmpl3Tg==} dev: true - /immediate/3.3.0: + /immediate@3.3.0: resolution: {integrity: sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==} dev: true - /immutable/4.1.0: + /immutable@4.1.0: resolution: {integrity: sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==} dev: true - /import-fresh/3.3.0: + /import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} dependencies: @@ -6510,35 +6549,35 @@ packages: resolve-from: 4.0.0 dev: true - /imurmurhash/0.1.4: + /imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} dev: true - /indent-string/4.0.0: + /indent-string@4.0.0: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} dev: true - /inflight/1.0.6: + /inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} dependencies: once: 1.4.0 wrappy: 1.0.2 dev: true - /inherits/2.0.3: + /inherits@2.0.3: resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} dev: true - /inherits/2.0.4: + /inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - /ini/1.3.8: + /ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} dev: true - /internal-slot/1.0.3: + /internal-slot@1.0.3: resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} engines: {node: '>= 0.4'} dependencies: @@ -6547,70 +6586,70 @@ packages: side-channel: 1.0.4 dev: true - /interpret/1.2.0: + /interpret@1.2.0: resolution: {integrity: sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==} engines: {node: '>= 0.10'} dev: true - /invariant/2.2.4: + /invariant@2.2.4: resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} dependencies: loose-envify: 1.4.0 dev: true - /invert-kv/1.0.0: + /invert-kv@1.0.0: resolution: {integrity: sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==} engines: {node: '>=0.10.0'} dev: true - /io-ts/1.10.4: + /io-ts@1.10.4: resolution: {integrity: sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==} dependencies: fp-ts: 1.19.3 dev: true - /ipaddr.js/1.9.0: + /ipaddr.js@1.9.0: resolution: {integrity: sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==} engines: {node: '>= 0.10'} dev: true - /is-accessor-descriptor/0.1.6: + /is-accessor-descriptor@0.1.6: resolution: {integrity: sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==} engines: {node: '>=0.10.0'} dependencies: kind-of: 3.2.2 dev: true - /is-accessor-descriptor/1.0.0: + /is-accessor-descriptor@1.0.0: resolution: {integrity: sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==} engines: {node: '>=0.10.0'} dependencies: kind-of: 6.0.3 dev: true - /is-arguments/1.0.4: + /is-arguments@1.0.4: resolution: {integrity: sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==} engines: {node: '>= 0.4'} dev: true - /is-arrayish/0.2.1: + /is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} dev: true - /is-bigint/1.0.4: + /is-bigint@1.0.4: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} dependencies: has-bigints: 1.0.2 dev: true - /is-binary-path/2.1.0: + /is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} dependencies: binary-extensions: 2.2.0 dev: true - /is-boolean-object/1.1.2: + /is-boolean-object@1.1.2: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} dependencies: @@ -6618,53 +6657,53 @@ packages: has-tostringtag: 1.0.0 dev: true - /is-buffer/1.1.6: + /is-buffer@1.1.6: resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} dev: true - /is-buffer/2.0.5: + /is-buffer@2.0.5: resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} engines: {node: '>=4'} dev: true - /is-callable/1.2.7: + /is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} dev: true - /is-ci/2.0.0: + /is-ci@2.0.0: resolution: {integrity: sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==} hasBin: true dependencies: ci-info: 2.0.0 dev: true - /is-core-module/2.10.0: + /is-core-module@2.10.0: resolution: {integrity: sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==} dependencies: has: 1.0.3 dev: true - /is-data-descriptor/0.1.4: + /is-data-descriptor@0.1.4: resolution: {integrity: sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==} engines: {node: '>=0.10.0'} dependencies: kind-of: 3.2.2 dev: true - /is-data-descriptor/1.0.0: + /is-data-descriptor@1.0.0: resolution: {integrity: sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==} engines: {node: '>=0.10.0'} dependencies: kind-of: 6.0.3 dev: true - /is-date-object/1.0.2: + /is-date-object@1.0.2: resolution: {integrity: sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==} engines: {node: '>= 0.4'} dev: true - /is-descriptor/0.1.6: + /is-descriptor@0.1.6: resolution: {integrity: sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==} engines: {node: '>=0.10.0'} dependencies: @@ -6673,7 +6712,7 @@ packages: kind-of: 5.1.0 dev: true - /is-descriptor/1.0.2: + /is-descriptor@1.0.2: resolution: {integrity: sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==} engines: {node: '>=0.10.0'} dependencies: @@ -6682,134 +6721,134 @@ packages: kind-of: 6.0.3 dev: true - /is-docker/2.2.1: + /is-docker@2.2.1: resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} engines: {node: '>=8'} hasBin: true dev: true - /is-extendable/0.1.1: + /is-extendable@0.1.1: resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} engines: {node: '>=0.10.0'} dev: true - /is-extendable/1.0.1: + /is-extendable@1.0.1: resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} engines: {node: '>=0.10.0'} dependencies: is-plain-object: 2.0.4 dev: true - /is-extglob/2.1.1: + /is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} dev: true - /is-finite/1.1.0: + /is-finite@1.1.0: resolution: {integrity: sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==} engines: {node: '>=0.10.0'} dev: true - /is-fn/1.0.0: + /is-fn@1.0.0: resolution: {integrity: sha512-XoFPJQmsAShb3jEQRfzf2rqXavq7fIqF/jOekp308JlThqrODnMpweVSGilKTCXELfLhltGP2AGgbQGVP8F1dg==} engines: {node: '>=0.10.0'} dev: true - /is-fullwidth-code-point/1.0.0: + /is-fullwidth-code-point@1.0.0: resolution: {integrity: sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==} engines: {node: '>=0.10.0'} dependencies: number-is-nan: 1.0.1 dev: true - /is-fullwidth-code-point/2.0.0: + /is-fullwidth-code-point@2.0.0: resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} engines: {node: '>=4'} dev: true - /is-fullwidth-code-point/3.0.0: + /is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} dev: true - /is-function/1.0.1: + /is-function@1.0.1: resolution: {integrity: sha512-coTeFCk0VaNTNO/FwMMaI30KOPOIkLp1q5M7dIVDn4Zop70KyGFZqXSgKClBisjrD3S2cVIuD7MD793/lyLGZQ==} dev: true - /is-generator-function/1.0.8: + /is-generator-function@1.0.8: resolution: {integrity: sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==} engines: {node: '>= 0.4'} dev: true - /is-glob/4.0.3: + /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} dependencies: is-extglob: 2.1.1 dev: true - /is-hex-prefixed/1.0.0: + /is-hex-prefixed@1.0.0: resolution: {integrity: sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==} engines: {node: '>=6.5.0', npm: '>=3'} dev: true - /is-lower-case/1.1.3: + /is-lower-case@1.1.3: resolution: {integrity: sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA==} dependencies: lower-case: 1.1.4 dev: true - /is-negative-zero/2.0.2: + /is-negative-zero@2.0.2: resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} engines: {node: '>= 0.4'} dev: true - /is-number-object/1.0.7: + /is-number-object@1.0.7: resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.0 dev: true - /is-number/3.0.0: + /is-number@3.0.0: resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} engines: {node: '>=0.10.0'} dependencies: kind-of: 3.2.2 dev: true - /is-number/7.0.0: + /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} dev: true - /is-object/1.0.1: + /is-object@1.0.1: resolution: {integrity: sha512-+XzmTRB/JXoIdK20Ge8K8PRsP5UlthLaVhIRxzIwQ73jRgER8iRw98DilvERx/tSjOHLy9JM4sKUfLRMB5ui0Q==} dev: true - /is-path-inside/3.0.3: + /is-path-inside@3.0.3: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} dev: true - /is-plain-obj/1.1.0: + /is-plain-obj@1.1.0: resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} engines: {node: '>=0.10.0'} dev: true - /is-plain-obj/2.1.0: + /is-plain-obj@2.1.0: resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} engines: {node: '>=8'} dev: true - /is-plain-object/2.0.4: + /is-plain-object@2.0.4: resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} engines: {node: '>=0.10.0'} dependencies: isobject: 3.0.1 dev: true - /is-regex/1.1.4: + /is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} dependencies: @@ -6817,37 +6856,37 @@ packages: has-tostringtag: 1.0.0 dev: true - /is-retry-allowed/1.2.0: + /is-retry-allowed@1.2.0: resolution: {integrity: sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==} engines: {node: '>=0.10.0'} dev: true - /is-shared-array-buffer/1.0.2: + /is-shared-array-buffer@1.0.2: resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} dependencies: call-bind: 1.0.2 dev: true - /is-stream/1.1.0: + /is-stream@1.1.0: resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} engines: {node: '>=0.10.0'} dev: true - /is-string/1.0.7: + /is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.0 dev: true - /is-symbol/1.0.3: + /is-symbol@1.0.3: resolution: {integrity: sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==} engines: {node: '>= 0.4'} dependencies: has-symbols: 1.0.3 dev: true - /is-typed-array/1.1.5: + /is-typed-array@1.1.5: resolution: {integrity: sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==} engines: {node: '>= 0.4'} dependencies: @@ -6858,76 +6897,76 @@ packages: has-symbols: 1.0.3 dev: true - /is-typedarray/1.0.0: + /is-typedarray@1.0.0: resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} dev: true - /is-unicode-supported/0.1.0: + /is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} dev: true - /is-upper-case/1.1.2: + /is-upper-case@1.1.2: resolution: {integrity: sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw==} dependencies: upper-case: 1.1.3 dev: true - /is-url/1.2.4: + /is-url@1.2.4: resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} dev: true - /is-utf8/0.2.1: + /is-utf8@0.2.1: resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==} dev: true - /is-weakref/1.0.2: + /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: call-bind: 1.0.2 dev: true - /is-windows/1.0.2: + /is-windows@1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} dev: true - /is-wsl/2.2.0: + /is-wsl@2.2.0: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} dependencies: is-docker: 2.2.1 dev: true - /isarray/0.0.1: + /isarray@0.0.1: resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} dev: true - /isarray/1.0.0: + /isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} dev: true - /isexe/2.0.0: + /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true - /isobject/2.1.0: + /isobject@2.1.0: resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} engines: {node: '>=0.10.0'} dependencies: isarray: 1.0.0 dev: true - /isobject/3.0.1: + /isobject@3.0.1: resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} engines: {node: '>=0.10.0'} dev: true - /isstream/0.1.2: + /isstream@0.1.2: resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} dev: true - /istanbul/0.4.5: + /istanbul@0.4.5: resolution: {integrity: sha512-nMtdn4hvK0HjUlzr1DrKSUY8ychprt8dzHOgY2KXsIhHu5PuQQEOTM27gV9Xblyon7aUH/TSFIjRHEODF/FRPg==} deprecated: |- This module is no longer maintained, try this instead: @@ -6951,7 +6990,7 @@ packages: wordwrap: 1.0.0 dev: true - /isurl/1.0.0: + /isurl@1.0.0: resolution: {integrity: sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==} engines: {node: '>= 4'} dependencies: @@ -6959,30 +6998,30 @@ packages: is-object: 1.0.1 dev: true - /js-sha3/0.5.5: + /js-sha3@0.5.5: resolution: {integrity: sha512-yLLwn44IVeunwjpDVTDZmQeVbB0h+dZpY2eO68B/Zik8hu6dH+rKeLxwua79GGIvW6xr8NBAcrtiUbYrTjEFTA==} dev: true - /js-sha3/0.5.7: + /js-sha3@0.5.7: resolution: {integrity: sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==} dev: true - /js-sha3/0.6.1: + /js-sha3@0.6.1: resolution: {integrity: sha512-2OHj7sAZ9gnJS4lQsgIsTslmqVrNQdDC99bvwYGQKU1w6k/gwsTLeGBfWt8yHCuTOGqk7DXzuVlK8J+dDXnG7A==} dev: true - /js-sha3/0.8.0: + /js-sha3@0.8.0: resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} - /js-tokens/3.0.2: + /js-tokens@3.0.2: resolution: {integrity: sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==} dev: true - /js-tokens/4.0.0: + /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} dev: true - /js-yaml/3.13.1: + /js-yaml@3.13.1: resolution: {integrity: sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==} hasBin: true dependencies: @@ -6990,7 +7029,7 @@ packages: esprima: 4.0.1 dev: true - /js-yaml/3.14.1: + /js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true dependencies: @@ -6998,40 +7037,41 @@ packages: esprima: 4.0.1 dev: true - /js-yaml/4.1.0: + /js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true dependencies: argparse: 2.0.1 dev: true - /jsbn/0.1.1: + /jsbn@0.1.1: resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} dev: true - /jsesc/0.5.0: + /jsesc@0.5.0: resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} hasBin: true dev: true - /jsesc/1.3.0: + /jsesc@1.3.0: resolution: {integrity: sha512-Mke0DA0QjUWuJlhsE0ZPPhYiJkRap642SmI/4ztCFaUs6V2AiH1sfecc+57NgaryfAA2VR3v6O+CSjC1jZJKOA==} hasBin: true dev: true - /json-buffer/3.0.0: + /json-buffer@3.0.0: resolution: {integrity: sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==} + requiresBuild: true dev: true - /json-buffer/3.0.1: + /json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} dev: true - /json-parse-even-better-errors/2.3.1: + /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} dev: true - /json-rpc-engine/3.8.0: + /json-rpc-engine@3.8.0: resolution: {integrity: sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA==} dependencies: async: 2.6.3 @@ -7044,43 +7084,43 @@ packages: - supports-color dev: true - /json-rpc-error/2.0.0: + /json-rpc-error@2.0.0: resolution: {integrity: sha512-EwUeWP+KgAZ/xqFpaP6YDAXMtCJi+o/QQpCQFIYyxr01AdADi2y413eM8hSqJcoQym9WMePAJWoaODEJufC4Ug==} dependencies: inherits: 2.0.4 dev: true - /json-rpc-random-id/1.0.1: + /json-rpc-random-id@1.0.1: resolution: {integrity: sha512-RJ9YYNCkhVDBuP4zN5BBtYAzEl03yq/jIIsyif0JY9qyJuQQZNeDK7anAPKKlyEtLSj2s8h6hNh2F8zO5q7ScA==} dev: true - /json-schema-traverse/0.4.1: + /json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} dev: true - /json-schema-traverse/1.0.0: + /json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} dev: true - /json-schema/0.2.3: + /json-schema@0.2.3: resolution: {integrity: sha512-a3xHnILGMtk+hDOqNwHzF6e2fNbiMrXZvxKQiEv2MlgQP+pjIOzqAmKYD2mDpXYE/44M7g+n9p2bKkYWDUcXCQ==} dev: true - /json-stable-stringify-without-jsonify/1.0.1: + /json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} dev: true - /json-stable-stringify/1.0.1: + /json-stable-stringify@1.0.1: resolution: {integrity: sha512-i/J297TW6xyj7sDFa7AmBPkQvLIxWr2kKPWI26tXydnZrzVAocNqn5DMNT1Mzk0vit1V5UkRM7C1KdVNp7Lmcg==} dependencies: jsonify: 0.0.0 dev: true - /json-stringify-safe/5.0.1: + /json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} dev: true - /json-to-ast/2.1.0: + /json-to-ast@2.1.0: resolution: {integrity: sha512-W9Lq347r8tA1DfMvAGn9QNcgYm4Wm7Yc+k8e6vezpMnRT+NHbtlxgNBXRVjXe9YM6eTn6+p/MKOlV/aABJcSnQ==} engines: {node: '>= 4'} dependencies: @@ -7088,24 +7128,24 @@ packages: grapheme-splitter: 1.0.4 dev: true - /json5/0.5.1: + /json5@0.5.1: resolution: {integrity: sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==} hasBin: true dev: true - /jsonfile/2.4.0: + /jsonfile@2.4.0: resolution: {integrity: sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==} optionalDependencies: graceful-fs: 4.2.10 dev: true - /jsonfile/4.0.0: + /jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} optionalDependencies: graceful-fs: 4.2.10 dev: true - /jsonfile/6.1.0: + /jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} dependencies: universalify: 2.0.0 @@ -7113,20 +7153,20 @@ packages: graceful-fs: 4.2.10 dev: true - /jsonify/0.0.0: + /jsonify@0.0.0: resolution: {integrity: sha512-trvBk1ki43VZptdBI5rIlG4YOzyeH/WefQt5rj1grasPn4iiZWKet8nkgc4GlsAylaztn0qZfUYOiTsASJFdNA==} dev: true - /jsonpointer/5.0.1: + /jsonpointer@5.0.1: resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} engines: {node: '>=0.10.0'} dev: true - /jsonschema/1.4.0: + /jsonschema@1.4.0: resolution: {integrity: sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw==} dev: true - /jsprim/1.4.1: + /jsprim@1.4.1: resolution: {integrity: sha512-4Dj8Rf+fQ+/Pn7C5qeEX02op1WfOss3PKTE9Nsop3Dx+6UPxlm1dr/og7o2cRa5hNN07CACr4NFzRLtj/rjWog==} engines: {'0': node >=0.6.0} dependencies: @@ -7136,7 +7176,7 @@ packages: verror: 1.10.0 dev: true - /keccak/3.0.2: + /keccak@3.0.2: resolution: {integrity: sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==} engines: {node: '>=10.0.0'} requiresBuild: true @@ -7146,93 +7186,94 @@ packages: readable-stream: 3.6.0 dev: true - /keccakjs/0.2.3: + /keccakjs@0.2.3: resolution: {integrity: sha512-BjLkNDcfaZ6l8HBG9tH0tpmDv3sS2mA7FNQxFHpCdzP3Gb2MVruXBSuoM66SnVxKJpAr5dKGdkHD+bDokt8fTg==} dependencies: browserify-sha3: 0.0.4 sha3: 1.2.6 dev: true - /keyv/3.1.0: + /keyv@3.1.0: resolution: {integrity: sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==} + requiresBuild: true dependencies: json-buffer: 3.0.0 dev: true - /keyv/4.5.0: + /keyv@4.5.0: resolution: {integrity: sha512-2YvuMsA+jnFGtBareKqgANOEKe1mk3HKiXu2fRmAfyxG0MJAywNhi5ttWA3PMjl4NmpyjZNbFifR2vNjW1znfA==} dependencies: json-buffer: 3.0.1 dev: true - /kind-of/3.2.2: + /kind-of@3.2.2: resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} engines: {node: '>=0.10.0'} dependencies: is-buffer: 1.1.6 dev: true - /kind-of/4.0.0: + /kind-of@4.0.0: resolution: {integrity: sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==} engines: {node: '>=0.10.0'} dependencies: is-buffer: 1.1.6 dev: true - /kind-of/5.1.0: + /kind-of@5.1.0: resolution: {integrity: sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==} engines: {node: '>=0.10.0'} dev: true - /kind-of/6.0.3: + /kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} dev: true - /klaw-sync/6.0.0: + /klaw-sync@6.0.0: resolution: {integrity: sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==} dependencies: graceful-fs: 4.2.10 dev: true - /klaw/1.3.1: + /klaw@1.3.1: resolution: {integrity: sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==} optionalDependencies: graceful-fs: 4.2.10 dev: true - /lcid/1.0.0: + /lcid@1.0.0: resolution: {integrity: sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==} engines: {node: '>=0.10.0'} dependencies: invert-kv: 1.0.0 dev: true - /level-codec/7.0.1: + /level-codec@7.0.1: resolution: {integrity: sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==} dev: true - /level-codec/9.0.2: + /level-codec@9.0.2: resolution: {integrity: sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==} engines: {node: '>=6'} dependencies: buffer: 5.7.1 dev: true - /level-errors/1.0.5: + /level-errors@1.0.5: resolution: {integrity: sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==} dependencies: errno: 0.1.8 dev: true - /level-errors/2.0.1: + /level-errors@2.0.1: resolution: {integrity: sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==} engines: {node: '>=6'} dependencies: errno: 0.1.8 dev: true - /level-iterator-stream/1.3.1: + /level-iterator-stream@1.3.1: resolution: {integrity: sha512-1qua0RHNtr4nrZBgYlpV0qHHeHpcRRWTxEZJ8xsemoHAXNL5tbooh4tPEEqIqsbWCAJBmUmkwYK/sW5OrFjWWw==} dependencies: inherits: 2.0.4 @@ -7241,7 +7282,7 @@ packages: xtend: 4.0.2 dev: true - /level-iterator-stream/2.0.3: + /level-iterator-stream@2.0.3: resolution: {integrity: sha512-I6Heg70nfF+e5Y3/qfthJFexhRw/Gi3bIymCoXAlijZdAcLaPuWSJs3KXyTYf23ID6g0o2QF62Yh+grOXY3Rig==} engines: {node: '>=4'} dependencies: @@ -7250,7 +7291,7 @@ packages: xtend: 4.0.2 dev: true - /level-iterator-stream/3.0.1: + /level-iterator-stream@3.0.1: resolution: {integrity: sha512-nEIQvxEED9yRThxvOrq8Aqziy4EGzrxSZK+QzEFAVuJvQ8glfyZ96GB6BoI4sBbLfjMXm2w4vu3Tkcm9obcY0g==} engines: {node: '>=6'} dependencies: @@ -7259,7 +7300,7 @@ packages: xtend: 4.0.2 dev: true - /level-mem/3.0.1: + /level-mem@3.0.1: resolution: {integrity: sha512-LbtfK9+3Ug1UmvvhR2DqLqXiPW1OJ5jEh0a3m9ZgAipiwpSxGj/qaVVy54RG5vAQN1nCuXqjvprCuKSCxcJHBg==} engines: {node: '>=6'} dependencies: @@ -7267,7 +7308,7 @@ packages: memdown: 3.0.0 dev: true - /level-packager/4.0.1: + /level-packager@4.0.1: resolution: {integrity: sha512-svCRKfYLn9/4CoFfi+d8krOtrp6RoX8+xm0Na5cgXMqSyRru0AnDYdLl+YI8u1FyS6gGZ94ILLZDE5dh2but3Q==} engines: {node: '>=6'} dependencies: @@ -7275,13 +7316,13 @@ packages: levelup: 3.1.1 dev: true - /level-post/1.0.7: + /level-post@1.0.7: resolution: {integrity: sha512-PWYqG4Q00asOrLhX7BejSajByB4EmG2GaKHfj3h5UmmZ2duciXLPGYWIjBzLECFWUGOZWlm5B20h/n3Gs3HKew==} dependencies: ltgt: 2.2.1 dev: true - /level-sublevel/6.6.4: + /level-sublevel@6.6.4: resolution: {integrity: sha512-pcCrTUOiO48+Kp6F1+UAzF/OtWqLcQVTVF39HLdZ3RO8XBoXt+XVPKZO1vVr1aUoxHZA9OtD2e1v7G+3S5KFDA==} dependencies: bytewise: 1.1.0 @@ -7296,12 +7337,12 @@ packages: xtend: 4.0.2 dev: true - /level-supports/4.0.1: + /level-supports@4.0.1: resolution: {integrity: sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==} engines: {node: '>=12'} dev: true - /level-transcoder/1.0.1: + /level-transcoder@1.0.1: resolution: {integrity: sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==} engines: {node: '>=12'} dependencies: @@ -7309,14 +7350,14 @@ packages: module-error: 1.0.2 dev: true - /level-ws/0.0.0: + /level-ws@0.0.0: resolution: {integrity: sha512-XUTaO/+Db51Uiyp/t7fCMGVFOTdtLS/NIACxE/GHsij15mKzxksZifKVjlXDF41JMUP/oM1Oc4YNGdKnc3dVLw==} dependencies: readable-stream: 1.0.34 xtend: 2.1.2 dev: true - /level-ws/1.0.0: + /level-ws@1.0.0: resolution: {integrity: sha512-RXEfCmkd6WWFlArh3X8ONvQPm8jNpfA0s/36M4QzLqrLEIt1iJE9WBHLZ5vZJK6haMjJPJGJCQWfjMNnRcq/9Q==} engines: {node: '>=6'} dependencies: @@ -7325,7 +7366,7 @@ packages: xtend: 4.0.2 dev: true - /level/8.0.0: + /level@8.0.0: resolution: {integrity: sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==} engines: {node: '>=12'} dependencies: @@ -7333,7 +7374,7 @@ packages: classic-level: 1.2.0 dev: true - /levelup/1.3.9: + /levelup@1.3.9: resolution: {integrity: sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==} dependencies: deferred-leveldown: 1.2.2 @@ -7345,7 +7386,7 @@ packages: xtend: 4.0.2 dev: true - /levelup/3.1.1: + /levelup@3.1.1: resolution: {integrity: sha512-9N10xRkUU4dShSRRFTBdNaBxofz+PGaIZO962ckboJZiNmLuhVT6FZ6ZKAsICKfUBO76ySaYU6fJWX/jnj3Lcg==} engines: {node: '>=6'} dependencies: @@ -7355,12 +7396,12 @@ packages: xtend: 4.0.2 dev: true - /leven/3.1.0: + /leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} engines: {node: '>=6'} dev: true - /levn/0.3.0: + /levn@0.3.0: resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} engines: {node: '>= 0.8.0'} dependencies: @@ -7368,7 +7409,7 @@ packages: type-check: 0.3.2 dev: true - /levn/0.4.1: + /levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} dependencies: @@ -7376,11 +7417,11 @@ packages: type-check: 0.4.0 dev: true - /lines-and-columns/1.2.4: + /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} dev: true - /load-json-file/1.1.0: + /load-json-file@1.1.0: resolution: {integrity: sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==} engines: {node: '>=0.10.0'} dependencies: @@ -7391,7 +7432,7 @@ packages: strip-bom: 2.0.0 dev: true - /locate-path/2.0.0: + /locate-path@2.0.0: resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} engines: {node: '>=4'} dependencies: @@ -7399,7 +7440,7 @@ packages: path-exists: 3.0.0 dev: true - /locate-path/3.0.0: + /locate-path@3.0.0: resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} engines: {node: '>=6'} dependencies: @@ -7407,60 +7448,60 @@ packages: path-exists: 3.0.0 dev: true - /locate-path/5.0.0: + /locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} dependencies: p-locate: 4.1.0 dev: true - /locate-path/6.0.0: + /locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} dependencies: p-locate: 5.0.0 dev: true - /lodash.assign/4.2.0: + /lodash.assign@4.2.0: resolution: {integrity: sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==} dev: true - /lodash.camelcase/4.3.0: + /lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} dev: true - /lodash.flatten/4.4.0: + /lodash.flatten@4.4.0: resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} dev: true - /lodash.mapvalues/4.6.0: + /lodash.mapvalues@4.6.0: resolution: {integrity: sha512-JPFqXFeZQ7BfS00H58kClY7SPVeHertPE0lNuCyZ26/XlN8TvakYD7b9bGyNmXbT/D3BbtPAAmq90gPWqLkxlQ==} dev: true - /lodash.merge/4.6.2: + /lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true - /lodash.truncate/4.4.2: + /lodash.truncate@4.4.2: resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} dev: true - /lodash/4.17.20: + /lodash@4.17.20: resolution: {integrity: sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==} dev: true - /lodash/4.17.21: + /lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} dev: true - /log-symbols/3.0.0: + /log-symbols@3.0.0: resolution: {integrity: sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==} engines: {node: '>=8'} dependencies: chalk: 2.4.2 dev: true - /log-symbols/4.1.0: + /log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} dependencies: @@ -7468,108 +7509,108 @@ packages: is-unicode-supported: 0.1.0 dev: true - /looper/2.0.0: + /looper@2.0.0: resolution: {integrity: sha512-6DzMHJcjbQX/UPHc1rRCBfKlLwDkvuGZ715cIR36wSdYqWXFT35uLXq5P/2orl3tz+t+VOVPxw4yPinQlUDGDQ==} dev: true - /looper/3.0.0: + /looper@3.0.0: resolution: {integrity: sha512-LJ9wplN/uSn72oJRsXTx+snxPet5c8XiZmOKCm906NVYu+ag6SB6vUcnJcWxgnl2NfbIyeobAn7Bwv6xRj2XJg==} dev: true - /loose-envify/1.4.0: + /loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true dependencies: js-tokens: 4.0.0 dev: true - /loupe/2.3.4: + /loupe@2.3.4: resolution: {integrity: sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==} dependencies: get-func-name: 2.0.0 - /lower-case-first/1.0.2: + /lower-case-first@1.0.2: resolution: {integrity: sha512-UuxaYakO7XeONbKrZf5FEgkantPf5DUqDayzP5VXZrtRPdH86s4kN47I8B3TW10S4QKiE3ziHNf3kRN//okHjA==} dependencies: lower-case: 1.1.4 dev: true - /lower-case/1.1.4: + /lower-case@1.1.4: resolution: {integrity: sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==} dev: true - /lowercase-keys/1.0.1: + /lowercase-keys@1.0.1: resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} engines: {node: '>=0.10.0'} dev: true - /lowercase-keys/2.0.0: + /lowercase-keys@2.0.0: resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} engines: {node: '>=8'} dev: true - /lowercase-keys/3.0.0: + /lowercase-keys@3.0.0: resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: true - /lru-cache/3.2.0: + /lru-cache@3.2.0: resolution: {integrity: sha512-91gyOKTc2k66UG6kHiH4h3S2eltcPwE1STVfMYC/NG+nZwf8IIuiamfmpGZjpbbxzSyEJaLC0tNSmhjlQUTJow==} dependencies: pseudomap: 1.0.2 dev: true - /lru-cache/5.1.1: + /lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} dependencies: yallist: 3.1.1 dev: true - /lru-cache/6.0.0: + /lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} dependencies: yallist: 4.0.0 dev: true - /lru_map/0.3.3: + /lru_map@0.3.3: resolution: {integrity: sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==} dev: true - /ltgt/2.1.3: + /ltgt@2.1.3: resolution: {integrity: sha512-5VjHC5GsENtIi5rbJd+feEpDKhfr7j0odoUR2Uh978g+2p93nd5o34cTjQWohXsPsCZeqoDnIqEf88mPCe0Pfw==} dev: true - /ltgt/2.2.1: + /ltgt@2.2.1: resolution: {integrity: sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==} dev: true - /make-error/1.3.6: + /make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} dev: true - /map-cache/0.2.2: + /map-cache@0.2.2: resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} engines: {node: '>=0.10.0'} dev: true - /map-visit/1.0.0: + /map-visit@1.0.0: resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} engines: {node: '>=0.10.0'} dependencies: object-visit: 1.0.1 dev: true - /markdown-table/1.1.3: + /markdown-table@1.1.3: resolution: {integrity: sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==} dev: true - /mcl-wasm/0.7.9: + /mcl-wasm@0.7.9: resolution: {integrity: sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==} engines: {node: '>=8.9.0'} dev: true - /md5.js/1.3.5: + /md5.js@1.3.5: resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} dependencies: hash-base: 3.1.0 @@ -7577,12 +7618,12 @@ packages: safe-buffer: 5.2.1 dev: true - /media-typer/0.3.0: + /media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} dev: true - /memdown/1.4.1: + /memdown@1.4.1: resolution: {integrity: sha512-iVrGHZB8i4OQfM155xx8akvG9FIj+ht14DX5CQkCTG4EHzZ3d3sgckIf/Lm9ivZalEsFuEVnWv2B2WZvbrro2w==} dependencies: abstract-leveldown: 2.7.2 @@ -7593,7 +7634,7 @@ packages: safe-buffer: 5.1.2 dev: true - /memdown/3.0.0: + /memdown@3.0.0: resolution: {integrity: sha512-tbV02LfZMWLcHcq4tw++NuqMO+FZX8tNJEiD2aNRm48ZZusVg5N8NART+dmBkepJVye986oixErf7jfXboMGMA==} engines: {node: '>=6'} dependencies: @@ -7605,7 +7646,7 @@ packages: safe-buffer: 5.1.2 dev: true - /memory-level/1.0.0: + /memory-level@1.0.0: resolution: {integrity: sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og==} engines: {node: '>=12'} dependencies: @@ -7614,21 +7655,21 @@ packages: module-error: 1.0.2 dev: true - /memorystream/0.3.1: + /memorystream@0.3.1: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} dev: true - /merge-descriptors/1.0.1: + /merge-descriptors@1.0.1: resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} dev: true - /merge2/1.4.1: + /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} dev: true - /merkle-patricia-tree/2.3.2: + /merkle-patricia-tree@2.3.2: resolution: {integrity: sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==} dependencies: async: 1.5.2 @@ -7641,7 +7682,7 @@ packages: semaphore: 1.1.0 dev: true - /merkle-patricia-tree/3.0.0: + /merkle-patricia-tree@3.0.0: resolution: {integrity: sha512-soRaMuNf/ILmw3KWbybaCjhx86EYeBbD8ph0edQCTed0JN/rxDt1EBN52Ajre3VyGo+91f8+/rfPIRQnnGMqmQ==} dependencies: async: 2.6.3 @@ -7653,12 +7694,12 @@ packages: semaphore: 1.1.0 dev: true - /methods/1.1.2: + /methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} dev: true - /micromatch/3.1.10: + /micromatch@3.1.10: resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} engines: {node: '>=0.10.0'} dependencies: @@ -7679,7 +7720,7 @@ packages: - supports-color dev: true - /micromatch/4.0.5: + /micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} dependencies: @@ -7687,7 +7728,7 @@ packages: picomatch: 2.3.1 dev: true - /miller-rabin/4.0.1: + /miller-rabin@4.0.1: resolution: {integrity: sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==} hasBin: true dependencies: @@ -7695,90 +7736,90 @@ packages: brorand: 1.1.0 dev: true - /mime-db/1.44.0: + /mime-db@1.44.0: resolution: {integrity: sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==} engines: {node: '>= 0.6'} dev: true - /mime-types/2.1.27: + /mime-types@2.1.27: resolution: {integrity: sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==} engines: {node: '>= 0.6'} dependencies: mime-db: 1.44.0 dev: true - /mime/1.6.0: + /mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} hasBin: true dev: true - /mimic-response/1.0.1: + /mimic-response@1.0.1: resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} engines: {node: '>=4'} dev: true - /mimic-response/3.1.0: + /mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} dev: true - /min-document/2.19.0: + /min-document@2.19.0: resolution: {integrity: sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==} dependencies: dom-walk: 0.1.1 dev: true - /minimalistic-assert/1.0.1: + /minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} - /minimalistic-crypto-utils/1.0.1: + /minimalistic-crypto-utils@1.0.1: resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} - /minimatch/3.0.4: + /minimatch@3.0.4: resolution: {integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==} dependencies: brace-expansion: 1.1.11 dev: true - /minimatch/3.1.2: + /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: brace-expansion: 1.1.11 dev: true - /minimatch/5.0.1: + /minimatch@5.0.1: resolution: {integrity: sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==} engines: {node: '>=10'} dependencies: brace-expansion: 2.0.1 dev: true - /minimatch/5.1.6: + /minimatch@5.1.6: resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} engines: {node: '>=10'} dependencies: brace-expansion: 2.0.1 dev: true - /minimist/1.2.6: + /minimist@1.2.6: resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==} dev: true - /minipass/2.9.0: + /minipass@2.9.0: resolution: {integrity: sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==} dependencies: safe-buffer: 5.2.1 yallist: 3.1.1 dev: true - /minizlib/1.3.3: + /minizlib@1.3.3: resolution: {integrity: sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==} dependencies: minipass: 2.9.0 dev: true - /mixin-deep/1.3.2: + /mixin-deep@1.3.2: resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} engines: {node: '>=0.10.0'} dependencies: @@ -7786,7 +7827,7 @@ packages: is-extendable: 1.0.1 dev: true - /mkdirp-promise/5.0.1: + /mkdirp-promise@5.0.1: resolution: {integrity: sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w==} engines: {node: '>=4'} deprecated: This package is broken and no longer maintained. 'mkdirp' itself supports promises now, please switch to that. @@ -7794,33 +7835,33 @@ packages: mkdirp: 1.0.4 dev: true - /mkdirp/0.5.5: + /mkdirp@0.5.5: resolution: {integrity: sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==} hasBin: true dependencies: minimist: 1.2.6 dev: true - /mkdirp/0.5.6: + /mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true dependencies: minimist: 1.2.6 dev: true - /mkdirp/1.0.4: + /mkdirp@1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} hasBin: true dev: true - /mnemonist/0.38.5: + /mnemonist@0.38.5: resolution: {integrity: sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==} dependencies: obliterator: 2.0.4 dev: true - /mocha/10.2.0: + /mocha@10.2.0: resolution: {integrity: sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==} engines: {node: '>= 14.0.0'} hasBin: true @@ -7828,7 +7869,7 @@ packages: ansi-colors: 4.1.1 browser-stdout: 1.3.1 chokidar: 3.5.3 - debug: 4.3.4_supports-color@8.1.1 + debug: 4.3.4(supports-color@8.1.1) diff: 5.0.0 escape-string-regexp: 4.0.0 find-up: 5.0.0 @@ -7848,7 +7889,7 @@ packages: yargs-unparser: 2.0.0 dev: true - /mocha/7.1.2: + /mocha@7.1.2: resolution: {integrity: sha512-o96kdRKMKI3E8U0bjnfqW4QMk12MwZ4mhdBTf+B5a1q9+aq2HRnj+3ZdJu0B/ZhJeK78MgYuv6L8d/rA5AeBJA==} engines: {node: '>= 8.10.0'} hasBin: true @@ -7856,7 +7897,7 @@ packages: ansi-colors: 3.2.3 browser-stdout: 1.3.1 chokidar: 3.3.0 - debug: 3.2.6_supports-color@6.0.0 + debug: 3.2.6(supports-color@6.0.0) diff: 3.5.0 escape-string-regexp: 1.0.5 find-up: 3.0.0 @@ -7879,7 +7920,7 @@ packages: yargs-unparser: 1.6.0 dev: true - /mocha/7.2.0: + /mocha@7.2.0: resolution: {integrity: sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==} engines: {node: '>= 8.10.0'} hasBin: true @@ -7887,7 +7928,7 @@ packages: ansi-colors: 3.2.3 browser-stdout: 1.3.1 chokidar: 3.3.0 - debug: 3.2.6_supports-color@6.0.0 + debug: 3.2.6(supports-color@6.0.0) diff: 3.5.0 escape-string-regexp: 1.0.5 find-up: 3.0.0 @@ -7910,36 +7951,36 @@ packages: yargs-unparser: 1.6.0 dev: true - /mock-fs/4.12.0: + /mock-fs@4.12.0: resolution: {integrity: sha512-/P/HtrlvBxY4o/PzXY9cCNBrdylDNxg7gnrv2sMNxj+UJ2m8jSpl0/A6fuJeNAWr99ZvGWH8XCbE0vmnM5KupQ==} dev: true - /module-error/1.0.2: + /module-error@1.0.2: resolution: {integrity: sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==} engines: {node: '>=10'} dev: true - /moment/2.29.4: + /moment@2.29.4: resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==} dev: true - /ms/2.0.0: + /ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} dev: true - /ms/2.1.1: + /ms@2.1.1: resolution: {integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==} dev: true - /ms/2.1.2: + /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} dev: true - /ms/2.1.3: + /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} dev: true - /multibase/0.6.1: + /multibase@0.6.1: resolution: {integrity: sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==} deprecated: This module has been superseded by the multiformats module dependencies: @@ -7947,7 +7988,7 @@ packages: buffer: 5.7.1 dev: true - /multibase/0.7.0: + /multibase@0.7.0: resolution: {integrity: sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==} deprecated: This module has been superseded by the multiformats module dependencies: @@ -7955,14 +7996,14 @@ packages: buffer: 5.7.1 dev: true - /multicodec/0.5.7: + /multicodec@0.5.7: resolution: {integrity: sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==} deprecated: This module has been superseded by the multiformats module dependencies: varint: 5.0.2 dev: true - /multicodec/1.0.4: + /multicodec@1.0.4: resolution: {integrity: sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==} deprecated: This module has been superseded by the multiformats module dependencies: @@ -7970,7 +8011,7 @@ packages: varint: 5.0.2 dev: true - /multihashes/0.4.21: + /multihashes@0.4.21: resolution: {integrity: sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==} dependencies: buffer: 5.7.1 @@ -7978,29 +8019,29 @@ packages: varint: 5.0.2 dev: true - /nan/2.13.2: + /nan@2.13.2: resolution: {integrity: sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==} dev: true - /nan/2.16.0: + /nan@2.16.0: resolution: {integrity: sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==} dev: true - /nano-base32/1.0.1: + /nano-base32@1.0.1: resolution: {integrity: sha512-sxEtoTqAPdjWVGv71Q17koMFGsOMSiHsIFEvzOM7cNp8BXB4AnEwmDabm5dorusJf/v1z7QxaZYxUorU9RKaAw==} dev: true - /nano-json-stream-parser/0.1.2: + /nano-json-stream-parser@0.1.2: resolution: {integrity: sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==} dev: true - /nanoid/3.3.3: + /nanoid@3.3.3: resolution: {integrity: sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true dev: true - /nanomatch/1.2.13: + /nanomatch@1.2.13: resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} engines: {node: '>=0.10.0'} dependencies: @@ -8019,72 +8060,72 @@ packages: - supports-color dev: true - /napi-macros/2.0.0: + /napi-macros@2.0.0: resolution: {integrity: sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==} dev: true - /natural-compare-lite/1.4.0: + /natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} dev: true - /natural-compare/1.4.0: + /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true - /negotiator/0.6.2: + /negotiator@0.6.2: resolution: {integrity: sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==} engines: {node: '>= 0.6'} dev: true - /neo-async/2.6.2: + /neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} dev: true - /neodoc/2.0.2: + /neodoc@2.0.2: resolution: {integrity: sha512-NAppJ0YecKWdhSXFYCHbo6RutiX8vOt/Jo3l46mUg6pQlpJNaqc5cGxdrW2jITQm5JIYySbFVPDl3RrREXNyPw==} dependencies: ansi-regex: 2.1.1 dev: true - /next-tick/1.1.0: + /next-tick@1.1.0: resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} dev: true - /nice-try/1.0.5: + /nice-try@1.0.5: resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} dev: true - /no-case/2.3.2: + /no-case@2.3.2: resolution: {integrity: sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==} dependencies: lower-case: 1.1.4 dev: true - /node-addon-api/2.0.2: + /node-addon-api@2.0.2: resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==} dev: true - /node-emoji/1.11.0: + /node-emoji@1.11.0: resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} dependencies: lodash: 4.17.21 dev: true - /node-environment-flags/1.0.6: + /node-environment-flags@1.0.6: resolution: {integrity: sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==} dependencies: object.getownpropertydescriptors: 2.1.4 semver: 5.7.1 dev: true - /node-fetch/1.7.3: + /node-fetch@1.7.3: resolution: {integrity: sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==} dependencies: encoding: 0.1.13 is-stream: 1.1.0 dev: true - /node-fetch/2.6.7: + /node-fetch@2.6.7: resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} engines: {node: 4.x || >=6.0.0} peerDependencies: @@ -8096,36 +8137,36 @@ packages: whatwg-url: 5.0.0 dev: true - /node-gyp-build/4.5.0: + /node-gyp-build@4.5.0: resolution: {integrity: sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==} hasBin: true dev: true - /node-interval-tree/2.1.2: + /node-interval-tree@2.1.2: resolution: {integrity: sha512-bJ9zMDuNGzVQg1xv0bCPzyEDxHgbrx7/xGj6CDokvizZZmastPsOh0JJLuY8wA5q2SfX1TLNMk7XNV8WxbGxzA==} engines: {node: '>= 14.0.0'} dependencies: shallowequal: 1.1.0 dev: true - /nofilter/1.0.4: + /nofilter@1.0.4: resolution: {integrity: sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==} engines: {node: '>=8'} dev: true - /nofilter/3.1.0: + /nofilter@3.1.0: resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==} engines: {node: '>=12.19'} dev: true - /nopt/3.0.6: + /nopt@3.0.6: resolution: {integrity: sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==} hasBin: true dependencies: abbrev: 1.1.1 dev: true - /normalize-package-data/2.5.0: + /normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} dependencies: hosted-git-info: 2.8.9 @@ -8134,33 +8175,34 @@ packages: validate-npm-package-license: 3.0.4 dev: true - /normalize-path/3.0.0: + /normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} dev: true - /normalize-url/4.5.1: + /normalize-url@4.5.1: resolution: {integrity: sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==} engines: {node: '>=8'} + requiresBuild: true dev: true - /normalize-url/6.1.0: + /normalize-url@6.1.0: resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} engines: {node: '>=10'} dev: true - /nth-check/2.1.1: + /nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} dependencies: boolbase: 1.0.0 dev: true - /number-is-nan/1.0.1: + /number-is-nan@1.0.1: resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==} engines: {node: '>=0.10.0'} dev: true - /number-to-bn/1.7.0: + /number-to-bn@1.7.0: resolution: {integrity: sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==} engines: {node: '>=6.5.0', npm: '>=3'} dependencies: @@ -8168,16 +8210,16 @@ packages: strip-hex-prefix: 1.0.0 dev: true - /oauth-sign/0.9.0: + /oauth-sign@0.9.0: resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} dev: true - /object-assign/4.1.1: + /object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} dev: true - /object-copy/0.1.0: + /object-copy@0.1.0: resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} engines: {node: '>=0.10.0'} dependencies: @@ -8186,11 +8228,11 @@ packages: kind-of: 3.2.2 dev: true - /object-inspect/1.12.2: + /object-inspect@1.12.2: resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} dev: true - /object-is/1.1.5: + /object-is@1.1.5: resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} engines: {node: '>= 0.4'} dependencies: @@ -8198,23 +8240,23 @@ packages: define-properties: 1.1.4 dev: true - /object-keys/0.4.0: + /object-keys@0.4.0: resolution: {integrity: sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==} dev: true - /object-keys/1.1.1: + /object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} dev: true - /object-visit/1.0.1: + /object-visit@1.0.1: resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} engines: {node: '>=0.10.0'} dependencies: isobject: 3.0.1 dev: true - /object.assign/4.1.0: + /object.assign@4.1.0: resolution: {integrity: sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==} engines: {node: '>= 0.4'} dependencies: @@ -8224,7 +8266,7 @@ packages: object-keys: 1.1.1 dev: true - /object.assign/4.1.4: + /object.assign@4.1.4: resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} engines: {node: '>= 0.4'} dependencies: @@ -8234,7 +8276,7 @@ packages: object-keys: 1.1.1 dev: true - /object.getownpropertydescriptors/2.1.4: + /object.getownpropertydescriptors@2.1.4: resolution: {integrity: sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ==} engines: {node: '>= 0.8'} dependencies: @@ -8244,44 +8286,45 @@ packages: es-abstract: 1.20.3 dev: true - /object.pick/1.3.0: + /object.pick@1.3.0: resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} engines: {node: '>=0.10.0'} dependencies: isobject: 3.0.1 dev: true - /obliterator/2.0.4: + /obliterator@2.0.4: resolution: {integrity: sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==} dev: true - /oboe/2.1.4: + /oboe@2.1.4: resolution: {integrity: sha512-ymBJ4xSC6GBXLT9Y7lirj+xbqBLa+jADGJldGEYG7u8sZbS9GyG+u1Xk9c5cbriKwSpCg41qUhPjvU5xOpvIyQ==} + requiresBuild: true dependencies: http-https: 1.0.0 dev: true optional: true - /oboe/2.1.5: + /oboe@2.1.5: resolution: {integrity: sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA==} dependencies: http-https: 1.0.0 dev: true - /on-finished/2.3.0: + /on-finished@2.3.0: resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==} engines: {node: '>= 0.8'} dependencies: ee-first: 1.1.1 dev: true - /once/1.4.0: + /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: wrappy: 1.0.2 dev: true - /open/7.4.2: + /open@7.4.2: resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} engines: {node: '>=8'} dependencies: @@ -8289,7 +8332,7 @@ packages: is-wsl: 2.2.0 dev: true - /optionator/0.8.3: + /optionator@0.8.3: resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} engines: {node: '>= 0.8.0'} dependencies: @@ -8301,7 +8344,7 @@ packages: word-wrap: 1.2.3 dev: true - /optionator/0.9.1: + /optionator@0.9.1: resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} engines: {node: '>= 0.8.0'} dependencies: @@ -8313,130 +8356,131 @@ packages: word-wrap: 1.2.3 dev: true - /os-homedir/1.0.2: + /os-homedir@1.0.2: resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} engines: {node: '>=0.10.0'} dev: true - /os-locale/1.4.0: + /os-locale@1.4.0: resolution: {integrity: sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==} engines: {node: '>=0.10.0'} dependencies: lcid: 1.0.0 dev: true - /os-tmpdir/1.0.2: + /os-tmpdir@1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} dev: true - /p-cancelable/0.3.0: + /p-cancelable@0.3.0: resolution: {integrity: sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==} engines: {node: '>=4'} dev: true - /p-cancelable/1.1.0: + /p-cancelable@1.1.0: resolution: {integrity: sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==} engines: {node: '>=6'} + requiresBuild: true dev: true - /p-cancelable/3.0.0: + /p-cancelable@3.0.0: resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} engines: {node: '>=12.20'} dev: true - /p-finally/1.0.0: + /p-finally@1.0.0: resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} engines: {node: '>=4'} dev: true - /p-limit/1.3.0: + /p-limit@1.3.0: resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} engines: {node: '>=4'} dependencies: p-try: 1.0.0 dev: true - /p-limit/2.3.0: + /p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} dependencies: p-try: 2.2.0 dev: true - /p-limit/3.1.0: + /p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} dependencies: yocto-queue: 0.1.0 dev: true - /p-locate/2.0.0: + /p-locate@2.0.0: resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} engines: {node: '>=4'} dependencies: p-limit: 1.3.0 dev: true - /p-locate/3.0.0: + /p-locate@3.0.0: resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} engines: {node: '>=6'} dependencies: p-limit: 2.3.0 dev: true - /p-locate/4.1.0: + /p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} dependencies: p-limit: 2.3.0 dev: true - /p-locate/5.0.0: + /p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} dependencies: p-limit: 3.1.0 dev: true - /p-map/4.0.0: + /p-map@4.0.0: resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} engines: {node: '>=10'} dependencies: aggregate-error: 3.1.0 dev: true - /p-timeout/1.2.1: + /p-timeout@1.2.1: resolution: {integrity: sha512-gb0ryzr+K2qFqFv6qi3khoeqMZF/+ajxQipEF6NteZVnvz9tzdsfAVj3lYtn1gAXvH5lfLwfxEII799gt/mRIA==} engines: {node: '>=4'} dependencies: p-finally: 1.0.0 dev: true - /p-try/1.0.0: + /p-try@1.0.0: resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} engines: {node: '>=4'} dev: true - /p-try/2.2.0: + /p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} dev: true - /param-case/2.1.1: + /param-case@2.1.1: resolution: {integrity: sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==} dependencies: no-case: 2.3.2 dev: true - /parent-module/1.0.1: + /parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} dependencies: callsites: 3.1.0 dev: true - /parse-asn1/5.1.5: + /parse-asn1@5.1.5: resolution: {integrity: sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==} dependencies: asn1.js: 4.10.1 @@ -8447,22 +8491,22 @@ packages: safe-buffer: 5.2.1 dev: true - /parse-cache-control/1.0.1: + /parse-cache-control@1.0.1: resolution: {integrity: sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==} dev: true - /parse-headers/2.0.3: + /parse-headers@2.0.3: resolution: {integrity: sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA==} dev: true - /parse-json/2.2.0: + /parse-json@2.2.0: resolution: {integrity: sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==} engines: {node: '>=0.10.0'} dependencies: error-ex: 1.3.2 dev: true - /parse-json/5.2.0: + /parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} dependencies: @@ -8472,37 +8516,37 @@ packages: lines-and-columns: 1.2.4 dev: true - /parse5-htmlparser2-tree-adapter/7.0.0: + /parse5-htmlparser2-tree-adapter@7.0.0: resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} dependencies: domhandler: 5.0.3 parse5: 7.1.1 dev: true - /parse5/7.1.1: + /parse5@7.1.1: resolution: {integrity: sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg==} dependencies: entities: 4.4.0 dev: true - /parseurl/1.3.3: + /parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} dev: true - /pascal-case/2.0.1: + /pascal-case@2.0.1: resolution: {integrity: sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ==} dependencies: camel-case: 3.0.0 upper-case-first: 1.1.2 dev: true - /pascalcase/0.1.1: + /pascalcase@0.1.1: resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} engines: {node: '>=0.10.0'} dev: true - /patch-package/6.2.2: + /patch-package@6.2.2: resolution: {integrity: sha512-YqScVYkVcClUY0v8fF0kWOjDYopzIM8e3bj/RU1DPeEF14+dCGm6UeOYm4jvCyxqIEQ5/eJzmbWfDWnUleFNMg==} engines: {npm: '>5'} hasBin: true @@ -8523,7 +8567,7 @@ packages: - supports-color dev: true - /patch-package/6.4.7: + /patch-package@6.4.7: resolution: {integrity: sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ==} engines: {npm: '>5'} hasBin: true @@ -8543,57 +8587,57 @@ packages: tmp: 0.0.33 dev: true - /path-browserify/1.0.1: + /path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} dev: true - /path-case/2.1.1: + /path-case@2.1.1: resolution: {integrity: sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q==} dependencies: no-case: 2.3.2 dev: true - /path-exists/2.1.0: + /path-exists@2.1.0: resolution: {integrity: sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==} engines: {node: '>=0.10.0'} dependencies: pinkie-promise: 2.0.1 dev: true - /path-exists/3.0.0: + /path-exists@3.0.0: resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} engines: {node: '>=4'} dev: true - /path-exists/4.0.0: + /path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} dev: true - /path-is-absolute/1.0.1: + /path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} dev: true - /path-key/2.0.1: + /path-key@2.0.1: resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} engines: {node: '>=4'} dev: true - /path-key/3.1.1: + /path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} dev: true - /path-parse/1.0.7: + /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} dev: true - /path-to-regexp/0.1.7: + /path-to-regexp@0.1.7: resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} dev: true - /path-type/1.1.0: + /path-type@1.1.0: resolution: {integrity: sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==} engines: {node: '>=0.10.0'} dependencies: @@ -8602,15 +8646,15 @@ packages: pinkie-promise: 2.0.1 dev: true - /path-type/4.0.0: + /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} dev: true - /pathval/1.1.1: + /pathval@1.1.1: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} - /pbkdf2/3.1.2: + /pbkdf2@3.1.2: resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==} engines: {node: '>=0.12'} dependencies: @@ -8621,85 +8665,86 @@ packages: sha.js: 2.4.11 dev: true - /performance-now/2.1.0: + /performance-now@2.1.0: resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} dev: true - /picomatch/2.3.1: + /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} dev: true - /pify/2.3.0: + /pify@2.3.0: resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} engines: {node: '>=0.10.0'} dev: true - /pify/4.0.1: + /pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} dev: true - /pinkie-promise/2.0.1: + /pinkie-promise@2.0.1: resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} engines: {node: '>=0.10.0'} dependencies: pinkie: 2.0.4 dev: true - /pinkie/2.0.4: + /pinkie@2.0.4: resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} engines: {node: '>=0.10.0'} dev: true - /pluralize/8.0.0: + /pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} dev: true - /posix-character-classes/0.1.1: + /posix-character-classes@0.1.1: resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==} engines: {node: '>=0.10.0'} dev: true - /postinstall-postinstall/2.1.0: + /postinstall-postinstall@2.1.0: resolution: {integrity: sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==} requiresBuild: true dev: true - /precond/0.2.3: + /precond@0.2.3: resolution: {integrity: sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ==} engines: {node: '>= 0.6'} dev: true - /prelude-ls/1.1.2: + /prelude-ls@1.1.2: resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} engines: {node: '>= 0.8.0'} dev: true - /prelude-ls/1.2.1: + /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} dev: true - /prepend-http/1.0.4: + /prepend-http@1.0.4: resolution: {integrity: sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==} engines: {node: '>=0.10.0'} dev: true - /prepend-http/2.0.0: + /prepend-http@2.0.0: resolution: {integrity: sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==} engines: {node: '>=4'} + requiresBuild: true dev: true - /prettier-linter-helpers/1.0.0: + /prettier-linter-helpers@1.0.0: resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} engines: {node: '>=6.0.0'} dependencies: fast-diff: 1.2.0 dev: true - /prettier-plugin-solidity/1.1.3_prettier@2.8.8: + /prettier-plugin-solidity@1.1.3(prettier@2.8.8): resolution: {integrity: sha512-fQ9yucPi2sBbA2U2Xjh6m4isUTJ7S7QLc/XDDsktqqxYfTwdYKJ0EnnywXHwCGAaYbQNK+HIYPL1OemxuMsgeg==} engines: {node: '>=12'} peerDependencies: @@ -8711,27 +8756,27 @@ packages: solidity-comments-extractor: 0.0.7 dev: true - /prettier/2.8.8: + /prettier@2.8.8: resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} engines: {node: '>=10.13.0'} hasBin: true dev: true - /private/0.1.8: + /private@0.1.8: resolution: {integrity: sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==} engines: {node: '>= 0.6'} dev: true - /process-nextick-args/2.0.1: + /process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} dev: true - /process/0.5.2: + /process@0.5.2: resolution: {integrity: sha512-oNpcutj+nYX2FjdEW7PGltWhXulAnFlM0My/k48L90hARCOJtvBbQXc/6itV2jDvU5xAAtonP+r6wmQgCcbAUA==} engines: {node: '>= 0.6.0'} dev: true - /promise-to-callback/1.0.0: + /promise-to-callback@1.0.0: resolution: {integrity: sha512-uhMIZmKM5ZteDMfLgJnoSq9GCwsNKrYau73Awf1jIy6/eUcuuZ3P+CD9zUv0kJsIUbU+x6uLNIhXhLHDs1pNPA==} engines: {node: '>=0.10.0'} dependencies: @@ -8739,13 +8784,13 @@ packages: set-immediate-shim: 1.0.1 dev: true - /promise/8.3.0: + /promise@8.3.0: resolution: {integrity: sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==} dependencies: asap: 2.0.6 dev: true - /proper-lockfile/4.1.2: + /proper-lockfile@4.1.2: resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} dependencies: graceful-fs: 4.2.10 @@ -8753,7 +8798,7 @@ packages: signal-exit: 3.0.7 dev: true - /proxy-addr/2.0.5: + /proxy-addr@2.0.5: resolution: {integrity: sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==} engines: {node: '>= 0.10'} dependencies: @@ -8761,19 +8806,19 @@ packages: ipaddr.js: 1.9.0 dev: true - /prr/1.0.1: + /prr@1.0.1: resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} dev: true - /pseudomap/1.0.2: + /pseudomap@1.0.2: resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} dev: true - /psl/1.9.0: + /psl@1.9.0: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} dev: true - /public-encrypt/4.0.3: + /public-encrypt@4.0.3: resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} dependencies: bn.js: 4.12.0 @@ -8784,15 +8829,15 @@ packages: safe-buffer: 5.2.1 dev: true - /pull-cat/1.1.11: + /pull-cat@1.1.11: resolution: {integrity: sha512-i3w+xZ3DCtTVz8S62hBOuNLRHqVDsHMNZmgrZsjPnsxXUgbWtXEee84lo1XswE7W2a3WHyqsNuDJTjVLAQR8xg==} dev: true - /pull-defer/0.2.3: + /pull-defer@0.2.3: resolution: {integrity: sha512-/An3KE7mVjZCqNhZsr22k1Tx8MACnUnHZZNPSJ0S62td8JtYr/AiRG42Vz7Syu31SoTLUzVIe61jtT/pNdjVYA==} dev: true - /pull-level/2.0.4: + /pull-level@2.0.4: resolution: {integrity: sha512-fW6pljDeUThpq5KXwKbRG3X7Ogk3vc75d5OQU/TvXXui65ykm+Bn+fiktg+MOx2jJ85cd+sheufPL+rw9QSVZg==} dependencies: level-post: 1.0.7 @@ -8804,70 +8849,70 @@ packages: stream-to-pull-stream: 1.7.3 dev: true - /pull-live/1.0.1: + /pull-live@1.0.1: resolution: {integrity: sha512-tkNz1QT5gId8aPhV5+dmwoIiA1nmfDOzJDlOOUpU5DNusj6neNd3EePybJ5+sITr2FwyCs/FVpx74YMCfc8YeA==} dependencies: pull-cat: 1.1.11 pull-stream: 3.6.14 dev: true - /pull-pushable/2.2.0: + /pull-pushable@2.2.0: resolution: {integrity: sha512-M7dp95enQ2kaHvfCt2+DJfyzgCSpWVR2h2kWYnVsW6ZpxQBx5wOu0QWOvQPVoPnBLUZYitYP2y7HyHkLQNeGXg==} dev: true - /pull-stream/3.6.14: + /pull-stream@3.6.14: resolution: {integrity: sha512-KIqdvpqHHaTUA2mCYcLG1ibEbu/LCKoJZsBWyv9lSYtPkJPBq8m3Hxa103xHi6D2thj5YXa0TqK3L3GUkwgnew==} dev: true - /pull-window/2.1.4: + /pull-window@2.1.4: resolution: {integrity: sha512-cbDzN76BMlcGG46OImrgpkMf/VkCnupj8JhsrpBw3aWBM9ye345aYnqitmZCgauBkc0HbbRRn9hCnsa3k2FNUg==} dependencies: looper: 2.0.0 dev: true - /pump/3.0.0: + /pump@3.0.0: resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} dependencies: end-of-stream: 1.4.4 once: 1.4.0 dev: true - /punycode/1.3.2: + /punycode@1.3.2: resolution: {integrity: sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==} dev: true - /punycode/2.1.0: + /punycode@2.1.0: resolution: {integrity: sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==} engines: {node: '>=6'} dev: true - /punycode/2.1.1: + /punycode@2.1.1: resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} engines: {node: '>=6'} dev: true - /pure-rand/5.0.3: + /pure-rand@5.0.3: resolution: {integrity: sha512-9N8x1h8dptBQpHyC7aZMS+iNOAm97WMGY0AFrguU1cpfW3I5jINkWe5BIY5md0ofy+1TCIELsVcm/GJXZSaPbw==} dev: true - /qs/6.11.0: + /qs@6.11.0: resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} engines: {node: '>=0.6'} dependencies: side-channel: 1.0.4 dev: true - /qs/6.5.3: + /qs@6.5.3: resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} engines: {node: '>=0.6'} dev: true - /qs/6.7.0: + /qs@6.7.0: resolution: {integrity: sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==} engines: {node: '>=0.6'} dev: true - /query-string/5.1.1: + /query-string@5.1.1: resolution: {integrity: sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==} engines: {node: '>=0.10.0'} dependencies: @@ -8876,40 +8921,40 @@ packages: strict-uri-encode: 1.1.0 dev: true - /querystring/0.2.0: + /querystring@0.2.0: resolution: {integrity: sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==} engines: {node: '>=0.4.x'} deprecated: The querystring API is considered Legacy. new code should use the URLSearchParams API instead. dev: true - /queue-microtask/1.2.3: + /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true - /quick-lru/5.1.1: + /quick-lru@5.1.1: resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} engines: {node: '>=10'} dev: true - /randombytes/2.1.0: + /randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: safe-buffer: 5.2.1 dev: true - /randomfill/1.0.4: + /randomfill@1.0.4: resolution: {integrity: sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==} dependencies: randombytes: 2.1.0 safe-buffer: 5.2.1 dev: true - /range-parser/1.2.1: + /range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} dev: true - /raw-body/2.4.0: + /raw-body@2.4.0: resolution: {integrity: sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==} engines: {node: '>= 0.8'} dependencies: @@ -8919,7 +8964,7 @@ packages: unpipe: 1.0.0 dev: true - /raw-body/2.5.1: + /raw-body@2.5.1: resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} engines: {node: '>= 0.8'} dependencies: @@ -8929,7 +8974,7 @@ packages: unpipe: 1.0.0 dev: true - /read-pkg-up/1.0.1: + /read-pkg-up@1.0.1: resolution: {integrity: sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==} engines: {node: '>=0.10.0'} dependencies: @@ -8937,7 +8982,7 @@ packages: read-pkg: 1.1.0 dev: true - /read-pkg/1.1.0: + /read-pkg@1.1.0: resolution: {integrity: sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==} engines: {node: '>=0.10.0'} dependencies: @@ -8946,7 +8991,7 @@ packages: path-type: 1.1.0 dev: true - /readable-stream/1.0.34: + /readable-stream@1.0.34: resolution: {integrity: sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==} dependencies: core-util-is: 1.0.3 @@ -8955,7 +9000,7 @@ packages: string_decoder: 0.10.31 dev: true - /readable-stream/2.3.7: + /readable-stream@2.3.7: resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} dependencies: core-util-is: 1.0.3 @@ -8967,7 +9012,7 @@ packages: util-deprecate: 1.0.2 dev: true - /readable-stream/3.6.0: + /readable-stream@3.6.0: resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} engines: {node: '>= 6'} dependencies: @@ -8976,52 +9021,52 @@ packages: util-deprecate: 1.0.2 dev: true - /readdirp/3.2.0: + /readdirp@3.2.0: resolution: {integrity: sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==} engines: {node: '>= 8'} dependencies: picomatch: 2.3.1 dev: true - /readdirp/3.6.0: + /readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} dependencies: picomatch: 2.3.1 dev: true - /rechoir/0.6.2: + /rechoir@0.6.2: resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} engines: {node: '>= 0.10'} dependencies: resolve: 1.22.1 dev: true - /recursive-readdir/2.2.2: + /recursive-readdir@2.2.2: resolution: {integrity: sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==} engines: {node: '>=0.10.0'} dependencies: minimatch: 3.0.4 dev: true - /reduce-flatten/2.0.0: + /reduce-flatten@2.0.0: resolution: {integrity: sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==} engines: {node: '>=6'} dev: true - /regenerate/1.4.2: + /regenerate@1.4.2: resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} dev: true - /regenerator-runtime/0.11.1: + /regenerator-runtime@0.11.1: resolution: {integrity: sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==} dev: true - /regenerator-runtime/0.13.9: + /regenerator-runtime@0.13.9: resolution: {integrity: sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==} dev: true - /regenerator-transform/0.10.1: + /regenerator-transform@0.10.1: resolution: {integrity: sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==} dependencies: babel-runtime: 6.26.0 @@ -9029,7 +9074,7 @@ packages: private: 0.1.8 dev: true - /regex-not/1.0.2: + /regex-not@1.0.2: resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} engines: {node: '>=0.10.0'} dependencies: @@ -9037,7 +9082,7 @@ packages: safe-regex: 1.1.0 dev: true - /regexp.prototype.flags/1.4.3: + /regexp.prototype.flags@1.4.3: resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} engines: {node: '>= 0.4'} dependencies: @@ -9046,7 +9091,7 @@ packages: functions-have-names: 1.2.3 dev: true - /regexpu-core/2.0.0: + /regexpu-core@2.0.0: resolution: {integrity: sha512-tJ9+S4oKjxY8IZ9jmjnp/mtytu1u3iyIQAfmI51IKWH6bFf7XR1ybtaO6j7INhZKXOTYADk7V5qxaqLkmNxiZQ==} dependencies: regenerate: 1.4.2 @@ -9054,49 +9099,49 @@ packages: regjsparser: 0.1.5 dev: true - /regjsgen/0.2.0: + /regjsgen@0.2.0: resolution: {integrity: sha512-x+Y3yA24uF68m5GA+tBjbGYo64xXVJpbToBaWCoSNSc1hdk6dfctaRWrNFTVJZIIhL5GxW8zwjoixbnifnK59g==} dev: true - /regjsparser/0.1.5: + /regjsparser@0.1.5: resolution: {integrity: sha512-jlQ9gYLfk2p3V5Ag5fYhA7fv7OHzd1KUH0PRP46xc3TgwjwgROIW572AfYg/X9kaNq/LJnu6oJcFRXlIrGoTRw==} hasBin: true dependencies: jsesc: 0.5.0 dev: true - /repeat-element/1.1.4: + /repeat-element@1.1.4: resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} engines: {node: '>=0.10.0'} dev: true - /repeat-string/1.6.1: + /repeat-string@1.6.1: resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} engines: {node: '>=0.10'} dev: true - /repeating/2.0.1: + /repeating@2.0.1: resolution: {integrity: sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==} engines: {node: '>=0.10.0'} dependencies: is-finite: 1.1.0 dev: true - /req-cwd/2.0.0: + /req-cwd@2.0.0: resolution: {integrity: sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==} engines: {node: '>=4'} dependencies: req-from: 2.0.0 dev: true - /req-from/2.0.0: + /req-from@2.0.0: resolution: {integrity: sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==} engines: {node: '>=4'} dependencies: resolve-from: 3.0.0 dev: true - /request-promise-core/1.1.4_request@2.88.2: + /request-promise-core@1.1.4(request@2.88.2): resolution: {integrity: sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==} engines: {node: '>=0.10.0'} peerDependencies: @@ -9106,7 +9151,7 @@ packages: request: 2.88.2 dev: true - /request-promise-native/1.0.9_request@2.88.2: + /request-promise-native@1.0.9(request@2.88.2): resolution: {integrity: sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==} engines: {node: '>=0.12.0'} deprecated: request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142 @@ -9114,12 +9159,12 @@ packages: request: ^2.34 dependencies: request: 2.88.2 - request-promise-core: 1.1.4_request@2.88.2 + request-promise-core: 1.1.4(request@2.88.2) stealthy-require: 1.1.1 tough-cookie: 2.5.0 dev: true - /request/2.88.2: + /request@2.88.2: resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} engines: {node: '>= 6'} deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 @@ -9146,59 +9191,59 @@ packages: uuid: 3.4.0 dev: true - /require-directory/2.1.1: + /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} dev: true - /require-from-string/1.2.1: + /require-from-string@1.2.1: resolution: {integrity: sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q==} engines: {node: '>=0.10.0'} dev: true - /require-from-string/2.0.2: + /require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} dev: true - /require-main-filename/1.0.1: + /require-main-filename@1.0.1: resolution: {integrity: sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==} dev: true - /require-main-filename/2.0.0: + /require-main-filename@2.0.0: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} dev: true - /resolve-alpn/1.2.1: + /resolve-alpn@1.2.1: resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} dev: true - /resolve-from/3.0.0: + /resolve-from@3.0.0: resolution: {integrity: sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==} engines: {node: '>=4'} dev: true - /resolve-from/4.0.0: + /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} dev: true - /resolve-url/0.2.1: + /resolve-url@0.2.1: resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} deprecated: https://github.com/lydell/resolve-url#deprecated dev: true - /resolve/1.1.7: + /resolve@1.1.7: resolution: {integrity: sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==} dev: true - /resolve/1.17.0: + /resolve@1.17.0: resolution: {integrity: sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==} dependencies: path-parse: 1.0.7 dev: true - /resolve/1.22.1: + /resolve@1.22.1: resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} hasBin: true dependencies: @@ -9207,102 +9252,103 @@ packages: supports-preserve-symlinks-flag: 1.0.0 dev: true - /responselike/1.0.2: + /responselike@1.0.2: resolution: {integrity: sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==} + requiresBuild: true dependencies: lowercase-keys: 1.0.1 dev: true - /responselike/2.0.1: + /responselike@2.0.1: resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} dependencies: lowercase-keys: 2.0.0 dev: true - /resumer/0.0.0: + /resumer@0.0.0: resolution: {integrity: sha512-Fn9X8rX8yYF4m81rZCK/5VmrmsSbqS/i3rDLl6ZZHAXgC2nTAx3dhwG8q8odP/RmdLa2YrybDJaAMg+X1ajY3w==} dependencies: through: 2.3.8 dev: true - /ret/0.1.15: + /ret@0.1.15: resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} engines: {node: '>=0.12'} dev: true - /retry/0.12.0: + /retry@0.12.0: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} dev: true - /reusify/1.0.4: + /reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} dev: true - /rimraf/2.7.1: + /rimraf@2.7.1: resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} hasBin: true dependencies: glob: 7.2.3 dev: true - /rimraf/3.0.2: + /rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} hasBin: true dependencies: glob: 7.2.3 dev: true - /ripemd160-min/0.0.6: + /ripemd160-min@0.0.6: resolution: {integrity: sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A==} engines: {node: '>=8'} dev: true - /ripemd160/2.0.2: + /ripemd160@2.0.2: resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} dependencies: hash-base: 3.1.0 inherits: 2.0.4 dev: true - /rlp/2.2.7: + /rlp@2.2.7: resolution: {integrity: sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==} hasBin: true dependencies: bn.js: 5.2.1 dev: true - /run-parallel-limit/1.1.0: + /run-parallel-limit@1.1.0: resolution: {integrity: sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==} dependencies: queue-microtask: 1.2.3 dev: true - /run-parallel/1.1.9: + /run-parallel@1.1.9: resolution: {integrity: sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==} dev: true - /rustbn.js/0.2.0: + /rustbn.js@0.2.0: resolution: {integrity: sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==} dev: true - /safe-buffer/5.1.2: + /safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} dev: true - /safe-buffer/5.2.1: + /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} dev: true - /safe-event-emitter/1.0.1: + /safe-event-emitter@1.0.1: resolution: {integrity: sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg==} deprecated: Renamed to @metamask/safe-event-emitter dependencies: events: 3.3.0 dev: true - /safe-regex-test/1.0.0: + /safe-regex-test@1.0.0: resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} dependencies: call-bind: 1.0.2 @@ -9310,17 +9356,17 @@ packages: is-regex: 1.1.4 dev: true - /safe-regex/1.1.0: + /safe-regex@1.1.0: resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} dependencies: ret: 0.1.15 dev: true - /safer-buffer/2.1.2: + /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} dev: true - /sc-istanbul/0.4.6: + /sc-istanbul@0.4.6: resolution: {integrity: sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==} hasBin: true dependencies: @@ -9340,21 +9386,22 @@ packages: wordwrap: 1.0.0 dev: true - /scrypt-js/2.0.4: + /scrypt-js@2.0.4: resolution: {integrity: sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==} dev: true - /scrypt-js/3.0.1: + /scrypt-js@3.0.1: resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==} - /scryptsy/1.2.1: + /scryptsy@1.2.1: resolution: {integrity: sha512-aldIRgMozSJ/Gl6K6qmJZysRP82lz83Wb42vl4PWN8SaLFHIaOzLPc9nUUW2jQN88CuGm5q5HefJ9jZ3nWSmTw==} + requiresBuild: true dependencies: pbkdf2: 3.1.2 dev: true optional: true - /secp256k1/3.7.1: + /secp256k1@3.7.1: resolution: {integrity: sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==} engines: {node: '>=4.0.0'} requiresBuild: true @@ -9369,7 +9416,7 @@ packages: safe-buffer: 5.2.1 dev: true - /secp256k1/4.0.3: + /secp256k1@4.0.3: resolution: {integrity: sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==} engines: {node: '>=10.0.0'} requiresBuild: true @@ -9379,31 +9426,31 @@ packages: node-gyp-build: 4.5.0 dev: true - /seedrandom/3.0.1: + /seedrandom@3.0.1: resolution: {integrity: sha512-1/02Y/rUeU1CJBAGLebiC5Lbo5FnB22gQbIFFYTLkwvp1xdABZJH1sn4ZT1MzXmPpzv+Rf/Lu2NcsLJiK4rcDg==} dev: true - /semaphore/1.1.0: + /semaphore@1.1.0: resolution: {integrity: sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==} engines: {node: '>=0.8.0'} dev: true - /semver/5.4.1: + /semver@5.4.1: resolution: {integrity: sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==} hasBin: true dev: true - /semver/5.7.1: + /semver@5.7.1: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} hasBin: true dev: true - /semver/6.3.0: + /semver@6.3.0: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} hasBin: true dev: true - /semver/7.3.7: + /semver@7.3.7: resolution: {integrity: sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==} engines: {node: '>=10'} hasBin: true @@ -9411,7 +9458,7 @@ packages: lru-cache: 6.0.0 dev: true - /semver/7.5.0: + /semver@7.5.0: resolution: {integrity: sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==} engines: {node: '>=10'} hasBin: true @@ -9419,7 +9466,7 @@ packages: lru-cache: 6.0.0 dev: true - /send/0.17.1: + /send@0.17.1: resolution: {integrity: sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==} engines: {node: '>= 0.8.0'} dependencies: @@ -9440,20 +9487,20 @@ packages: - supports-color dev: true - /sentence-case/2.1.1: + /sentence-case@2.1.1: resolution: {integrity: sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ==} dependencies: no-case: 2.3.2 upper-case-first: 1.1.2 dev: true - /serialize-javascript/6.0.0: + /serialize-javascript@6.0.0: resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} dependencies: randombytes: 2.1.0 dev: true - /serve-static/1.14.1: + /serve-static@1.14.1: resolution: {integrity: sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==} engines: {node: '>= 0.8.0'} dependencies: @@ -9465,7 +9512,7 @@ packages: - supports-color dev: true - /servify/0.1.12: + /servify@0.1.12: resolution: {integrity: sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==} engines: {node: '>=6'} dependencies: @@ -9478,16 +9525,16 @@ packages: - supports-color dev: true - /set-blocking/2.0.0: + /set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} dev: true - /set-immediate-shim/1.0.1: + /set-immediate-shim@1.0.1: resolution: {integrity: sha512-Li5AOqrZWCVA2n5kryzEmqai6bKSIvpz5oUJHPVj6+dsbD3X1ixtsY5tEnsaNpH3pFAHmG8eIHUrtEtohrg+UQ==} engines: {node: '>=0.10.0'} dev: true - /set-value/2.0.1: + /set-value@2.0.1: resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} engines: {node: '>=0.10.0'} dependencies: @@ -9497,23 +9544,23 @@ packages: split-string: 3.1.0 dev: true - /setimmediate/1.0.4: + /setimmediate@1.0.4: resolution: {integrity: sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==} dev: true - /setimmediate/1.0.5: + /setimmediate@1.0.5: resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} dev: true - /setprototypeof/1.1.1: + /setprototypeof@1.1.1: resolution: {integrity: sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==} dev: true - /setprototypeof/1.2.0: + /setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} dev: true - /sha.js/2.4.11: + /sha.js@2.4.11: resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} hasBin: true dependencies: @@ -9521,55 +9568,55 @@ packages: safe-buffer: 5.2.1 dev: true - /sha1/1.1.1: + /sha1@1.1.1: resolution: {integrity: sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==} dependencies: charenc: 0.0.2 crypt: 0.0.2 dev: true - /sha3/1.2.6: + /sha3@1.2.6: resolution: {integrity: sha512-KgLGmJGrmNB4JWVsAV11Yk6KbvsAiygWJc7t5IebWva/0NukNrjJqhtKhzy3Eiv2AKuGvhZZt7dt1mDo7HkoiQ==} requiresBuild: true dependencies: nan: 2.13.2 dev: true - /sha3/2.1.4: + /sha3@2.1.4: resolution: {integrity: sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg==} dependencies: buffer: 6.0.3 dev: true - /shallowequal/1.1.0: + /shallowequal@1.1.0: resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} dev: true - /shebang-command/1.2.0: + /shebang-command@1.2.0: resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} engines: {node: '>=0.10.0'} dependencies: shebang-regex: 1.0.0 dev: true - /shebang-command/2.0.0: + /shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} dependencies: shebang-regex: 3.0.0 dev: true - /shebang-regex/1.0.0: + /shebang-regex@1.0.0: resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} engines: {node: '>=0.10.0'} dev: true - /shebang-regex/3.0.0: + /shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} dev: true - /shelljs/0.8.3: + /shelljs@0.8.3: resolution: {integrity: sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==} engines: {node: '>=4'} hasBin: true @@ -9579,7 +9626,7 @@ packages: rechoir: 0.6.2 dev: true - /side-channel/1.0.4: + /side-channel@1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} dependencies: call-bind: 1.0.2 @@ -9587,15 +9634,15 @@ packages: object-inspect: 1.12.2 dev: true - /signal-exit/3.0.7: + /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} dev: true - /simple-concat/1.0.0: + /simple-concat@1.0.0: resolution: {integrity: sha512-pgxq9iGMSS24atefsqEznXW1Te610qB4pwMdrEg6mxczHh7sPtPyiixkP/VaQic8JjZofnIvT7CDeKlHqfbPBg==} dev: true - /simple-get/2.8.1: + /simple-get@2.8.1: resolution: {integrity: sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==} dependencies: decompress-response: 3.3.0 @@ -9603,22 +9650,22 @@ packages: simple-concat: 1.0.0 dev: true - /slash/1.0.0: + /slash@1.0.0: resolution: {integrity: sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==} engines: {node: '>=0.10.0'} dev: true - /slash/2.0.0: + /slash@2.0.0: resolution: {integrity: sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==} engines: {node: '>=6'} dev: true - /slash/3.0.0: + /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} dev: true - /slice-ansi/4.0.0: + /slice-ansi@4.0.0: resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} engines: {node: '>=10'} dependencies: @@ -9627,13 +9674,13 @@ packages: is-fullwidth-code-point: 3.0.0 dev: true - /snake-case/2.1.0: + /snake-case@2.1.0: resolution: {integrity: sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q==} dependencies: no-case: 2.3.2 dev: true - /snapdragon-node/2.1.1: + /snapdragon-node@2.1.1: resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} engines: {node: '>=0.10.0'} dependencies: @@ -9642,14 +9689,14 @@ packages: snapdragon-util: 3.0.1 dev: true - /snapdragon-util/3.0.1: + /snapdragon-util@3.0.1: resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==} engines: {node: '>=0.10.0'} dependencies: kind-of: 3.2.2 dev: true - /snapdragon/0.8.2: + /snapdragon@0.8.2: resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} engines: {node: '>=0.10.0'} dependencies: @@ -9665,7 +9712,7 @@ packages: - supports-color dev: true - /solc/0.4.26: + /solc@0.4.26: resolution: {integrity: sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==} hasBin: true dependencies: @@ -9676,7 +9723,7 @@ packages: yargs: 4.8.1 dev: true - /solc/0.6.12: + /solc@0.6.12: resolution: {integrity: sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g==} engines: {node: '>=8.0.0'} hasBin: true @@ -9691,14 +9738,14 @@ packages: tmp: 0.0.33 dev: true - /solc/0.7.3_debug@4.3.4: + /solc@0.7.3(debug@4.3.4): resolution: {integrity: sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==} engines: {node: '>=8.0.0'} hasBin: true dependencies: command-exists: 1.2.9 commander: 3.0.2 - follow-redirects: 1.15.2_debug@4.3.4 + follow-redirects: 1.15.2(debug@4.3.4) fs-extra: 0.30.0 js-sha3: 0.8.0 memorystream: 0.3.1 @@ -9709,7 +9756,7 @@ packages: - debug dev: true - /solhint-plugin-prettier/0.0.5_x46sgpbsioqs6smmgnper2ntba: + /solhint-plugin-prettier@0.0.5(prettier-plugin-solidity@1.1.3)(prettier@2.8.8): resolution: {integrity: sha512-7jmWcnVshIrO2FFinIvDQmhQpfpS2rRRn3RejiYgnjIE68xO2bvrYvjqVNfrio4xH9ghOqn83tKuTzLjEbmGIA==} peerDependencies: prettier: ^1.15.0 || ^2.0.0 @@ -9717,10 +9764,10 @@ packages: dependencies: prettier: 2.8.8 prettier-linter-helpers: 1.0.0 - prettier-plugin-solidity: 1.1.3_prettier@2.8.8 + prettier-plugin-solidity: 1.1.3(prettier@2.8.8) dev: true - /solhint/3.4.1: + /solhint@3.4.1: resolution: {integrity: sha512-pzZn2RlZhws1XwvLPVSsxfHrwsteFf5eySOhpAytzXwKQYbTCJV6z8EevYDiSVKMpWrvbKpEtJ055CuEmzp4Xg==} hasBin: true dependencies: @@ -9745,11 +9792,11 @@ packages: prettier: 2.8.8 dev: true - /solidity-ast/0.4.45: + /solidity-ast@0.4.45: resolution: {integrity: sha512-N6uqfaDulVZqjpjru+KvMLjV89M3hesyr/1/t8nkjohRagFSDmDxZvb9viKV98pdwpMzs61Nt2JAApgh0fkL0g==} dev: true - /solidity-comments-darwin-arm64/0.0.2: + /solidity-comments-darwin-arm64@0.0.2: resolution: {integrity: sha512-HidWkVLSh7v+Vu0CA7oI21GWP/ZY7ro8g8OmIxE8oTqyMwgMbE8F1yc58Sj682Hj199HCZsjmtn1BE4PCbLiGA==} engines: {node: '>= 10'} cpu: [arm64] @@ -9758,7 +9805,7 @@ packages: dev: true optional: true - /solidity-comments-darwin-x64/0.0.2: + /solidity-comments-darwin-x64@0.0.2: resolution: {integrity: sha512-Zjs0Ruz6faBTPT6fBecUt6qh4CdloT8Bwoc0+qxRoTn9UhYscmbPQkUgQEbS0FQPysYqVzzxJB4h1Ofbf4wwtA==} engines: {node: '>= 10'} cpu: [x64] @@ -9767,11 +9814,11 @@ packages: dev: true optional: true - /solidity-comments-extractor/0.0.7: + /solidity-comments-extractor@0.0.7: resolution: {integrity: sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==} dev: true - /solidity-comments-freebsd-x64/0.0.2: + /solidity-comments-freebsd-x64@0.0.2: resolution: {integrity: sha512-8Qe4mpjuAxFSwZJVk7B8gAoLCdbtS412bQzBwk63L8dmlHogvE39iT70aAk3RHUddAppT5RMBunlPUCFYJ3ZTw==} engines: {node: '>= 10'} cpu: [x64] @@ -9780,7 +9827,7 @@ packages: dev: true optional: true - /solidity-comments-linux-arm64-gnu/0.0.2: + /solidity-comments-linux-arm64-gnu@0.0.2: resolution: {integrity: sha512-spkb0MZZnmrP+Wtq4UxP+nyPAVRe82idOjqndolcNR0S9Xvu4ebwq+LvF4HiUgjTDmeiqYiFZQ8T9KGdLSIoIg==} engines: {node: '>= 10'} cpu: [arm64] @@ -9789,7 +9836,7 @@ packages: dev: true optional: true - /solidity-comments-linux-arm64-musl/0.0.2: + /solidity-comments-linux-arm64-musl@0.0.2: resolution: {integrity: sha512-guCDbHArcjE+JDXYkxx5RZzY1YF6OnAKCo+sTC5fstyW/KGKaQJNPyBNWuwYsQiaEHpvhW1ha537IvlGek8GqA==} engines: {node: '>= 10'} cpu: [arm64] @@ -9798,7 +9845,7 @@ packages: dev: true optional: true - /solidity-comments-linux-x64-gnu/0.0.2: + /solidity-comments-linux-x64-gnu@0.0.2: resolution: {integrity: sha512-zIqLehBK/g7tvrFmQljrfZXfkEeLt2v6wbe+uFu6kH/qAHZa7ybt8Vc0wYcmjo2U0PeBm15d79ee3AkwbIjFdQ==} engines: {node: '>= 10'} cpu: [x64] @@ -9807,7 +9854,7 @@ packages: dev: true optional: true - /solidity-comments-linux-x64-musl/0.0.2: + /solidity-comments-linux-x64-musl@0.0.2: resolution: {integrity: sha512-R9FeDloVlFGTaVkOlELDVC7+1Tjx5WBPI5L8r0AGOPHK3+jOcRh6sKYpI+VskSPDc3vOO46INkpDgUXrKydlIw==} engines: {node: '>= 10'} cpu: [x64] @@ -9816,7 +9863,7 @@ packages: dev: true optional: true - /solidity-comments-win32-arm64-msvc/0.0.2: + /solidity-comments-win32-arm64-msvc@0.0.2: resolution: {integrity: sha512-QnWJoCQcJj+rnutULOihN9bixOtYWDdF5Rfz9fpHejL1BtNjdLW1om55XNVHGAHPqBxV4aeQQ6OirKnp9zKsug==} engines: {node: '>= 10'} cpu: [arm64] @@ -9825,7 +9872,7 @@ packages: dev: true optional: true - /solidity-comments-win32-ia32-msvc/0.0.2: + /solidity-comments-win32-ia32-msvc@0.0.2: resolution: {integrity: sha512-vUg4nADtm/NcOtlIymG23NWJUSuMsvX15nU7ynhGBsdKtt8xhdP3C/zA6vjDk8Jg+FXGQL6IHVQ++g/7rSQi0w==} engines: {node: '>= 10'} cpu: [ia32] @@ -9834,7 +9881,7 @@ packages: dev: true optional: true - /solidity-comments-win32-x64-msvc/0.0.2: + /solidity-comments-win32-x64-msvc@0.0.2: resolution: {integrity: sha512-36j+KUF4V/y0t3qatHm/LF5sCUCBx2UndxE1kq5bOzh/s+nQgatuyB+Pd5BfuPQHdWu2KaExYe20FlAa6NL7+Q==} engines: {node: '>= 10'} cpu: [x64] @@ -9843,7 +9890,7 @@ packages: dev: true optional: true - /solidity-comments/0.0.2: + /solidity-comments@0.0.2: resolution: {integrity: sha512-G+aK6qtyUfkn1guS8uzqUeua1dURwPlcOjoTYW/TwmXAcE7z/1+oGCfZUdMSe4ZMKklNbVZNiG5ibnF8gkkFfw==} engines: {node: '>= 12'} optionalDependencies: @@ -9859,7 +9906,7 @@ packages: solidity-comments-win32-x64-msvc: 0.0.2 dev: true - /solidity-coverage/0.8.4_hardhat@2.12.7: + /solidity-coverage@0.8.4(hardhat@2.12.7): resolution: {integrity: sha512-xeHOfBOjdMF6hWTbt42iH4x+7j1Atmrf5OldDPMxI+i/COdExUxszOswD9qqvcBTaLGiOrrpnh9UZjSpt4rBsg==} hasBin: true peerDependencies: @@ -9875,7 +9922,7 @@ packages: ghost-testrpc: 0.0.2 global-modules: 2.0.0 globby: 10.0.2 - hardhat: 2.12.7_goz53koj4ourpjwgrks4nqbe6i + hardhat: 2.12.7(ts-node@10.0.0)(typescript@4.9.5) jsonschema: 1.4.0 lodash: 4.17.21 mocha: 7.1.2 @@ -9890,13 +9937,13 @@ packages: - supports-color dev: true - /sort-any/2.0.0: + /sort-any@2.0.0: resolution: {integrity: sha512-T9JoiDewQEmWcnmPn/s9h/PH9t3d/LSWi0RgVmXSuDYeZXTZOZ1/wrK2PHaptuR1VXe3clLLt0pD6sgVOwjNEA==} dependencies: lodash: 4.17.21 dev: true - /source-map-resolve/0.5.3: + /source-map-resolve@0.5.3: resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} deprecated: See https://github.com/lydell/source-map-resolve#deprecated dependencies: @@ -9907,32 +9954,32 @@ packages: urix: 0.1.0 dev: true - /source-map-support/0.4.18: + /source-map-support@0.4.18: resolution: {integrity: sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==} dependencies: source-map: 0.5.7 dev: true - /source-map-support/0.5.12: + /source-map-support@0.5.12: resolution: {integrity: sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==} dependencies: buffer-from: 1.1.2 source-map: 0.6.1 dev: true - /source-map-support/0.5.21: + /source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} dependencies: buffer-from: 1.1.2 source-map: 0.6.1 dev: true - /source-map-url/0.4.1: + /source-map-url@0.4.1: resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} deprecated: See https://github.com/lydell/source-map-url#deprecated dev: true - /source-map/0.2.0: + /source-map@0.2.0: resolution: {integrity: sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==} engines: {node: '>=0.8.0'} requiresBuild: true @@ -9941,50 +9988,50 @@ packages: dev: true optional: true - /source-map/0.5.7: + /source-map@0.5.7: resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} engines: {node: '>=0.10.0'} dev: true - /source-map/0.6.1: + /source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} dev: true - /spdx-correct/3.1.1: + /spdx-correct@3.1.1: resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==} dependencies: spdx-expression-parse: 3.0.1 spdx-license-ids: 3.0.12 dev: true - /spdx-exceptions/2.3.0: + /spdx-exceptions@2.3.0: resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} dev: true - /spdx-expression-parse/3.0.1: + /spdx-expression-parse@3.0.1: resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} dependencies: spdx-exceptions: 2.3.0 spdx-license-ids: 3.0.12 dev: true - /spdx-license-ids/3.0.12: + /spdx-license-ids@3.0.12: resolution: {integrity: sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==} dev: true - /split-string/3.1.0: + /split-string@3.1.0: resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} engines: {node: '>=0.10.0'} dependencies: extend-shallow: 3.0.2 dev: true - /sprintf-js/1.0.3: + /sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} dev: true - /sshpk/1.16.1: + /sshpk@1.16.1: resolution: {integrity: sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==} engines: {node: '>=0.10.0'} hasBin: true @@ -10000,14 +10047,14 @@ packages: tweetnacl: 0.14.5 dev: true - /stacktrace-parser/0.1.10: + /stacktrace-parser@0.1.10: resolution: {integrity: sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==} engines: {node: '>=6'} dependencies: type-fest: 0.7.1 dev: true - /static-extend/0.1.2: + /static-extend@0.1.2: resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} engines: {node: '>=0.10.0'} dependencies: @@ -10015,43 +10062,43 @@ packages: object-copy: 0.1.0 dev: true - /statuses/1.5.0: + /statuses@1.5.0: resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} engines: {node: '>= 0.6'} dev: true - /statuses/2.0.1: + /statuses@2.0.1: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} dev: true - /stealthy-require/1.1.1: + /stealthy-require@1.1.1: resolution: {integrity: sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==} engines: {node: '>=0.10.0'} dev: true - /stream-to-pull-stream/1.7.3: + /stream-to-pull-stream@1.7.3: resolution: {integrity: sha512-6sNyqJpr5dIOQdgNy/xcDWwDuzAsAwVzhzrWlAPAQ7Lkjx/rv0wgvxEyKwTq6FmNd5rjTrELt/CLmaSw7crMGg==} dependencies: looper: 3.0.0 pull-stream: 3.6.14 dev: true - /streamsearch/1.1.0: + /streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} dev: true - /strict-uri-encode/1.1.0: + /strict-uri-encode@1.1.0: resolution: {integrity: sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==} engines: {node: '>=0.10.0'} dev: true - /string-format/2.0.0: + /string-format@2.0.0: resolution: {integrity: sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==} dev: true - /string-width/1.0.2: + /string-width@1.0.2: resolution: {integrity: sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==} engines: {node: '>=0.10.0'} dependencies: @@ -10060,7 +10107,7 @@ packages: strip-ansi: 3.0.1 dev: true - /string-width/2.1.1: + /string-width@2.1.1: resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} engines: {node: '>=4'} dependencies: @@ -10068,7 +10115,7 @@ packages: strip-ansi: 4.0.0 dev: true - /string-width/3.1.0: + /string-width@3.1.0: resolution: {integrity: sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==} engines: {node: '>=6'} dependencies: @@ -10077,7 +10124,7 @@ packages: strip-ansi: 5.2.0 dev: true - /string-width/4.2.3: + /string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} dependencies: @@ -10086,7 +10133,7 @@ packages: strip-ansi: 6.0.1 dev: true - /string.prototype.trim/1.2.6: + /string.prototype.trim@1.2.6: resolution: {integrity: sha512-8lMR2m+U0VJTPp6JjvJTtGyc4FIGq9CdRt7O9p6T0e6K4vjU+OP+SQJpbe/SBmRcCUIvNUnjsbmY6lnMp8MhsQ==} engines: {node: '>= 0.4'} dependencies: @@ -10095,7 +10142,7 @@ packages: es-abstract: 1.20.3 dev: true - /string.prototype.trimend/1.0.5: + /string.prototype.trimend@1.0.5: resolution: {integrity: sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==} dependencies: call-bind: 1.0.2 @@ -10103,7 +10150,7 @@ packages: es-abstract: 1.20.3 dev: true - /string.prototype.trimstart/1.0.5: + /string.prototype.trimstart@1.0.5: resolution: {integrity: sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==} dependencies: call-bind: 1.0.2 @@ -10111,132 +10158,132 @@ packages: es-abstract: 1.20.3 dev: true - /string_decoder/0.10.31: + /string_decoder@0.10.31: resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} dev: true - /string_decoder/1.1.1: + /string_decoder@1.1.1: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} dependencies: safe-buffer: 5.1.2 dev: true - /string_decoder/1.3.0: + /string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} dependencies: safe-buffer: 5.2.1 dev: true - /strip-ansi/3.0.1: + /strip-ansi@3.0.1: resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} engines: {node: '>=0.10.0'} dependencies: ansi-regex: 2.1.1 dev: true - /strip-ansi/4.0.0: + /strip-ansi@4.0.0: resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==} engines: {node: '>=4'} dependencies: ansi-regex: 3.0.1 dev: true - /strip-ansi/5.2.0: + /strip-ansi@5.2.0: resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} engines: {node: '>=6'} dependencies: ansi-regex: 4.1.1 dev: true - /strip-ansi/6.0.1: + /strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} dependencies: ansi-regex: 5.0.1 dev: true - /strip-bom/2.0.0: + /strip-bom@2.0.0: resolution: {integrity: sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==} engines: {node: '>=0.10.0'} dependencies: is-utf8: 0.2.1 dev: true - /strip-hex-prefix/1.0.0: + /strip-hex-prefix@1.0.0: resolution: {integrity: sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==} engines: {node: '>=6.5.0', npm: '>=3'} dependencies: is-hex-prefixed: 1.0.0 dev: true - /strip-indent/2.0.0: + /strip-indent@2.0.0: resolution: {integrity: sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA==} engines: {node: '>=4'} dev: true - /strip-json-comments/2.0.1: + /strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} dev: true - /strip-json-comments/3.1.1: + /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} dev: true - /supports-color/2.0.0: + /supports-color@2.0.0: resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==} engines: {node: '>=0.8.0'} dev: true - /supports-color/3.2.3: + /supports-color@3.2.3: resolution: {integrity: sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==} engines: {node: '>=0.8.0'} dependencies: has-flag: 1.0.0 dev: true - /supports-color/5.5.0: + /supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} dependencies: has-flag: 3.0.0 dev: true - /supports-color/6.0.0: + /supports-color@6.0.0: resolution: {integrity: sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==} engines: {node: '>=6'} dependencies: has-flag: 3.0.0 dev: true - /supports-color/7.2.0: + /supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} dependencies: has-flag: 4.0.0 dev: true - /supports-color/8.1.1: + /supports-color@8.1.1: resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} engines: {node: '>=10'} dependencies: has-flag: 4.0.0 dev: true - /supports-preserve-symlinks-flag/1.0.0: + /supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} dev: true - /swap-case/1.1.2: + /swap-case@1.1.2: resolution: {integrity: sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ==} dependencies: lower-case: 1.1.4 upper-case: 1.1.3 dev: true - /swarm-js/0.1.40: + /swarm-js@0.1.40: resolution: {integrity: sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==} dependencies: bluebird: 3.7.2 @@ -10256,7 +10303,7 @@ packages: - utf-8-validate dev: true - /sync-request/6.1.0: + /sync-request@6.1.0: resolution: {integrity: sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==} engines: {node: '>=8.0.0'} dependencies: @@ -10265,13 +10312,13 @@ packages: then-request: 6.0.2 dev: true - /sync-rpc/1.3.6: + /sync-rpc@1.3.6: resolution: {integrity: sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==} dependencies: get-port: 3.2.0 dev: true - /table-layout/1.0.2: + /table-layout@1.0.2: resolution: {integrity: sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==} engines: {node: '>=8.0.0'} dependencies: @@ -10281,7 +10328,7 @@ packages: wordwrapjs: 4.0.1 dev: true - /table/6.8.0: + /table@6.8.0: resolution: {integrity: sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==} engines: {node: '>=10.0.0'} dependencies: @@ -10292,7 +10339,7 @@ packages: strip-ansi: 6.0.1 dev: true - /table/6.8.1: + /table@6.8.1: resolution: {integrity: sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==} engines: {node: '>=10.0.0'} dependencies: @@ -10303,7 +10350,7 @@ packages: strip-ansi: 6.0.1 dev: true - /tape/4.16.1: + /tape@4.16.1: resolution: {integrity: sha512-U4DWOikL5gBYUrlzx+J0oaRedm2vKLFbtA/+BRAXboGWpXO7bMP8ddxlq3Cse2bvXFQ0jZMOj6kk3546mvCdFg==} hasBin: true dependencies: @@ -10324,7 +10371,7 @@ packages: through: 2.3.8 dev: true - /tar/4.4.19: + /tar@4.4.19: resolution: {integrity: sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==} engines: {node: '>=4.5'} dependencies: @@ -10337,7 +10384,7 @@ packages: yallist: 3.1.1 dev: true - /test-value/2.1.0: + /test-value@2.1.0: resolution: {integrity: sha512-+1epbAxtKeXttkGFMTX9H42oqzOTufR1ceCF+GYA5aOmvaPq9wd4PUS8329fn2RRLGNeUkgRLnVpycjx8DsO2w==} engines: {node: '>=0.10.0'} dependencies: @@ -10345,16 +10392,16 @@ packages: typical: 2.6.1 dev: true - /testrpc/0.0.1: + /testrpc@0.0.1: resolution: {integrity: sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==} deprecated: testrpc has been renamed to ganache-cli, please use this package from now on. dev: true - /text-table/0.2.0: + /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true - /then-request/6.0.2: + /then-request@6.0.2: resolution: {integrity: sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==} engines: {node: '>=6.0.0'} dependencies: @@ -10371,61 +10418,62 @@ packages: qs: 6.11.0 dev: true - /through/2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - dev: true - - /through2/2.0.5: + /through2@2.0.5: resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} dependencies: readable-stream: 2.3.7 xtend: 4.0.2 dev: true - /timed-out/4.0.1: + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: true + + /timed-out@4.0.1: resolution: {integrity: sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==} engines: {node: '>=0.10.0'} dev: true - /title-case/2.1.1: + /title-case@2.1.1: resolution: {integrity: sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q==} dependencies: no-case: 2.3.2 upper-case: 1.1.3 dev: true - /tmp/0.0.33: + /tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} dependencies: os-tmpdir: 1.0.2 dev: true - /tmp/0.1.0: + /tmp@0.1.0: resolution: {integrity: sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==} engines: {node: '>=6'} dependencies: rimraf: 2.7.1 dev: true - /to-fast-properties/1.0.3: + /to-fast-properties@1.0.3: resolution: {integrity: sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==} engines: {node: '>=0.10.0'} dev: true - /to-object-path/0.3.0: + /to-object-path@0.3.0: resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} engines: {node: '>=0.10.0'} dependencies: kind-of: 3.2.2 dev: true - /to-readable-stream/1.0.0: + /to-readable-stream@1.0.0: resolution: {integrity: sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==} engines: {node: '>=6'} + requiresBuild: true dev: true - /to-regex-range/2.1.1: + /to-regex-range@2.1.1: resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==} engines: {node: '>=0.10.0'} dependencies: @@ -10433,14 +10481,14 @@ packages: repeat-string: 1.6.1 dev: true - /to-regex-range/5.0.1: + /to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} dependencies: is-number: 7.0.0 dev: true - /to-regex/3.0.2: + /to-regex@3.0.2: resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} engines: {node: '>=0.10.0'} dependencies: @@ -10450,17 +10498,17 @@ packages: safe-regex: 1.1.0 dev: true - /toidentifier/1.0.0: + /toidentifier@1.0.0: resolution: {integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==} engines: {node: '>=0.6'} dev: true - /toidentifier/1.0.1: + /toidentifier@1.0.1: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} dev: true - /tough-cookie/2.5.0: + /tough-cookie@2.5.0: resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} engines: {node: '>=0.8'} dependencies: @@ -10468,16 +10516,16 @@ packages: punycode: 2.1.1 dev: true - /tr46/0.0.3: + /tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} dev: true - /trim-right/1.0.1: + /trim-right@1.0.1: resolution: {integrity: sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==} engines: {node: '>=0.10.0'} dev: true - /ts-command-line-args/2.5.1: + /ts-command-line-args@2.5.1: resolution: {integrity: sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==} hasBin: true dependencies: @@ -10487,11 +10535,11 @@ packages: string-format: 2.0.0 dev: true - /ts-essentials/1.0.4: + /ts-essentials@1.0.4: resolution: {integrity: sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ==} dev: true - /ts-essentials/6.0.7_typescript@4.9.5: + /ts-essentials@6.0.7(typescript@4.9.5): resolution: {integrity: sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==} peerDependencies: typescript: '>=3.7.0' @@ -10499,7 +10547,7 @@ packages: typescript: 4.9.5 dev: true - /ts-essentials/7.0.3_typescript@4.9.5: + /ts-essentials@7.0.3(typescript@4.9.5): resolution: {integrity: sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==} peerDependencies: typescript: '>=3.7.0' @@ -10507,7 +10555,7 @@ packages: typescript: 4.9.5 dev: true - /ts-generator/0.1.1: + /ts-generator@0.1.1: resolution: {integrity: sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ==} hasBin: true dependencies: @@ -10522,7 +10570,7 @@ packages: ts-essentials: 1.0.4 dev: true - /ts-node/10.0.0_zlol4fzmmjgb3bdeviopae4asm: + /ts-node@10.0.0(@types/node@15.14.9)(typescript@4.9.5): resolution: {integrity: sha512-ROWeOIUvfFbPZkoDis0L/55Fk+6gFQNZwwKPLinacRl6tsxstTF1DbAcLKkovwnpKMVvOMHP1TIbnwXwtLg1gg==} engines: {node: '>=12.0.0'} hasBin: true @@ -10551,19 +10599,19 @@ packages: yn: 3.1.1 dev: true - /tslib/1.14.1: + /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} dev: true - /tslib/2.4.0: + /tslib@2.4.0: resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} dev: true - /tsort/0.0.1: + /tsort@0.0.1: resolution: {integrity: sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==} dev: true - /tsutils/3.21.0_typescript@4.9.5: + /tsutils@3.21.0(typescript@4.9.5): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} peerDependencies: @@ -10573,58 +10621,58 @@ packages: typescript: 4.9.5 dev: true - /tunnel-agent/0.6.0: + /tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} dependencies: safe-buffer: 5.2.1 dev: true - /tweetnacl-util/0.15.1: + /tweetnacl-util@0.15.1: resolution: {integrity: sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==} dev: true - /tweetnacl/0.14.5: + /tweetnacl@0.14.5: resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} dev: true - /tweetnacl/1.0.3: + /tweetnacl@1.0.3: resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} dev: true - /type-check/0.3.2: + /type-check@0.3.2: resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} engines: {node: '>= 0.8.0'} dependencies: prelude-ls: 1.1.2 dev: true - /type-check/0.4.0: + /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} dependencies: prelude-ls: 1.2.1 dev: true - /type-detect/4.0.8: + /type-detect@4.0.8: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} - /type-fest/0.20.2: + /type-fest@0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} dev: true - /type-fest/0.21.3: + /type-fest@0.21.3: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} dev: true - /type-fest/0.7.1: + /type-fest@0.7.1: resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} engines: {node: '>=8'} dev: true - /type-is/1.6.18: + /type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} dependencies: @@ -10632,38 +10680,38 @@ packages: mime-types: 2.1.27 dev: true - /type/1.2.0: + /type@1.2.0: resolution: {integrity: sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==} dev: true - /type/2.0.0: + /type@2.0.0: resolution: {integrity: sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==} dev: true - /typechain/3.0.0_typescript@4.9.5: + /typechain@3.0.0(typescript@4.9.5): resolution: {integrity: sha512-ft4KVmiN3zH4JUFu2WJBrwfHeDf772Tt2d8bssDTo/YcckKW2D+OwFrHXRC6hJvO3mHjFQTihoMV6fJOi0Hngg==} hasBin: true dependencies: command-line-args: 4.0.7 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) fs-extra: 7.0.1 js-sha3: 0.8.0 lodash: 4.17.21 - ts-essentials: 6.0.7_typescript@4.9.5 + ts-essentials: 6.0.7(typescript@4.9.5) ts-generator: 0.1.1 transitivePeerDependencies: - supports-color - typescript dev: true - /typechain/8.2.0_typescript@4.9.5: + /typechain@8.2.0(typescript@4.9.5): resolution: {integrity: sha512-tZqhqjxJ9xAS/Lh32jccTjMkpx7sTdUVVHAy5Bf0TIer5QFNYXotiX74oCvoVYjyxUKDK3MXHtMFzMyD3kE+jg==} hasBin: true peerDependencies: typescript: '>=4.3.0' dependencies: '@types/prettier': 2.7.1 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) fs-extra: 7.0.1 glob: 7.1.7 js-sha3: 0.8.0 @@ -10671,57 +10719,57 @@ packages: mkdirp: 1.0.4 prettier: 2.8.8 ts-command-line-args: 2.5.1 - ts-essentials: 7.0.3_typescript@4.9.5 + ts-essentials: 7.0.3(typescript@4.9.5) typescript: 4.9.5 transitivePeerDependencies: - supports-color dev: true - /typedarray-to-buffer/3.1.5: + /typedarray-to-buffer@3.1.5: resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} dependencies: is-typedarray: 1.0.0 dev: true - /typedarray/0.0.6: + /typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} dev: true - /typescript/4.9.5: + /typescript@4.9.5: resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} engines: {node: '>=4.2.0'} hasBin: true dev: true - /typewise-core/1.2.0: + /typewise-core@1.2.0: resolution: {integrity: sha512-2SCC/WLzj2SbUwzFOzqMCkz5amXLlxtJqDKTICqg30x+2DZxcfZN2MvQZmGfXWKNWaKK9pBPsvkcwv8bF/gxKg==} dev: true - /typewise/1.0.3: + /typewise@1.0.3: resolution: {integrity: sha512-aXofE06xGhaQSPzt8hlTY+/YWQhm9P0jYUp1f2XtmW/3Bk0qzXcyFWAtPoo2uTGQj1ZwbDuSyuxicq+aDo8lCQ==} dependencies: typewise-core: 1.2.0 dev: true - /typewiselite/1.0.0: + /typewiselite@1.0.0: resolution: {integrity: sha512-J9alhjVHupW3Wfz6qFRGgQw0N3gr8hOkw6zm7FZ6UR1Cse/oD9/JVok7DNE9TT9IbciDHX2Ex9+ksE6cRmtymw==} dev: true - /typical/2.6.1: + /typical@2.6.1: resolution: {integrity: sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg==} dev: true - /typical/4.0.0: + /typical@4.0.0: resolution: {integrity: sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==} engines: {node: '>=8'} dev: true - /typical/5.2.0: + /typical@5.2.0: resolution: {integrity: sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==} engines: {node: '>=8'} dev: true - /uglify-js/3.17.3: + /uglify-js@3.17.3: resolution: {integrity: sha512-JmMFDME3iufZnBpyKL+uS78LRiC+mK55zWfM5f/pWBJfpOttXAqYfdDGRukYhJuyRinvPVAtUhvy7rlDybNtFg==} engines: {node: '>=0.8.0'} hasBin: true @@ -10729,11 +10777,11 @@ packages: dev: true optional: true - /ultron/1.1.1: + /ultron@1.1.1: resolution: {integrity: sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==} dev: true - /unbox-primitive/1.0.2: + /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: call-bind: 1.0.2 @@ -10742,24 +10790,25 @@ packages: which-boxed-primitive: 1.0.2 dev: true - /underscore/1.9.1: + /underscore@1.9.1: resolution: {integrity: sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==} + requiresBuild: true dev: true optional: true - /undici/5.10.0: + /undici@5.10.0: resolution: {integrity: sha512-c8HsD3IbwmjjbLvoZuRI26TZic+TSEe8FPMLLOkN1AfYRhdjnKBU6yL+IwcSCbdZiX4e5t0lfMDLDCqj4Sq70g==} engines: {node: '>=12.18'} dev: true - /undici/5.19.1: + /undici@5.19.1: resolution: {integrity: sha512-YiZ61LPIgY73E7syxCDxxa3LV2yl3sN8spnIuTct60boiiRaE1J8mNWHO8Im2Zi/sFrPusjLlmRPrsyraSqX6A==} engines: {node: '>=12.18'} dependencies: busboy: 1.6.0 dev: true - /union-value/1.0.1: + /union-value@1.0.1: resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} engines: {node: '>=0.10.0'} dependencies: @@ -10769,27 +10818,27 @@ packages: set-value: 2.0.1 dev: true - /universalify/0.1.2: + /universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} dev: true - /universalify/2.0.0: + /universalify@2.0.0: resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} engines: {node: '>= 10.0.0'} dev: true - /unorm/1.6.0: + /unorm@1.6.0: resolution: {integrity: sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==} engines: {node: '>= 0.4.0'} dev: true - /unpipe/1.0.0: + /unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} dev: true - /unset-value/1.0.0: + /unset-value@1.0.0: resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} engines: {node: '>=0.10.0'} dependencies: @@ -10797,63 +10846,64 @@ packages: isobject: 3.0.1 dev: true - /upper-case-first/1.1.2: + /upper-case-first@1.1.2: resolution: {integrity: sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ==} dependencies: upper-case: 1.1.3 dev: true - /upper-case/1.1.3: + /upper-case@1.1.3: resolution: {integrity: sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==} dev: true - /uri-js/4.4.1: + /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: punycode: 2.1.1 dev: true - /urix/0.1.0: + /urix@0.1.0: resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} deprecated: Please see https://github.com/lydell/urix#deprecated dev: true - /url-parse-lax/1.0.0: + /url-parse-lax@1.0.0: resolution: {integrity: sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==} engines: {node: '>=0.10.0'} dependencies: prepend-http: 1.0.4 dev: true - /url-parse-lax/3.0.0: + /url-parse-lax@3.0.0: resolution: {integrity: sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==} engines: {node: '>=4'} + requiresBuild: true dependencies: prepend-http: 2.0.0 dev: true - /url-set-query/1.0.0: + /url-set-query@1.0.0: resolution: {integrity: sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==} dev: true - /url-to-options/1.0.1: + /url-to-options@1.0.1: resolution: {integrity: sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==} engines: {node: '>= 4'} dev: true - /url/0.11.0: + /url@0.11.0: resolution: {integrity: sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==} dependencies: punycode: 1.3.2 querystring: 0.2.0 dev: true - /use/3.1.1: + /use@3.1.1: resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} engines: {node: '>=0.10.0'} dev: true - /utf-8-validate/5.0.9: + /utf-8-validate@5.0.9: resolution: {integrity: sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==} engines: {node: '>=6.14.2'} requiresBuild: true @@ -10861,15 +10911,15 @@ packages: node-gyp-build: 4.5.0 dev: true - /utf8/3.0.0: + /utf8@3.0.0: resolution: {integrity: sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==} dev: true - /util-deprecate/1.0.2: + /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: true - /util.promisify/1.1.1: + /util.promisify@1.1.1: resolution: {integrity: sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw==} dependencies: call-bind: 1.0.2 @@ -10879,7 +10929,7 @@ packages: object.getownpropertydescriptors: 2.1.4 dev: true - /util/0.12.3: + /util@0.12.3: resolution: {integrity: sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==} dependencies: inherits: 2.0.4 @@ -10890,50 +10940,50 @@ packages: which-typed-array: 1.1.4 dev: true - /utils-merge/1.0.1: + /utils-merge@1.0.1: resolution: {integrity: sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=} engines: {node: '>= 0.4.0'} dev: true - /uuid/2.0.1: + /uuid@2.0.1: resolution: {integrity: sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==} deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. dev: true - /uuid/3.3.2: + /uuid@3.3.2: resolution: {integrity: sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==} deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. hasBin: true dev: true - /uuid/3.4.0: + /uuid@3.4.0: resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. hasBin: true dev: true - /uuid/8.3.2: + /uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true dev: true - /validate-npm-package-license/3.0.4: + /validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} dependencies: spdx-correct: 3.1.1 spdx-expression-parse: 3.0.1 dev: true - /varint/5.0.2: + /varint@5.0.2: resolution: {integrity: sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==} dev: true - /vary/1.1.2: + /vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} dev: true - /verror/1.10.0: + /verror@1.10.0: resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} engines: {'0': node >=0.6.0} dependencies: @@ -10942,9 +10992,10 @@ packages: extsprintf: 1.4.0 dev: true - /web3-bzz/1.2.11: + /web3-bzz@1.2.11: resolution: {integrity: sha512-XGpWUEElGypBjeFyUhTkiPXFbDVD6Nr/S5jznE3t8cWUA0FxRf1n3n/NuIZeb0H9RkN2Ctd/jNma/k8XGa3YKg==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: '@types/node': 12.19.16 got: 9.6.0 @@ -10957,7 +11008,7 @@ packages: dev: true optional: true - /web3-bzz/1.7.4: + /web3-bzz@1.7.4: resolution: {integrity: sha512-w9zRhyEqTK/yi0LGRHjZMcPCfP24LBjYXI/9YxFw9VqsIZ9/G0CRCnUt12lUx0A56LRAMpF7iQ8eA73aBcO29Q==} engines: {node: '>=8.0.0'} requiresBuild: true @@ -10971,7 +11022,7 @@ packages: - utf-8-validate dev: true - /web3-bzz/1.8.0: + /web3-bzz@1.8.0: resolution: {integrity: sha512-caDtdKeLi7+2Vb+y+cq2yyhkNjnxkFzVW0j1DtemarBg3dycG1iEl75CVQMLNO6Wkg+HH9tZtRnUyFIe5LIUeQ==} engines: {node: '>=8.0.0'} requiresBuild: true @@ -10985,9 +11036,10 @@ packages: - utf-8-validate dev: true - /web3-core-helpers/1.2.11: + /web3-core-helpers@1.2.11: resolution: {integrity: sha512-PEPoAoZd5ME7UfbnCZBdzIerpe74GEvlwT4AjOmHeCVZoIFk7EqvOZDejJHt+feJA6kMVTdd0xzRNN295UhC1A==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: underscore: 1.9.1 web3-eth-iban: 1.2.11 @@ -10995,7 +11047,7 @@ packages: dev: true optional: true - /web3-core-helpers/1.7.4: + /web3-core-helpers@1.7.4: resolution: {integrity: sha512-F8PH11qIkE/LpK4/h1fF/lGYgt4B6doeMi8rukeV/s4ivseZHHslv1L6aaijLX/g/j4PsFmR42byynBI/MIzFg==} engines: {node: '>=8.0.0'} dependencies: @@ -11003,7 +11055,7 @@ packages: web3-utils: 1.7.4 dev: true - /web3-core-helpers/1.8.0: + /web3-core-helpers@1.8.0: resolution: {integrity: sha512-nMAVwZB3rEp/khHI2BvFy0e/xCryf501p5NGjswmJtEM+Zrd3Biaw52JrB1qAZZIzCA8cmLKaOgdfamoDOpWdw==} engines: {node: '>=8.0.0'} dependencies: @@ -11011,9 +11063,10 @@ packages: web3-utils: 1.8.0 dev: true - /web3-core-method/1.2.11: + /web3-core-method@1.2.11: resolution: {integrity: sha512-ff0q76Cde94HAxLDZ6DbdmKniYCQVtvuaYh+rtOUMB6kssa5FX0q3vPmixi7NPooFnbKmmZCM6NvXg4IreTPIw==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: '@ethersproject/transactions': 5.7.0 underscore: 1.9.1 @@ -11024,7 +11077,7 @@ packages: dev: true optional: true - /web3-core-method/1.7.4: + /web3-core-method@1.7.4: resolution: {integrity: sha512-56K7pq+8lZRkxJyzf5MHQPI9/VL3IJLoy4L/+q8HRdZJ3CkB1DkXYaXGU2PeylG1GosGiSzgIfu1ljqS7CP9xQ==} engines: {node: '>=8.0.0'} dependencies: @@ -11035,7 +11088,7 @@ packages: web3-utils: 1.7.4 dev: true - /web3-core-method/1.8.0: + /web3-core-method@1.8.0: resolution: {integrity: sha512-c94RAzo3gpXwf2rf8rL8C77jOzNWF4mXUoUfZYYsiY35cJFd46jQDPI00CB5+ZbICTiA5mlVzMj4e7jAsTqiLA==} engines: {node: '>=8.0.0'} dependencies: @@ -11046,31 +11099,33 @@ packages: web3-utils: 1.8.0 dev: true - /web3-core-promievent/1.2.11: + /web3-core-promievent@1.2.11: resolution: {integrity: sha512-il4McoDa/Ox9Agh4kyfQ8Ak/9ABYpnF8poBLL33R/EnxLsJOGQG2nZhkJa3I067hocrPSjEdlPt/0bHXsln4qA==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: eventemitter3: 4.0.4 dev: true optional: true - /web3-core-promievent/1.7.4: + /web3-core-promievent@1.7.4: resolution: {integrity: sha512-o4uxwXKDldN7ER7VUvDfWsqTx9nQSP1aDssi1XYXeYC2xJbVo0n+z6ryKtmcoWoRdRj7uSpVzal3nEmlr480mA==} engines: {node: '>=8.0.0'} dependencies: eventemitter3: 4.0.4 dev: true - /web3-core-promievent/1.8.0: + /web3-core-promievent@1.8.0: resolution: {integrity: sha512-FGLyjAuOaAQ+ZhV6iuw9tg/9WvIkSZXKHQ4mdTyQ8MxVraOtFivOCbuLLsGgapfHYX+RPxsc1j1YzQjKoupagQ==} engines: {node: '>=8.0.0'} dependencies: eventemitter3: 4.0.4 dev: true - /web3-core-requestmanager/1.2.11: + /web3-core-requestmanager@1.2.11: resolution: {integrity: sha512-oFhBtLfOiIbmfl6T6gYjjj9igOvtyxJ+fjS+byRxiwFJyJ5BQOz4/9/17gWR1Cq74paTlI7vDGxYfuvfE/mKvA==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: underscore: 1.9.1 web3-core-helpers: 1.2.11 @@ -11082,7 +11137,7 @@ packages: dev: true optional: true - /web3-core-requestmanager/1.7.4: + /web3-core-requestmanager@1.7.4: resolution: {integrity: sha512-IuXdAm65BQtPL4aI6LZJJOrKAs0SM5IK2Cqo2/lMNvVMT9Kssq6qOk68Uf7EBDH0rPuINi+ReLP+uH+0g3AnPA==} engines: {node: '>=8.0.0'} dependencies: @@ -11095,7 +11150,7 @@ packages: - supports-color dev: true - /web3-core-requestmanager/1.8.0: + /web3-core-requestmanager@1.8.0: resolution: {integrity: sha512-2AoYCs3Owl5foWcf4uKPONyqFygSl9T54L8b581U16nsUirjhoTUGK/PBhMDVcLCmW4QQmcY5A8oPFpkQc1TTg==} engines: {node: '>=8.0.0'} dependencies: @@ -11109,9 +11164,10 @@ packages: - supports-color dev: true - /web3-core-subscriptions/1.2.11: + /web3-core-subscriptions@1.2.11: resolution: {integrity: sha512-qEF/OVqkCvQ7MPs1JylIZCZkin0aKK9lDxpAtQ1F8niEDGFqn7DT8E/vzbIa0GsOjL2fZjDhWJsaW+BSoAW1gg==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: eventemitter3: 4.0.4 underscore: 1.9.1 @@ -11119,7 +11175,7 @@ packages: dev: true optional: true - /web3-core-subscriptions/1.7.4: + /web3-core-subscriptions@1.7.4: resolution: {integrity: sha512-VJvKWaXRyxk2nFWumOR94ut9xvjzMrRtS38c4qj8WBIRSsugrZr5lqUwgndtj0qx4F+50JhnU++QEqUEAtKm3g==} engines: {node: '>=8.0.0'} dependencies: @@ -11127,7 +11183,7 @@ packages: web3-core-helpers: 1.7.4 dev: true - /web3-core-subscriptions/1.8.0: + /web3-core-subscriptions@1.8.0: resolution: {integrity: sha512-7lHVRzDdg0+Gcog55lG6Q3D8JV+jN+4Ly6F8cSn9xFUAwOkdbgdWsjknQG7t7CDWy21DQkvdiY2BJF8S68AqOA==} engines: {node: '>=8.0.0'} dependencies: @@ -11135,9 +11191,10 @@ packages: web3-core-helpers: 1.8.0 dev: true - /web3-core/1.2.11: + /web3-core@1.2.11: resolution: {integrity: sha512-CN7MEYOY5ryo5iVleIWRE3a3cZqVaLlIbIzDPsvQRUfzYnvzZQRZBm9Mq+ttDi2STOOzc1MKylspz/o3yq/LjQ==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: '@types/bn.js': 4.11.6 '@types/node': 12.19.16 @@ -11151,7 +11208,7 @@ packages: dev: true optional: true - /web3-core/1.7.4: + /web3-core@1.7.4: resolution: {integrity: sha512-L0DCPlIh9bgIED37tYbe7bsWrddoXYc897ANGvTJ6MFkSNGiMwDkTLWSgYd9Mf8qu8b4iuPqXZHMwIo4atoh7Q==} engines: {node: '>=8.0.0'} dependencies: @@ -11166,7 +11223,7 @@ packages: - supports-color dev: true - /web3-core/1.8.0: + /web3-core@1.8.0: resolution: {integrity: sha512-9sCA+Z02ci6zoY2bAquFiDjujRwmSKHiSGi4B8IstML8okSytnzXk1izHYSynE7ahIkguhjWAuXFvX76F5rAbA==} engines: {node: '>=8.0.0'} dependencies: @@ -11182,9 +11239,10 @@ packages: - supports-color dev: true - /web3-eth-abi/1.2.11: + /web3-eth-abi@1.2.11: resolution: {integrity: sha512-PkRYc0+MjuLSgg03QVWqWlQivJqRwKItKtEpRUaxUAeLE7i/uU39gmzm2keHGcQXo3POXAbOnMqkDvOep89Crg==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: '@ethersproject/abi': 5.0.0-beta.153 underscore: 1.9.1 @@ -11192,7 +11250,7 @@ packages: dev: true optional: true - /web3-eth-abi/1.7.4: + /web3-eth-abi@1.7.4: resolution: {integrity: sha512-eMZr8zgTbqyL9MCTCAvb67RbVyN5ZX7DvA0jbLOqRWCiw+KlJKTGnymKO6jPE8n5yjk4w01e165Qb11hTDwHgg==} engines: {node: '>=8.0.0'} dependencies: @@ -11200,7 +11258,7 @@ packages: web3-utils: 1.7.4 dev: true - /web3-eth-abi/1.8.0: + /web3-eth-abi@1.8.0: resolution: {integrity: sha512-xPeMb2hS9YLQK/Q5YZpkcmzoRGM+/R8bogSrYHhNC3hjZSSU0YRH+1ZKK0f9YF4qDZaPMI8tKWIMSCDIpjG6fg==} engines: {node: '>=8.0.0'} dependencies: @@ -11208,9 +11266,10 @@ packages: web3-utils: 1.8.0 dev: true - /web3-eth-accounts/1.2.11: + /web3-eth-accounts@1.2.11: resolution: {integrity: sha512-6FwPqEpCfKIh3nSSGeo3uBm2iFSnFJDfwL3oS9pyegRBXNsGRVpgiW63yhNzL0796StsvjHWwQnQHsZNxWAkGw==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: crypto-browserify: 3.12.0 eth-lib: 0.2.8 @@ -11228,7 +11287,7 @@ packages: dev: true optional: true - /web3-eth-accounts/1.7.4: + /web3-eth-accounts@1.7.4: resolution: {integrity: sha512-Y9vYLRKP7VU7Cgq6wG1jFaG2k3/eIuiTKAG8RAuQnb6Cd9k5BRqTm5uPIiSo0AP/u11jDomZ8j7+WEgkU9+Btw==} engines: {node: '>=8.0.0'} dependencies: @@ -11247,7 +11306,7 @@ packages: - supports-color dev: true - /web3-eth-accounts/1.8.0: + /web3-eth-accounts@1.8.0: resolution: {integrity: sha512-HQ/MDSv4bexwJLvnqsM6xpGE7c2NVOqyhzOZFyMUKXbIwIq85T3TaLnM9pCN7XqMpDcfxqiZ3q43JqQVkzHdmw==} engines: {node: '>=8.0.0'} dependencies: @@ -11267,9 +11326,10 @@ packages: - supports-color dev: true - /web3-eth-contract/1.2.11: + /web3-eth-contract@1.2.11: resolution: {integrity: sha512-MzYuI/Rq2o6gn7vCGcnQgco63isPNK5lMAan2E51AJLknjSLnOxwNY3gM8BcKoy4Z+v5Dv00a03Xuk78JowFow==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: '@types/bn.js': 4.11.6 underscore: 1.9.1 @@ -11285,7 +11345,7 @@ packages: dev: true optional: true - /web3-eth-contract/1.7.4: + /web3-eth-contract@1.7.4: resolution: {integrity: sha512-ZgSZMDVI1pE9uMQpK0T0HDT2oewHcfTCv0osEqf5qyn5KrcQDg1GT96/+S0dfqZ4HKj4lzS5O0rFyQiLPQ8LzQ==} engines: {node: '>=8.0.0'} dependencies: @@ -11301,7 +11361,7 @@ packages: - supports-color dev: true - /web3-eth-contract/1.8.0: + /web3-eth-contract@1.8.0: resolution: {integrity: sha512-6xeXhW2YoCrz2Ayf2Vm4srWiMOB6LawkvxWJDnUWJ8SMATg4Pgu42C/j8rz/enXbYWt2IKuj0kk8+QszxQbK+Q==} engines: {node: '>=8.0.0'} dependencies: @@ -11318,9 +11378,10 @@ packages: - supports-color dev: true - /web3-eth-ens/1.2.11: + /web3-eth-ens@1.2.11: resolution: {integrity: sha512-dbW7dXP6HqT1EAPvnniZVnmw6TmQEKF6/1KgAxbo8iBBYrVTMDGFQUUnZ+C4VETGrwwaqtX4L9d/FrQhZ6SUiA==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: content-hash: 2.5.2 eth-ens-namehash: 2.0.8 @@ -11336,7 +11397,7 @@ packages: dev: true optional: true - /web3-eth-ens/1.7.4: + /web3-eth-ens@1.7.4: resolution: {integrity: sha512-Gw5CVU1+bFXP5RVXTCqJOmHn71X2ghNk9VcEH+9PchLr0PrKbHTA3hySpsPco1WJAyK4t8SNQVlNr3+bJ6/WZA==} engines: {node: '>=8.0.0'} dependencies: @@ -11352,7 +11413,7 @@ packages: - supports-color dev: true - /web3-eth-ens/1.8.0: + /web3-eth-ens@1.8.0: resolution: {integrity: sha512-/eFbQEwvsMOEiOhw9/iuRXCsPkqAmHHWuFOrThQkozRgcnSTRnvxkkRC/b6koiT5/HaKeUs4yQDg+/ixsIxZxA==} engines: {node: '>=8.0.0'} dependencies: @@ -11369,16 +11430,17 @@ packages: - supports-color dev: true - /web3-eth-iban/1.2.11: + /web3-eth-iban@1.2.11: resolution: {integrity: sha512-ozuVlZ5jwFC2hJY4+fH9pIcuH1xP0HEFhtWsR69u9uDIANHLPQQtWYmdj7xQ3p2YT4bQLq/axKhZi7EZVetmxQ==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: bn.js: 4.12.0 web3-utils: 1.2.11 dev: true optional: true - /web3-eth-iban/1.7.4: + /web3-eth-iban@1.7.4: resolution: {integrity: sha512-XyrsgWlZQMv5gRcjXMsNvAoCRvV5wN7YCfFV5+tHUCqN8g9T/o4XUS20vDWD0k4HNiAcWGFqT1nrls02MGZ08w==} engines: {node: '>=8.0.0'} dependencies: @@ -11386,7 +11448,7 @@ packages: web3-utils: 1.7.4 dev: true - /web3-eth-iban/1.8.0: + /web3-eth-iban@1.8.0: resolution: {integrity: sha512-4RbvUxcMpo/e5811sE3a6inJ2H4+FFqUVmlRYs0RaXaxiHweahSRBNcpO0UWgmlePTolj0rXqPT2oEr0DuC8kg==} engines: {node: '>=8.0.0'} dependencies: @@ -11394,9 +11456,10 @@ packages: web3-utils: 1.8.0 dev: true - /web3-eth-personal/1.2.11: + /web3-eth-personal@1.2.11: resolution: {integrity: sha512-42IzUtKq9iHZ8K9VN0vAI50iSU9tOA1V7XU2BhF/tb7We2iKBVdkley2fg26TxlOcKNEHm7o6HRtiiFsVK4Ifw==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: '@types/node': 12.19.16 web3-core: 1.2.11 @@ -11409,7 +11472,7 @@ packages: dev: true optional: true - /web3-eth-personal/1.7.4: + /web3-eth-personal@1.7.4: resolution: {integrity: sha512-O10C1Hln5wvLQsDhlhmV58RhXo+GPZ5+W76frSsyIrkJWLtYQTCr5WxHtRC9sMD1idXLqODKKgI2DL+7xeZ0/g==} engines: {node: '>=8.0.0'} dependencies: @@ -11423,7 +11486,7 @@ packages: - supports-color dev: true - /web3-eth-personal/1.8.0: + /web3-eth-personal@1.8.0: resolution: {integrity: sha512-L7FT4nR3HmsfZyIAhFpEctKkYGOjRC2h6iFKs9gnFCHZga8yLcYcGaYOBIoYtaKom99MuGBoosayWt/Twh7F5A==} engines: {node: '>=8.0.0'} dependencies: @@ -11438,9 +11501,10 @@ packages: - supports-color dev: true - /web3-eth/1.2.11: + /web3-eth@1.2.11: resolution: {integrity: sha512-REvxW1wJ58AgHPcXPJOL49d1K/dPmuw4LjPLBPStOVkQjzDTVmJEIsiLwn2YeuNDd4pfakBwT8L3bz1G1/wVsQ==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: underscore: 1.9.1 web3-core: 1.2.11 @@ -11460,7 +11524,7 @@ packages: dev: true optional: true - /web3-eth/1.7.4: + /web3-eth@1.7.4: resolution: {integrity: sha512-JG0tTMv0Ijj039emXNHi07jLb0OiWSA9O24MRSk5vToTQyDNXihdF2oyq85LfHuF690lXZaAXrjhtLNlYqb7Ug==} engines: {node: '>=8.0.0'} dependencies: @@ -11480,7 +11544,7 @@ packages: - supports-color dev: true - /web3-eth/1.8.0: + /web3-eth@1.8.0: resolution: {integrity: sha512-hist52os3OT4TQFB/GxPSMxTh3995sz6LPvQpPvj7ktSbpg9RNSFaSsPlCT63wUAHA3PZb1FemkAIeQM5t72Lw==} engines: {node: '>=8.0.0'} dependencies: @@ -11501,9 +11565,10 @@ packages: - supports-color dev: true - /web3-net/1.2.11: + /web3-net@1.2.11: resolution: {integrity: sha512-sjrSDj0pTfZouR5BSTItCuZ5K/oZPVdVciPQ6981PPPIwJJkCMeVjD7I4zO3qDPCnBjBSbWvVnLdwqUBPtHxyg==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: web3-core: 1.2.11 web3-core-method: 1.2.11 @@ -11513,7 +11578,7 @@ packages: dev: true optional: true - /web3-net/1.7.4: + /web3-net@1.7.4: resolution: {integrity: sha512-d2Gj+DIARHvwIdmxFQ4PwAAXZVxYCR2lET0cxz4KXbE5Og3DNjJi+MoPkX+WqoUXqimu/EOd4Cd+7gefqVAFDg==} engines: {node: '>=8.0.0'} dependencies: @@ -11524,7 +11589,7 @@ packages: - supports-color dev: true - /web3-net/1.8.0: + /web3-net@1.8.0: resolution: {integrity: sha512-kX6EAacK7QrOe7DOh0t5yHS5q2kxZmTCxPVwSz9io9xBeE4n4UhmzGJ/VfhP2eM3OPKYeypcR3LEO6zZ8xn2vw==} engines: {node: '>=8.0.0'} dependencies: @@ -11536,7 +11601,7 @@ packages: - supports-color dev: true - /web3-provider-engine/14.2.1: + /web3-provider-engine@14.2.1: resolution: {integrity: sha512-iSv31h2qXkr9vrL6UZDm4leZMc32SjWJFGOp/D92JXfcEboCqraZyuExDkpxKw8ziTufXieNM7LSXNHzszYdJw==} dependencies: async: 2.6.3 @@ -11566,16 +11631,17 @@ packages: - utf-8-validate dev: true - /web3-providers-http/1.2.11: + /web3-providers-http@1.2.11: resolution: {integrity: sha512-psh4hYGb1+ijWywfwpB2cvvOIMISlR44F/rJtYkRmQ5jMvG4FOCPlQJPiHQZo+2cc3HbktvvSJzIhkWQJdmvrA==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: web3-core-helpers: 1.2.11 xhr2-cookies: 1.1.0 dev: true optional: true - /web3-providers-http/1.7.4: + /web3-providers-http@1.7.4: resolution: {integrity: sha512-AU+/S+49rcogUER99TlhW+UBMk0N2DxvN54CJ2pK7alc2TQ7+cprNPLHJu4KREe8ndV0fT6JtWUfOMyTvl+FRA==} engines: {node: '>=8.0.0'} dependencies: @@ -11583,7 +11649,7 @@ packages: xhr2-cookies: 1.1.0 dev: true - /web3-providers-http/1.8.0: + /web3-providers-http@1.8.0: resolution: {integrity: sha512-/MqxwRzExohBWW97mqlCSW/+NHydGRyoEDUS1bAIF2YjfKFwyRtHgrEzOojzkC9JvB+8LofMvbXk9CcltpZapw==} engines: {node: '>=8.0.0'} dependencies: @@ -11595,9 +11661,10 @@ packages: - encoding dev: true - /web3-providers-ipc/1.2.11: + /web3-providers-ipc@1.2.11: resolution: {integrity: sha512-yhc7Y/k8hBV/KlELxynWjJDzmgDEDjIjBzXK+e0rHBsYEhdCNdIH5Psa456c+l0qTEU2YzycF8VAjYpWfPnBpQ==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: oboe: 2.1.4 underscore: 1.9.1 @@ -11605,7 +11672,7 @@ packages: dev: true optional: true - /web3-providers-ipc/1.7.4: + /web3-providers-ipc@1.7.4: resolution: {integrity: sha512-jhArOZ235dZy8fS8090t60nTxbd1ap92ibQw5xIrAQ9m7LcZKNfmLAQUVsD+3dTFvadRMi6z1vCO7zRi84gWHw==} engines: {node: '>=8.0.0'} dependencies: @@ -11613,7 +11680,7 @@ packages: web3-core-helpers: 1.7.4 dev: true - /web3-providers-ipc/1.8.0: + /web3-providers-ipc@1.8.0: resolution: {integrity: sha512-tAXHtVXNUOgehaBU8pzAlB3qhjn/PRpjdzEjzHNFqtRRTwzSEKOJxFeEhaUA4FzHnTlbnrs8ujHWUitcp1elfg==} engines: {node: '>=8.0.0'} dependencies: @@ -11621,9 +11688,10 @@ packages: web3-core-helpers: 1.8.0 dev: true - /web3-providers-ws/1.2.11: + /web3-providers-ws@1.2.11: resolution: {integrity: sha512-ZxnjIY1Er8Ty+cE4migzr43zA/+72AF1myzsLaU5eVgdsfV7Jqx7Dix1hbevNZDKFlSoEyq/3j/jYalh3So1Zg==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: eventemitter3: 4.0.4 underscore: 1.9.1 @@ -11634,7 +11702,7 @@ packages: dev: true optional: true - /web3-providers-ws/1.7.4: + /web3-providers-ws@1.7.4: resolution: {integrity: sha512-g72X77nrcHMFU8hRzQJzfgi/072n8dHwRCoTw+WQrGp+XCQ71fsk2qIu3Tp+nlp5BPn8bRudQbPblVm2uT4myQ==} engines: {node: '>=8.0.0'} dependencies: @@ -11645,7 +11713,7 @@ packages: - supports-color dev: true - /web3-providers-ws/1.8.0: + /web3-providers-ws@1.8.0: resolution: {integrity: sha512-bcZtSifsqyJxwkfQYamfdIRp4nhj9eJd7cxHg1uUkfLJK125WP96wyJL1xbPt7qt0MpfnTFn8/UuIqIB6nFENg==} engines: {node: '>=8.0.0'} dependencies: @@ -11656,9 +11724,10 @@ packages: - supports-color dev: true - /web3-shh/1.2.11: + /web3-shh@1.2.11: resolution: {integrity: sha512-B3OrO3oG1L+bv3E1sTwCx66injW1A8hhwpknDUbV+sw3fehFazA06z9SGXUefuFI1kVs4q2vRi0n4oCcI4dZDg==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: web3-core: 1.2.11 web3-core-method: 1.2.11 @@ -11669,7 +11738,7 @@ packages: dev: true optional: true - /web3-shh/1.7.4: + /web3-shh@1.7.4: resolution: {integrity: sha512-mlSZxSYcMkuMCxqhTYnZkUdahZ11h+bBv/8TlkXp/IHpEe4/Gg+KAbmfudakq3EzG/04z70XQmPgWcUPrsEJ+A==} engines: {node: '>=8.0.0'} requiresBuild: true @@ -11682,7 +11751,7 @@ packages: - supports-color dev: true - /web3-shh/1.8.0: + /web3-shh@1.8.0: resolution: {integrity: sha512-DNRgSa9Jf9xYFUGKSMylrf+zt3MPjhI2qF+UWX07o0y3+uf8zalDGiJOWvIS4upAsdPiKKVJ7co+Neof47OMmg==} engines: {node: '>=8.0.0'} requiresBuild: true @@ -11696,9 +11765,10 @@ packages: - supports-color dev: true - /web3-utils/1.2.11: + /web3-utils@1.2.11: resolution: {integrity: sha512-3Tq09izhD+ThqHEaWYX4VOT7dNPdZiO+c/1QMA0s5X2lDFKK/xHJb7cyTRRVzN2LvlHbR7baS1tmQhSua51TcQ==} engines: {node: '>=8.0.0'} + requiresBuild: true dependencies: bn.js: 4.12.0 eth-lib: 0.2.8 @@ -11711,7 +11781,7 @@ packages: dev: true optional: true - /web3-utils/1.7.4: + /web3-utils@1.7.4: resolution: {integrity: sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==} engines: {node: '>=8.0.0'} dependencies: @@ -11724,7 +11794,7 @@ packages: utf8: 3.0.0 dev: true - /web3-utils/1.8.0: + /web3-utils@1.8.0: resolution: {integrity: sha512-7nUIl7UWpLVka2f09CMbKOSEvorvHnaugIabU4mj7zfMvm0tSByLcEu3eyV9qgS11qxxLuOkzBIwCstTflhmpQ==} engines: {node: '>=8.0.0'} dependencies: @@ -11737,7 +11807,7 @@ packages: utf8: 3.0.0 dev: true - /web3/1.2.11: + /web3@1.2.11: resolution: {integrity: sha512-mjQ8HeU41G6hgOYm1pmeH0mRAeNKJGnJEUzDMoerkpw7QUQT4exVREgF1MYPvL/z6vAshOXei25LE/t/Bxl8yQ==} engines: {node: '>=8.0.0'} requiresBuild: true @@ -11756,7 +11826,7 @@ packages: dev: true optional: true - /web3/1.7.4: + /web3@1.7.4: resolution: {integrity: sha512-iFGK5jO32vnXM/ASaJBaI0+gVR6uHozvYdxkdhaeOCD6HIQ4iIXadbO2atVpE9oc/H8l2MovJ4LtPhG7lIBN8A==} engines: {node: '>=8.0.0'} requiresBuild: true @@ -11774,7 +11844,7 @@ packages: - utf-8-validate dev: true - /web3/1.8.0: + /web3@1.8.0: resolution: {integrity: sha512-sldr9stK/SALSJTgI/8qpnDuBJNMGjVR84hJ+AcdQ+MLBGLMGsCDNubCoyO6qgk1/Y9SQ7ignegOI/7BPLoiDA==} engines: {node: '>=8.0.0'} requiresBuild: true @@ -11793,11 +11863,11 @@ packages: - utf-8-validate dev: true - /webidl-conversions/3.0.1: + /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} dev: true - /websocket/1.0.32: + /websocket@1.0.32: resolution: {integrity: sha512-i4yhcllSP4wrpoPMU2N0TQ/q0O94LRG/eUQjEAamRltjQ1oT1PFFKOG4i877OlJgCG8rw6LrrowJp+TYCEWF7Q==} engines: {node: '>=4.0.0'} dependencies: @@ -11811,7 +11881,7 @@ packages: - supports-color dev: true - /websocket/1.0.34: + /websocket@1.0.34: resolution: {integrity: sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==} engines: {node: '>=4.0.0'} dependencies: @@ -11825,18 +11895,18 @@ packages: - supports-color dev: true - /whatwg-fetch/2.0.4: + /whatwg-fetch@2.0.4: resolution: {integrity: sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==} dev: true - /whatwg-url/5.0.0: + /whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} dependencies: tr46: 0.0.3 webidl-conversions: 3.0.1 dev: true - /which-boxed-primitive/1.0.2: + /which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} dependencies: is-bigint: 1.0.4 @@ -11846,15 +11916,15 @@ packages: is-symbol: 1.0.3 dev: true - /which-module/1.0.0: + /which-module@1.0.0: resolution: {integrity: sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==} dev: true - /which-module/2.0.0: + /which-module@2.0.0: resolution: {integrity: sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==} dev: true - /which-typed-array/1.1.4: + /which-typed-array@1.1.4: resolution: {integrity: sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==} engines: {node: '>= 0.4'} dependencies: @@ -11867,14 +11937,14 @@ packages: is-typed-array: 1.1.5 dev: true - /which/1.3.1: + /which@1.3.1: resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} hasBin: true dependencies: isexe: 2.0.0 dev: true - /which/2.0.2: + /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true @@ -11882,28 +11952,28 @@ packages: isexe: 2.0.0 dev: true - /wide-align/1.1.3: + /wide-align@1.1.3: resolution: {integrity: sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==} dependencies: string-width: 2.1.1 dev: true - /window-size/0.2.0: + /window-size@0.2.0: resolution: {integrity: sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw==} engines: {node: '>= 0.10.0'} hasBin: true dev: true - /word-wrap/1.2.3: + /word-wrap@1.2.3: resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} engines: {node: '>=0.10.0'} dev: true - /wordwrap/1.0.0: + /wordwrap@1.0.0: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} dev: true - /wordwrapjs/4.0.1: + /wordwrapjs@4.0.1: resolution: {integrity: sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==} engines: {node: '>=8.0.0'} dependencies: @@ -11911,11 +11981,11 @@ packages: typical: 5.2.0 dev: true - /workerpool/6.2.1: + /workerpool@6.2.1: resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} dev: true - /wrap-ansi/2.1.0: + /wrap-ansi@2.1.0: resolution: {integrity: sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==} engines: {node: '>=0.10.0'} dependencies: @@ -11923,7 +11993,7 @@ packages: strip-ansi: 3.0.1 dev: true - /wrap-ansi/5.1.0: + /wrap-ansi@5.1.0: resolution: {integrity: sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==} engines: {node: '>=6'} dependencies: @@ -11932,7 +12002,7 @@ packages: strip-ansi: 5.2.0 dev: true - /wrap-ansi/7.0.0: + /wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} dependencies: @@ -11941,11 +12011,11 @@ packages: strip-ansi: 6.0.1 dev: true - /wrappy/1.0.2: + /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} dev: true - /ws/3.3.3: + /ws@3.3.3: resolution: {integrity: sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==} peerDependencies: bufferutil: ^4.0.1 @@ -11961,7 +12031,7 @@ packages: ultron: 1.1.1 dev: true - /ws/5.2.3: + /ws@5.2.3: resolution: {integrity: sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA==} peerDependencies: bufferutil: ^4.0.1 @@ -11975,7 +12045,7 @@ packages: async-limiter: 1.0.1 dev: true - /ws/7.4.6: + /ws@7.4.6: resolution: {integrity: sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==} engines: {node: '>=8.3.0'} peerDependencies: @@ -11987,7 +12057,7 @@ packages: utf-8-validate: optional: true - /ws/7.5.9: + /ws@7.5.9: resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} engines: {node: '>=8.3.0'} peerDependencies: @@ -12000,13 +12070,13 @@ packages: optional: true dev: true - /xhr-request-promise/0.1.2: + /xhr-request-promise@0.1.2: resolution: {integrity: sha512-yAQlCCNLwPgoGxw4k+IdRp1uZ7MZibS4kFw2boSUOesjnmvcxxj73j5a8KavE5Bzas++8P49OpJ4m8qjWGiDsA==} dependencies: xhr-request: 1.1.0 dev: true - /xhr-request/1.1.0: + /xhr-request@1.1.0: resolution: {integrity: sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==} dependencies: buffer-to-arraybuffer: 0.0.5 @@ -12018,7 +12088,13 @@ packages: xhr: 2.5.0 dev: true - /xhr/2.5.0: + /xhr2-cookies@1.1.0: + resolution: {integrity: sha512-hjXUA6q+jl/bd8ADHcVfFsSPIf+tyLIjuO9TwJC9WI6JP2zKcS7C+p56I9kCLLsaCiNT035iYvEUUzdEFj/8+g==} + dependencies: + cookiejar: 2.1.2 + dev: true + + /xhr@2.5.0: resolution: {integrity: sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==} dependencies: global: 4.3.2 @@ -12027,75 +12103,69 @@ packages: xtend: 4.0.2 dev: true - /xhr2-cookies/1.1.0: - resolution: {integrity: sha512-hjXUA6q+jl/bd8ADHcVfFsSPIf+tyLIjuO9TwJC9WI6JP2zKcS7C+p56I9kCLLsaCiNT035iYvEUUzdEFj/8+g==} - dependencies: - cookiejar: 2.1.2 - dev: true - - /xmlhttprequest/1.8.0: + /xmlhttprequest@1.8.0: resolution: {integrity: sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==} engines: {node: '>=0.4.0'} dev: true - /xtend/2.1.2: + /xtend@2.1.2: resolution: {integrity: sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==} engines: {node: '>=0.4'} dependencies: object-keys: 0.4.0 dev: true - /xtend/4.0.2: + /xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} dev: true - /y18n/3.2.2: + /y18n@3.2.2: resolution: {integrity: sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==} dev: true - /y18n/4.0.3: + /y18n@4.0.3: resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} dev: true - /y18n/5.0.8: + /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} dev: true - /yaeti/0.0.6: + /yaeti@0.0.6: resolution: {integrity: sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==} engines: {node: '>=0.10.32'} dev: true - /yallist/3.1.1: + /yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} dev: true - /yallist/4.0.0: + /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} dev: true - /yargs-parser/13.1.2: + /yargs-parser@13.1.2: resolution: {integrity: sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==} dependencies: camelcase: 5.3.1 decamelize: 1.2.0 dev: true - /yargs-parser/2.4.1: + /yargs-parser@2.4.1: resolution: {integrity: sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA==} dependencies: camelcase: 3.0.0 lodash.assign: 4.2.0 dev: true - /yargs-parser/20.2.4: + /yargs-parser@20.2.4: resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} engines: {node: '>=10'} dev: true - /yargs-unparser/1.6.0: + /yargs-unparser@1.6.0: resolution: {integrity: sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==} engines: {node: '>=6'} dependencies: @@ -12104,7 +12174,7 @@ packages: yargs: 13.3.2 dev: true - /yargs-unparser/2.0.0: + /yargs-unparser@2.0.0: resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} engines: {node: '>=10'} dependencies: @@ -12114,7 +12184,7 @@ packages: is-plain-obj: 2.1.0 dev: true - /yargs/13.3.2: + /yargs@13.3.2: resolution: {integrity: sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==} dependencies: cliui: 5.0.0 @@ -12129,7 +12199,7 @@ packages: yargs-parser: 13.1.2 dev: true - /yargs/16.2.0: + /yargs@16.2.0: resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} engines: {node: '>=10'} dependencies: @@ -12142,7 +12212,7 @@ packages: yargs-parser: 20.2.4 dev: true - /yargs/4.8.1: + /yargs@4.8.1: resolution: {integrity: sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA==} dependencies: cliui: 3.2.0 @@ -12161,12 +12231,12 @@ packages: yargs-parser: 2.4.1 dev: true - /yn/3.1.1: + /yn@3.1.1: resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} engines: {node: '>=6'} dev: true - /yocto-queue/0.1.0: + /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: true diff --git a/contracts/scripts/native_solc6_compile b/contracts/scripts/native_solc6_compile deleted file mode 100755 index ae3be9b56d0..00000000000 --- a/contracts/scripts/native_solc6_compile +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash - -# This script generates .abi and .bin files for a selected .sol contract. -# Example call: -# ./contracts/scripts/native_solc_compile dev/Operator.sol -# -# The resulting abi and bin files are stored in ./contracts/solc/v0.6 - -SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; cd .. && pwd -P )" - -solc-select use 0.6.6 -solc --overwrite --optimize --optimize-runs 1000000 --metadata-hash none \ - -o $SCRIPTPATH/solc/v0.6 \ - --abi --bin --allow-paths $SCRIPTPATH/src/v0.6,$SCRIPTPATH/src/v0.6/dev,$SCRIPTPATH/src/v0.6/interfaces,$SCRIPTPATH/src/v0.6/examples,$SCRIPTPATH/src/v0.6/tests,$SCRIPTPATH/src/v0.6/vendor \ - $SCRIPTPATH/src/v0.6/$1 diff --git a/contracts/scripts/native_solc7_compile b/contracts/scripts/native_solc7_compile deleted file mode 100755 index dc4c08e72e7..00000000000 --- a/contracts/scripts/native_solc7_compile +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash - -# This script generates .abi and .bin files for a selected .sol contract. -# Example call: -# ./contracts/scripts/native_solc_compile dev/Operator.sol -# -# The resulting abi and bin files are stored in ./contracts/solc/v0.7 - -SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; cd .. && pwd -P )" - -solc-select use 0.7.6 -solc --overwrite --optimize --optimize-runs 1000000 --metadata-hash none \ - -o $SCRIPTPATH/solc/v0.7 \ - --abi --bin --allow-paths $SCRIPTPATH/src/v0.7,$SCRIPTPATH/src/v0.7/dev,$SCRIPTPATH/src/v0.7/interfaces,$SCRIPTPATH/src/v0.7/tests,$SCRIPTPATH/src/v0.7/vendor \ - $SCRIPTPATH/src/v0.7/$1 \ No newline at end of file diff --git a/contracts/scripts/native_solc8_15_compile b/contracts/scripts/native_solc8_15_compile deleted file mode 100755 index 944a53a7e1a..00000000000 --- a/contracts/scripts/native_solc8_15_compile +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -# This script generates .abi and .bin files for a selected .sol contract. -# Example call: -# ./contracts/scripts/native_solc_compile dev/Operator.sol -# -# The resulting abi and bin files are stored in ./contracts/solc/v0.8 - -ROOT="$( - cd "$(dirname "$0")" >/dev/null 2>&1 - cd ../../ && pwd -P -)" - -solc-select use 0.8.15 -solc @openzeppelin/=$ROOT/contracts/node_modules/@openzeppelin/ --overwrite --optimize --optimize-runs 1000000 --metadata-hash none \ - -o $ROOT/contracts/solc/v0.8.15 \ - --abi --bin \ - --allow-paths $ROOT/contracts/src/v0.8,$ROOT/contracts/src/v0.8/dev,$ROOT/contracts/src/v0.8/interfaces,$ROOT/contracts/src/v0.8/mocks,$ROOT/contracts/src/v0.8/tests,$ROOT/contracts/src/v0.8/vendor,$ROOT/contracts/node_modules/.pnpm/@openzeppelin+contracts@4.3.3/node_modules/@openzeppelin/contracts,$ROOT/contracts/node_modules/.pnpm/@openzeppelin+contracts-upgradeable@4.7.3/node_modules/@openzeppelin/contracts-upgradeable \ - $ROOT/contracts/src/v0.8/$1 diff --git a/contracts/scripts/native_solc8_16_compile b/contracts/scripts/native_solc8_16_compile deleted file mode 100755 index d6083d50fa1..00000000000 --- a/contracts/scripts/native_solc8_16_compile +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -# This script generates .abi and .bin files for a selected .sol contract. -# Example call: -# ./contracts/scripts/native_solc_compile dev/Operator.sol -# -# The resulting abi and bin files are stored in ./contracts/solc/v0.8 - -ROOT="$( - cd "$(dirname "$0")" >/dev/null 2>&1 - cd ../../ && pwd -P -)" - -solc-select use 0.8.16 -solc @openzeppelin/=$ROOT/contracts/node_modules/@openzeppelin/ --overwrite --optimize --optimize-runs 1000000 --metadata-hash none \ - -o $ROOT/contracts/solc/v0.8.16 \ - --abi --bin \ - --allow-paths $ROOT/contracts/src/v0.8,$ROOT/contracts/src/v0.8/dev,$ROOT/contracts/src/v0.8/interfaces,$ROOT/contracts/src/v0.8/mocks,$ROOT/contracts/src/v0.8/tests,$ROOT/contracts/src/v0.8/vendor,$ROOT/contracts/node_modules/.pnpm/@openzeppelin+contracts@4.3.3/node_modules/@openzeppelin/contracts,$ROOT/contracts/node_modules/.pnpm/@openzeppelin+contracts-upgradeable@4.7.3/node_modules/@openzeppelin/contracts-upgradeable \ - $ROOT/contracts/src/v0.8/$1 diff --git a/contracts/scripts/native_solc8_19_compile_ocr2vrf b/contracts/scripts/native_solc8_19_compile_ocr2vrf deleted file mode 100755 index a3779430aff..00000000000 --- a/contracts/scripts/native_solc8_19_compile_ocr2vrf +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env bash - -# This script generates .abi and .bin files for a selected .sol contract. -# Example call: -# ./contracts/scripts/native_solc_compile dev/Operator.sol -# -# The resulting abi and bin files are stored in ./contracts/solc/v0.8 - -ROOT="$( - cd "$(dirname "$0")" >/dev/null 2>&1 - cd ../../ && pwd -P -)" - -solc-select use 0.8.19 -# Optionally set optimize runs from arguments (default = 1000) -OPTIMIZE_RUNS="${3}" - -solc-select use 0.8.19 -solc @openzeppelin/=$ROOT/contracts/node_modules/@openzeppelin/ --overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \ - -o $ROOT/contracts/solc/v0.8.19 \ - --abi --bin \ - --allow-paths $ROOT/contracts/src/v0.8,$ROOT/../$2/contracts,$ROOT/contracts/src/v0.8/dev,$ROOT/contracts/src/v0.8/interfaces,$ROOT/contracts/src/v0.8/mocks,$ROOT/contracts/src/v0.8/tests,$ROOT/contracts/src/v0.8/vendor,$ROOT/contracts/node_modules/.pnpm/@openzeppelin+contracts@4.3.3/node_modules/@openzeppelin/contracts,$ROOT/contracts/node_modules/.pnpm/@openzeppelin+contracts-upgradeable@4.7.3/node_modules/@openzeppelin/contracts-upgradeable \ - $ROOT/contracts/src/v0.8/$1 diff --git a/contracts/scripts/native_solc8_6_compile b/contracts/scripts/native_solc8_6_compile deleted file mode 100755 index bd60589e0e5..00000000000 --- a/contracts/scripts/native_solc8_6_compile +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash - -# This script generates .abi and .bin files for a selected .sol contract. -# Example call: -# ./contracts/scripts/native_solc_compile dev/Operator.sol -# -# The resulting abi and bin files are stored in ./contracts/solc/v0.8 - -ROOT="$( - cd "$(dirname "$0")" >/dev/null 2>&1 - cd ../../ && pwd -P -)" - -# Optionally set optimize runs from arguments (default = 1000000) -OPTIMIZE_RUNS="${2:-1000000}" - -solc-select use 0.8.6 -solc @openzeppelin/=$ROOT/contracts/node_modules/@openzeppelin/ --overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \ - -o $ROOT/contracts/solc/v0.8.6 \ - --abi --bin \ - --allow-paths $ROOT/contracts/src/v0.8,$ROOT/contracts/src/v0.8/dev,$ROOT/contracts/src/v0.8/interfaces,$ROOT/contracts/src/v0.8/mocks,$ROOT/contracts/src/v0.8/tests,$ROOT/contracts/src/v0.8/vendor,$ROOT/contracts/node_modules/.pnpm/@openzeppelin+contracts@4.3.3/node_modules/@openzeppelin/contracts,$ROOT/contracts/node_modules/.pnpm/@openzeppelin+contracts-upgradeable@4.7.3/node_modules/@openzeppelin/contracts-upgradeable,$ROOT/contracts/node_modules/.pnpm/@openzeppelin+contracts-upgradeable@4.8.1/node_modules/@openzeppelin/contracts-upgradeable \ - $ROOT/contracts/src/v0.8/$1 diff --git a/contracts/scripts/native_solc_compile_all b/contracts/scripts/native_solc_compile_all index d85b4b32150..e695c49206c 100755 --- a/contracts/scripts/native_solc_compile_all +++ b/contracts/scripts/native_solc_compile_all @@ -2,145 +2,17 @@ set -e +echo " ┌──────────────────────────────────────────────┐" +echo " │ Compiling *all* contracts... │" +echo " └──────────────────────────────────────────────┘" + SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" -echo $SCRIPTPATH python3 -m pip install --require-hashes -r $SCRIPTPATH/requirements.txt -solc-select install 0.6.6 -solc-select install 0.7.6 -solc-select install 0.8.6 -solc-select install 0.8.15 -solc-select install 0.8.16 -solc-select install 0.8.19 - -$SCRIPTPATH/native_solc6_compile Flags.sol -$SCRIPTPATH/native_solc6_compile Oracle.sol -$SCRIPTPATH/native_solc6_compile FluxAggregator.sol -$SCRIPTPATH/native_solc6_compile VRF.sol -$SCRIPTPATH/native_solc6_compile VRFCoordinator.sol -$SCRIPTPATH/native_solc6_compile tests/VRFRequestIDBaseTestHelper.sol -$SCRIPTPATH/native_solc6_compile tests/VRFTestHelper.sol -$SCRIPTPATH/native_solc6_compile Chainlink.sol -$SCRIPTPATH/native_solc6_compile VRFRequestIDBase.sol -$SCRIPTPATH/native_solc6_compile tests/VRFConsumer.sol -$SCRIPTPATH/native_solc6_compile ChainlinkClient.sol -$SCRIPTPATH/native_solc6_compile VRFConsumerBase.sol -$SCRIPTPATH/native_solc6_compile BlockhashStore.sol -$SCRIPTPATH/native_solc6_compile tests/TestAPIConsumer.sol -$SCRIPTPATH/native_solc6_compile tests/MockETHLINKAggregator.sol -$SCRIPTPATH/native_solc6_compile tests/MockGASAggregator.sol - -$SCRIPTPATH/native_solc7_compile tests/MultiWordConsumer.sol -$SCRIPTPATH/native_solc7_compile Operator.sol -$SCRIPTPATH/native_solc7_compile AuthorizedForwarder.sol -$SCRIPTPATH/native_solc7_compile AuthorizedReceiver.sol -$SCRIPTPATH/native_solc7_compile OperatorFactory.sol -$SCRIPTPATH/native_solc7_compile tests/Consumer.sol -$SCRIPTPATH/native_solc7_compile tests/VRFCoordinatorMock.sol - -# Keeper -$SCRIPTPATH/native_solc7_compile KeeperRegistry1_1.sol -$SCRIPTPATH/native_solc7_compile UpkeepRegistrationRequests.sol -$SCRIPTPATH/native_solc7_compile tests/UpkeepPerformCounterRestrictive.sol -$SCRIPTPATH/native_solc7_compile tests/UpkeepCounter.sol -$SCRIPTPATH/native_solc8_6_compile automation/upkeeps/CronUpkeepFactory.sol -$SCRIPTPATH/native_solc8_6_compile automation/1_2/KeeperRegistrar1_2.sol -$SCRIPTPATH/native_solc8_6_compile automation/1_2/KeeperRegistry1_2.sol -$SCRIPTPATH/native_solc8_6_compile automation/1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.sol -$SCRIPTPATH/native_solc8_6_compile automation/1_3/KeeperRegistry1_3.sol -$SCRIPTPATH/native_solc8_6_compile automation/1_3/KeeperRegistryLogic1_3.sol -$SCRIPTPATH/native_solc8_6_compile automation/2_0/KeeperRegistrar2_0.sol -$SCRIPTPATH/native_solc8_6_compile automation/2_0/KeeperRegistry2_0.sol -$SCRIPTPATH/native_solc8_6_compile automation/2_0/KeeperRegistryLogic2_0.sol -$SCRIPTPATH/native_solc8_16_compile dev/automation/2_1/KeeperRegistry2_1.sol -$SCRIPTPATH/native_solc8_16_compile dev/automation/2_1/KeeperRegistryLogicA2_1.sol -$SCRIPTPATH/native_solc8_16_compile dev/automation/2_1/KeeperRegistryLogicB2_1.sol -$SCRIPTPATH/native_solc8_16_compile dev/automation/2_1/interfaces/IKeeperRegistryMaster.sol -$SCRIPTPATH/native_solc8_16_compile dev/automation/2_1/interfaces/ILogAutomation.sol -$SCRIPTPATH/native_solc8_16_compile dev/automation/2_1/AutomationUtils2_1.sol -$SCRIPTPATH/native_solc8_6_compile dev/automation/tests/LogUpkeepCounter.sol -$SCRIPTPATH/native_solc8_16_compile dev/automation/tests/LogTriggeredFeedLookup.sol -$SCRIPTPATH/native_solc8_6_compile automation/UpkeepTranscoder.sol -$SCRIPTPATH/native_solc8_6_compile tests/VerifiableLoadUpkeep.sol -$SCRIPTPATH/native_solc8_6_compile tests/VerifiableLoadMercuryUpkeep.sol -$SCRIPTPATH/native_solc8_15_compile tests/MercuryUpkeep.sol -$SCRIPTPATH/native_solc8_15_compile dev/automation/2_1/interfaces/FeedLookupCompatibleInterface.sol -$SCRIPTPATH/native_solc8_16_compile tests/AutomationConsumerBenchmark.sol -$SCRIPTPATH/native_solc8_6_compile automation/mocks/MockAggregatorProxy.sol - -# Aggregators -$SCRIPTPATH/native_solc8_6_compile interfaces/AggregatorV2V3Interface.sol - -$SCRIPTPATH/native_solc8_6_compile Chainlink.sol -$SCRIPTPATH/native_solc8_6_compile ChainlinkClient.sol - -# VRF -$SCRIPTPATH/native_solc8_6_compile vrf/VRFRequestIDBase.sol -$SCRIPTPATH/native_solc8_6_compile vrf/VRFConsumerBase.sol -$SCRIPTPATH/native_solc8_6_compile vrf/testhelpers/VRFConsumer.sol -$SCRIPTPATH/native_solc8_6_compile vrf/testhelpers/VRFRequestIDBaseTestHelper.sol -$SCRIPTPATH/native_solc8_6_compile mocks/VRFCoordinatorMock.sol - -# VRF V2 -$SCRIPTPATH/native_solc8_6_compile vrf/VRFConsumerBaseV2.sol -$SCRIPTPATH/native_solc8_6_compile vrf/testhelpers/VRFConsumerV2.sol -$SCRIPTPATH/native_solc8_6_compile vrf/testhelpers/VRFMaliciousConsumerV2.sol -$SCRIPTPATH/native_solc8_6_compile vrf/testhelpers/VRFTestHelper.sol -$SCRIPTPATH/native_solc8_6_compile vrf/testhelpers/VRFV2RevertingExample.sol -$SCRIPTPATH/native_solc8_6_compile vrf/testhelpers/VRFV2ProxyAdmin.sol -$SCRIPTPATH/native_solc8_6_compile vrf/testhelpers/VRFV2TransparentUpgradeableProxy.sol -$SCRIPTPATH/native_solc8_6_compile vrf/testhelpers/VRFConsumerV2UpgradeableExample.sol -$SCRIPTPATH/native_solc8_6_compile vrf/BatchBlockhashStore.sol -$SCRIPTPATH/native_solc8_6_compile vrf/BatchVRFCoordinatorV2.sol -$SCRIPTPATH/native_solc8_6_compile vrf/testhelpers/VRFCoordinatorV2TestHelper.sol -$SCRIPTPATH/native_solc8_6_compile vrf/VRFCoordinatorV2.sol 10000 -$SCRIPTPATH/native_solc8_6_compile vrf/VRFOwner.sol - -# VRF V2Plus -$SCRIPTPATH/native_solc8_6_compile dev/vrf/testhelpers/VRFV2PlusConsumerExample.sol -$SCRIPTPATH/native_solc8_6_compile dev/vrf/VRFCoordinatorV2Plus.sol 1000 -$SCRIPTPATH/native_solc8_6_compile dev/vrf/BatchVRFCoordinatorV2Plus.sol -$SCRIPTPATH/native_solc8_6_compile dev/vrf/VRFV2PlusWrapper.sol -$SCRIPTPATH/native_solc8_6_compile dev/vrf/testhelpers/VRFConsumerV2PlusUpgradeableExample.sol -$SCRIPTPATH/native_solc8_6_compile dev/vrf/testhelpers/VRFMaliciousConsumerV2Plus.sol -$SCRIPTPATH/native_solc8_6_compile dev/vrf/testhelpers/VRFV2PlusExternalSubOwnerExample.sol -$SCRIPTPATH/native_solc8_6_compile dev/vrf/testhelpers/VRFV2PlusSingleConsumerExample.sol -$SCRIPTPATH/native_solc8_6_compile dev/vrf/testhelpers/VRFV2PlusWrapperConsumerExample.sol -$SCRIPTPATH/native_solc8_6_compile dev/vrf/testhelpers/VRFV2PlusRevertingExample.sol -$SCRIPTPATH/native_solc8_6_compile dev/vrf/testhelpers/VRFConsumerV2PlusUpgradeableExample.sol -$SCRIPTPATH/native_solc8_6_compile dev/vrf/libraries/VRFV2PlusClient.sol - -# VRF V2 Wrapper -$SCRIPTPATH/native_solc8_6_compile vrf/VRFV2Wrapper.sol -$SCRIPTPATH/native_solc8_6_compile interfaces/VRFV2WrapperInterface.sol -$SCRIPTPATH/native_solc8_6_compile vrf/VRFV2WrapperConsumerBase.sol -$SCRIPTPATH/native_solc8_6_compile vrf/testhelpers/VRFV2WrapperConsumerExample.sol - -# VRF Consumers and Mocks -$SCRIPTPATH/native_solc8_6_compile vrf/testhelpers/VRFExternalSubOwnerExample.sol -$SCRIPTPATH/native_solc8_6_compile vrf/testhelpers/VRFSingleConsumerExample.sol -$SCRIPTPATH/native_solc8_6_compile vrf/testhelpers/VRFOwnerlessConsumerExample.sol -$SCRIPTPATH/native_solc8_6_compile vrf/testhelpers/VRFLoadTestOwnerlessConsumer.sol -$SCRIPTPATH/native_solc8_6_compile vrf/testhelpers/VRFLoadTestExternalSubOwner.sol -$SCRIPTPATH/native_solc8_6_compile vrf/testhelpers/VRFV2LoadTestWithMetrics.sol - -# Keepers x VRF v2 -$SCRIPTPATH/native_solc8_6_compile KeepersVRFConsumer.sol - -# Feeds -$SCRIPTPATH/native_solc8_6_compile dev/DerivedPriceFeed.sol - -# Log tester -$SCRIPTPATH/native_solc8_6_compile tests/LogEmitter.sol - -# Chainlink Functions -$SCRIPTPATH/native_solc_compile_all_functions - -# llo-feeds -$SCRIPTPATH/native_solc_compile_all_llo - -# Mocks -$SCRIPTPATH/native_solc8_6_compile mocks/FunctionsOracleEventsMock.sol -$SCRIPTPATH/native_solc8_6_compile mocks/FunctionsBillingRegistryEventsMock.sol -# Transmission -$SCRIPTPATH/transmission/native_solc_compile_all_transmission +# 6 and 7 are legacy contracts, for each other product we have a native_solc_compile_all_$product script +# These scripts can be run individually, or all together with this script. +# To add new CL products, simply write a native_solc_compile_all_$product script and add it to the list below. +for product in 6 7 feeds functions llo-feeds transmission vrf automation logpoller events_mock shared +do + $SCRIPTPATH/native_solc_compile_all_$product +done diff --git a/contracts/scripts/native_solc_compile_all_6 b/contracts/scripts/native_solc_compile_all_6 new file mode 100755 index 00000000000..7f8f4fa6957 --- /dev/null +++ b/contracts/scripts/native_solc_compile_all_6 @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +set -e + +echo " ┌──────────────────────────────────────────────┐" +echo " │ Compiling legacy Solidity 0.6 contracts... │" +echo " └──────────────────────────────────────────────┘" + +SOLC_VERSION="0.6.6" +OPTIMIZE_RUNS=1000000 + + +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 () { + solc --overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \ + -o $ROOT/contracts/solc/v0.6 \ + --abi --bin --allow-paths $ROOT/contracts/src/v0.6 \ + $ROOT/contracts/src/v0.6/$1 +} + +compileContract Flags.sol +compileContract Oracle.sol +compileContract FluxAggregator.sol +compileContract VRF.sol +compileContract VRFCoordinator.sol +compileContract tests/VRFRequestIDBaseTestHelper.sol +compileContract tests/VRFTestHelper.sol +compileContract Chainlink.sol +compileContract VRFRequestIDBase.sol +compileContract tests/VRFConsumer.sol +compileContract ChainlinkClient.sol +compileContract VRFConsumerBase.sol +compileContract BlockhashStore.sol +compileContract tests/TestAPIConsumer.sol +compileContract tests/MockETHLINKAggregator.sol +compileContract tests/MockGASAggregator.sol \ No newline at end of file diff --git a/contracts/scripts/native_solc_compile_all_7 b/contracts/scripts/native_solc_compile_all_7 new file mode 100755 index 00000000000..b2d76b3cb5f --- /dev/null +++ b/contracts/scripts/native_solc_compile_all_7 @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +set -e + +echo " ┌──────────────────────────────────────────────┐" +echo " │ Compiling legacy Solidity 0.7 contracts... │" +echo " └──────────────────────────────────────────────┘" + +SOLC_VERSION="0.7.6" +OPTIMIZE_RUNS=1000000 + + +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 () { + solc --overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \ + -o $ROOT/contracts/solc/v0.7 \ + --abi --bin --allow-paths $ROOT/contracts/src/v0.7 \ + $ROOT/contracts/src/v0.7/$1 +} + +compileContract tests/MultiWordConsumer.sol +compileContract Operator.sol +compileContract AuthorizedForwarder.sol +compileContract AuthorizedReceiver.sol +compileContract OperatorFactory.sol +compileContract tests/Consumer.sol +compileContract tests/VRFCoordinatorMock.sol + +# Keeper/Automation +compileContract KeeperRegistry1_1.sol +compileContract KeeperRegistry1_1Mock.sol +compileContract UpkeepRegistrationRequests.sol +compileContract tests/UpkeepPerformCounterRestrictive.sol +compileContract tests/UpkeepCounter.sol \ No newline at end of file diff --git a/contracts/scripts/native_solc_compile_all_automation b/contracts/scripts/native_solc_compile_all_automation new file mode 100755 index 00000000000..b6de82b8892 --- /dev/null +++ b/contracts/scripts/native_solc_compile_all_automation @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +set -e + +echo " ┌──────────────────────────────────────────────┐" +echo " │ Compiling Automation contracts... │" +echo " └──────────────────────────────────────────────┘" + +SOLC_VERSION="0.8.6" +OPTIMIZE_RUNS=1000000 + + +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 () { + solc @openzeppelin/=$ROOT/contracts/node_modules/@openzeppelin/ --overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \ + -o $ROOT/contracts/solc/v$SOLC_VERSION \ + --abi --bin --allow-paths $ROOT/contracts/src/v0.8,$ROOT/contracts/node_modules\ + $ROOT/contracts/src/v0.8/$1 +} + +compileContract automation/upkeeps/CronUpkeepFactory.sol +compileContract automation/1_2/KeeperRegistrar1_2.sol +compileContract automation/1_2/KeeperRegistry1_2.sol +compileContract automation/1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.sol +compileContract automation/1_3/KeeperRegistry1_3.sol +compileContract automation/1_3/KeeperRegistryLogic1_3.sol +compileContract automation/2_0/KeeperRegistrar2_0.sol +compileContract automation/2_0/KeeperRegistry2_0.sol +compileContract automation/2_0/KeeperRegistryLogic2_0.sol +compileContract automation/UpkeepTranscoder.sol +compileContract automation/mocks/MockAggregatorProxy.sol +compileContract dev/automation/tests/LogUpkeepCounter.sol + +# Keepers x VRF v2 +compileContract KeepersVRFConsumer.sol + +compileContract automation/mocks/KeeperRegistrar1_2Mock.sol +compileContract automation/mocks/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.sol + +SOLC_VERSION="0.8.16" + +solc-select install $SOLC_VERSION +solc-select use $SOLC_VERSION +export SOLC_VERSION=$SOLC_VERSION + +# v0.8.16 +compileContract dev/automation/2_1/AutomationRegistrar2_1.sol +compileContract dev/automation/2_1/KeeperRegistry2_1.sol +compileContract dev/automation/2_1/KeeperRegistryLogicA2_1.sol +compileContract dev/automation/2_1/KeeperRegistryLogicB2_1.sol +compileContract dev/automation/2_1/interfaces/IKeeperRegistryMaster.sol +compileContract dev/automation/2_1/interfaces/ILogAutomation.sol +compileContract dev/automation/2_1/AutomationUtils2_1.sol +compileContract dev/automation/2_1/AutomationForwarderLogic.sol +compileContract dev/automation/tests/LogTriggeredFeedLookup.sol +compileContract dev/automation/tests/DummyProtocol.sol +compileContract dev/automation/2_1/interfaces/FeedLookupCompatibleInterface.sol + +compileContract tests/VerifiableLoadUpkeep.sol +compileContract tests/VerifiableLoadMercuryUpkeep.sol +compileContract tests/VerifiableLoadLogTriggerUpkeep.sol +compileContract tests/AutomationConsumerBenchmark.sol +compileContract tests/MercuryUpkeep.sol diff --git a/contracts/scripts/native_solc_compile_all_events_mock b/contracts/scripts/native_solc_compile_all_events_mock new file mode 100755 index 00000000000..993530e2fa1 --- /dev/null +++ b/contracts/scripts/native_solc_compile_all_events_mock @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +set -e + +echo " ┌──────────────────────────────────────────────┐" +echo " │ Compiling Events Mock contracts... │" +echo " └──────────────────────────────────────────────┘" + +SOLC_VERSION="0.8.6" +OPTIMIZE_RUNS=1000000 + + +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 () { + solc --overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \ + -o $ROOT/contracts/solc/v$SOLC_VERSION \ + --abi --bin --allow-paths $ROOT/contracts/src/v0.8\ + $ROOT/contracts/src/v0.8/$1 +} + +# This script is used to compile the contracts for the Events Mocks used in the tests. +compileContract mocks/FunctionsOracleEventsMock.sol +compileContract mocks/FunctionsBillingRegistryEventsMock.sol \ No newline at end of file diff --git a/contracts/scripts/native_solc_compile_all_feeds b/contracts/scripts/native_solc_compile_all_feeds new file mode 100755 index 00000000000..e37ca833ac6 --- /dev/null +++ b/contracts/scripts/native_solc_compile_all_feeds @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +set -e + +echo " ┌──────────────────────────────────────────────┐" +echo " │ Compiling Feeds contracts... │" +echo " └──────────────────────────────────────────────┘" + +SOLC_VERSION="0.8.6" +OPTIMIZE_RUNS=1000000 + + +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 () { + solc --overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \ + -o $ROOT/contracts/solc/v$SOLC_VERSION \ + --abi --bin --allow-paths $ROOT/contracts/src/v0.8\ + $ROOT/contracts/src/v0.8/$1 +} + +# Aggregators +compileContract interfaces/AggregatorV2V3Interface.sol +compileContract Chainlink.sol +compileContract ChainlinkClient.sol + +# Feeds +compileContract dev/DerivedPriceFeed.sol \ No newline at end of file diff --git a/contracts/scripts/native_solc_compile_all_functions b/contracts/scripts/native_solc_compile_all_functions index 10aa78bece7..904ad0563b3 100755 --- a/contracts/scripts/native_solc_compile_all_functions +++ b/contracts/scripts/native_solc_compile_all_functions @@ -2,40 +2,41 @@ set -e -# Optionally set optimize runs from arguments (default = 1000000) -OPTIMIZE_RUNS="${2:-1000000}" +echo " ┌──────────────────────────────────────────────┐" +echo " │ Compiling Functions contracts... │" +echo " └──────────────────────────────────────────────┘" + +SOLC_VERSION="0.8.6" +OPTIMIZE_RUNS=1000000 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 -ROOT="$( - cd "$(dirname "$0")" >/dev/null 2>&1 - cd ../../ && pwd -P -)" +solc-select install $SOLC_VERSION +solc-select use $SOLC_VERSION +export SOLC_VERSION=$SOLC_VERSION + compileContract () { - solc @openzeppelin/=$ROOT/contracts/node_modules/@openzeppelin/ --overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \ + solc --overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \ -o $ROOT/contracts/solc/v$SOLC_VERSION/functions/$1 \ --abi --bin \ - --allow-paths $ROOT/contracts/src/v0.8,$ROOT/contracts/src/v0.8/functions,$ROOT/contracts/node_modules/.pnpm/@openzeppelin+contracts-upgradeable@4.8.1/node_modules/@openzeppelin/contracts-upgradeable \ + --allow-paths $ROOT/contracts/src/v0.8,$ROOT/contracts/src/v0.8/functions \ $ROOT/contracts/src/v0.8/functions/$2 } ########################## # Version 0 (Testnet Beta) ########################## -## Set solidity version -SOLC_VERSION="0.8.6" -solc-select install $SOLC_VERSION -solc-select use $SOLC_VERSION -export SOLC_VERSION=$SOLC_VERSION -####################### + compileContract 0_0_0 dev/0_0_0/Functions.sol compileContract 0_0_0 dev/0_0_0/FunctionsBillingRegistry.sol compileContract 0_0_0 dev/0_0_0/FunctionsClient.sol compileContract 0_0_0 dev/0_0_0/FunctionsOracle.sol compileContract 0_0_0 dev/0_0_0/example/FunctionsClientExample.sol + # Test helpers compileContract 0_0_0 tests/0_0_0/testhelpers/FunctionsBillingRegistryWithInit.sol compileContract 0_0_0 tests/0_0_0/testhelpers/FunctionsOracleWithInit.sol @@ -43,16 +44,17 @@ compileContract 0_0_0 tests/0_0_0/testhelpers/FunctionsOracleWithInit.sol ############################ # Version 1 (Mainnet Preview) ############################ -## Set solidity version + SOLC_VERSION="0.8.19" solc-select install $SOLC_VERSION solc-select use $SOLC_VERSION export SOLC_VERSION=$SOLC_VERSION -####################### -compileContract 1_0_0 dev/1_0_0/Functions.sol + +compileContract 1_0_0 dev/1_0_0/libraries/FunctionsRequest.sol compileContract 1_0_0 dev/1_0_0/FunctionsRouter.sol compileContract 1_0_0 dev/1_0_0/FunctionsCoordinator.sol compileContract 1_0_0 dev/1_0_0/accessControl/TermsOfServiceAllowList.sol compileContract 1_0_0 dev/1_0_0/example/FunctionsClientExample.sol -# Test helpers -compileContract 1_0_0 tests/1_0_0/testhelpers/FunctionsCoordinatorTestHelper.sol \ No newline at end of file +## Test helpers +compileContract 1_0_0 tests/1_0_0/testhelpers/FunctionsCoordinatorTestHelper.sol +compileContract 1_0_0 tests/1_0_0/testhelpers/FunctionsLoadTestClient.sol \ No newline at end of file diff --git a/contracts/scripts/native_solc_compile_all_llo b/contracts/scripts/native_solc_compile_all_llo-feeds similarity index 64% rename from contracts/scripts/native_solc_compile_all_llo rename to contracts/scripts/native_solc_compile_all_llo-feeds index b454bcfcb77..7c09857451c 100755 --- a/contracts/scripts/native_solc_compile_all_llo +++ b/contracts/scripts/native_solc_compile_all_llo-feeds @@ -2,6 +2,10 @@ set -e +echo " ┌──────────────────────────────────────────────┐" +echo " │ Compiling Low Latency Oracle contracts... │" +echo " └──────────────────────────────────────────────┘" + SOLC_VERSION="0.8.16" OPTIMIZE_RUNS=15000 @@ -23,6 +27,8 @@ compileContract () { compileContract llo-feeds/Verifier.sol compileContract llo-feeds/VerifierProxy.sol +compileContract llo-feeds/dev/FeeManager.sol +compileContract llo-feeds/dev/RewardManager.sol #Test | Mocks compileContract llo-feeds/test/mocks/ErroredVerifier.sol diff --git a/contracts/scripts/native_solc_compile_all_logpoller b/contracts/scripts/native_solc_compile_all_logpoller new file mode 100755 index 00000000000..91a0606dba8 --- /dev/null +++ b/contracts/scripts/native_solc_compile_all_logpoller @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +set -e + +echo " ┌──────────────────────────────────────────────┐" +echo " │ Compiling LogPoller contracts... │" +echo " └──────────────────────────────────────────────┘" + +SOLC_VERSION="0.8.19" +OPTIMIZE_RUNS=1000000 + + +SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; 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 + +ROOT="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; cd ../../ && pwd -P )" + +compileContract () { + solc --overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \ + -o $ROOT/contracts/solc/v$SOLC_VERSION \ + --abi --bin --allow-paths $ROOT/contracts/src/v0.8\ + $ROOT/contracts/src/v0.8/$1 +} + + +compileContract tests/LogEmitter.sol \ No newline at end of file diff --git a/contracts/scripts/native_solc_compile_all_ocr2vrf b/contracts/scripts/native_solc_compile_all_ocr2vrf index 70576d40727..42478d7ebc2 100755 --- a/contracts/scripts/native_solc_compile_all_ocr2vrf +++ b/contracts/scripts/native_solc_compile_all_ocr2vrf @@ -2,17 +2,38 @@ 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 )" -echo $SCRIPTPATH +ROOT="$( cd "$(dirname "$0")" >/dev/null 2>&1; cd ../../ && pwd -P )" python3 -m pip install --require-hashes -r $SCRIPTPATH/requirements.txt -solc-select install 0.8.19 -## Change me. -FOLDER="ocr2vrf-origin" +solc-select install $SOLC_VERSION +solc-select use $SOLC_VERSION +export SOLC_VERSION=$SOLC_VERSION + + +compileContract () { + solc --overwrite --optimize --optimize-runs $2 --metadata-hash none \ + -o $ROOT/contracts/solc/v0.8.19 \ + --abi --bin \ + --allow-paths $ROOT/../$FOLDER/contracts \ + $ROOT/$1 +} # OCR2VRF -$SCRIPTPATH/native_solc8_19_compile_ocr2vrf ../../../../$FOLDER/contracts/DKG.sol $FOLDER 1000000 -$SCRIPTPATH/native_solc8_19_compile_ocr2vrf ../../../../$FOLDER/contracts/VRFBeacon.sol $FOLDER 1000000 -$SCRIPTPATH/native_solc8_19_compile_ocr2vrf ../../../../$FOLDER/contracts/VRFCoordinator.sol $FOLDER 1 -$SCRIPTPATH/native_solc8_19_compile_ocr2vrf ../../../../$FOLDER/contracts/test/TestBeaconVRFConsumer.sol $FOLDER 1000000 -$SCRIPTPATH/native_solc8_19_compile_ocr2vrf ../../../../$FOLDER/contracts/test/LoadTestBeaconVRFConsumer.sol $FOLDER 1000000 +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/scripts/native_solc_compile_all_shared b/contracts/scripts/native_solc_compile_all_shared new file mode 100755 index 00000000000..e7199f81feb --- /dev/null +++ b/contracts/scripts/native_solc_compile_all_shared @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +set -e + +echo " ┌──────────────────────────────────────────────┐" +echo " │ Compiling shared contracts... │" +echo " └──────────────────────────────────────────────┘" + +SOLC_VERSION="0.8.19" +OPTIMIZE_RUNS=1000000 + + +SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; 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 + +ROOT="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; cd ../../ && pwd -P )" + +compileContract () { + solc --overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \ + -o $ROOT/contracts/solc/v$SOLC_VERSION \ + --abi --bin --allow-paths $ROOT/contracts/src/v0.8\ + $ROOT/contracts/src/v0.8/$1 +} + +compileContract shared/token/ERC677/BurnMintERC677.sol +compileContract shared/token/ERC677/LinkToken.sol +compileContract vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/ERC20.sol diff --git a/contracts/scripts/native_solc_compile_all_transmission b/contracts/scripts/native_solc_compile_all_transmission new file mode 100755 index 00000000000..6537757f429 --- /dev/null +++ b/contracts/scripts/native_solc_compile_all_transmission @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +set -e + +echo " ┌──────────────────────────────────────────────┐" +echo " │ Compiling Transmission contracts... │" +echo " └──────────────────────────────────────────────┘" + +SOLC_VERSION="0.8.15" +OPTIMIZE_RUNS=1000000 + +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 () { + solc --overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \ + -o $ROOT/contracts/solc/v$SOLC_VERSION \ + --abi --bin --allow-paths $ROOT/contracts/src/v0.8\ + $ROOT/contracts/src/v0.8/$1 +} + +# Contracts +compileContract dev/transmission/4337/SCA.sol +compileContract dev/transmission/4337/Paymaster.sol +compileContract dev/transmission/4337/SmartContractAccountFactory.sol + +# Testhelpers +compileContract dev/transmission/testhelpers/SmartContractAccountHelper.sol +compileContract dev/transmission/testhelpers/Greeter.sol + +# Vendor +compileContract vendor/entrypoint/core/EntryPoint.sol diff --git a/contracts/scripts/native_solc_compile_all_vrf b/contracts/scripts/native_solc_compile_all_vrf new file mode 100755 index 00000000000..8b35ac45748 --- /dev/null +++ b/contracts/scripts/native_solc_compile_all_vrf @@ -0,0 +1,85 @@ +#!/usr/bin/env bash + +set -e + +echo " ┌──────────────────────────────────────────────┐" +echo " │ Compiling VRF contracts... │" +echo " └──────────────────────────────────────────────┘" + +SOLC_VERSION="0.8.6" +OPTIMIZE_RUNS=1000000 + +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 () { + solc @openzeppelin/=$ROOT/contracts/node_modules/@openzeppelin/ --overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \ + -o $ROOT/contracts/solc/v$SOLC_VERSION \ + --abi --bin --allow-paths $ROOT/contracts/src/v0.8,$ROOT/contracts/node_modules\ + $ROOT/contracts/src/v0.8/$1 +} + +compileContractAltOpts () { + solc @openzeppelin/=$ROOT/contracts/node_modules/@openzeppelin/ --overwrite --optimize --optimize-runs $2 --metadata-hash none \ + -o $ROOT/contracts/solc/v$SOLC_VERSION \ + --abi --bin --allow-paths $ROOT/contracts/src/v0.8,$ROOT/contracts/node_modules\ + $ROOT/contracts/src/v0.8/$1 +} + +# VRF +compileContract vrf/VRFRequestIDBase.sol +compileContract vrf/VRFConsumerBase.sol +compileContract vrf/testhelpers/VRFConsumer.sol +compileContract vrf/testhelpers/VRFRequestIDBaseTestHelper.sol +compileContract mocks/VRFCoordinatorMock.sol + +# VRF V2 +compileContract vrf/VRFConsumerBaseV2.sol +compileContract vrf/testhelpers/VRFConsumerV2.sol +compileContract vrf/testhelpers/VRFMaliciousConsumerV2.sol +compileContract vrf/testhelpers/VRFTestHelper.sol +compileContract vrf/testhelpers/VRFV2RevertingExample.sol +compileContract vrf/testhelpers/VRFV2ProxyAdmin.sol +compileContract vrf/testhelpers/VRFV2TransparentUpgradeableProxy.sol +compileContract vrf/testhelpers/VRFConsumerV2UpgradeableExample.sol +compileContract vrf/BatchBlockhashStore.sol +compileContract vrf/BatchVRFCoordinatorV2.sol +compileContract vrf/testhelpers/VRFCoordinatorV2TestHelper.sol +compileContractAltOpts vrf/VRFCoordinatorV2.sol 10000 +compileContract vrf/VRFOwner.sol + +# VRF V2Plus +compileContract dev/vrf/testhelpers/VRFV2PlusConsumerExample.sol +compileContractAltOpts dev/vrf/VRFCoordinatorV2Plus.sol 500 +compileContract dev/vrf/BatchVRFCoordinatorV2Plus.sol +compileContract dev/vrf/VRFV2PlusWrapper.sol +compileContract dev/vrf/testhelpers/VRFConsumerV2PlusUpgradeableExample.sol +compileContract dev/vrf/testhelpers/VRFMaliciousConsumerV2Plus.sol +compileContract dev/vrf/testhelpers/VRFV2PlusExternalSubOwnerExample.sol +compileContract dev/vrf/testhelpers/VRFV2PlusSingleConsumerExample.sol +compileContract dev/vrf/testhelpers/VRFV2PlusWrapperConsumerExample.sol +compileContract dev/vrf/testhelpers/VRFV2PlusRevertingExample.sol +compileContract dev/vrf/testhelpers/VRFConsumerV2PlusUpgradeableExample.sol +compileContract dev/vrf/libraries/VRFV2PlusClient.sol +compileContract dev/vrf/testhelpers/VRFCoordinatorV2Plus_V2Example.sol +compileContract dev/vrf/TrustedBlockhashStore.sol + +# VRF V2 Wrapper +compileContract vrf/VRFV2Wrapper.sol +compileContract interfaces/VRFV2WrapperInterface.sol +compileContract vrf/VRFV2WrapperConsumerBase.sol +compileContract vrf/testhelpers/VRFV2WrapperConsumerExample.sol + +# VRF Consumers and Mocks +compileContract vrf/testhelpers/VRFExternalSubOwnerExample.sol +compileContract vrf/testhelpers/VRFSingleConsumerExample.sol +compileContract vrf/testhelpers/VRFOwnerlessConsumerExample.sol +compileContract vrf/testhelpers/VRFLoadTestOwnerlessConsumer.sol +compileContract vrf/testhelpers/VRFLoadTestExternalSubOwner.sol +compileContract vrf/testhelpers/VRFV2LoadTestWithMetrics.sol +compileContract vrf/testhelpers/VRFV2OwnerTestConsumer.sol diff --git a/contracts/scripts/native_solc_compile_events_mock b/contracts/scripts/native_solc_compile_events_mock deleted file mode 100755 index 381e4068d57..00000000000 --- a/contracts/scripts/native_solc_compile_events_mock +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -set -e - -SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" -echo $SCRIPTPATH -python3 -m pip install --require-hashes -r $SCRIPTPATH/requirements.txt -solc-select install 0.8.6 - -# Mocks -$SCRIPTPATH/native_solc8_6_compile mocks/FunctionsOracleEventsMock.sol -$SCRIPTPATH/native_solc8_6_compile mocks/FunctionsBillingRegistryEventsMock.sol \ No newline at end of file diff --git a/contracts/scripts/requirements.txt b/contracts/scripts/requirements.txt index 38d247c9775..50cda389b7b 100644 --- a/contracts/scripts/requirements.txt +++ b/contracts/scripts/requirements.txt @@ -1 +1,3 @@ -solc-select==0.2.0 --hash=sha256:faa2fb5d43b77b6dc48ce73cb863b27631c477d0a350403294ff186c51bd744e +solc-select==1.0.4 --hash=sha256:db7b9de009af6de3a5416b80bbe5b6d636bf314703c016319b8c1231e248a6c7 +pycryptodome==3.18.0 --hash=sha256:c9adee653fc882d98956e33ca2c1fb582e23a8af7ac82fee75bd6113c55a0413 +packaging==23.1 --hash=sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f \ No newline at end of file diff --git a/contracts/scripts/transmission/native_solc_compile_all_transmission b/contracts/scripts/transmission/native_solc_compile_all_transmission deleted file mode 100755 index 833d86bce9b..00000000000 --- a/contracts/scripts/transmission/native_solc_compile_all_transmission +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash - -set -e - -SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; cd ..; pwd -P )" -echo $SCRIPTPATH -python3 -m pip install --require-hashes -r $SCRIPTPATH/requirements.txt -solc-select install 0.8.15 - -# Contracts -$SCRIPTPATH/native_solc8_15_compile dev/transmission/4337/SCA.sol -$SCRIPTPATH/native_solc8_15_compile dev/transmission/4337/Paymaster.sol -$SCRIPTPATH/native_solc8_15_compile dev/transmission/4337/SmartContractAccountFactory.sol - -# Testhelpers -$SCRIPTPATH/native_solc8_15_compile dev/transmission/testhelpers/SmartContractAccountHelper.sol -$SCRIPTPATH/native_solc8_15_compile dev/transmission/testhelpers/Greeter.sol - -# Vendor -$SCRIPTPATH/native_solc8_15_compile dev/vendor/entrypoint/core/EntryPoint.sol diff --git a/contracts/src/v0.7/KeeperRegistry1_1Mock.sol b/contracts/src/v0.7/KeeperRegistry1_1Mock.sol new file mode 100644 index 00000000000..3acbfb5e7af --- /dev/null +++ b/contracts/src/v0.7/KeeperRegistry1_1Mock.sol @@ -0,0 +1,351 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; + +contract KeeperRegistry1_1Mock { + event ConfigSet( + uint32 paymentPremiumPPB, + uint24 blockCountPerTurn, + uint32 checkGasLimit, + uint24 stalenessSeconds, + uint16 gasCeilingMultiplier, + uint256 fallbackGasPrice, + uint256 fallbackLinkPrice + ); + event FlatFeeSet(uint32 flatFeeMicroLink); + event FundsAdded(uint256 indexed id, address indexed from, uint96 amount); + event FundsWithdrawn(uint256 indexed id, uint256 amount, address to); + event KeepersUpdated(address[] keepers, address[] payees); + event OwnershipTransferRequested(address indexed from, address indexed to); + event OwnershipTransferred(address indexed from, address indexed to); + event Paused(address account); + event PayeeshipTransferRequested(address indexed keeper, address indexed from, address indexed to); + event PayeeshipTransferred(address indexed keeper, address indexed from, address indexed to); + event PaymentWithdrawn(address indexed keeper, uint256 indexed amount, address indexed to, address payee); + event RegistrarChanged(address indexed from, address indexed to); + event Unpaused(address account); + event UpkeepCanceled(uint256 indexed id, uint64 indexed atBlockHeight); + event UpkeepPerformed( + uint256 indexed id, + bool indexed success, + address indexed from, + uint96 payment, + bytes performData + ); + event UpkeepRegistered(uint256 indexed id, uint32 executeGas, address admin); + + function emitConfigSet( + uint32 paymentPremiumPPB, + uint24 blockCountPerTurn, + uint32 checkGasLimit, + uint24 stalenessSeconds, + uint16 gasCeilingMultiplier, + uint256 fallbackGasPrice, + uint256 fallbackLinkPrice + ) public { + emit ConfigSet( + paymentPremiumPPB, + blockCountPerTurn, + checkGasLimit, + stalenessSeconds, + gasCeilingMultiplier, + fallbackGasPrice, + fallbackLinkPrice + ); + } + + function emitFlatFeeSet(uint32 flatFeeMicroLink) public { + emit FlatFeeSet(flatFeeMicroLink); + } + + function emitFundsAdded(uint256 id, address from, uint96 amount) public { + emit FundsAdded(id, from, amount); + } + + function emitFundsWithdrawn(uint256 id, uint256 amount, address to) public { + emit FundsWithdrawn(id, amount, to); + } + + function emitKeepersUpdated(address[] memory keepers, address[] memory payees) public { + emit KeepersUpdated(keepers, payees); + } + + function emitOwnershipTransferRequested(address from, address to) public { + emit OwnershipTransferRequested(from, to); + } + + function emitOwnershipTransferred(address from, address to) public { + emit OwnershipTransferred(from, to); + } + + function emitPaused(address account) public { + emit Paused(account); + } + + function emitPayeeshipTransferRequested(address keeper, address from, address to) public { + emit PayeeshipTransferRequested(keeper, from, to); + } + + function emitPayeeshipTransferred(address keeper, address from, address to) public { + emit PayeeshipTransferred(keeper, from, to); + } + + function emitPaymentWithdrawn(address keeper, uint256 amount, address to, address payee) public { + emit PaymentWithdrawn(keeper, amount, to, payee); + } + + function emitRegistrarChanged(address from, address to) public { + emit RegistrarChanged(from, to); + } + + function emitUnpaused(address account) public { + emit Unpaused(account); + } + + function emitUpkeepCanceled(uint256 id, uint64 atBlockHeight) public { + emit UpkeepCanceled(id, atBlockHeight); + } + + function emitUpkeepPerformed( + uint256 id, + bool success, + address from, + uint96 payment, + bytes memory performData + ) public { + emit UpkeepPerformed(id, success, from, payment, performData); + } + + function emitUpkeepRegistered(uint256 id, uint32 executeGas, address admin) public { + emit UpkeepRegistered(id, executeGas, admin); + } + + uint256 private s_upkeepCount; + + // Function to set the current number of registered upkeeps + function setUpkeepCount(uint256 _upkeepCount) external { + s_upkeepCount = _upkeepCount; + } + + // Function to get the current number of registered upkeeps + function getUpkeepCount() external view returns (uint256) { + return s_upkeepCount; + } + + uint256[] private s_canceledUpkeepList; + + // Function to set the current number of canceled upkeeps + function setCanceledUpkeepList(uint256[] memory _canceledUpkeepList) external { + s_canceledUpkeepList = _canceledUpkeepList; + } + + // Function to set the current number of canceled upkeeps + function getCanceledUpkeepList() external view returns (uint256[] memory) { + return s_canceledUpkeepList; + } + + address[] private s_keeperList; + + // Function to set the keeper list for testing purposes + function setKeeperList(address[] memory _keepers) external { + s_keeperList = _keepers; + } + + // Function to get the keeper list + function getKeeperList() external view returns (address[] memory) { + return s_keeperList; + } + + struct Config { + uint32 paymentPremiumPPB; + uint32 flatFeeMicroLink; // min 0.000001 LINK, max 4294 LINK + uint24 blockCountPerTurn; + uint32 checkGasLimit; + uint24 stalenessSeconds; + uint16 gasCeilingMultiplier; + } + + Config private s_config; + uint256 private s_fallbackGasPrice; + uint256 private s_fallbackLinkPrice; + + // Function to set the configuration for testing purposes + function setConfig( + uint32 _paymentPremiumPPB, + uint32 _flatFeeMicroLink, + uint24 _blockCountPerTurn, + uint32 _checkGasLimit, + uint24 _stalenessSeconds, + uint16 _gasCeilingMultiplier, + uint256 _fallbackGasPrice, + uint256 _fallbackLinkPrice + ) external { + s_config.paymentPremiumPPB = _paymentPremiumPPB; + s_config.flatFeeMicroLink = _flatFeeMicroLink; + s_config.blockCountPerTurn = _blockCountPerTurn; + s_config.checkGasLimit = _checkGasLimit; + s_config.stalenessSeconds = _stalenessSeconds; + s_config.gasCeilingMultiplier = _gasCeilingMultiplier; + s_fallbackGasPrice = _fallbackGasPrice; + s_fallbackLinkPrice = _fallbackLinkPrice; + } + + // Function to get the configuration + function getConfig() + external + view + returns ( + uint32 paymentPremiumPPB, + uint24 blockCountPerTurn, + uint32 checkGasLimit, + uint24 stalenessSeconds, + uint16 gasCeilingMultiplier, + uint256 fallbackGasPrice, + uint256 fallbackLinkPrice + ) + { + return ( + s_config.paymentPremiumPPB, + s_config.blockCountPerTurn, + s_config.checkGasLimit, + s_config.stalenessSeconds, + s_config.gasCeilingMultiplier, + s_fallbackGasPrice, + s_fallbackLinkPrice + ); + } + + struct Upkeep { + address target; + uint32 executeGas; + uint96 balance; + address admin; + uint64 maxValidBlocknumber; + address lastKeeper; + } + + mapping(uint256 => Upkeep) private s_upkeep; + mapping(uint256 => bytes) private s_checkData; + + // Function to set the upkeep and checkData for testing purposes + function setUpkeep( + uint256 id, + address _target, + uint32 _executeGas, + uint96 _balance, + address _admin, + uint64 _maxValidBlocknumber, + address _lastKeeper, + bytes memory _checkData + ) external { + Upkeep memory upkeep = Upkeep({ + target: _target, + executeGas: _executeGas, + balance: _balance, + admin: _admin, + maxValidBlocknumber: _maxValidBlocknumber, + lastKeeper: _lastKeeper + }); + + s_upkeep[id] = upkeep; + s_checkData[id] = _checkData; + } + + // Function to get the upkeep and checkData + function getUpkeep( + uint256 id + ) + external + view + returns ( + address target, + uint32 executeGas, + bytes memory checkData, + uint96 balance, + address lastKeeper, + address admin, + uint64 maxValidBlocknumber + ) + { + Upkeep memory reg = s_upkeep[id]; + return ( + reg.target, + reg.executeGas, + s_checkData[id], + reg.balance, + reg.lastKeeper, + reg.admin, + reg.maxValidBlocknumber + ); + } + + mapping(uint256 => uint96) private s_minBalances; + + // Function to set the minimum balance for a specific upkeep id + function setMinBalance(uint256 id, uint96 minBalance) external { + s_minBalances[id] = minBalance; + } + + // Function to get the minimum balance for a specific upkeep id + function getMinBalanceForUpkeep(uint256 id) external view returns (uint96) { + return s_minBalances[id]; + } + + struct UpkeepData { + bytes performData; + uint256 maxLinkPayment; + uint256 gasLimit; + uint256 adjustedGasWei; + uint256 linkEth; + } + + mapping(uint256 => UpkeepData) private s_upkeepData; + + // Function to set mock data for the checkUpkeep function + function setCheckUpkeepData( + uint256 id, + bytes memory performData, + uint256 maxLinkPayment, + uint256 gasLimit, + uint256 adjustedGasWei, + uint256 linkEth + ) external { + s_upkeepData[id] = UpkeepData({ + performData: performData, + maxLinkPayment: maxLinkPayment, + gasLimit: gasLimit, + adjustedGasWei: adjustedGasWei, + linkEth: linkEth + }); + } + + // Mock checkUpkeep function + function checkUpkeep( + uint256 id, + address from + ) + external + view + returns ( + bytes memory performData, + uint256 maxLinkPayment, + uint256 gasLimit, + uint256 adjustedGasWei, + uint256 linkEth + ) + { + UpkeepData storage data = s_upkeepData[id]; + return (data.performData, data.maxLinkPayment, data.gasLimit, data.adjustedGasWei, data.linkEth); + } + + mapping(uint256 => bool) private s_upkeepSuccess; + + // Function to set mock return data for the performUpkeep function + function setPerformUpkeepSuccess(uint256 id, bool success) external { + s_upkeepSuccess[id] = success; + } + + // Mock performUpkeep function + function performUpkeep(uint256 id, bytes calldata performData) external returns (bool success) { + return s_upkeepSuccess[id]; + } +} diff --git a/contracts/src/v0.8/ChainlinkClient.sol b/contracts/src/v0.8/ChainlinkClient.sol index 00231ca5e97..fda69143f45 100644 --- a/contracts/src/v0.8/ChainlinkClient.sol +++ b/contracts/src/v0.8/ChainlinkClient.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import "./Chainlink.sol"; import "./interfaces/ENSInterface.sol"; -import "./interfaces/LinkTokenInterface.sol"; +import "./shared/interfaces/LinkTokenInterface.sol"; import "./interfaces/ChainlinkRequestInterface.sol"; import "./interfaces/OperatorInterface.sol"; import "./interfaces/PointerInterface.sol"; diff --git a/contracts/src/v0.8/PermissionedForwardProxy.sol b/contracts/src/v0.8/PermissionedForwardProxy.sol index 9e3cf736636..6206bd5420c 100644 --- a/contracts/src/v0.8/PermissionedForwardProxy.sol +++ b/contracts/src/v0.8/PermissionedForwardProxy.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.6; import "@openzeppelin/contracts/utils/Address.sol"; -import "./ConfirmedOwner.sol"; +import "./shared/access/ConfirmedOwner.sol"; /** * @title PermissionedForwardProxy diff --git a/contracts/src/v0.8/SimpleWriteAccessController.sol b/contracts/src/v0.8/SimpleWriteAccessController.sol index 7c770bca3b2..75459173989 100644 --- a/contracts/src/v0.8/SimpleWriteAccessController.sol +++ b/contracts/src/v0.8/SimpleWriteAccessController.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "./ConfirmedOwner.sol"; +import "./shared/access/ConfirmedOwner.sol"; import "./interfaces/AccessControllerInterface.sol"; /** diff --git a/contracts/src/v0.8/ValidatorProxy.sol b/contracts/src/v0.8/ValidatorProxy.sol index ac83a162f05..ea81719270b 100644 --- a/contracts/src/v0.8/ValidatorProxy.sol +++ b/contracts/src/v0.8/ValidatorProxy.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "./ConfirmedOwner.sol"; +import "./shared/access/ConfirmedOwner.sol"; import "./interfaces/AggregatorValidatorInterface.sol"; import "./interfaces/TypeAndVersionInterface.sol"; diff --git a/contracts/src/v0.8/automation/1_2/KeeperRegistrar1_2.sol b/contracts/src/v0.8/automation/1_2/KeeperRegistrar1_2.sol index dd9f9206d0b..e3e10de131d 100644 --- a/contracts/src/v0.8/automation/1_2/KeeperRegistrar1_2.sol +++ b/contracts/src/v0.8/automation/1_2/KeeperRegistrar1_2.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.6; -import "../../interfaces/LinkTokenInterface.sol"; -import "../../interfaces/automation/1_2/KeeperRegistryInterface1_2.sol"; +import "../interfaces/1_2/KeeperRegistryInterface1_2.sol"; import "../../interfaces/TypeAndVersionInterface.sol"; -import "../../ConfirmedOwner.sol"; -import "../../interfaces/ERC677ReceiverInterface.sol"; +import "../../shared/interfaces/LinkTokenInterface.sol"; +import "../../shared/access/ConfirmedOwner.sol"; +import "../../shared/interfaces/IERC677Receiver.sol"; /** * @notice Contract to accept requests for upkeep registrations @@ -17,7 +17,7 @@ import "../../interfaces/ERC677ReceiverInterface.sol"; * The idea is to have same interface(functions,events) for UI or anyone using this contract irrespective of auto approve being enabled or not. * they can just listen to `RegistrationRequested` & `RegistrationApproved` events and know the status on registrations. */ -contract KeeperRegistrar is TypeAndVersionInterface, ConfirmedOwner, ERC677ReceiverInterface { +contract KeeperRegistrar is TypeAndVersionInterface, ConfirmedOwner, IERC677Receiver { /** * 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. diff --git a/contracts/src/v0.8/automation/1_2/KeeperRegistry1_2.sol b/contracts/src/v0.8/automation/1_2/KeeperRegistry1_2.sol index ed86ffcc159..70bd176f82e 100644 --- a/contracts/src/v0.8/automation/1_2/KeeperRegistry1_2.sol +++ b/contracts/src/v0.8/automation/1_2/KeeperRegistry1_2.sol @@ -6,15 +6,15 @@ import "@openzeppelin/contracts/utils/Address.sol"; import "@openzeppelin/contracts/security/Pausable.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "../KeeperBase.sol"; -import "../../ConfirmedOwner.sol"; import "../../interfaces/TypeAndVersionInterface.sol"; import "../../interfaces/AggregatorV3Interface.sol"; -import "../../interfaces/LinkTokenInterface.sol"; -import "../../interfaces/automation/KeeperCompatibleInterface.sol"; -import "../../interfaces/automation/1_2/KeeperRegistryInterface1_2.sol"; -import "../../interfaces/automation/MigratableKeeperRegistryInterface.sol"; -import "../../interfaces/automation/UpkeepTranscoderInterface.sol"; -import "../../interfaces/ERC677ReceiverInterface.sol"; +import "../interfaces/KeeperCompatibleInterface.sol"; +import "../interfaces/1_2/KeeperRegistryInterface1_2.sol"; +import "../interfaces/MigratableKeeperRegistryInterface.sol"; +import "../interfaces/UpkeepTranscoderInterface.sol"; +import "../../shared/interfaces/IERC677Receiver.sol"; +import "../../shared/interfaces/LinkTokenInterface.sol"; +import "../../shared/access/ConfirmedOwner.sol"; struct Upkeep { uint96 balance; @@ -38,7 +38,7 @@ contract KeeperRegistry1_2 is Pausable, KeeperRegistryExecutableInterface, MigratableKeeperRegistryInterface, - ERC677ReceiverInterface + IERC677Receiver { using Address for address; using EnumerableSet for EnumerableSet.UintSet; diff --git a/contracts/src/v0.8/automation/1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.sol b/contracts/src/v0.8/automation/1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.sol index a2f84d3e063..dd6c83565bb 100644 --- a/contracts/src/v0.8/automation/1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.sol +++ b/contracts/src/v0.8/automation/1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.6; -import {AutomationRegistryExecutableInterface} from "../../interfaces/automation/1_2/AutomationRegistryInterface1_2.sol"; -import {ConfirmedOwner} from "../../ConfirmedOwner.sol"; +import {AutomationRegistryExecutableInterface} from "../interfaces/1_2/AutomationRegistryInterface1_2.sol"; +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; /** * @notice This contract serves as a wrapper around a keeper registry's checkUpkeep function. diff --git a/contracts/src/v0.8/automation/1_3/KeeperRegistry1_3.sol b/contracts/src/v0.8/automation/1_3/KeeperRegistry1_3.sol index e97ad4adcb4..7f75ae87af2 100644 --- a/contracts/src/v0.8/automation/1_3/KeeperRegistry1_3.sol +++ b/contracts/src/v0.8/automation/1_3/KeeperRegistry1_3.sol @@ -6,10 +6,10 @@ import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "./KeeperRegistryBase1_3.sol"; import "./KeeperRegistryLogic1_3.sol"; -import {AutomationRegistryExecutableInterface} from "../../interfaces/automation/1_3/AutomationRegistryInterface1_3.sol"; -import "../../interfaces/automation/MigratableKeeperRegistryInterface.sol"; +import {AutomationRegistryExecutableInterface} from "../interfaces/1_3/AutomationRegistryInterface1_3.sol"; +import "../interfaces/MigratableKeeperRegistryInterface.sol"; import "../../interfaces/TypeAndVersionInterface.sol"; -import "../../interfaces/ERC677ReceiverInterface.sol"; +import "../../shared/interfaces/IERC677Receiver.sol"; /** * @notice Registry for adding work for Chainlink Keepers to perform on client @@ -21,7 +21,7 @@ contract KeeperRegistry1_3 is TypeAndVersionInterface, AutomationRegistryExecutableInterface, MigratableKeeperRegistryInterface, - ERC677ReceiverInterface + IERC677Receiver { using Address for address; using EnumerableSet for EnumerableSet.UintSet; diff --git a/contracts/src/v0.8/automation/1_3/KeeperRegistryBase1_3.sol b/contracts/src/v0.8/automation/1_3/KeeperRegistryBase1_3.sol index f3ba3ea24be..2f5156ee081 100644 --- a/contracts/src/v0.8/automation/1_3/KeeperRegistryBase1_3.sol +++ b/contracts/src/v0.8/automation/1_3/KeeperRegistryBase1_3.sol @@ -6,12 +6,12 @@ import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import "../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol"; import "../../vendor/@eth-optimism/contracts/0.8.6/contracts/L2/predeploys/OVM_GasPriceOracle.sol"; import "../ExecutionPrevention.sol"; -import {Config, State, Upkeep} from "../../interfaces/automation/1_3/AutomationRegistryInterface1_3.sol"; -import "../../ConfirmedOwner.sol"; +import {Config, State, Upkeep} from "../interfaces/1_3/AutomationRegistryInterface1_3.sol"; +import "../../shared/access/ConfirmedOwner.sol"; import "../../interfaces/AggregatorV3Interface.sol"; -import "../../interfaces/LinkTokenInterface.sol"; -import "../../interfaces/automation/KeeperCompatibleInterface.sol"; -import "../../interfaces/automation/UpkeepTranscoderInterface.sol"; +import "../../shared/interfaces/LinkTokenInterface.sol"; +import "../interfaces/KeeperCompatibleInterface.sol"; +import "../interfaces/UpkeepTranscoderInterface.sol"; /** * @notice Base Keeper Registry contract, contains shared logic between diff --git a/contracts/src/v0.8/automation/1_3/KeeperRegistryLogic1_3.sol b/contracts/src/v0.8/automation/1_3/KeeperRegistryLogic1_3.sol index 2a9cd08302a..fd7c3afdc1c 100644 --- a/contracts/src/v0.8/automation/1_3/KeeperRegistryLogic1_3.sol +++ b/contracts/src/v0.8/automation/1_3/KeeperRegistryLogic1_3.sol @@ -4,8 +4,8 @@ pragma solidity 0.8.6; import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "./KeeperRegistryBase1_3.sol"; -import "../../interfaces/automation/MigratableKeeperRegistryInterface.sol"; -import "../../interfaces/automation/UpkeepTranscoderInterface.sol"; +import "../interfaces/MigratableKeeperRegistryInterface.sol"; +import "../interfaces/UpkeepTranscoderInterface.sol"; /** * @notice Logic contract, works in tandem with KeeperRegistry as a proxy diff --git a/contracts/src/v0.8/automation/2_0/KeeperRegistrar2_0.sol b/contracts/src/v0.8/automation/2_0/KeeperRegistrar2_0.sol index 0b449184ac5..15cba57e7bb 100644 --- a/contracts/src/v0.8/automation/2_0/KeeperRegistrar2_0.sol +++ b/contracts/src/v0.8/automation/2_0/KeeperRegistrar2_0.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.6; -import "../../interfaces/LinkTokenInterface.sol"; -import "../../interfaces/automation/2_0/AutomationRegistryInterface2_0.sol"; +import "../../shared/interfaces/LinkTokenInterface.sol"; +import "../interfaces/2_0/AutomationRegistryInterface2_0.sol"; import "../../interfaces/TypeAndVersionInterface.sol"; -import "../../ConfirmedOwner.sol"; -import "../../interfaces/ERC677ReceiverInterface.sol"; +import "../../shared/access/ConfirmedOwner.sol"; +import "../../shared/interfaces/IERC677Receiver.sol"; /** * @notice Contract to accept requests for upkeep registrations @@ -17,7 +17,7 @@ import "../../interfaces/ERC677ReceiverInterface.sol"; * The idea is to have same interface(functions,events) for UI or anyone using this contract irrespective of auto approve being enabled or not. * they can just listen to `RegistrationRequested` & `RegistrationApproved` events and know the status on registrations. */ -contract KeeperRegistrar2_0 is TypeAndVersionInterface, ConfirmedOwner, ERC677ReceiverInterface { +contract KeeperRegistrar2_0 is TypeAndVersionInterface, ConfirmedOwner, IERC677Receiver { /** * 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. diff --git a/contracts/src/v0.8/automation/2_0/KeeperRegistry2_0.sol b/contracts/src/v0.8/automation/2_0/KeeperRegistry2_0.sol index 477e19b9b3c..bc928bd4292 100644 --- a/contracts/src/v0.8/automation/2_0/KeeperRegistry2_0.sol +++ b/contracts/src/v0.8/automation/2_0/KeeperRegistry2_0.sol @@ -5,11 +5,11 @@ import "../../vendor/openzeppelin-solidity/v4.7.3/contracts/proxy/Proxy.sol"; import "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; import "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; import "./KeeperRegistryBase2_0.sol"; -import {AutomationRegistryExecutableInterface, UpkeepInfo} from "../../interfaces/automation/2_0/AutomationRegistryInterface2_0.sol"; -import "../../interfaces/automation/MigratableKeeperRegistryInterface.sol"; -import "../../interfaces/automation/MigratableKeeperRegistryInterfaceV2.sol"; -import "../../interfaces/ERC677ReceiverInterface.sol"; -import "../../OCR2Abstract.sol"; +import {AutomationRegistryExecutableInterface, UpkeepInfo} from "../interfaces/2_0/AutomationRegistryInterface2_0.sol"; +import "../interfaces/MigratableKeeperRegistryInterface.sol"; +import "../interfaces/MigratableKeeperRegistryInterfaceV2.sol"; +import "../../shared/interfaces/IERC677Receiver.sol"; +import {OCR2Abstract} from "../../shared/ocr2/OCR2Abstract.sol"; /** _. _|_ _ ._ _ _._|_o _ ._ o _ _ ._ _| _ __|_o._ @@ -27,7 +27,7 @@ contract KeeperRegistry2_0 is AutomationRegistryExecutableInterface, MigratableKeeperRegistryInterface, MigratableKeeperRegistryInterfaceV2, - ERC677ReceiverInterface + IERC677Receiver { using Address for address; using EnumerableSet for EnumerableSet.UintSet; diff --git a/contracts/src/v0.8/automation/2_0/KeeperRegistryBase2_0.sol b/contracts/src/v0.8/automation/2_0/KeeperRegistryBase2_0.sol index 1f2fab2ee7a..74a13d71100 100644 --- a/contracts/src/v0.8/automation/2_0/KeeperRegistryBase2_0.sol +++ b/contracts/src/v0.8/automation/2_0/KeeperRegistryBase2_0.sol @@ -4,14 +4,14 @@ pragma solidity 0.8.6; import "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; import "../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol"; import "../../vendor/@eth-optimism/contracts/0.8.6/contracts/L2/predeploys/OVM_GasPriceOracle.sol"; -import {ArbSys} from "../../dev/vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; +import {ArbSys} from "../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; import "../ExecutionPrevention.sol"; -import {OnchainConfig, State, UpkeepFailureReason} from "../../interfaces/automation/2_0/AutomationRegistryInterface2_0.sol"; -import "../../ConfirmedOwner.sol"; +import {OnchainConfig, State, UpkeepFailureReason} from "../interfaces/2_0/AutomationRegistryInterface2_0.sol"; +import "../../shared/access/ConfirmedOwner.sol"; import "../../interfaces/AggregatorV3Interface.sol"; -import "../../interfaces/LinkTokenInterface.sol"; -import "../../interfaces/automation/KeeperCompatibleInterface.sol"; -import "../../interfaces/automation/UpkeepTranscoderInterface.sol"; +import "../../shared/interfaces/LinkTokenInterface.sol"; +import "../interfaces/KeeperCompatibleInterface.sol"; +import "../interfaces/UpkeepTranscoderInterface.sol"; /** * @notice relevant state of an upkeep which is used in transmit function diff --git a/contracts/src/v0.8/automation/2_0/KeeperRegistryLogic2_0.sol b/contracts/src/v0.8/automation/2_0/KeeperRegistryLogic2_0.sol index 2787fca87c1..7e6134a178f 100644 --- a/contracts/src/v0.8/automation/2_0/KeeperRegistryLogic2_0.sol +++ b/contracts/src/v0.8/automation/2_0/KeeperRegistryLogic2_0.sol @@ -4,8 +4,8 @@ pragma solidity 0.8.6; import "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; import "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; import "./KeeperRegistryBase2_0.sol"; -import "../../interfaces/automation/MigratableKeeperRegistryInterfaceV2.sol"; -import "../../interfaces/automation/UpkeepTranscoderInterfaceV2.sol"; +import "../interfaces/MigratableKeeperRegistryInterfaceV2.sol"; +import "../interfaces/UpkeepTranscoderInterfaceV2.sol"; /** * @notice Logic contract, works in tandem with KeeperRegistry as a proxy diff --git a/contracts/src/v0.8/automation/AutomationCompatible.sol b/contracts/src/v0.8/automation/AutomationCompatible.sol index b0abd44b05f..5634956ea70 100644 --- a/contracts/src/v0.8/automation/AutomationCompatible.sol +++ b/contracts/src/v0.8/automation/AutomationCompatible.sol @@ -2,6 +2,6 @@ pragma solidity ^0.8.0; import "./AutomationBase.sol"; -import "../interfaces/automation/AutomationCompatibleInterface.sol"; +import "./interfaces/AutomationCompatibleInterface.sol"; abstract contract AutomationCompatible is AutomationBase, AutomationCompatibleInterface {} diff --git a/contracts/src/v0.8/automation/HeartbeatRequester.sol b/contracts/src/v0.8/automation/HeartbeatRequester.sol index def7a67bbd0..d5802a79580 100644 --- a/contracts/src/v0.8/automation/HeartbeatRequester.sol +++ b/contracts/src/v0.8/automation/HeartbeatRequester.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.6; import "./../interfaces/TypeAndVersionInterface.sol"; -import "./../ConfirmedOwner.sol"; +import "../shared/access/ConfirmedOwner.sol"; // defines some interfaces for type safety and reduces encoding/decoding // does not use the full interfaces intentionally because the requester only uses a fraction of them diff --git a/contracts/src/v0.8/automation/KeeperCompatible.sol b/contracts/src/v0.8/automation/KeeperCompatible.sol index b3cf2820ecc..f5263eda7b9 100644 --- a/contracts/src/v0.8/automation/KeeperCompatible.sol +++ b/contracts/src/v0.8/automation/KeeperCompatible.sol @@ -5,4 +5,4 @@ pragma solidity ^0.8.0; import {AutomationCompatible as KeeperCompatible} from "./AutomationCompatible.sol"; import {AutomationBase as KeeperBase} from "./AutomationBase.sol"; -import {AutomationCompatibleInterface as KeeperCompatibleInterface} from "../interfaces/automation/AutomationCompatibleInterface.sol"; +import {AutomationCompatibleInterface as KeeperCompatibleInterface} from "./interfaces/AutomationCompatibleInterface.sol"; diff --git a/contracts/src/v0.8/automation/UpkeepTranscoder.sol b/contracts/src/v0.8/automation/UpkeepTranscoder.sol index 5271c520758..450da8c14a1 100644 --- a/contracts/src/v0.8/automation/UpkeepTranscoder.sol +++ b/contracts/src/v0.8/automation/UpkeepTranscoder.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; -import "../interfaces/automation/UpkeepTranscoderInterface.sol"; +import "./interfaces/UpkeepTranscoderInterface.sol"; import "../interfaces/TypeAndVersionInterface.sol"; /** diff --git a/contracts/src/v0.8/interfaces/automation/1_2/AutomationRegistryInterface1_2.sol b/contracts/src/v0.8/automation/interfaces/1_2/AutomationRegistryInterface1_2.sol similarity index 100% rename from contracts/src/v0.8/interfaces/automation/1_2/AutomationRegistryInterface1_2.sol rename to contracts/src/v0.8/automation/interfaces/1_2/AutomationRegistryInterface1_2.sol diff --git a/contracts/src/v0.8/interfaces/automation/1_2/KeeperRegistryInterface1_2.sol b/contracts/src/v0.8/automation/interfaces/1_2/KeeperRegistryInterface1_2.sol similarity index 100% rename from contracts/src/v0.8/interfaces/automation/1_2/KeeperRegistryInterface1_2.sol rename to contracts/src/v0.8/automation/interfaces/1_2/KeeperRegistryInterface1_2.sol diff --git a/contracts/src/v0.8/interfaces/automation/1_3/AutomationRegistryInterface1_3.sol b/contracts/src/v0.8/automation/interfaces/1_3/AutomationRegistryInterface1_3.sol similarity index 100% rename from contracts/src/v0.8/interfaces/automation/1_3/AutomationRegistryInterface1_3.sol rename to contracts/src/v0.8/automation/interfaces/1_3/AutomationRegistryInterface1_3.sol diff --git a/contracts/src/v0.8/interfaces/automation/2_0/AutomationRegistryInterface2_0.sol b/contracts/src/v0.8/automation/interfaces/2_0/AutomationRegistryInterface2_0.sol similarity index 100% rename from contracts/src/v0.8/interfaces/automation/2_0/AutomationRegistryInterface2_0.sol rename to contracts/src/v0.8/automation/interfaces/2_0/AutomationRegistryInterface2_0.sol diff --git a/contracts/src/v0.8/interfaces/automation/AutomationCompatibleInterface.sol b/contracts/src/v0.8/automation/interfaces/AutomationCompatibleInterface.sol similarity index 100% rename from contracts/src/v0.8/interfaces/automation/AutomationCompatibleInterface.sol rename to contracts/src/v0.8/automation/interfaces/AutomationCompatibleInterface.sol diff --git a/contracts/src/v0.8/interfaces/automation/KeeperCompatibleInterface.sol b/contracts/src/v0.8/automation/interfaces/KeeperCompatibleInterface.sol similarity index 100% rename from contracts/src/v0.8/interfaces/automation/KeeperCompatibleInterface.sol rename to contracts/src/v0.8/automation/interfaces/KeeperCompatibleInterface.sol diff --git a/contracts/src/v0.8/interfaces/automation/MigratableKeeperRegistryInterface.sol b/contracts/src/v0.8/automation/interfaces/MigratableKeeperRegistryInterface.sol similarity index 95% rename from contracts/src/v0.8/interfaces/automation/MigratableKeeperRegistryInterface.sol rename to contracts/src/v0.8/automation/interfaces/MigratableKeeperRegistryInterface.sol index b9a47269061..d279d93984e 100644 --- a/contracts/src/v0.8/interfaces/automation/MigratableKeeperRegistryInterface.sol +++ b/contracts/src/v0.8/automation/interfaces/MigratableKeeperRegistryInterface.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; -import "../../automation/UpkeepFormat.sol"; +import "../UpkeepFormat.sol"; interface MigratableKeeperRegistryInterface { /** diff --git a/contracts/src/v0.8/interfaces/automation/MigratableKeeperRegistryInterfaceV2.sol b/contracts/src/v0.8/automation/interfaces/MigratableKeeperRegistryInterfaceV2.sol similarity index 95% rename from contracts/src/v0.8/interfaces/automation/MigratableKeeperRegistryInterfaceV2.sol rename to contracts/src/v0.8/automation/interfaces/MigratableKeeperRegistryInterfaceV2.sol index d13ee4c1670..17ca3673dc2 100644 --- a/contracts/src/v0.8/interfaces/automation/MigratableKeeperRegistryInterfaceV2.sol +++ b/contracts/src/v0.8/automation/interfaces/MigratableKeeperRegistryInterfaceV2.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; -import "../../automation/UpkeepFormat.sol"; +import "../UpkeepFormat.sol"; interface MigratableKeeperRegistryInterfaceV2 { /** diff --git a/contracts/src/v0.8/interfaces/automation/UpkeepTranscoderInterface.sol b/contracts/src/v0.8/automation/interfaces/UpkeepTranscoderInterface.sol similarity index 85% rename from contracts/src/v0.8/interfaces/automation/UpkeepTranscoderInterface.sol rename to contracts/src/v0.8/automation/interfaces/UpkeepTranscoderInterface.sol index 555a1600294..aa0c3c6a7f0 100644 --- a/contracts/src/v0.8/interfaces/automation/UpkeepTranscoderInterface.sol +++ b/contracts/src/v0.8/automation/interfaces/UpkeepTranscoderInterface.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -import "../../automation/UpkeepFormat.sol"; +import "../UpkeepFormat.sol"; pragma solidity ^0.8.0; diff --git a/contracts/src/v0.8/interfaces/automation/UpkeepTranscoderInterfaceV2.sol b/contracts/src/v0.8/automation/interfaces/UpkeepTranscoderInterfaceV2.sol similarity index 100% rename from contracts/src/v0.8/interfaces/automation/UpkeepTranscoderInterfaceV2.sol rename to contracts/src/v0.8/automation/interfaces/UpkeepTranscoderInterfaceV2.sol diff --git a/contracts/src/v0.8/libraries/external/Cron.sol b/contracts/src/v0.8/automation/libraries/external/Cron.sol similarity index 100% rename from contracts/src/v0.8/libraries/external/Cron.sol rename to contracts/src/v0.8/automation/libraries/external/Cron.sol diff --git a/contracts/src/v0.8/libraries/internal/Cron.sol b/contracts/src/v0.8/automation/libraries/internal/Cron.sol similarity index 99% rename from contracts/src/v0.8/libraries/internal/Cron.sol rename to contracts/src/v0.8/automation/libraries/internal/Cron.sol index 2cc50945b0d..fe72c412b60 100644 --- a/contracts/src/v0.8/libraries/internal/Cron.sol +++ b/contracts/src/v0.8/automation/libraries/internal/Cron.sol @@ -33,8 +33,8 @@ pragma solidity 0.8.6; -import "../../vendor/Strings.sol"; -import "../../vendor/DateTime.sol"; +import "../../../vendor/Strings.sol"; +import "../../../vendor/DateTime.sol"; // The fields of a cron spec, by name string constant MINUTE = "minute"; diff --git a/contracts/src/v0.8/automation/mocks/KeeperRegistrar1_2Mock.sol b/contracts/src/v0.8/automation/mocks/KeeperRegistrar1_2Mock.sol new file mode 100644 index 00000000000..b147c98e9ae --- /dev/null +++ b/contracts/src/v0.8/automation/mocks/KeeperRegistrar1_2Mock.sol @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.6; + +contract KeeperRegistrar1_2Mock { + event AutoApproveAllowedSenderSet(address indexed senderAddress, bool allowed); + event ConfigChanged( + uint8 autoApproveConfigType, + uint32 autoApproveMaxAllowed, + address keeperRegistry, + uint96 minLINKJuels + ); + event OwnershipTransferRequested(address indexed from, address indexed to); + event OwnershipTransferred(address indexed from, address indexed to); + event RegistrationApproved(bytes32 indexed hash, string displayName, uint256 indexed upkeepId); + event RegistrationRejected(bytes32 indexed hash); + event RegistrationRequested( + bytes32 indexed hash, + string name, + bytes encryptedEmail, + address indexed upkeepContract, + uint32 gasLimit, + address adminAddress, + bytes checkData, + uint96 amount, + uint8 indexed source + ); + + function emitAutoApproveAllowedSenderSet(address senderAddress, bool allowed) public { + emit AutoApproveAllowedSenderSet(senderAddress, allowed); + } + + function emitConfigChanged( + uint8 autoApproveConfigType, + uint32 autoApproveMaxAllowed, + address keeperRegistry, + uint96 minLINKJuels + ) public { + emit ConfigChanged(autoApproveConfigType, autoApproveMaxAllowed, keeperRegistry, minLINKJuels); + } + + function emitOwnershipTransferRequested(address from, address to) public { + emit OwnershipTransferRequested(from, to); + } + + function emitOwnershipTransferred(address from, address to) public { + emit OwnershipTransferred(from, to); + } + + function emitRegistrationApproved(bytes32 hash, string memory displayName, uint256 upkeepId) public { + emit RegistrationApproved(hash, displayName, upkeepId); + } + + function emitRegistrationRejected(bytes32 hash) public { + emit RegistrationRejected(hash); + } + + function emitRegistrationRequested( + bytes32 hash, + string memory name, + bytes memory encryptedEmail, + address upkeepContract, + uint32 gasLimit, + address adminAddress, + bytes memory checkData, + uint96 amount, + uint8 source + ) public { + emit RegistrationRequested( + hash, + name, + encryptedEmail, + upkeepContract, + gasLimit, + adminAddress, + checkData, + amount, + source + ); + } + + enum AutoApproveType { + DISABLED, + ENABLED_SENDER_ALLOWLIST, + ENABLED_ALL + } + + AutoApproveType public s_autoApproveConfigType; + uint32 public s_autoApproveMaxAllowed; + uint32 public s_approvedCount; + address public s_keeperRegistry; + uint256 public s_minLINKJuels; + + // Function to set mock return data for the getRegistrationConfig function + function setRegistrationConfig( + AutoApproveType _autoApproveConfigType, + uint32 _autoApproveMaxAllowed, + uint32 _approvedCount, + address _keeperRegistry, + uint256 _minLINKJuels + ) external { + s_autoApproveConfigType = _autoApproveConfigType; + s_autoApproveMaxAllowed = _autoApproveMaxAllowed; + s_approvedCount = _approvedCount; + s_keeperRegistry = _keeperRegistry; + s_minLINKJuels = _minLINKJuels; + } + + // Mock getRegistrationConfig function + function getRegistrationConfig() + external + view + returns ( + AutoApproveType autoApproveConfigType, + uint32 autoApproveMaxAllowed, + uint32 approvedCount, + address keeperRegistry, + uint256 minLINKJuels + ) + { + return (s_autoApproveConfigType, s_autoApproveMaxAllowed, s_approvedCount, s_keeperRegistry, s_minLINKJuels); + } +} diff --git a/contracts/src/v0.8/automation/mocks/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.sol b/contracts/src/v0.8/automation/mocks/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.sol new file mode 100644 index 00000000000..87e93c637ee --- /dev/null +++ b/contracts/src/v0.8/automation/mocks/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.6; + +contract KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock { + event OwnershipTransferRequested(address indexed from, address indexed to); + event OwnershipTransferred(address indexed from, address indexed to); + + function emitOwnershipTransferRequested(address from, address to) public { + emit OwnershipTransferRequested(from, to); + } + + function emitOwnershipTransferred(address from, address to) public { + emit OwnershipTransferred(from, to); + } + + bool public s_mockResult; + bytes public s_mockPayload; + uint256 public s_mockGas; + + // Function to set mock return data for the measureCheckGas function + function setMeasureCheckGasResult(bool result, bytes memory payload, uint256 gas) external { + s_mockResult = result; + s_mockPayload = payload; + s_mockGas = gas; + } + + // Mock measureCheckGas function + function measureCheckGas(uint256 id, address from) external returns (bool, bytes memory, uint256) { + return (s_mockResult, s_mockPayload, s_mockGas); + } +} diff --git a/contracts/src/v0.8/tests/CronTestHelper.sol b/contracts/src/v0.8/automation/testhelpers/CronTestHelper.sol similarity index 100% rename from contracts/src/v0.8/tests/CronTestHelper.sol rename to contracts/src/v0.8/automation/testhelpers/CronTestHelper.sol diff --git a/contracts/src/v0.8/tests/CronUpkeepTestHelper.sol b/contracts/src/v0.8/automation/testhelpers/CronUpkeepTestHelper.sol similarity index 96% rename from contracts/src/v0.8/tests/CronUpkeepTestHelper.sol rename to contracts/src/v0.8/automation/testhelpers/CronUpkeepTestHelper.sol index 4f6a6419620..8ede4ea3933 100644 --- a/contracts/src/v0.8/tests/CronUpkeepTestHelper.sol +++ b/contracts/src/v0.8/automation/testhelpers/CronUpkeepTestHelper.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.6; -import "../automation/upkeeps/CronUpkeep.sol"; +import "../upkeeps/CronUpkeep.sol"; import {Cron, Spec} from "../libraries/internal/Cron.sol"; /** diff --git a/contracts/src/v0.8/automation/upkeeps/CronUpkeep.sol b/contracts/src/v0.8/automation/upkeeps/CronUpkeep.sol index 5ae7d2f8aee..614b84635ab 100644 --- a/contracts/src/v0.8/automation/upkeeps/CronUpkeep.sol +++ b/contracts/src/v0.8/automation/upkeeps/CronUpkeep.sol @@ -21,11 +21,11 @@ pragma solidity 0.8.6; import "@openzeppelin/contracts/security/Pausable.sol"; import "@openzeppelin/contracts/proxy/Proxy.sol"; import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; -import "../../ConfirmedOwner.sol"; +import "../../shared/access/ConfirmedOwner.sol"; import "../KeeperBase.sol"; -import "../../interfaces/automation/KeeperCompatibleInterface.sol"; -import {Cron as CronInternal, Spec} from "../../libraries/internal/Cron.sol"; -import {Cron as CronExternal} from "../../libraries/external/Cron.sol"; +import "../interfaces/KeeperCompatibleInterface.sol"; +import {Cron as CronInternal, Spec} from "../libraries/internal/Cron.sol"; +import {Cron as CronExternal} from "../libraries/external/Cron.sol"; /** * @title The CronUpkeep contract diff --git a/contracts/src/v0.8/automation/upkeeps/CronUpkeepDelegate.sol b/contracts/src/v0.8/automation/upkeeps/CronUpkeepDelegate.sol index 9a446b6715e..ec2c2a0fd91 100644 --- a/contracts/src/v0.8/automation/upkeeps/CronUpkeepDelegate.sol +++ b/contracts/src/v0.8/automation/upkeeps/CronUpkeepDelegate.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.6; import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; -import {Cron, Spec} from "../../libraries/internal/Cron.sol"; +import {Cron, Spec} from "../libraries/internal/Cron.sol"; /** * @title The CronUpkeepDelegate contract diff --git a/contracts/src/v0.8/automation/upkeeps/CronUpkeepFactory.sol b/contracts/src/v0.8/automation/upkeeps/CronUpkeepFactory.sol index f88945e9c91..cd9ae5d7a92 100644 --- a/contracts/src/v0.8/automation/upkeeps/CronUpkeepFactory.sol +++ b/contracts/src/v0.8/automation/upkeeps/CronUpkeepFactory.sol @@ -4,8 +4,8 @@ pragma solidity 0.8.6; import "./CronUpkeep.sol"; import "./CronUpkeepDelegate.sol"; -import "../../ConfirmedOwner.sol"; -import {Spec, Cron as CronExternal} from "../../libraries/external/Cron.sol"; +import "../../shared/access/ConfirmedOwner.sol"; +import {Spec, Cron as CronExternal} from "../libraries/external/Cron.sol"; /** * @title The CronUpkeepFactory contract diff --git a/contracts/src/v0.8/automation/upkeeps/ERC20BalanceMonitor.sol b/contracts/src/v0.8/automation/upkeeps/ERC20BalanceMonitor.sol index 3f16d6a1200..69f36f92cc6 100644 --- a/contracts/src/v0.8/automation/upkeeps/ERC20BalanceMonitor.sol +++ b/contracts/src/v0.8/automation/upkeeps/ERC20BalanceMonitor.sol @@ -2,8 +2,8 @@ pragma solidity ^0.8.4; -import "../../ConfirmedOwner.sol"; -import "../../interfaces/automation/KeeperCompatibleInterface.sol"; +import "../../shared/access/ConfirmedOwner.sol"; +import "../interfaces/KeeperCompatibleInterface.sol"; import "../../vendor/openzeppelin-solidity/v4.7.0/contracts/security/Pausable.sol"; import "../../vendor/openzeppelin-solidity/v4.7.0/contracts/token/ERC20/utils/SafeERC20.sol"; diff --git a/contracts/src/v0.8/automation/upkeeps/EthBalanceMonitor.sol b/contracts/src/v0.8/automation/upkeeps/EthBalanceMonitor.sol index fc4107a0ac6..c7d8a306e58 100644 --- a/contracts/src/v0.8/automation/upkeeps/EthBalanceMonitor.sol +++ b/contracts/src/v0.8/automation/upkeeps/EthBalanceMonitor.sol @@ -2,8 +2,8 @@ pragma solidity 0.8.6; -import "../../ConfirmedOwner.sol"; -import "../../interfaces/automation/KeeperCompatibleInterface.sol"; +import "../../shared/access/ConfirmedOwner.sol"; +import "../interfaces/KeeperCompatibleInterface.sol"; import "@openzeppelin/contracts/security/Pausable.sol"; /** diff --git a/contracts/src/v0.8/dev/ArbitrumCrossDomainForwarder.sol b/contracts/src/v0.8/dev/ArbitrumCrossDomainForwarder.sol index 63cae522548..cc04e0e4a00 100644 --- a/contracts/src/v0.8/dev/ArbitrumCrossDomainForwarder.sol +++ b/contracts/src/v0.8/dev/ArbitrumCrossDomainForwarder.sol @@ -2,8 +2,8 @@ pragma solidity ^0.8.0; import "../interfaces/TypeAndVersionInterface.sol"; -import "./vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol"; -import "./vendor/openzeppelin-solidity/v4.3.1/contracts/utils/Address.sol"; +import "./../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol"; +import "../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; import "./CrossDomainForwarder.sol"; /** diff --git a/contracts/src/v0.8/dev/ArbitrumCrossDomainGovernor.sol b/contracts/src/v0.8/dev/ArbitrumCrossDomainGovernor.sol index 930926ce4c2..8e93bd2935d 100644 --- a/contracts/src/v0.8/dev/ArbitrumCrossDomainGovernor.sol +++ b/contracts/src/v0.8/dev/ArbitrumCrossDomainGovernor.sol @@ -2,8 +2,8 @@ pragma solidity ^0.8.0; import "./interfaces/DelegateForwarderInterface.sol"; -import "./vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol"; -import "./vendor/openzeppelin-solidity/v4.3.1/contracts/utils/Address.sol"; +import "./../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol"; +import "../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; import "./ArbitrumCrossDomainForwarder.sol"; /** diff --git a/contracts/src/v0.8/dev/ArbitrumSequencerUptimeFeed.sol b/contracts/src/v0.8/dev/ArbitrumSequencerUptimeFeed.sol index 5efc5a07ef4..0191bbd88a3 100644 --- a/contracts/src/v0.8/dev/ArbitrumSequencerUptimeFeed.sol +++ b/contracts/src/v0.8/dev/ArbitrumSequencerUptimeFeed.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.4; -import {AddressAliasHelper} from "./vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol"; +import {AddressAliasHelper} from "./../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol"; import {ForwarderInterface} from "./interfaces/ForwarderInterface.sol"; import {AggregatorInterface} from "../interfaces/AggregatorInterface.sol"; import {AggregatorV3Interface} from "../interfaces/AggregatorV3Interface.sol"; @@ -10,7 +10,7 @@ import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol import {FlagsInterface} from "./interfaces/FlagsInterface.sol"; import {ArbitrumSequencerUptimeFeedInterface} from "./interfaces/ArbitrumSequencerUptimeFeedInterface.sol"; import {SimpleReadAccessController} from "../SimpleReadAccessController.sol"; -import {ConfirmedOwner} from "../ConfirmedOwner.sol"; +import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol"; /** * @title ArbitrumSequencerUptimeFeed - L2 sequencer uptime status aggregator diff --git a/contracts/src/v0.8/dev/ArbitrumValidator.sol b/contracts/src/v0.8/dev/ArbitrumValidator.sol index dd856c130a7..4e8d9a8537e 100644 --- a/contracts/src/v0.8/dev/ArbitrumValidator.sol +++ b/contracts/src/v0.8/dev/ArbitrumValidator.sol @@ -11,9 +11,9 @@ import "../SimpleWriteAccessController.sol"; import "./interfaces/ArbitrumSequencerUptimeFeedInterface.sol"; import "./interfaces/FlagsInterface.sol"; import "./interfaces/IArbitrumDelayedInbox.sol"; -import "./vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol"; -import "./vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; -import "./vendor/openzeppelin-solidity/v4.3.1/contracts/utils/Address.sol"; +import "./../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol"; +import "../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; +import "../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; /** * @title ArbitrumValidator - makes xDomain L2 Flags contract call (using L2 xDomain Forwarder contract) diff --git a/contracts/src/v0.8/dev/CrossDomainOwnable.sol b/contracts/src/v0.8/dev/CrossDomainOwnable.sol index cd5f309dff2..7a055ddad9e 100644 --- a/contracts/src/v0.8/dev/CrossDomainOwnable.sol +++ b/contracts/src/v0.8/dev/CrossDomainOwnable.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../ConfirmedOwner.sol"; +import "../shared/access/ConfirmedOwner.sol"; import "./interfaces/CrossDomainOwnableInterface.sol"; /** diff --git a/contracts/src/v0.8/dev/OptimismCrossDomainForwarder.sol b/contracts/src/v0.8/dev/OptimismCrossDomainForwarder.sol index 15a64512516..9da3db692b9 100644 --- a/contracts/src/v0.8/dev/OptimismCrossDomainForwarder.sol +++ b/contracts/src/v0.8/dev/OptimismCrossDomainForwarder.sol @@ -5,8 +5,8 @@ import "../interfaces/TypeAndVersionInterface.sol"; /* ./dev dependencies - to be moved from ./dev after audit */ import "./CrossDomainForwarder.sol"; -import "./vendor/@eth-optimism/contracts/0.4.7/contracts/optimistic-ethereum/iOVM/bridge/messaging/iOVM_CrossDomainMessenger.sol"; -import "./vendor/openzeppelin-solidity/v4.3.1/contracts/utils/Address.sol"; +import "../vendor/@eth-optimism/contracts/0.4.7/contracts/optimistic-ethereum/iOVM/bridge/messaging/iOVM_CrossDomainMessenger.sol"; +import "../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; /** * @title OptimismCrossDomainForwarder - L1 xDomain account representation diff --git a/contracts/src/v0.8/dev/OptimismCrossDomainGovernor.sol b/contracts/src/v0.8/dev/OptimismCrossDomainGovernor.sol index ef77a1f2f6b..4c878b36068 100644 --- a/contracts/src/v0.8/dev/OptimismCrossDomainGovernor.sol +++ b/contracts/src/v0.8/dev/OptimismCrossDomainGovernor.sol @@ -2,8 +2,8 @@ pragma solidity ^0.8.0; import "./interfaces/DelegateForwarderInterface.sol"; -import "./vendor/@eth-optimism/contracts/0.4.7/contracts/optimistic-ethereum/iOVM/bridge/messaging/iOVM_CrossDomainMessenger.sol"; -import "./vendor/openzeppelin-solidity/v4.3.1/contracts/utils/Address.sol"; +import "../vendor/@eth-optimism/contracts/0.4.7/contracts/optimistic-ethereum/iOVM/bridge/messaging/iOVM_CrossDomainMessenger.sol"; +import "../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; import "./OptimismCrossDomainForwarder.sol"; /** diff --git a/contracts/src/v0.8/dev/OptimismSequencerUptimeFeed.sol b/contracts/src/v0.8/dev/OptimismSequencerUptimeFeed.sol index f51d29b42e3..86215f87237 100644 --- a/contracts/src/v0.8/dev/OptimismSequencerUptimeFeed.sol +++ b/contracts/src/v0.8/dev/OptimismSequencerUptimeFeed.sol @@ -7,7 +7,7 @@ import {AggregatorV2V3Interface} from "../interfaces/AggregatorV2V3Interface.sol import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol"; import {OptimismSequencerUptimeFeedInterface} from "./interfaces/OptimismSequencerUptimeFeedInterface.sol"; import {SimpleReadAccessController} from "../SimpleReadAccessController.sol"; -import {ConfirmedOwner} from "../ConfirmedOwner.sol"; +import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol"; import {IL2CrossDomainMessenger} from "@eth-optimism/contracts/L2/messaging/IL2CrossDomainMessenger.sol"; /** diff --git a/contracts/src/v0.8/dev/OptimismValidator.sol b/contracts/src/v0.8/dev/OptimismValidator.sol index ba5a5da53cf..f08f2e323de 100644 --- a/contracts/src/v0.8/dev/OptimismValidator.sol +++ b/contracts/src/v0.8/dev/OptimismValidator.sol @@ -9,7 +9,7 @@ import "../SimpleWriteAccessController.sol"; import "./interfaces/OptimismSequencerUptimeFeedInterface.sol"; import "@eth-optimism/contracts/L1/messaging/IL1CrossDomainMessenger.sol"; -import "./vendor/openzeppelin-solidity/v4.3.1/contracts/utils/Address.sol"; +import "../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; /** * @title OptimismValidator - makes cross chain call to update the Sequencer Uptime Feed on L2 diff --git a/contracts/src/v0.8/dev/VRFSubscriptionBalanceMonitor.sol b/contracts/src/v0.8/dev/VRFSubscriptionBalanceMonitor.sol index bd04de6a4b6..91124709742 100644 --- a/contracts/src/v0.8/dev/VRFSubscriptionBalanceMonitor.sol +++ b/contracts/src/v0.8/dev/VRFSubscriptionBalanceMonitor.sol @@ -2,10 +2,10 @@ pragma solidity 0.8.6; -import "../ConfirmedOwner.sol"; -import "../interfaces/automation/KeeperCompatibleInterface.sol"; +import "../shared/access/ConfirmedOwner.sol"; +import "../automation/interfaces/KeeperCompatibleInterface.sol"; import "../interfaces/VRFCoordinatorV2Interface.sol"; -import "../interfaces/LinkTokenInterface.sol"; +import "../shared/interfaces/LinkTokenInterface.sol"; import "@openzeppelin/contracts/security/Pausable.sol"; /** diff --git a/contracts/src/v0.8/dev/automation/2_1/AutomationForwarder.sol b/contracts/src/v0.8/dev/automation/2_1/AutomationForwarder.sol index dd365ca5ad6..1391a2babe7 100644 --- a/contracts/src/v0.8/dev/automation/2_1/AutomationForwarder.sol +++ b/contracts/src/v0.8/dev/automation/2_1/AutomationForwarder.sol @@ -12,18 +12,15 @@ uint256 constant PERFORM_GAS_CUSHION = 5_000; * which stays consistent between migrations. The Forwarder also exposes the registry address, so that users who * want to programatically interact with the registry (ie top up funds) can do so. */ -contract AutomationForwarder is TypeAndVersionInterface { - IAutomationRegistryConsumer private s_registry; +contract AutomationForwarder { address private immutable i_target; - uint256 private immutable i_upkeepID; - string public constant override typeAndVersion = "AutomationForwarder 1.0.0"; - - error NotAuthorized(); + address private immutable i_logic; + IAutomationRegistryConsumer private s_registry; - constructor(uint256 upkeepID, address target, address registry) { + constructor(address target, address registry, address logic) { s_registry = IAutomationRegistryConsumer(registry); i_target = target; - i_upkeepID = upkeepID; + i_logic = logic; } /** @@ -33,7 +30,7 @@ contract AutomationForwarder is TypeAndVersionInterface { * @return success indicating whether the target call succeeded or failed */ function forward(uint256 gasAmount, bytes memory data) external returns (bool success, uint256 gasUsed) { - if (msg.sender != address(s_registry)) revert NotAuthorized(); + if (msg.sender != address(s_registry)) revert(); address target = i_target; gasUsed = gasleft(); assembly { @@ -59,33 +56,34 @@ contract AutomationForwarder is TypeAndVersionInterface { return (success, gasUsed); } - /** - * @notice updateRegistry is called by the registry during migrations - * @param newRegistry is the registry that this forwarder is being migrated to - */ - function updateRegistry(address newRegistry) external { - if (msg.sender != address(s_registry)) revert NotAuthorized(); - s_registry = IAutomationRegistryConsumer(newRegistry); - } - - /** - * @notice gets the registry address - */ - function getRegistry() external view returns (IAutomationRegistryConsumer) { - return s_registry; - } - - /** - * @notice gets the target contract address - */ function getTarget() external view returns (address) { return i_target; } - /** - * @notice gets the upkeepID that this forwarder belongs to - */ - function getUpkeepID() external view returns (uint256) { - return i_upkeepID; + fallback() external { + // copy to memory for assembly access + address logic = i_logic; + // copied directly from OZ's Proxy contract + assembly { + // Copy msg.data. We take full control of memory in this inline assembly + // block because it will not return to Solidity code. We overwrite the + // Solidity scratch pad at memory position 0. + calldatacopy(0, 0, calldatasize()) + + // out and outsize are 0 because we don't know the size yet. + let result := delegatecall(gas(), logic, 0, calldatasize(), 0, 0) + + // Copy the returned data. + returndatacopy(0, 0, returndatasize()) + + switch result + // delegatecall returns 0 on error. + case 0 { + revert(0, returndatasize()) + } + default { + return(0, returndatasize()) + } + } } } diff --git a/contracts/src/v0.8/dev/automation/2_1/AutomationForwarderLogic.sol b/contracts/src/v0.8/dev/automation/2_1/AutomationForwarderLogic.sol new file mode 100644 index 00000000000..0a5535ce061 --- /dev/null +++ b/contracts/src/v0.8/dev/automation/2_1/AutomationForwarderLogic.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.16; + +import {IAutomationRegistryConsumer} from "./interfaces/IAutomationRegistryConsumer.sol"; +import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; + +contract AutomationForwarderLogic is ITypeAndVersion { + IAutomationRegistryConsumer private s_registry; + + string public constant typeAndVersion = "AutomationForwarder 1.0.0"; + + /** + * @notice updateRegistry is called by the registry during migrations + * @param newRegistry is the registry that this forwarder is being migrated to + */ + function updateRegistry(address newRegistry) external { + if (msg.sender != address(s_registry)) revert(); + s_registry = IAutomationRegistryConsumer(newRegistry); + } + + function getRegistry() external view returns (IAutomationRegistryConsumer) { + return s_registry; + } +} diff --git a/contracts/src/v0.8/dev/automation/2_1/AutomationRegistrar2_1.sol b/contracts/src/v0.8/dev/automation/2_1/AutomationRegistrar2_1.sol index c37a1b1d079..0f60426cfa2 100644 --- a/contracts/src/v0.8/dev/automation/2_1/AutomationRegistrar2_1.sol +++ b/contracts/src/v0.8/dev/automation/2_1/AutomationRegistrar2_1.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.16; -import "../../../interfaces/LinkTokenInterface.sol"; +import "../../../shared/interfaces/LinkTokenInterface.sol"; import "./interfaces/IKeeperRegistryMaster.sol"; import "../../../interfaces/TypeAndVersionInterface.sol"; -import "../../../ConfirmedOwner.sol"; -import "../../../interfaces/ERC677ReceiverInterface.sol"; +import "../../../shared/access/ConfirmedOwner.sol"; +import "../../../shared/interfaces/IERC677Receiver.sol"; /** * @notice Contract to accept requests for upkeep registrations @@ -17,7 +17,7 @@ import "../../../interfaces/ERC677ReceiverInterface.sol"; * The idea is to have same interface(functions,events) for UI or anyone using this contract irrespective of auto approve being enabled or not. * they can just listen to `RegistrationRequested` & `RegistrationApproved` events and know the status on registrations. */ -contract AutomationRegistrar2_1 is TypeAndVersionInterface, ConfirmedOwner, ERC677ReceiverInterface { +contract AutomationRegistrar2_1 is TypeAndVersionInterface, ConfirmedOwner, IERC677Receiver { /** * 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. diff --git a/contracts/src/v0.8/dev/automation/2_1/AutomationUtils2_1.sol b/contracts/src/v0.8/dev/automation/2_1/AutomationUtils2_1.sol index 738a0f42deb..3de56b6a1d0 100644 --- a/contracts/src/v0.8/dev/automation/2_1/AutomationUtils2_1.sol +++ b/contracts/src/v0.8/dev/automation/2_1/AutomationUtils2_1.sol @@ -15,7 +15,6 @@ import "./interfaces/ILogAutomation.sol"; */ struct LogTriggerConfig { address contractAddress; - // TODO - bytes1? uint8 filterSelector; // denotes which topics apply to filter ex 000, 101, 111...only last 3 bits apply bytes32 topic0; bytes32 topic1; @@ -27,15 +26,15 @@ contract AutomationUtils2_1 { /** * @dev this can be removed as OnchainConfig is now exposed directly from the registry */ - function _onChainConfig(KeeperRegistryBase2_1.OnchainConfig memory) external {} + function _onChainConfig(KeeperRegistryBase2_1.OnchainConfig memory) external {} // 0x2ff92a81 - function _report(KeeperRegistryBase2_1.Report memory) external {} + function _report(KeeperRegistryBase2_1.Report memory) external {} // 0xe65d6546 - function _logTriggerConfig(LogTriggerConfig memory) external {} + function _logTriggerConfig(LogTriggerConfig memory) external {} // 0x21f373d7 - function _logTrigger(KeeperRegistryBase2_1.LogTrigger memory) external {} + function _logTrigger(KeeperRegistryBase2_1.LogTrigger memory) external {} // 0x1c8d8260 - function _conditionalTrigger(KeeperRegistryBase2_1.ConditionalTrigger memory) external {} + function _conditionalTrigger(KeeperRegistryBase2_1.ConditionalTrigger memory) external {} // 0x4b6df294 - function _log(Log memory) external {} + function _log(Log memory) external {} // 0xe9720a49 } diff --git a/contracts/src/v0.8/dev/automation/2_1/KeeperRegistry2_1.sol b/contracts/src/v0.8/dev/automation/2_1/KeeperRegistry2_1.sol index a2b86007d28..db3a9b14113 100644 --- a/contracts/src/v0.8/dev/automation/2_1/KeeperRegistry2_1.sol +++ b/contracts/src/v0.8/dev/automation/2_1/KeeperRegistry2_1.sol @@ -5,14 +5,14 @@ import "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/proxy/Proxy.sol"; import "./KeeperRegistryBase2_1.sol"; import "./KeeperRegistryLogicB2_1.sol"; import "./Chainable.sol"; -import "../../../interfaces/ERC677ReceiverInterface.sol"; -import "../../../OCR2Abstract.sol"; +import "../../../shared/interfaces/IERC677Receiver.sol"; +import "../../../shared/ocr2/OCR2Abstract.sol"; /** * @notice Registry for adding work for Chainlink Keepers to perform on client * contracts. Clients must support the Upkeep interface. */ -contract KeeperRegistry2_1 is KeeperRegistryBase2_1, OCR2Abstract, Chainable, ERC677ReceiverInterface { +contract KeeperRegistry2_1 is KeeperRegistryBase2_1, OCR2Abstract, Chainable, IERC677Receiver { using Address for address; using EnumerableSet for EnumerableSet.UintSet; using EnumerableSet for EnumerableSet.AddressSet; @@ -49,7 +49,8 @@ contract KeeperRegistry2_1 is KeeperRegistryBase2_1, OCR2Abstract, Chainable, ER logicA.getMode(), logicA.getLinkAddress(), logicA.getLinkNativeFeedAddress(), - logicA.getFastGasFeedAddress() + logicA.getFastGasFeedAddress(), + logicA.getAutomationForwarderLogic() ) Chainable(address(logicA)) {} @@ -89,13 +90,12 @@ contract KeeperRegistry2_1 is KeeperRegistryBase2_1, OCR2Abstract, Chainable, ER upkeepTransmitInfo[i].maxLinkPayment = _getMaxLinkPayment( hotVars, upkeepTransmitInfo[i].triggerType, - upkeepTransmitInfo[i].upkeep.performGas, + uint32(report.gasLimits[i]), uint32(report.performDatas[i].length), report.fastGasWei, report.linkNative, true ); - upkeepTransmitInfo[i].upkeepTriggerID = _upkeepTriggerID(report.upkeepIds[i], report.triggers[i]); (upkeepTransmitInfo[i].earlyChecksPassed, upkeepTransmitInfo[i].dedupID) = _prePerformChecks( report.upkeepIds[i], report.triggers[i], @@ -166,7 +166,7 @@ contract KeeperRegistry2_1 is KeeperRegistryBase2_1, OCR2Abstract, Chainable, ER reimbursement + premium, upkeepTransmitInfo[i].gasUsed, upkeepTransmitInfo[i].gasOverhead, - upkeepTransmitInfo[i].upkeepTriggerID + report.triggers[i] ); } } @@ -231,7 +231,7 @@ contract KeeperRegistry2_1 is KeeperRegistryBase2_1, OCR2Abstract, Chainable, ER uint64 offchainConfigVersion, bytes memory offchainConfig ) external override { - setConfig( + setConfigTypeSafe( signers, transmitters, f, @@ -241,7 +241,7 @@ contract KeeperRegistry2_1 is KeeperRegistryBase2_1, OCR2Abstract, Chainable, ER ); } - function setConfig( + function setConfigTypeSafe( address[] memory signers, address[] memory transmitters, uint8 f, @@ -279,9 +279,11 @@ contract KeeperRegistry2_1 is KeeperRegistryBase2_1, OCR2Abstract, Chainable, ER address temp; for (uint256 i = 0; i < signers.length; i++) { if (s_signers[signers[i]].active) revert RepeatedSigner(); + if (signers[i] == ZERO_ADDRESS) revert InvalidSigner(); s_signers[signers[i]] = Signer({active: true, index: uint8(i)}); temp = transmitters[i]; + if (temp == ZERO_ADDRESS) revert InvalidTransmitter(); transmitter = s_transmitters[temp]; if (transmitter.active) revert RepeatedTransmitter(); transmitter.active = true; diff --git a/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryBase2_1.sol b/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryBase2_1.sol index 12b05e3bfce..45501eaae95 100644 --- a/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryBase2_1.sol +++ b/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryBase2_1.sol @@ -6,15 +6,15 @@ import "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol import "../../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol"; import "../../../vendor/@eth-optimism/contracts/0.8.9/contracts/L2/predeploys/OVM_GasPriceOracle.sol"; import "../../../automation/ExecutionPrevention.sol"; -import {ArbSys} from "../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; +import {ArbSys} from "../../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; import "./interfaces/FeedLookupCompatibleInterface.sol"; import "./interfaces/ILogAutomation.sol"; -import {AutomationForwarder} from "./AutomationForwarder.sol"; -import "../../../ConfirmedOwner.sol"; +import {IAutomationForwarder} from "./interfaces/IAutomationForwarder.sol"; +import "../../../shared/access/ConfirmedOwner.sol"; import "../../../interfaces/AggregatorV3Interface.sol"; -import "../../../interfaces/LinkTokenInterface.sol"; -import "../../../interfaces/automation/KeeperCompatibleInterface.sol"; -import "../../../interfaces/automation/UpkeepTranscoderInterface.sol"; +import "../../../shared/interfaces/LinkTokenInterface.sol"; +import "../../../automation/interfaces/KeeperCompatibleInterface.sol"; +import "../../../automation/interfaces/UpkeepTranscoderInterface.sol"; /** * @notice Base Keeper Registry contract, contains shared logic between @@ -51,8 +51,6 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention { bytes internal constant L1_FEE_DATA_PADDING = "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; - uint256 internal constant TRANSMIT_GAS_OVERHEAD = 1_000_000; // Used only by offchain caller - uint256 internal constant CHECK_GAS_OVERHEAD = 400_000; // Used only by offchain caller uint256 internal constant REGISTRY_CONDITIONAL_OVERHEAD = 90_000; // Used in maxPayment estimation, and in capping overheads during actual payment uint256 internal constant REGISTRY_LOG_OVERHEAD = 110_000; // Used only in maxPayment estimation, and in capping overheads during actual payment. uint256 internal constant REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD = 20; // Used only in maxPayment estimation, and in capping overheads during actual payment. Value scales with performData length. @@ -70,6 +68,7 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention { AggregatorV3Interface internal immutable i_linkNativeFeed; AggregatorV3Interface internal immutable i_fastGasFeed; Mode internal immutable i_mode; + address internal immutable i_automationForwarderLogic; /** * @dev - The storage is gas optimised for one and only one function - transmit. All the storage accessed in transmit @@ -105,18 +104,30 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention { error ArrayHasNoEntries(); error CannotCancel(); + error CheckDataExceedsLimit(); + error ConfigDigestMismatch(); error DuplicateEntry(); + error DuplicateSigners(); error GasLimitCanOnlyIncrease(); error GasLimitOutsideRange(); + error IncorrectNumberOfFaultyOracles(); + error IncorrectNumberOfSignatures(); + error IncorrectNumberOfSigners(); error IndexOutOfRange(); error InsufficientFunds(); error InvalidDataLength(); error InvalidTrigger(); error InvalidPayee(); error InvalidRecipient(); + error InvalidReport(); + error InvalidSigner(); + error InvalidTransmitter(); error InvalidTriggerType(); + error MaxCheckDataSizeCanOnlyIncrease(); + error MaxPerformDataSizeCanOnlyIncrease(); error MigrationNotPermitted(); error NotAContract(); + error OnlyActiveSigners(); error OnlyActiveTransmitters(); error OnlyCallableByAdmin(); error OnlyCallableByLINKToken(); @@ -130,28 +141,18 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention { error OnlyUnpausedUpkeep(); error ParameterLengthError(); error PaymentGreaterThanAllLINK(); + error ReentrantCall(); + error RegistryPaused(); + error RepeatedSigner(); + error RepeatedTransmitter(); error TargetCheckReverted(bytes reason); + error TooManyOracles(); error TranscoderNotSet(); + error UpkeepAlreadyExists(); error UpkeepCancelled(); error UpkeepNotCanceled(); error UpkeepNotNeeded(); error ValueNotChanged(); - error ConfigDigestMismatch(); - error IncorrectNumberOfSignatures(); - error OnlyActiveSigners(); - error DuplicateSigners(); - error TooManyOracles(); - error IncorrectNumberOfSigners(); - error IncorrectNumberOfFaultyOracles(); - error RepeatedSigner(); - error RepeatedTransmitter(); - error CheckDataExceedsLimit(); - error MaxCheckDataSizeCanOnlyIncrease(); - error MaxPerformDataSizeCanOnlyIncrease(); - error InvalidReport(); - error RegistryPaused(); - error ReentrantCall(); - error UpkeepAlreadyExists(); enum MigrationPermission { NONE, @@ -263,20 +264,17 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention { * @member amountSpent the amount this upkeep has spent * @member balance the balance of this upkeep * @member lastPerformedBlockNumber the last block number when this upkeep was performed - * @member target the contract which needs to be serviced */ struct Upkeep { bool paused; uint32 performGas; uint32 maxValidBlocknumber; - AutomationForwarder forwarder; + IAutomationForwarder forwarder; // 0 bytes left in 1st EVM word - not written to in transmit uint96 amountSpent; uint96 balance; uint32 lastPerformedBlockNumber; // 2 bytes left in 2nd EVM word - written in transmit path - address target; - // 12 bytes left in 3rd EVM word - neither written to nor read in transmit } /** @@ -360,7 +358,6 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention { * @member triggerType the type of trigger * @member gasUsed gasUsed by this upkeep in perform * @member gasOverhead gasOverhead for this upkeep - * @member upkeepTriggerID unique ID used to identify an upkeep/trigger combo * @member dedupID unique ID used to dedup an upkeep/trigger combo */ struct UpkeepTransmitInfo { @@ -371,7 +368,6 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention { Trigger triggerType; uint256 gasUsed; uint256 gasOverhead; - bytes32 upkeepTriggerID; bytes32 dedupID; } @@ -409,22 +405,26 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention { } event AdminPrivilegeConfigSet(address indexed admin, bytes privilegeConfig); + event CancelledUpkeepReport(uint256 indexed id, bytes trigger); + event DedupKeyAdded(bytes32 indexed dedupKey); event FundsAdded(uint256 indexed id, address indexed from, uint96 amount); event FundsWithdrawn(uint256 indexed id, uint256 amount, address to); + event InsufficientFundsUpkeepReport(uint256 indexed id, bytes trigger); event OwnerFundsWithdrawn(uint96 amount); + event Paused(address account); event PayeesUpdated(address[] transmitters, address[] payees); event PayeeshipTransferRequested(address indexed transmitter, address indexed from, address indexed to); event PayeeshipTransferred(address indexed transmitter, address indexed from, address indexed to); event PaymentWithdrawn(address indexed transmitter, uint256 indexed amount, address indexed to, address payee); - event UpkeepPrivilegeConfigSet(uint256 indexed id, bytes privilegeConfig); - event UpkeepAdminTransferRequested(uint256 indexed id, address indexed from, address indexed to); + event ReorgedUpkeepReport(uint256 indexed id, bytes trigger); + event StaleUpkeepReport(uint256 indexed id, bytes trigger); event UpkeepAdminTransferred(uint256 indexed id, address indexed from, address indexed to); + event UpkeepAdminTransferRequested(uint256 indexed id, address indexed from, address indexed to); event UpkeepCanceled(uint256 indexed id, uint64 indexed atBlockHeight); event UpkeepCheckDataSet(uint256 indexed id, bytes newCheckData); event UpkeepGasLimitSet(uint256 indexed id, uint96 gasLimit); - event UpkeepOffchainConfigSet(uint256 indexed id, bytes offchainConfig); - event UpkeepTriggerConfigSet(uint256 indexed id, bytes triggerConfig); event UpkeepMigrated(uint256 indexed id, uint256 remainingBalance, address destination); + event UpkeepOffchainConfigSet(uint256 indexed id, bytes offchainConfig); event UpkeepPaused(uint256 indexed id); event UpkeepPerformed( uint256 indexed id, @@ -432,16 +432,13 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention { uint96 totalPayment, uint256 gasUsed, uint256 gasOverhead, - bytes32 upkeepTriggerID + bytes trigger ); + event UpkeepPrivilegeConfigSet(uint256 indexed id, bytes privilegeConfig); event UpkeepReceived(uint256 indexed id, uint256 startingBalance, address importedFrom); - event UpkeepUnpaused(uint256 indexed id); event UpkeepRegistered(uint256 indexed id, uint32 performGas, address admin); - event StaleUpkeepReport(uint256 indexed id, bytes32 upkeepTriggerID); - event ReorgedUpkeepReport(uint256 indexed id, bytes32 upkeepTriggerID); - event InsufficientFundsUpkeepReport(uint256 indexed id, bytes32 upkeepTriggerID); - event CancelledUpkeepReport(uint256 indexed id, bytes32 upkeepTriggerID); - event Paused(address account); + event UpkeepTriggerConfigSet(uint256 indexed id, bytes triggerConfig); + event UpkeepUnpaused(uint256 indexed id); event Unpaused(address account); /** @@ -450,11 +447,18 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention { * @param linkNativeFeed address of the LINK/Native price feed * @param fastGasFeed address of the Fast Gas price feed */ - constructor(Mode mode, address link, address linkNativeFeed, address fastGasFeed) ConfirmedOwner(msg.sender) { + constructor( + Mode mode, + address link, + address linkNativeFeed, + address fastGasFeed, + address automationForwarderLogic + ) ConfirmedOwner(msg.sender) { i_mode = mode; i_link = LinkTokenInterface(link); i_linkNativeFeed = AggregatorV3Interface(linkNativeFeed); i_fastGasFeed = AggregatorV3Interface(fastGasFeed); + i_automationForwarderLogic = automationForwarderLogic; } /////////////////////////////////////////////////////////////////////////////////////// @@ -479,11 +483,10 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention { bytes memory offchainConfig ) internal { if (s_hotVars.paused) revert RegistryPaused(); - if (!upkeep.target.isContract()) revert NotAContract(); if (checkData.length > s_storage.maxCheckDataSize) revert CheckDataExceedsLimit(); if (upkeep.performGas < PERFORM_GAS_MIN || upkeep.performGas > s_storage.maxPerformGas) revert GasLimitOutsideRange(); - if (s_upkeep[id].target != ZERO_ADDRESS) revert UpkeepAlreadyExists(); + if (address(s_upkeep[id].forwarder) != address(0)) revert UpkeepAlreadyExists(); s_upkeep[id] = upkeep; s_upkeepAdmin[id] = admin; s_checkData[id] = checkData; @@ -691,6 +694,20 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention { return Trigger(uint8(rawID[15])); } + function _checkPayload( + uint256 upkeepId, + Trigger triggerType, + bytes memory triggerData + ) internal view returns (bytes memory) { + if (triggerType == Trigger.CONDITION) { + return abi.encodeWithSelector(CHECK_SELECTOR, s_checkData[upkeepId]); + } else if (triggerType == Trigger.LOG) { + Log memory log = abi.decode(triggerData, (Log)); + return abi.encodeWithSelector(CHECK_LOG_SELECTOR, log, s_checkData[upkeepId]); + } + revert InvalidTriggerType(); + } + /** * @dev _decodeReport decodes a serialized report into a Report struct */ @@ -730,16 +747,14 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention { if (transmitInfo.upkeep.maxValidBlocknumber <= _blockNum()) { // Can happen when an upkeep got cancelled after report was generated. // However we have a CANCELLATION_DELAY of 50 blocks so shouldn't happen in practice - emit CancelledUpkeepReport(upkeepId, transmitInfo.upkeepTriggerID); + emit CancelledUpkeepReport(upkeepId, rawTrigger); return (false, dedupID); } - if (transmitInfo.upkeep.balance < transmitInfo.maxLinkPayment) { - // Can happen due to flucutations in gas / link prices - emit InsufficientFundsUpkeepReport(upkeepId, transmitInfo.upkeepTriggerID); + // Can happen due to fluctuations in gas / link prices + emit InsufficientFundsUpkeepReport(upkeepId, rawTrigger); return (false, dedupID); } - return (true, dedupID); } @@ -754,7 +769,7 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention { ConditionalTrigger memory trigger = abi.decode(rawTrigger, (ConditionalTrigger)); if (trigger.blockNum < transmitInfo.upkeep.lastPerformedBlockNumber) { // Can happen when another report performed this upkeep after this report was generated - emit StaleUpkeepReport(upkeepId, transmitInfo.upkeepTriggerID); + emit StaleUpkeepReport(upkeepId, rawTrigger); return false; } if ( @@ -767,7 +782,7 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention { // 2. blockHash at trigger block number was same as trigger time. This is an optional check which is // applied if DON sends non empty trigger.blockHash. Note: It only works for last 256 blocks on chain // when it is sent - emit ReorgedUpkeepReport(upkeepId, transmitInfo.upkeepTriggerID); + emit ReorgedUpkeepReport(upkeepId, rawTrigger); return false; } return true; @@ -785,11 +800,11 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention { trigger.blockNum >= _blockNum() ) { // Reorg protection is same as conditional trigger upkeeps - emit ReorgedUpkeepReport(upkeepId, transmitInfo.upkeepTriggerID); + emit ReorgedUpkeepReport(upkeepId, rawTrigger); return (false, dedupID); } if (s_dedupKeys[dedupID]) { - emit StaleUpkeepReport(upkeepId, transmitInfo.upkeepTriggerID); + emit StaleUpkeepReport(upkeepId, rawTrigger); return (false, dedupID); } return (true, dedupID); @@ -832,6 +847,7 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention { s_upkeep[upkeepID].lastPerformedBlockNumber = uint32(_blockNum()); } else if (upkeepTransmitInfo.triggerType == Trigger.LOG) { s_dedupKeys[upkeepTransmitInfo.dedupID] = true; + emit DedupKeyAdded(upkeepTransmitInfo.dedupID); } } @@ -840,7 +856,7 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention { * transmitter and the exact gas required by the Upkeep */ function _performUpkeep( - AutomationForwarder forwarder, + IAutomationForwarder forwarder, uint256 performGas, bytes memory performData ) internal nonReentrant returns (bool success, uint256 gasUsed) { @@ -930,16 +946,6 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention { } } - /** - * @dev returns a unique identifier for an upkeep/trigger combo - * @param upkeepID the upkeep id - * @param trigger the raw trigger bytes - * @return upkeepTriggerID the unique identifier for the upkeep/trigger combo - */ - function _upkeepTriggerID(uint256 upkeepID, bytes memory trigger) internal pure returns (bytes32 upkeepTriggerID) { - return keccak256(abi.encodePacked(upkeepID, trigger)); - } - /** * @dev replicates Open Zeppelin's ReentrancyGuard but optimized to fit our storage */ diff --git a/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryLogicA2_1.sol b/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryLogicA2_1.sol index bba3580c546..ca3d6f7efd0 100644 --- a/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryLogicA2_1.sol +++ b/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryLogicA2_1.sol @@ -5,8 +5,8 @@ import "./KeeperRegistryBase2_1.sol"; import "./KeeperRegistryLogicB2_1.sol"; import "./Chainable.sol"; import {AutomationForwarder} from "./AutomationForwarder.sol"; -import "../../../interfaces/automation/UpkeepTranscoderInterfaceV2.sol"; -import "../../../interfaces/automation/MigratableKeeperRegistryInterfaceV2.sol"; +import "../../../automation/interfaces/UpkeepTranscoderInterfaceV2.sol"; +import "../../../automation/interfaces/MigratableKeeperRegistryInterfaceV2.sol"; /** * @notice Logic contract, works in tandem with KeeperRegistry as a proxy @@ -26,7 +26,8 @@ contract KeeperRegistryLogicA2_1 is KeeperRegistryBase2_1, Chainable { logicB.getMode(), logicB.getLinkAddress(), logicB.getLinkNativeFeedAddress(), - logicB.getFastGasFeedAddress() + logicB.getFastGasFeedAddress(), + logicB.getAutomationForwarderLogic() ) Chainable(address(logicB)) {} @@ -34,7 +35,7 @@ contract KeeperRegistryLogicA2_1 is KeeperRegistryBase2_1, Chainable { /** * @notice called by the automation DON to check if work is needed * @param id the upkeep ID to check for work needed - * @param checkData the data passed to the upkeep contract's checkUpkeep function + * @param triggerData extra contextual data about the trigger (not used in all code paths) * @dev this one of the core functions called in the hot path * @dev there is a 2nd checkUpkeep function (below) that is being maintained for backwards compatibility * @dev there is an incongruency on what gets returned during failure modes @@ -42,7 +43,7 @@ contract KeeperRegistryLogicA2_1 is KeeperRegistryBase2_1, Chainable { */ function checkUpkeep( uint256 id, - bytes memory checkData + bytes memory triggerData ) public cannotExecute @@ -79,14 +80,10 @@ contract KeeperRegistryLogicA2_1 is KeeperRegistryBase2_1, Chainable { return (false, bytes(""), UpkeepFailureReason.INSUFFICIENT_BALANCE, 0, upkeep.performGas, 0, 0); } - bytes memory callData; - if (triggerType == Trigger.CONDITION) { - callData = abi.encodeWithSelector(CHECK_SELECTOR, checkData); - } else { - callData = bytes.concat(CHECK_LOG_SELECTOR, checkData); - } + bytes memory callData = _checkPayload(id, triggerType, triggerData); + gasUsed = gasleft(); - (bool success, bytes memory result) = upkeep.target.call{gas: s_storage.checkGasLimit}(callData); + (bool success, bytes memory result) = upkeep.forwarder.getTarget().call{gas: s_storage.checkGasLimit}(callData); gasUsed = gasUsed - gasleft(); if (!success) { @@ -157,7 +154,7 @@ contract KeeperRegistryLogicA2_1 is KeeperRegistryBase2_1, Chainable { uint256 linkNative ) { - return checkUpkeep(id, s_checkData[id]); + return checkUpkeep(id, bytes("")); } /** @@ -195,7 +192,7 @@ contract KeeperRegistryLogicA2_1 is KeeperRegistryBase2_1, Chainable { { Upkeep memory upkeep = s_upkeep[id]; gasUsed = gasleft(); - (bool success, bytes memory result) = upkeep.target.call{gas: s_storage.checkGasLimit}(payload); + (bool success, bytes memory result) = upkeep.forwarder.getTarget().call{gas: s_storage.checkGasLimit}(payload); gasUsed = gasUsed - gasleft(); if (!success) { return (false, bytes(""), UpkeepFailureReason.CALLBACK_REVERTED, gasUsed); @@ -231,12 +228,14 @@ contract KeeperRegistryLogicA2_1 is KeeperRegistryBase2_1, Chainable { bytes memory offchainConfig ) public returns (uint256 id) { if (msg.sender != owner() && !s_registrars.contains(msg.sender)) revert OnlyCallableByOwnerOrRegistrar(); + if (!target.isContract()) revert NotAContract(); id = _createID(triggerType); - AutomationForwarder forwarder = new AutomationForwarder(id, target, address(this)); + IAutomationForwarder forwarder = IAutomationForwarder( + address(new AutomationForwarder(target, address(this), i_automationForwarderLogic)) + ); _createUpkeep( id, Upkeep({ - target: target, performGas: gasLimit, balance: 0, maxValidBlocknumber: UINT32_MAX, @@ -367,7 +366,15 @@ contract KeeperRegistryLogicA2_1 is KeeperRegistryBase2_1, Chainable { emit UpkeepMigrated(id, upkeep.balance, destination); } s_expectedLinkBalance = s_expectedLinkBalance - totalBalanceRemaining; - bytes memory encodedUpkeeps = abi.encode(ids, upkeeps, admins, checkDatas, triggerConfigs, offchainConfigs); + bytes memory encodedUpkeeps = abi.encode( + ids, + upkeeps, + new address[](ids.length), + admins, + checkDatas, + triggerConfigs, + offchainConfigs + ); MigratableKeeperRegistryInterfaceV2(destination).receiveUpkeeps( UpkeepTranscoderInterfaceV2(s_storage.transcoder).transcodeUpkeeps( UPKEEP_VERSION_BASE, @@ -381,7 +388,7 @@ contract KeeperRegistryLogicA2_1 is KeeperRegistryBase2_1, Chainable { /** * @notice received upkeeps migrated from another registry * @param encodedUpkeeps the raw upkeep data to import - * @dev this function is never called direcly, it is only called by another registry's migrate function + * @dev this function is never called directly, it is only called by another registry's migrate function */ function receiveUpkeeps(bytes calldata encodedUpkeeps) external { if ( @@ -391,14 +398,17 @@ contract KeeperRegistryLogicA2_1 is KeeperRegistryBase2_1, Chainable { ( uint256[] memory ids, Upkeep[] memory upkeeps, + address[] memory targets, address[] memory upkeepAdmins, bytes[] memory checkDatas, bytes[] memory triggerConfigs, bytes[] memory offchainConfigs - ) = abi.decode(encodedUpkeeps, (uint256[], Upkeep[], address[], bytes[], bytes[], bytes[])); + ) = abi.decode(encodedUpkeeps, (uint256[], Upkeep[], address[], address[], bytes[], bytes[], bytes[])); for (uint256 idx = 0; idx < ids.length; idx++) { if (address(upkeeps[idx].forwarder) == ZERO_ADDRESS) { - upkeeps[idx].forwarder = new AutomationForwarder(ids[idx], upkeeps[idx].target, address(this)); + upkeeps[idx].forwarder = IAutomationForwarder( + address(new AutomationForwarder(targets[idx], address(this), i_automationForwarderLogic)) + ); } _createUpkeep( ids[idx], @@ -415,7 +425,7 @@ contract KeeperRegistryLogicA2_1 is KeeperRegistryBase2_1, Chainable { /** * @notice sets the upkeep trigger config * @param id the upkeepID to change the trigger for - * @param triggerConfig the new triggerconfig + * @param triggerConfig the new trigger config */ function setUpkeepTriggerConfig(uint256 id, bytes calldata triggerConfig) external { _requireAdminAndNotCancelled(id); diff --git a/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryLogicB2_1.sol b/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryLogicB2_1.sol index 8cc0c137453..c34d2a01aaf 100644 --- a/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryLogicB2_1.sol +++ b/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryLogicB2_1.sol @@ -15,8 +15,9 @@ contract KeeperRegistryLogicB2_1 is KeeperRegistryBase2_1 { Mode mode, address link, address linkNativeFeed, - address fastGasFeed - ) KeeperRegistryBase2_1(mode, link, linkNativeFeed, fastGasFeed) {} + address fastGasFeed, + address automationForwarderLogic + ) KeeperRegistryBase2_1(mode, link, linkNativeFeed, fastGasFeed, automationForwarderLogic) {} /////////////////////// // UPKEEP MANAGEMENT // @@ -166,7 +167,7 @@ contract KeeperRegistryLogicB2_1 is KeeperRegistryBase2_1 { ///////////////////////////// /** - * @notice sets the privledge config for an upkeep + * @notice sets the privilege config for an upkeep */ function setUpkeepPrivilegeConfig(uint256 upkeepId, bytes calldata newPrivilegeConfig) external { if (msg.sender != s_storage.upkeepPrivilegeManager) { @@ -188,7 +189,7 @@ contract KeeperRegistryLogicB2_1 is KeeperRegistryBase2_1 { } /** - * @notice allows the owner to withdraw any LINK accidentially sent to the contract + * @notice allows the owner to withdraw any LINK accidentally sent to the contract */ function recoverFunds() external onlyOwner { uint256 total = i_link.balanceOf(address(this)); @@ -239,8 +240,8 @@ contract KeeperRegistryLogicB2_1 is KeeperRegistryBase2_1 { } /** - * @notice sets a generic bytes field used to indicate the privledges that this admin address had - * @param admin the address to set privledges for + * @notice sets a generic bytes field used to indicate the privilege that this admin address had + * @param admin the address to set privilege for * @param newPrivilegeConfig the privileges that this admin has */ function setAdminPrivilegeConfig(address admin, bytes calldata newPrivilegeConfig) external { @@ -255,14 +256,6 @@ contract KeeperRegistryLogicB2_1 is KeeperRegistryBase2_1 { // GETTERS // ///////////// - function getTransmitGasOverhead() external pure returns (uint256) { - return TRANSMIT_GAS_OVERHEAD; - } - - function getCheckGasOverhead() external pure returns (uint256) { - return CHECK_GAS_OVERHEAD; - } - function getConditionalGasOverhead() external pure returns (uint256) { return REGISTRY_CONDITIONAL_OVERHEAD; } @@ -299,6 +292,10 @@ contract KeeperRegistryLogicB2_1 is KeeperRegistryBase2_1 { return address(i_fastGasFeed); } + function getAutomationForwarderLogic() external view returns (address) { + return i_automationForwarderLogic; + } + function upkeepTranscoderVersion() public pure returns (UpkeepFormat) { return UPKEEP_TRANSCODER_VERSION_BASE; } @@ -314,8 +311,9 @@ contract KeeperRegistryLogicB2_1 is KeeperRegistryBase2_1 { */ function getUpkeep(uint256 id) external view returns (UpkeepInfo memory upkeepInfo) { Upkeep memory reg = s_upkeep[id]; + address target = address(reg.forwarder) == address(0) ? address(0) : reg.forwarder.getTarget(); upkeepInfo = UpkeepInfo({ - target: reg.target, + target: target, performGas: reg.performGas, checkData: s_checkData[id], balance: reg.balance, @@ -501,7 +499,14 @@ contract KeeperRegistryLogicB2_1 is KeeperRegistryBase2_1 { /** * @notice returns the upkeep's forwarder contract */ - function getForwarder(uint256 upkeepID) external view returns (AutomationForwarder) { + function getForwarder(uint256 upkeepID) external view returns (IAutomationForwarder) { return s_upkeep[upkeepID].forwarder; } + + /** + * @notice returns the upkeep's forwarder contract + */ + function hasDedupKey(bytes32 dedupKey) external view returns (bool) { + return s_dedupKeys[dedupKey]; + } } diff --git a/contracts/src/v0.8/dev/automation/2_1/UpkeepTranscoder4_0.sol b/contracts/src/v0.8/dev/automation/2_1/UpkeepTranscoder4_0.sol index b4b3b1a97f3..43979bd05bf 100644 --- a/contracts/src/v0.8/dev/automation/2_1/UpkeepTranscoder4_0.sol +++ b/contracts/src/v0.8/dev/automation/2_1/UpkeepTranscoder4_0.sol @@ -2,11 +2,11 @@ pragma solidity 0.8.16; -import "../../../interfaces/automation/UpkeepTranscoderInterfaceV2.sol"; +import "../../../automation/interfaces/UpkeepTranscoderInterfaceV2.sol"; import "../../../interfaces/TypeAndVersionInterface.sol"; import {KeeperRegistryBase2_1 as R21} from "./KeeperRegistryBase2_1.sol"; -import {AutomationForwarder} from "./AutomationForwarder.sol"; -import {AutomationRegistryBaseInterface, UpkeepInfo} from "../../../interfaces/automation/2_0/AutomationRegistryInterface2_0.sol"; +import {IAutomationForwarder} from "./interfaces/IAutomationForwarder.sol"; +import {AutomationRegistryBaseInterface, UpkeepInfo} from "../../../automation/interfaces/2_0/AutomationRegistryInterface2_0.sol"; enum RegistryVersion { V12, @@ -63,7 +63,7 @@ contract UpkeepTranscoder4_0 is UpkeepTranscoderInterfaceV2, TypeAndVersionInter */ string public constant override typeAndVersion = "UpkeepTranscoder 4.0.0"; uint32 internal constant UINT32_MAX = type(uint32).max; - AutomationForwarder internal constant ZERO_FORWARDER = AutomationForwarder(address(0)); + IAutomationForwarder internal constant ZERO_FORWARDER = IAutomationForwarder(address(0)); /** * @notice transcodeUpkeeps transforms upkeep data from the format expected by @@ -91,6 +91,7 @@ contract UpkeepTranscoder4_0 is UpkeepTranscoderInterfaceV2, TypeAndVersionInter if (ids.length != upkeepsV12.length || ids.length != checkDatas.length) { revert InvalidTranscoding(); } + address[] memory targets = new address[](ids.length); address[] memory admins = new address[](ids.length); R21.Upkeep[] memory newUpkeeps = new R21.Upkeep[](ids.length); UpkeepV12 memory upkeepV12; @@ -100,15 +101,15 @@ contract UpkeepTranscoder4_0 is UpkeepTranscoderInterfaceV2, TypeAndVersionInter performGas: upkeepV12.executeGas, maxValidBlocknumber: UINT32_MAX, // maxValidBlocknumber is uint64 in V1, hence a new default value is provided paused: false, // migrated upkeeps are not paused by default - target: upkeepV12.target, forwarder: ZERO_FORWARDER, amountSpent: upkeepV12.amountSpent, balance: upkeepV12.balance, lastPerformedBlockNumber: 0 }); + targets[idx] = upkeepV12.target; admins[idx] = upkeepV12.admin; } - return abi.encode(ids, newUpkeeps, admins, checkDatas, new bytes[](ids.length), new bytes[](ids.length)); + return abi.encode(ids, newUpkeeps, targets, admins, checkDatas, new bytes[](ids.length), new bytes[](ids.length)); } // v1.3 => v2.1 if (fromVersion == uint8(RegistryVersion.V13)) { @@ -119,6 +120,7 @@ contract UpkeepTranscoder4_0 is UpkeepTranscoderInterfaceV2, TypeAndVersionInter if (ids.length != upkeepsV13.length || ids.length != checkDatas.length) { revert InvalidTranscoding(); } + address[] memory targets = new address[](ids.length); address[] memory admins = new address[](ids.length); R21.Upkeep[] memory newUpkeeps = new R21.Upkeep[](ids.length); UpkeepV13 memory upkeepV13; @@ -128,15 +130,15 @@ contract UpkeepTranscoder4_0 is UpkeepTranscoderInterfaceV2, TypeAndVersionInter performGas: upkeepV13.executeGas, maxValidBlocknumber: upkeepV13.maxValidBlocknumber, paused: upkeepV13.paused, - target: upkeepV13.target, forwarder: ZERO_FORWARDER, amountSpent: upkeepV13.amountSpent, balance: upkeepV13.balance, lastPerformedBlockNumber: 0 }); + targets[idx] = upkeepV13.target; admins[idx] = upkeepV13.admin; } - return abi.encode(ids, newUpkeeps, admins, checkDatas, new bytes[](ids.length), new bytes[](ids.length)); + return abi.encode(ids, newUpkeeps, targets, admins, checkDatas, new bytes[](ids.length), new bytes[](ids.length)); } // v2.0 => v2.1 if (fromVersion == uint8(RegistryVersion.V20)) { @@ -146,9 +148,9 @@ contract UpkeepTranscoder4_0 is UpkeepTranscoderInterfaceV2, TypeAndVersionInter revert InvalidTranscoding(); } // bit of a hack - transcodeUpkeeps should be a pure function - AutomationRegistryBaseInterface registry20 = AutomationRegistryBaseInterface(msg.sender); R21.Upkeep[] memory newUpkeeps = new R21.Upkeep[](ids.length); - bytes[] memory offchainConfigs = new bytes[](ids.length); + bytes[] memory emptyBytes = new bytes[](ids.length); + address[] memory targets = new address[](ids.length); UpkeepV20 memory upkeepV20; for (uint256 idx = 0; idx < ids.length; idx++) { upkeepV20 = upkeepsV20[idx]; @@ -156,15 +158,14 @@ contract UpkeepTranscoder4_0 is UpkeepTranscoderInterfaceV2, TypeAndVersionInter performGas: upkeepV20.executeGas, maxValidBlocknumber: upkeepV20.maxValidBlocknumber, paused: upkeepV20.paused, - target: upkeepV20.target, forwarder: ZERO_FORWARDER, amountSpent: upkeepV20.amountSpent, balance: upkeepV20.balance, lastPerformedBlockNumber: 0 }); - offchainConfigs[idx] = registry20.getUpkeep(ids[idx]).offchainConfig; + targets[idx] = upkeepV20.target; } - return abi.encode(ids, newUpkeeps, admins, checkDatas, new bytes[](ids.length), offchainConfigs); + return abi.encode(ids, newUpkeeps, targets, admins, checkDatas, emptyBytes, emptyBytes); } // v2.1 => v2.1 if (fromVersion == uint8(RegistryVersion.V21)) { diff --git a/contracts/src/v0.8/dev/automation/2_1/interfaces/IAutomationForwarder.sol b/contracts/src/v0.8/dev/automation/2_1/interfaces/IAutomationForwarder.sol new file mode 100644 index 00000000000..fbf9743d0ca --- /dev/null +++ b/contracts/src/v0.8/dev/automation/2_1/interfaces/IAutomationForwarder.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {ITypeAndVersion} from "../../../../shared/interfaces/ITypeAndVersion.sol"; +import {IAutomationRegistryConsumer} from "./IAutomationRegistryConsumer.sol"; + +interface IAutomationForwarder is ITypeAndVersion { + function forward(uint256 gasAmount, bytes memory data) external returns (bool success, uint256 gasUsed); + + function updateRegistry(address newRegistry) external; + + function getRegistry() external view returns (IAutomationRegistryConsumer); + + function getTarget() external view returns (address); +} diff --git a/contracts/src/v0.8/dev/automation/2_1/interfaces/IKeeperRegistryMaster.sol b/contracts/src/v0.8/dev/automation/2_1/interfaces/IKeeperRegistryMaster.sol index c7f5482c6ae..cab4d61c5b9 100644 --- a/contracts/src/v0.8/dev/automation/2_1/interfaces/IKeeperRegistryMaster.sol +++ b/contracts/src/v0.8/dev/automation/2_1/interfaces/IKeeperRegistryMaster.sol @@ -1,4 +1,4 @@ -// abi-checksum: 0x6565db16782f234c7deba02db44ac01288fa7e6e063f5b02a4a6825a5826c481 +// abi-checksum: 0x0ed34e4b36bd7b4a5447152c2d61491e6ba7ed944b11e4dfef4fea184708975e // SPDX-License-Identifier: MIT // !! THIS FILE WAS AUTOGENERATED BY abi-to-sol v0.6.6. SEE SOURCE BELOW. !! pragma solidity ^0.8.4; @@ -21,6 +21,8 @@ interface IKeeperRegistryMaster { error InvalidPayee(); error InvalidRecipient(); error InvalidReport(); + error InvalidSigner(); + error InvalidTransmitter(); error InvalidTrigger(); error InvalidTriggerType(); error MaxCheckDataSizeCanOnlyIncrease(); @@ -55,7 +57,7 @@ interface IKeeperRegistryMaster { error UpkeepNotNeeded(); error ValueNotChanged(); event AdminPrivilegeConfigSet(address indexed admin, bytes privilegeConfig); - event CancelledUpkeepReport(uint256 indexed id, bytes32 upkeepTriggerID); + event CancelledUpkeepReport(uint256 indexed id, bytes trigger); event ConfigSet( uint32 previousConfigBlockNumber, bytes32 configDigest, @@ -67,9 +69,10 @@ interface IKeeperRegistryMaster { uint64 offchainConfigVersion, bytes offchainConfig ); + event DedupKeyAdded(bytes32 indexed dedupKey); event FundsAdded(uint256 indexed id, address indexed from, uint96 amount); event FundsWithdrawn(uint256 indexed id, uint256 amount, address to); - event InsufficientFundsUpkeepReport(uint256 indexed id, bytes32 upkeepTriggerID); + event InsufficientFundsUpkeepReport(uint256 indexed id, bytes trigger); event OwnerFundsWithdrawn(uint96 amount); event OwnershipTransferRequested(address indexed from, address indexed to); event OwnershipTransferred(address indexed from, address indexed to); @@ -78,8 +81,8 @@ interface IKeeperRegistryMaster { event PayeeshipTransferRequested(address indexed transmitter, address indexed from, address indexed to); event PayeeshipTransferred(address indexed transmitter, address indexed from, address indexed to); event PaymentWithdrawn(address indexed transmitter, uint256 indexed amount, address indexed to, address payee); - event ReorgedUpkeepReport(uint256 indexed id, bytes32 upkeepTriggerID); - event StaleUpkeepReport(uint256 indexed id, bytes32 upkeepTriggerID); + event ReorgedUpkeepReport(uint256 indexed id, bytes trigger); + event StaleUpkeepReport(uint256 indexed id, bytes trigger); event Transmitted(bytes32 configDigest, uint32 epoch); event Unpaused(address account); event UpkeepAdminTransferRequested(uint256 indexed id, address indexed from, address indexed to); @@ -96,7 +99,7 @@ interface IKeeperRegistryMaster { uint96 totalPayment, uint256 gasUsed, uint256 gasOverhead, - bytes32 upkeepTriggerID + bytes trigger ); event UpkeepPrivilegeConfigSet(uint256 indexed id, bytes privilegeConfig); event UpkeepReceived(uint256 indexed id, uint256 startingBalance, address importedFrom); @@ -122,16 +125,16 @@ interface IKeeperRegistryMaster { address[] memory signers, address[] memory transmitters, uint8 f, - KeeperRegistryBase2_1.OnchainConfig memory onchainConfig, + bytes memory onchainConfigBytes, uint64 offchainConfigVersion, bytes memory offchainConfig ) external; - function setConfig( + function setConfigTypeSafe( address[] memory signers, address[] memory transmitters, uint8 f, - bytes memory onchainConfigBytes, + KeeperRegistryBase2_1.OnchainConfig memory onchainConfig, uint64 offchainConfigVersion, bytes memory offchainConfig ) external; @@ -162,7 +165,7 @@ interface IKeeperRegistryMaster { function checkUpkeep( uint256 id, - bytes memory checkData + bytes memory triggerData ) external returns ( @@ -226,12 +229,12 @@ interface IKeeperRegistryMaster { function getAdminPrivilegeConfig(address admin) external view returns (bytes memory); + function getAutomationForwarderLogic() external view returns (address); + function getBalance(uint256 id) external view returns (uint96 balance); function getCancellationDelay() external pure returns (uint256); - function getCheckGasOverhead() external pure returns (uint256); - function getConditionalGasOverhead() external pure returns (uint256); function getFastGasFeedAddress() external view returns (address); @@ -271,8 +274,6 @@ interface IKeeperRegistryMaster { uint8 f ); - function getTransmitGasOverhead() external pure returns (uint256); - function getTransmitterInfo( address query ) external view returns (bool active, uint8 index, uint96 balance, uint96 lastCollected, address payee); @@ -285,6 +286,8 @@ interface IKeeperRegistryMaster { function getUpkeepTriggerConfig(uint256 upkeepId) external view returns (bytes memory); + function hasDedupKey(bytes32 dedupKey) external view returns (bool); + function pause() external; function pauseUpkeep(uint256 id) external; @@ -372,5 +375,5 @@ interface KeeperRegistryBase2_1 { // THIS FILE WAS AUTOGENERATED FROM THE FOLLOWING ABI JSON: /* -[{"inputs":[{"internalType":"contract KeeperRegistryLogicB2_1","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":[],"name":"InsufficientFunds","type":"error"},{"inputs":[],"name":"InvalidDataLength","type":"error"},{"inputs":[],"name":"InvalidPayee","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidReport","type":"error"},{"inputs":[],"name":"InvalidTrigger","type":"error"},{"inputs":[],"name":"InvalidTriggerType","type":"error"},{"inputs":[],"name":"MaxCheckDataSizeCanOnlyIncrease","type":"error"},{"inputs":[],"name":"MaxPerformDataSizeCanOnlyIncrease","type":"error"},{"inputs":[],"name":"MigrationNotPermitted","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":"OnlyPausedUpkeep","type":"error"},{"inputs":[],"name":"OnlySimulatedBackend","type":"error"},{"inputs":[],"name":"OnlyUnpausedUpkeep","type":"error"},{"inputs":[],"name":"ParameterLengthError","type":"error"},{"inputs":[],"name":"PaymentGreaterThanAllLINK","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":"UpkeepAlreadyExists","type":"error"},{"inputs":[],"name":"UpkeepCancelled","type":"error"},{"inputs":[],"name":"UpkeepNotCanceled","type":"error"},{"inputs":[],"name":"UpkeepNotNeeded","type":"error"},{"inputs":[],"name":"ValueNotChanged","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"},{"indexed":false,"internalType":"bytes32","name":"upkeepTriggerID","type":"bytes32"}],"name":"CancelledUpkeepReport","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":"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":"bytes32","name":"upkeepTriggerID","type":"bytes32"}],"name":"InsufficientFundsUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint96","name":"amount","type":"uint96"}],"name":"OwnerFundsWithdrawn","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":"bytes32","name":"upkeepTriggerID","type":"bytes32"}],"name":"ReorgedUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"upkeepTriggerID","type":"bytes32"}],"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":"bytes32","name":"upkeepTriggerID","type":"bytes32"}],"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":"nonpayable","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"},{"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 KeeperRegistryBase2_1.OnchainConfig","name":"onchainConfig","type":"tuple"},{"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"},{"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":"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":"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 KeeperRegistryLogicB2_1","name":"logicB","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint96","name":"amount","type":"uint96"}],"name":"addFunds","outputs":[],"stateMutability":"nonpayable","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":"enum KeeperRegistryBase2_1.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":"checkData","type":"bytes"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum KeeperRegistryBase2_1.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":"linkNative","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":"enum KeeperRegistryBase2_1.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":"linkNative","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":"enum KeeperRegistryBase2_1.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"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 KeeperRegistryBase2_1.Trigger","name":"triggerType","type":"uint8"},{"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":"target","type":"address"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"bytes","name":"checkData","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"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"setUpkeepTriggerConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum KeeperRegistryBase2_1.Mode","name":"mode","type":"uint8"},{"internalType":"address","name":"link","type":"address"},{"internalType":"address","name":"linkNativeFeed","type":"address"},{"internalType":"address","name":"fastGasFeed","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":"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":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getBalance","outputs":[{"internalType":"uint96","name":"balance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCancellationDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getCheckGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getConditionalGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","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 AutomationForwarder","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkNativeFeedAddress","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":"enum KeeperRegistryBase2_1.Trigger","name":"triggerType","type":"uint8"},{"internalType":"uint32","name":"gasLimit","type":"uint32"}],"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":"getMode","outputs":[{"internalType":"enum KeeperRegistryBase2_1.Mode","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"}],"name":"getPeerRegistryMigrationPermission","outputs":[{"internalType":"enum KeeperRegistryBase2_1.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":[{"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 KeeperRegistryBase2_1.State","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 KeeperRegistryBase2_1.OnchainConfig","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":"getTransmitGasOverhead","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 KeeperRegistryBase2_1.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 KeeperRegistryBase2_1.UpkeepInfo","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":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"pauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"recoverFunds","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 KeeperRegistryBase2_1.MigrationPermission","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":"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":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"unpauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"upkeepTranscoderVersion","outputs":[{"internalType":"enum UpkeepFormat","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"upkeepVersion","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawOwnerFunds","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"}] +[{"inputs":[{"internalType":"contract KeeperRegistryLogicB2_1","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":[],"name":"InsufficientFunds","type":"error"},{"inputs":[],"name":"InvalidDataLength","type":"error"},{"inputs":[],"name":"InvalidPayee","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidReport","type":"error"},{"inputs":[],"name":"InvalidSigner","type":"error"},{"inputs":[],"name":"InvalidTransmitter","type":"error"},{"inputs":[],"name":"InvalidTrigger","type":"error"},{"inputs":[],"name":"InvalidTriggerType","type":"error"},{"inputs":[],"name":"MaxCheckDataSizeCanOnlyIncrease","type":"error"},{"inputs":[],"name":"MaxPerformDataSizeCanOnlyIncrease","type":"error"},{"inputs":[],"name":"MigrationNotPermitted","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":"OnlyPausedUpkeep","type":"error"},{"inputs":[],"name":"OnlySimulatedBackend","type":"error"},{"inputs":[],"name":"OnlyUnpausedUpkeep","type":"error"},{"inputs":[],"name":"ParameterLengthError","type":"error"},{"inputs":[],"name":"PaymentGreaterThanAllLINK","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":"UpkeepAlreadyExists","type":"error"},{"inputs":[],"name":"UpkeepCancelled","type":"error"},{"inputs":[],"name":"UpkeepNotCanceled","type":"error"},{"inputs":[],"name":"UpkeepNotNeeded","type":"error"},{"inputs":[],"name":"ValueNotChanged","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"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"CancelledUpkeepReport","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":"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":"uint96","name":"amount","type":"uint96"}],"name":"OwnerFundsWithdrawn","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":"nonpayable","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":"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 KeeperRegistryBase2_1.OnchainConfig","name":"onchainConfig","type":"tuple"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"setConfigTypeSafe","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":"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 KeeperRegistryLogicB2_1","name":"logicB","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint96","name":"amount","type":"uint96"}],"name":"addFunds","outputs":[],"stateMutability":"nonpayable","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":"enum KeeperRegistryBase2_1.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":"enum KeeperRegistryBase2_1.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":"linkNative","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":"enum KeeperRegistryBase2_1.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":"linkNative","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":"enum KeeperRegistryBase2_1.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"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 KeeperRegistryBase2_1.Trigger","name":"triggerType","type":"uint8"},{"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":"target","type":"address"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"bytes","name":"checkData","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"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"setUpkeepTriggerConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum KeeperRegistryBase2_1.Mode","name":"mode","type":"uint8"},{"internalType":"address","name":"link","type":"address"},{"internalType":"address","name":"linkNativeFeed","type":"address"},{"internalType":"address","name":"fastGasFeed","type":"address"},{"internalType":"address","name":"automationForwarderLogic","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":"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":"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":[],"name":"getCancellationDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getConditionalGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","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":"getLinkAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkNativeFeedAddress","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":"enum KeeperRegistryBase2_1.Trigger","name":"triggerType","type":"uint8"},{"internalType":"uint32","name":"gasLimit","type":"uint32"}],"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":"getMode","outputs":[{"internalType":"enum KeeperRegistryBase2_1.Mode","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"}],"name":"getPeerRegistryMigrationPermission","outputs":[{"internalType":"enum KeeperRegistryBase2_1.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":[{"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 KeeperRegistryBase2_1.State","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 KeeperRegistryBase2_1.OnchainConfig","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":[{"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 KeeperRegistryBase2_1.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 KeeperRegistryBase2_1.UpkeepInfo","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":[{"internalType":"bytes32","name":"dedupKey","type":"bytes32"}],"name":"hasDedupKey","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[],"name":"recoverFunds","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 KeeperRegistryBase2_1.MigrationPermission","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":"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":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"unpauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"upkeepTranscoderVersion","outputs":[{"internalType":"enum UpkeepFormat","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"upkeepVersion","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawOwnerFunds","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"}] */ diff --git a/contracts/src/v0.8/dev/automation/2_1/interfaces/ILogAutomation.sol b/contracts/src/v0.8/dev/automation/2_1/interfaces/ILogAutomation.sol index ce405fdef0e..ebb098ee31c 100644 --- a/contracts/src/v0.8/dev/automation/2_1/interfaces/ILogAutomation.sol +++ b/contracts/src/v0.8/dev/automation/2_1/interfaces/ILogAutomation.sol @@ -22,13 +22,17 @@ interface ILogAutomation { * method. * @param log the raw log data matching the filter that this contract has * registered as a trigger + * @param checkData user-specified extra data to provide context to this upkeep * @return upkeepNeeded boolean to indicate whether the keeper should call * performUpkeep or not. * @return performData bytes that the keeper should call performUpkeep with, if * upkeep is needed. If you would like to encode data to decode later, try * `abi.encode`. */ - function checkLog(Log calldata log) external returns (bool upkeepNeeded, bytes memory performData); + function checkLog( + Log calldata log, + bytes memory checkData + ) external returns (bool upkeepNeeded, bytes memory performData); /** * @notice method that is actually executed by the keepers, via the registry. diff --git a/contracts/src/v0.8/dev/automation/2_1/test/AutomationForwarder.t.sol b/contracts/src/v0.8/dev/automation/2_1/test/AutomationForwarder.t.sol index 2b5d76e98d1..d876def8bf0 100644 --- a/contracts/src/v0.8/dev/automation/2_1/test/AutomationForwarder.t.sol +++ b/contracts/src/v0.8/dev/automation/2_1/test/AutomationForwarder.t.sol @@ -2,7 +2,9 @@ pragma solidity 0.8.16; import {IAutomationRegistryConsumer} from "../interfaces/IAutomationRegistryConsumer.sol"; +import {IAutomationForwarder} from "../interfaces/IAutomationForwarder.sol"; import {AutomationForwarder} from "../AutomationForwarder.sol"; +import {AutomationForwarderLogic} from "../AutomationForwarderLogic.sol"; import {MockKeeperRegistry2_1} from "../mocks/MockKeeperRegistry2_1.sol"; import {UpkeepCounter} from "../mocks/UpkeepCounter.sol"; import {BaseTest} from "./BaseTest.t.sol"; @@ -11,7 +13,8 @@ import {BaseTest} from "./BaseTest.t.sol"; // forge test --match-path src/v0.8/dev/automation/2_1/test/AutomationForwarder.t.sol contract AutomationForwarderSetUp is BaseTest { - AutomationForwarder internal forwarder; + IAutomationForwarder internal forwarder; + AutomationForwarderLogic internal logicContract; IAutomationRegistryConsumer internal default_registry; UpkeepCounter internal default_target; uint256 constant GAS = 1e18; @@ -21,7 +24,10 @@ contract AutomationForwarderSetUp is BaseTest { default_registry = IAutomationRegistryConsumer(new MockKeeperRegistry2_1()); default_target = new UpkeepCounter(10000, 1); vm.startPrank(address(default_registry)); - forwarder = new AutomationForwarder(1, address(default_target), address(default_registry)); + logicContract = new AutomationForwarderLogic(); + forwarder = IAutomationForwarder( + address(new AutomationForwarder(address(default_target), address(default_registry), address(logicContract))) + ); // OWNER not necessary? OWNER = address(default_registry); } @@ -57,7 +63,7 @@ contract AutomationForwarder_forward is AutomationForwarderSetUp { uint256 prevCount = default_target.counter(); bytes memory selector = getSelector("performUpkeep(bytes)", ""); changePrank(STRANGER); - vm.expectRevert(AutomationForwarder.NotAuthorized.selector); + vm.expectRevert(); (bool val, uint256 gasUsed) = forwarder.forward(GAS, selector); assertFalse(val); assertEq(gasUsed, 0); @@ -77,7 +83,7 @@ contract AutomationForwarder_updateRegistry is AutomationForwarderSetUp { function testNotFromRegistryNotAuthorizedReverts() public { address newRegistry = address(1); changePrank(STRANGER); - vm.expectRevert(AutomationForwarder.NotAuthorized.selector); + vm.expectRevert(); forwarder.updateRegistry(address(newRegistry)); } } diff --git a/contracts/src/v0.8/dev/automation/CanaryUpkeep1_2.sol b/contracts/src/v0.8/dev/automation/CanaryUpkeep1_2.sol index 6e24fa9e2ca..bf711eb565f 100644 --- a/contracts/src/v0.8/dev/automation/CanaryUpkeep1_2.sol +++ b/contracts/src/v0.8/dev/automation/CanaryUpkeep1_2.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.6; -import "../../interfaces/automation/KeeperCompatibleInterface.sol"; -import "../../interfaces/automation/1_2/KeeperRegistryInterface1_2.sol"; -import "../../ConfirmedOwner.sol"; +import "../../automation/interfaces/KeeperCompatibleInterface.sol"; +import "../../automation/interfaces/1_2/KeeperRegistryInterface1_2.sol"; +import "../../shared/access/ConfirmedOwner.sol"; error NoKeeperNodes(); error InsufficientInterval(); diff --git a/contracts/src/v0.8/dev/automation/UpkeepTranscoder3_0.sol b/contracts/src/v0.8/dev/automation/UpkeepTranscoder3_0.sol index 0cb54ce09bd..618f97db8fd 100644 --- a/contracts/src/v0.8/dev/automation/UpkeepTranscoder3_0.sol +++ b/contracts/src/v0.8/dev/automation/UpkeepTranscoder3_0.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.6; -import "../../interfaces/automation/UpkeepTranscoderInterface.sol"; +import "../../automation/interfaces/UpkeepTranscoderInterface.sol"; import "../../interfaces/TypeAndVersionInterface.sol"; import {Upkeep as UpkeepV1} from "../../automation/1_2/KeeperRegistry1_2.sol"; import {Upkeep as UpkeepV2} from "../../automation/1_3/KeeperRegistryBase1_3.sol"; diff --git a/contracts/src/v0.8/dev/automation/tests/LogTriggeredFeedLookup.sol b/contracts/src/v0.8/dev/automation/tests/LogTriggeredFeedLookup.sol index 3aa2b187b86..f7861c34554 100644 --- a/contracts/src/v0.8/dev/automation/tests/LogTriggeredFeedLookup.sol +++ b/contracts/src/v0.8/dev/automation/tests/LogTriggeredFeedLookup.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.16; import {ILogAutomation, Log} from "../2_1/interfaces/ILogAutomation.sol"; import "../2_1/interfaces/FeedLookupCompatibleInterface.sol"; -import {ArbSys} from "../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; +import {ArbSys} from "../../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; interface IVerifierProxy { /** @@ -36,12 +36,14 @@ contract LogTriggeredFeedLookup is ILogAutomation, FeedLookupCompatibleInterface // for mercury config bool public useArbitrumBlockNum; + bool public verify; string[] public feedsHex = ["0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"]; string public feedParamKey = "feedIdHex"; string public timeParamKey = "blockNumber"; - constructor(bool _useArbitrumBlockNum) { + constructor(bool _useArbitrumBlockNum, bool _verify) { useArbitrumBlockNum = _useArbitrumBlockNum; + verify = _verify; } function setTimeParamKey(string memory timeParam) external { @@ -56,7 +58,10 @@ contract LogTriggeredFeedLookup is ILogAutomation, FeedLookupCompatibleInterface feedsHex = newFeeds; } - function checkLog(Log calldata log) external override returns (bool upkeepNeeded, bytes memory performData) { + function checkLog( + Log calldata log, + bytes memory + ) external override returns (bool upkeepNeeded, bytes memory performData) { uint256 blockNum = getBlockNumber(); // filter by event signature @@ -78,7 +83,10 @@ contract LogTriggeredFeedLookup is ILogAutomation, FeedLookupCompatibleInterface (bytes[] memory values, bytes memory extraData) = abi.decode(performData, (bytes[], bytes)); (uint256 orderId, uint256 amount, address exchange) = abi.decode(extraData, (uint256, uint256, address)); - bytes memory verifiedResponse; // = VERIFIER.verify(values[0]); + bytes memory verifiedResponse = ""; + if (verify) { + verifiedResponse = VERIFIER.verify(values[0]); + } emit PerformingLogTriggerUpkeep( tx.origin, @@ -94,7 +102,7 @@ contract LogTriggeredFeedLookup is ILogAutomation, FeedLookupCompatibleInterface function checkCallback( bytes[] memory values, bytes memory extraData - ) external view override returns (bool upkeepNeeded, bytes memory performData) { + ) external view override returns (bool, bytes memory) { // do sth about the chainlinkBlob data in values and extraData bytes memory performData = abi.encode(values, extraData); return (true, performData); diff --git a/contracts/src/v0.8/dev/automation/tests/LogUpkeepCounter.sol b/contracts/src/v0.8/dev/automation/tests/LogUpkeepCounter.sol index 73795b3b1b1..84e53b65493 100644 --- a/contracts/src/v0.8/dev/automation/tests/LogUpkeepCounter.sol +++ b/contracts/src/v0.8/dev/automation/tests/LogUpkeepCounter.sol @@ -48,7 +48,7 @@ contract LogUpkeepCounter is ILogAutomation { emit Trigger(1, 2, 3); } - function checkLog(Log calldata log) external view override returns (bool, bytes memory) { + function checkLog(Log calldata log, bytes memory) external view override returns (bool, bytes memory) { require(eligible(), "not eligible"); if (log.topics[0] == sig1 || log.topics[0] == sig2 || log.topics[0] == sig3 || log.topics[0] == sig4) { return (true, abi.encode(log)); diff --git a/contracts/src/v0.8/dev/automation/upkeeps/LinkAvailableBalanceMonitor.sol b/contracts/src/v0.8/dev/automation/upkeeps/LinkAvailableBalanceMonitor.sol index 45e5e971f6a..1ed1237f615 100644 --- a/contracts/src/v0.8/dev/automation/upkeeps/LinkAvailableBalanceMonitor.sol +++ b/contracts/src/v0.8/dev/automation/upkeeps/LinkAvailableBalanceMonitor.sol @@ -2,8 +2,8 @@ pragma solidity 0.8.6; -import "../../../ConfirmedOwner.sol"; -import "../../../interfaces/automation/KeeperCompatibleInterface.sol"; +import "../../../shared/access/ConfirmedOwner.sol"; +import "../../../automation/interfaces/KeeperCompatibleInterface.sol"; import "../../../vendor/openzeppelin-solidity/v4.7.0/contracts/security/Pausable.sol"; import "../../../vendor/openzeppelin-solidity/v4.7.0/contracts/token/ERC20/IERC20.sol"; import "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableMap.sol"; diff --git a/contracts/src/v0.8/dev/interfaces/IArbitrumDelayedInbox.sol b/contracts/src/v0.8/dev/interfaces/IArbitrumDelayedInbox.sol index cb2228db72b..d209551b0c9 100644 --- a/contracts/src/v0.8/dev/interfaces/IArbitrumDelayedInbox.sol +++ b/contracts/src/v0.8/dev/interfaces/IArbitrumDelayedInbox.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IInbox.sol"; +import "../../vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IInbox.sol"; /** * @notice This interface extends Arbitrum's IInbox interface to include diff --git a/contracts/src/v0.8/dev/interfaces/IVRFCoordinatorV2Plus.sol b/contracts/src/v0.8/dev/interfaces/IVRFCoordinatorV2Plus.sol index 3b6f5b6773c..ea37fb83875 100644 --- a/contracts/src/v0.8/dev/interfaces/IVRFCoordinatorV2Plus.sol +++ b/contracts/src/v0.8/dev/interfaces/IVRFCoordinatorV2Plus.sol @@ -36,7 +36,7 @@ interface IVRFCoordinatorV2Plus { * numWords - The number of uint256 random values you'd like to receive * in your fulfillRandomWords callback. Note these numbers are expanded in a * secure way by the VRFCoordinator from a single random value supplied by the oracle. - * nativePayment - Whether payment should be made in ETH or LINK. + * extraArgs - abi-encoded extra args * @return requestId - A unique identifier of the request. Can be used to match * a request to a response in fulfillRandomWords. */ @@ -110,4 +110,6 @@ interface IVRFCoordinatorV2Plus { * otherwise. */ function pendingRequestExists(uint256 subId) external view returns (bool); + + function fundSubscriptionWithEth(uint256 subId) external payable; } diff --git a/contracts/src/v0.8/dev/interfaces/IVRFSubscriptionV2Plus.sol b/contracts/src/v0.8/dev/interfaces/IVRFSubscriptionV2Plus.sol index 741f8f59066..47b31d98bd1 100644 --- a/contracts/src/v0.8/dev/interfaces/IVRFSubscriptionV2Plus.sol +++ b/contracts/src/v0.8/dev/interfaces/IVRFSubscriptionV2Plus.sol @@ -60,12 +60,25 @@ interface IVRFSubscriptionV2Plus { * @param subId - ID of the subscription * @return balance - LINK balance of the subscription in juels. * @return ethBalance - ETH balance of the subscription in wei. + * @return reqCount - Requests count of subscription. * @return owner - owner of the subscription. * @return consumers - list of consumer address which are able to use this subscription. */ function getSubscription( uint256 subId - ) external view returns (uint96 balance, uint96 ethBalance, address owner, address[] memory consumers); + ) + external + view + returns (uint96 balance, uint96 ethBalance, uint64 reqCount, address owner, address[] memory consumers); + + /** + * @notice Paginate through all active VRF subscriptions. + * @param startIndex index of the subscription to start from + * @param maxCount maximum number of subscriptions to return, 0 to return all + * @dev the order of IDs in the list is **not guaranteed**, therefore, if making successive calls, one + * @dev should consider keeping the blockheight constant to ensure a holistic picture of the contract state + */ + function getActiveSubscriptionIds(uint256 startIndex, uint256 maxCount) external view returns (uint256[] memory); /** * @notice Fund a subscription with ETH. diff --git a/contracts/src/v0.8/dev/ocr2/OCR2Base.sol b/contracts/src/v0.8/dev/ocr2/OCR2Base.sol index 17bb2bfe84e..5e50d99f213 100644 --- a/contracts/src/v0.8/dev/ocr2/OCR2Base.sol +++ b/contracts/src/v0.8/dev/ocr2/OCR2Base.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../ConfirmedOwner.sol"; +import "../../shared/access/ConfirmedOwner.sol"; import "./OCR2Abstract.sol"; /** diff --git a/contracts/src/v0.8/dev/transmission/4337/Paymaster.sol b/contracts/src/v0.8/dev/transmission/4337/Paymaster.sol index cd474ddb47d..52d50d2e2c7 100644 --- a/contracts/src/v0.8/dev/transmission/4337/Paymaster.sol +++ b/contracts/src/v0.8/dev/transmission/4337/Paymaster.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.15; -import "../../vendor/entrypoint/interfaces/IPaymaster.sol"; +import "../../../vendor/entrypoint/interfaces/IPaymaster.sol"; import "./SCALibrary.sol"; -import "../../vendor/entrypoint/core/Helpers.sol"; -import "../../../interfaces/LinkTokenInterface.sol"; +import "../../../vendor/entrypoint/core/Helpers.sol"; +import "../../../shared/interfaces/LinkTokenInterface.sol"; import "../../../interfaces/AggregatorV3Interface.sol"; import "./SCALibrary.sol"; -import "../../../ConfirmedOwner.sol"; +import "../../../shared/access/ConfirmedOwner.sol"; /// @dev LINK token paymaster implementation. /// TODO: more documentation. diff --git a/contracts/src/v0.8/dev/transmission/4337/SCA.sol b/contracts/src/v0.8/dev/transmission/4337/SCA.sol index 5013d7f5d21..bf1ddf41af9 100644 --- a/contracts/src/v0.8/dev/transmission/4337/SCA.sol +++ b/contracts/src/v0.8/dev/transmission/4337/SCA.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT -import "../../vendor/entrypoint/interfaces/IAccount.sol"; +import "../../../vendor/entrypoint/interfaces/IAccount.sol"; import "./SCALibrary.sol"; -import "../../vendor/entrypoint/core/Helpers.sol"; +import "../../../vendor/entrypoint/core/Helpers.sol"; /// TODO: decide on a compiler version. Must not be dynamic, and must be > 0.8.12. pragma solidity 0.8.15; diff --git a/contracts/src/v0.8/dev/vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol b/contracts/src/v0.8/dev/vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol deleted file mode 100644 index e27417018ff..00000000000 --- a/contracts/src/v0.8/dev/vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol +++ /dev/null @@ -1,39 +0,0 @@ -pragma solidity >=0.4.21 <0.9.0; - -interface ArbGasInfo { - // return gas prices in wei, assuming the specified aggregator is used - // ( - // per L2 tx, - // per L1 calldata unit, (zero byte = 4 units, nonzero byte = 16 units) - // per storage allocation, - // per ArbGas base, - // per ArbGas congestion, - // per ArbGas total - // ) - function getPricesInWeiWithAggregator(address aggregator) external view returns (uint, uint, uint, uint, uint, uint); - - // return gas prices in wei, as described above, assuming the caller's preferred aggregator is used - // if the caller hasn't specified a preferred aggregator, the default aggregator is assumed - function getPricesInWei() external view returns (uint, uint, uint, uint, uint, uint); - - // return prices in ArbGas (per L2 tx, per L1 calldata unit, per storage allocation), - // assuming the specified aggregator is used - function getPricesInArbGasWithAggregator(address aggregator) external view returns (uint, uint, uint); - - // return gas prices in ArbGas, as described above, assuming the caller's preferred aggregator is used - // if the caller hasn't specified a preferred aggregator, the default aggregator is assumed - function getPricesInArbGas() external view returns (uint, uint, uint); - - // return gas accounting parameters (speedLimitPerSecond, gasPoolMax, maxTxGasLimit) - function getGasAccountingParams() external view returns (uint, uint, uint); - - // get ArbOS's estimate of the L1 gas price in wei - function getL1GasPriceEstimate() external view returns(uint); - - // set ArbOS's estimate of the L1 gas price in wei - // reverts unless called by chain owner or designated gas oracle (if any) - function setL1GasPriceEstimate(uint priceInWei) external; - - // get L1 gas fees paid by the current transaction (txBaseFeeWei, calldataFeeWei) - function getCurrentTxL1GasFees() external view returns(uint); -} \ No newline at end of file diff --git a/contracts/src/v0.8/dev/vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol b/contracts/src/v0.8/dev/vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol deleted file mode 100644 index 6966acb8a21..00000000000 --- a/contracts/src/v0.8/dev/vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2021-2022, Offchain Labs, Inc. -// For license information, see https://github.com/nitro/blob/master/LICENSE -// SPDX-License-Identifier: BUSL-1.1 - -pragma solidity >=0.4.21 <0.9.0; - -/** - * @title System level functionality - * @notice For use by contracts to interact with core L2-specific functionality. - * Precompiled contract that exists in every Arbitrum chain at address(100), 0x0000000000000000000000000000000000000064. - */ -interface ArbSys { - /** - * @notice Get Arbitrum block number (distinct from L1 block number; Arbitrum genesis block has block number 0) - * @return block number as int - */ - function arbBlockNumber() external view returns (uint256); - - /** - * @notice Get Arbitrum block hash (reverts unless currentBlockNum-256 <= arbBlockNum < currentBlockNum) - * @return block hash - */ - function arbBlockHash(uint256 arbBlockNum) external view returns (bytes32); - - /** - * @notice Gets the rollup's unique chain identifier - * @return Chain identifier as int - */ - function arbChainID() external view returns (uint256); - - /** - * @notice Get internal version number identifying an ArbOS build - * @return version number as int - */ - function arbOSVersion() external view returns (uint256); - - /** - * @notice Returns 0 since Nitro has no concept of storage gas - * @return uint 0 - */ - function getStorageGasAvailable() external view returns (uint256); - - /** - * @notice (deprecated) check if current call is top level (meaning it was triggered by an EoA or a L1 contract) - * @dev this call has been deprecated and may be removed in a future release - * @return true if current execution frame is not a call by another L2 contract - */ - function isTopLevelCall() external view returns (bool); - - /** - * @notice map L1 sender contract address to its L2 alias - * @param sender sender address - * @param unused argument no longer used - * @return aliased sender address - */ - function mapL1SenderContractAddressToL2Alias(address sender, address unused) - external - pure - returns (address); - - /** - * @notice check if the caller (of this caller of this) is an aliased L1 contract address - * @return true iff the caller's address is an alias for an L1 contract address - */ - function wasMyCallersAddressAliased() external view returns (bool); - - /** - * @notice return the address of the caller (of this caller of this), without applying L1 contract address aliasing - * @return address of the caller's caller, without applying L1 contract address aliasing - */ - function myCallersAddressWithoutAliasing() external view returns (address); - - /** - * @notice Send given amount of Eth to dest from sender. - * This is a convenience function, which is equivalent to calling sendTxToL1 with empty data. - * @param destination recipient address on L1 - * @return unique identifier for this L2-to-L1 transaction. - */ - function withdrawEth(address destination) external payable returns (uint256); - - /** - * @notice Send a transaction to L1 - * @dev it is not possible to execute on the L1 any L2-to-L1 transaction which contains data - * to a contract address without any code (as enforced by the Bridge contract). - * @param destination recipient address on L1 - * @param data (optional) calldata for L1 contract call - * @return a unique identifier for this L2-to-L1 transaction. - */ - function sendTxToL1(address destination, bytes calldata data) - external - payable - returns (uint256); - - /** - * @notice Get send Merkle tree state - * @return size number of sends in the history - * @return root root hash of the send history - * @return partials hashes of partial subtrees in the send history tree - */ - function sendMerkleTreeState() - external - view - returns ( - uint256 size, - bytes32 root, - bytes32[] memory partials - ); - - /** - * @notice creates a send txn from L2 to L1 - * @param position = (level << 192) + leaf = (0 << 192) + leaf = leaf - */ - event L2ToL1Tx( - address caller, - address indexed destination, - uint256 indexed hash, - uint256 indexed position, - uint256 arbBlockNum, - uint256 ethBlockNum, - uint256 timestamp, - uint256 callvalue, - bytes data - ); - - /// @dev DEPRECATED in favour of the new L2ToL1Tx event above after the nitro upgrade - event L2ToL1Transaction( - address caller, - address indexed destination, - uint256 indexed uniqueId, - uint256 indexed batchNumber, - uint256 indexInBatch, - uint256 arbBlockNum, - uint256 ethBlockNum, - uint256 timestamp, - uint256 callvalue, - bytes data - ); - - /** - * @notice logs a merkle branch for proof synthesis - * @param reserved an index meant only to align the 4th index with L2ToL1Transaction's 4th event - * @param hash the merkle hash - * @param position = (level << 192) + leaf - */ - event SendMerkleUpdate( - uint256 indexed reserved, - bytes32 indexed hash, - uint256 indexed position - ); -} diff --git a/contracts/src/v0.8/dev/vendor/@eth-optimism/contracts/0.8.6/contracts/L2/predeploys/OVM_GasPriceOracle.sol b/contracts/src/v0.8/dev/vendor/@eth-optimism/contracts/0.8.6/contracts/L2/predeploys/OVM_GasPriceOracle.sol deleted file mode 100644 index 2ab825f8333..00000000000 --- a/contracts/src/v0.8/dev/vendor/@eth-optimism/contracts/0.8.6/contracts/L2/predeploys/OVM_GasPriceOracle.sol +++ /dev/null @@ -1,162 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.6; - -/* External Imports */ -import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; - -/** - * @title OVM_GasPriceOracle - * @dev This contract exposes the current l2 gas price, a measure of how congested the network - * currently is. This measure is used by the Sequencer to determine what fee to charge for - * transactions. When the system is more congested, the l2 gas price will increase and fees - * will also increase as a result. - * - * All public variables are set while generating the initial L2 state. The - * constructor doesn't run in practice as the L2 state generation script uses - * the deployed bytecode instead of running the initcode. - */ -contract OVM_GasPriceOracle is Ownable { - /************* - * Variables * - *************/ - - // Current L2 gas price - uint256 public gasPrice; - // Current L1 base fee - uint256 public l1BaseFee; - // Amortized cost of batch submission per transaction - uint256 public overhead; - // Value to scale the fee up by - uint256 public scalar; - // Number of decimals of the scalar - uint256 public decimals; - - /*************** - * Constructor * - ***************/ - - /** - * @param _owner Address that will initially own this contract. - */ - constructor(address _owner) Ownable() { - transferOwnership(_owner); - } - - /********** - * Events * - **********/ - - event GasPriceUpdated(uint256); - event L1BaseFeeUpdated(uint256); - event OverheadUpdated(uint256); - event ScalarUpdated(uint256); - event DecimalsUpdated(uint256); - - /******************** - * Public Functions * - ********************/ - - /** - * Allows the owner to modify the l2 gas price. - * @param _gasPrice New l2 gas price. - */ - // slither-disable-next-line external-function - function setGasPrice(uint256 _gasPrice) public onlyOwner { - gasPrice = _gasPrice; - emit GasPriceUpdated(_gasPrice); - } - - /** - * Allows the owner to modify the l1 base fee. - * @param _baseFee New l1 base fee - */ - // slither-disable-next-line external-function - function setL1BaseFee(uint256 _baseFee) public onlyOwner { - l1BaseFee = _baseFee; - emit L1BaseFeeUpdated(_baseFee); - } - - /** - * Allows the owner to modify the overhead. - * @param _overhead New overhead - */ - // slither-disable-next-line external-function - function setOverhead(uint256 _overhead) public onlyOwner { - overhead = _overhead; - emit OverheadUpdated(_overhead); - } - - /** - * Allows the owner to modify the scalar. - * @param _scalar New scalar - */ - // slither-disable-next-line external-function - function setScalar(uint256 _scalar) public onlyOwner { - scalar = _scalar; - emit ScalarUpdated(_scalar); - } - - /** - * Allows the owner to modify the decimals. - * @param _decimals New decimals - */ - // slither-disable-next-line external-function - function setDecimals(uint256 _decimals) public onlyOwner { - decimals = _decimals; - emit DecimalsUpdated(_decimals); - } - - /** - * Computes the L1 portion of the fee - * based on the size of the RLP encoded tx - * and the current l1BaseFee - * @param _data Unsigned RLP encoded tx, 6 elements - * @return L1 fee that should be paid for the tx - */ - // slither-disable-next-line external-function - function getL1Fee(bytes memory _data) public view returns (uint256) { - uint256 l1GasUsed = getL1GasUsed(_data); - uint256 l1Fee = l1GasUsed * l1BaseFee; - uint256 divisor = 10**decimals; - uint256 unscaled = l1Fee * scalar; - uint256 scaled = unscaled / divisor; - return scaled; - } - - // solhint-disable max-line-length - /** - * Computes the amount of L1 gas used for a transaction - * The overhead represents the per batch gas overhead of - * posting both transaction and state roots to L1 given larger - * batch sizes. - * 4 gas for 0 byte - * https://github.com/ethereum/go-ethereum/blob/9ada4a2e2c415e6b0b51c50e901336872e028872/params/protocol_params.go#L33 - * 16 gas for non zero byte - * https://github.com/ethereum/go-ethereum/blob/9ada4a2e2c415e6b0b51c50e901336872e028872/params/protocol_params.go#L87 - * This will need to be updated if calldata gas prices change - * Account for the transaction being unsigned - * Padding is added to account for lack of signature on transaction - * 1 byte for RLP V prefix - * 1 byte for V - * 1 byte for RLP R prefix - * 32 bytes for R - * 1 byte for RLP S prefix - * 32 bytes for S - * Total: 68 bytes of padding - * @param _data Unsigned RLP encoded tx, 6 elements - * @return Amount of L1 gas used for a transaction - */ - // solhint-enable max-line-length - function getL1GasUsed(bytes memory _data) public view returns (uint256) { - uint256 total = 0; - for (uint256 i = 0; i < _data.length; i++) { - if (_data[i] == 0) { - total += 4; - } else { - total += 16; - } - } - uint256 unsigned = total + overhead; - return unsigned + (68 * 16); - } -} \ No newline at end of file diff --git a/contracts/src/v0.8/dev/vrf/BlockhashStore.sol b/contracts/src/v0.8/dev/vrf/BlockhashStore.sol new file mode 100644 index 00000000000..107746f8019 --- /dev/null +++ b/contracts/src/v0.8/dev/vrf/BlockhashStore.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.6; + +import "../../ChainSpecificUtil.sol"; + +/** + * @title BlockhashStore + * @notice This contract provides a way to access blockhashes older than + * the 256 block limit imposed by the BLOCKHASH opcode. + * You may assume that any blockhash stored by the contract is correct. + * Note that the contract depends on the format of serialized Ethereum + * blocks. If a future hardfork of Ethereum changes that format, the + * logic in this contract may become incorrect and an updated version + * would have to be deployed. + */ +contract BlockhashStore { + mapping(uint => bytes32) internal s_blockhashes; + + /** + * @notice stores blockhash of a given block, assuming it is available through BLOCKHASH + * @param n the number of the block whose blockhash should be stored + */ + function store(uint256 n) public { + bytes32 h = ChainSpecificUtil.getBlockhash(uint64(n)); + require(h != 0x0, "blockhash(n) failed"); + s_blockhashes[n] = h; + } + + /** + * @notice stores blockhash of the earliest block still available through BLOCKHASH. + */ + function storeEarliest() external { + store(ChainSpecificUtil.getBlockNumber() - 256); + } + + /** + * @notice stores blockhash after verifying blockheader of child/subsequent block + * @param n the number of the block whose blockhash should be stored + * @param header the rlp-encoded blockheader of block n+1. We verify its correctness by checking + * that it hashes to a stored blockhash, and then extract parentHash to get the n-th blockhash. + */ + function storeVerifyHeader(uint256 n, bytes memory header) public { + require(keccak256(header) == s_blockhashes[n + 1], "header has unknown blockhash"); + + // At this point, we know that header is the correct blockheader for block n+1. + + // The header is an rlp-encoded list. The head item of that list is the 32-byte blockhash of the parent block. + // Based on how rlp works, we know that blockheaders always have the following form: + // 0xf9____a0PARENTHASH... + // ^ ^ ^ + // | | | + // | | +--- PARENTHASH is 32 bytes. rlpenc(PARENTHASH) is 0xa || PARENTHASH. + // | | + // | +--- 2 bytes containing the sum of the lengths of the encoded list items + // | + // +--- 0xf9 because we have a list and (sum of lengths of encoded list items) fits exactly into two bytes. + // + // As a consequence, the PARENTHASH is always at offset 4 of the rlp-encoded block header. + + bytes32 parentHash; + assembly { + parentHash := mload(add(header, 36)) // 36 = 32 byte offset for length prefix of ABI-encoded array + // + 4 byte offset of PARENTHASH (see above) + } + + s_blockhashes[n] = parentHash; + } + + /** + * @notice gets a blockhash from the store. If no hash is known, this function reverts. + * @param n the number of the block whose blockhash should be returned + */ + function getBlockhash(uint256 n) external view returns (bytes32) { + bytes32 h = s_blockhashes[n]; + require(h != 0x0, "blockhash not found in store"); + return h; + } +} diff --git a/contracts/src/v0.8/dev/vrf/SubscriptionAPI.sol b/contracts/src/v0.8/dev/vrf/SubscriptionAPI.sol index 69f96b5683f..3113385ecac 100644 --- a/contracts/src/v0.8/dev/vrf/SubscriptionAPI.sol +++ b/contracts/src/v0.8/dev/vrf/SubscriptionAPI.sol @@ -1,15 +1,20 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../interfaces/LinkTokenInterface.sol"; -import "../../ConfirmedOwner.sol"; -import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; -import "../../interfaces/ERC677ReceiverInterface.sol"; +import "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import "../../shared/interfaces/LinkTokenInterface.sol"; +import "../../shared/access/ConfirmedOwner.sol"; +import "../../interfaces/AggregatorV3Interface.sol"; +import "../../shared/interfaces/IERC677Receiver.sol"; import "../interfaces/IVRFSubscriptionV2Plus.sol"; -abstract contract SubscriptionAPI is ConfirmedOwner, ReentrancyGuard, ERC677ReceiverInterface, IVRFSubscriptionV2Plus { +abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscriptionV2Plus { + using EnumerableSet for EnumerableSet.UintSet; + /// @dev may not be provided upon construction on some chains due to lack of availability LinkTokenInterface public LINK; + /// @dev may not be provided upon construction on some chains due to lack of availability + AggregatorV3Interface public LINK_ETH_FEED; // We need to maintain a list of consuming addresses. // This bound ensures we are able to loop over them as needed. @@ -29,6 +34,7 @@ abstract contract SubscriptionAPI is ConfirmedOwner, ReentrancyGuard, ERC677Rece event EthFundsRecovered(address to, uint256 amount); error LinkAlreadySet(); error FailedToSendEther(); + error IndexOutOfRange(); // We use the subscription struct (1 word) // at fulfillment time. @@ -38,8 +44,7 @@ abstract contract SubscriptionAPI is ConfirmedOwner, ReentrancyGuard, ERC677Rece // a uint96 is large enough to hold around ~8e28 wei, or 80 billion ether. // That should be enough to cover most (if not all) subscriptions. uint96 ethBalance; // Common eth balance used for all consumer requests. - - // TODO: put back request count? + uint64 reqCount; } // We use the config for the mgmt APIs struct SubscriptionConfig { @@ -59,6 +64,13 @@ abstract contract SubscriptionAPI is ConfirmedOwner, ReentrancyGuard, ERC677Rece mapping(uint256 => Subscription) /* subId */ /* subscription */ internal s_subscriptions; // subscription nonce used to construct subID. Rises monotonically uint64 public s_currentSubNonce; + // track all subscription id's that were created by this contract + // note: access should be through the getActiveSubscriptionIds() view function + // which takes a starting index and a max number to fetch in order to allow + // "pagination" of the subscription ids. in the event a very large number of + // subscription id's are stored in this set, they cannot be retrieved in a + // single RPC call without violating various size limits. + EnumerableSet.UintSet internal s_subIds; // s_totalBalance tracks the total link sent to/from // this contract through onTokenTransfer, cancelSubscription and oracleWithdraw. // A discrepancy with this contract's link balance indicates someone @@ -81,14 +93,51 @@ abstract contract SubscriptionAPI is ConfirmedOwner, ReentrancyGuard, ERC677Rece event SubscriptionOwnerTransferRequested(uint256 indexed subId, address from, address to); event SubscriptionOwnerTransferred(uint256 indexed subId, address from, address to); + struct Config { + uint16 minimumRequestConfirmations; + uint32 maxGasLimit; + // Reentrancy protection. + bool reentrancyLock; + // stalenessSeconds is how long before we consider the feed price to be stale + // and fallback to fallbackWeiPerUnitLink. + uint32 stalenessSeconds; + // Gas to cover oracle payment after we calculate the payment. + // We make it configurable in case those operations are repriced. + // The recommended number is below, though it may vary slightly + // if certain chains do not implement certain EIP's. + // 21000 + // base cost of the transaction + // 100 + 5000 + // warm subscription balance read and update. See https://eips.ethereum.org/EIPS/eip-2929 + // 2*2100 + 5000 - // cold read oracle address and oracle balance and first time oracle balance update, note first time will be 20k, but 5k subsequently + // 4800 + // request delete refund (refunds happen after execution), note pre-london fork was 15k. See https://eips.ethereum.org/EIPS/eip-3529 + // 6685 + // Positive static costs of argument encoding etc. note that it varies by +/- x*12 for every x bytes of non-zero data in the proof. + // Total: 37,185 gas. + uint32 gasAfterPaymentCalculation; + } + Config public s_config; + + error Reentrant(); + modifier nonReentrant() { + if (s_config.reentrancyLock) { + revert Reentrant(); + } + _; + } + constructor() ConfirmedOwner(msg.sender) {} - function setLINK(address link) external onlyOwner { + /** + * @notice set the LINK token contract and link eth feed to be + * used by this coordinator + * @param link - address of link token + * @param linkEthFeed address of the link eth feed + */ + function setLINKAndLINKETHFeed(address link, address linkEthFeed) external onlyOwner { // Disallow re-setting link token because the logic wouldn't really make sense if (address(LINK) != address(0)) { revert LinkAlreadySet(); } LINK = LinkTokenInterface(link); + LINK_ETH_FEED = AggregatorV3Interface(linkEthFeed); } /** @@ -217,33 +266,62 @@ abstract contract SubscriptionAPI is ConfirmedOwner, ReentrancyGuard, ERC677Rece */ function getSubscription( uint256 subId - ) public view override returns (uint96 balance, uint96 ethBalance, address owner, address[] memory consumers) { + ) + public + view + override + returns (uint96 balance, uint96 ethBalance, uint64 reqCount, address owner, address[] memory consumers) + { if (s_subscriptionConfigs[subId].owner == address(0)) { revert InvalidSubscription(); } return ( s_subscriptions[subId].balance, s_subscriptions[subId].ethBalance, + s_subscriptions[subId].reqCount, s_subscriptionConfigs[subId].owner, s_subscriptionConfigs[subId].consumers ); } + /** + * @inheritdoc IVRFSubscriptionV2Plus + */ + function getActiveSubscriptionIds( + uint256 startIndex, + uint256 maxCount + ) external view override returns (uint256[] memory) { + uint256 numSubs = s_subIds.length(); + if (startIndex >= numSubs) revert IndexOutOfRange(); + uint256 endIndex = startIndex + maxCount; + endIndex = endIndex > numSubs || maxCount == 0 ? numSubs : endIndex; + uint256[] memory ids = new uint256[](endIndex - startIndex); + for (uint256 idx = 0; idx < ids.length; idx++) { + ids[idx] = s_subIds.at(idx + startIndex); + } + return ids; + } + /** * @inheritdoc IVRFSubscriptionV2Plus */ function createSubscription() external override nonReentrant returns (uint256) { + // Generate a subscription id that is globally unique. uint256 subId = uint256( keccak256(abi.encodePacked(msg.sender, blockhash(block.number - 1), address(this), s_currentSubNonce)) ); + // Increment the subscription nonce counter. s_currentSubNonce++; + // Initialize storage variables. address[] memory consumers = new address[](0); - s_subscriptions[subId] = Subscription({balance: 0, ethBalance: 0}); + s_subscriptions[subId] = Subscription({balance: 0, ethBalance: 0, reqCount: 0}); s_subscriptionConfigs[subId] = SubscriptionConfig({ owner: msg.sender, requestedOwner: address(0), consumers: consumers }); + // Update the s_subIds set, which tracks all subscription ids created in this contract. + s_subIds.add(subId); emit SubscriptionCreated(subId, msg.sender); return subId; @@ -311,6 +389,7 @@ abstract contract SubscriptionAPI is ConfirmedOwner, ReentrancyGuard, ERC677Rece } delete s_subscriptionConfigs[subId]; delete s_subscriptions[subId]; + s_subIds.remove(subId); s_totalBalance -= balance; s_totalEthBalance -= ethBalance; return (balance, ethBalance); diff --git a/contracts/src/v0.8/dev/vrf/TrustedBlockhashStore.sol b/contracts/src/v0.8/dev/vrf/TrustedBlockhashStore.sol new file mode 100644 index 00000000000..bbbc08f3a22 --- /dev/null +++ b/contracts/src/v0.8/dev/vrf/TrustedBlockhashStore.sol @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.6; + +import "../../ChainSpecificUtil.sol"; +import "../../shared/access/ConfirmedOwner.sol"; +import "./BlockhashStore.sol"; + +contract TrustedBlockhashStore is ConfirmedOwner, BlockhashStore { + error NotInWhitelist(); + error InvalidTrustedBlockhashes(); + error InvalidRecentBlockhash(); + + mapping(address => bool) public s_whitelistStatus; + address[] public s_whitelist; + + constructor(address[] memory whitelist) ConfirmedOwner(msg.sender) { + setWhitelist(whitelist); + } + + /** + * @notice sets the whitelist of addresses that can store blockhashes + * @param whitelist the whitelist of addresses that can store blockhashes + */ + function setWhitelist(address[] memory whitelist) public onlyOwner { + address[] memory previousWhitelist = s_whitelist; + s_whitelist = whitelist; + + // Unset whitelist status for all addresses in the previous whitelist, + // and set whitelist status for all addresses in the new whitelist. + for (uint256 i = 0; i < previousWhitelist.length; i++) { + s_whitelistStatus[previousWhitelist[i]] = false; + } + for (uint256 i = 0; i < whitelist.length; i++) { + s_whitelistStatus[whitelist[i]] = true; + } + } + + /** + * @notice stores a list of blockhashes and their respective blocks, only callable + * by a whitelisted address + * @param blockhashes the list of blockhashes and their respective blocks + */ + function storeTrusted( + uint256[] calldata blockNums, + bytes32[] calldata blockhashes, + uint256 recentBlockNumber, + bytes32 recentBlockhash + ) external { + bytes32 onChainHash = ChainSpecificUtil.getBlockhash(uint64(recentBlockNumber)); + if (onChainHash != recentBlockhash) { + revert InvalidRecentBlockhash(); + } + + if (!s_whitelistStatus[msg.sender]) { + revert NotInWhitelist(); + } + + if (blockNums.length != blockhashes.length) { + revert InvalidTrustedBlockhashes(); + } + + for (uint256 i = 0; i < blockNums.length; i++) { + s_blockhashes[blockNums[i]] = blockhashes[i]; + } + } +} diff --git a/contracts/src/v0.8/dev/vrf/VRFConsumerBaseV2Plus.sol b/contracts/src/v0.8/dev/vrf/VRFConsumerBaseV2Plus.sol index 2909312e548..ed1f918212c 100644 --- a/contracts/src/v0.8/dev/vrf/VRFConsumerBaseV2Plus.sol +++ b/contracts/src/v0.8/dev/vrf/VRFConsumerBaseV2Plus.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.4; import "../interfaces/IVRFMigratableCoordinatorV2Plus.sol"; import "../interfaces/IVRFMigratableConsumerV2Plus.sol"; -import "../../ConfirmedOwner.sol"; +import "../../shared/access/ConfirmedOwner.sol"; /** **************************************************************************** * @notice Interface for contracts using VRF randomness diff --git a/contracts/src/v0.8/dev/vrf/VRFCoordinatorV2Plus.sol b/contracts/src/v0.8/dev/vrf/VRFCoordinatorV2Plus.sol index b29e2b0042e..f08fe8c8f24 100644 --- a/contracts/src/v0.8/dev/vrf/VRFCoordinatorV2Plus.sol +++ b/contracts/src/v0.8/dev/vrf/VRFCoordinatorV2Plus.sol @@ -1,9 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.4; -import "../../interfaces/LinkTokenInterface.sol"; +import "../../shared/interfaces/LinkTokenInterface.sol"; import "../../interfaces/BlockhashStoreInterface.sol"; -import "../../interfaces/AggregatorV3Interface.sol"; import "../../interfaces/TypeAndVersionInterface.sol"; import "../../vrf/VRF.sol"; import "./VRFConsumerBaseV2Plus.sol"; @@ -13,8 +12,6 @@ import "./libraries/VRFV2PlusClient.sol"; import "../interfaces/IVRFCoordinatorV2PlusMigration.sol"; contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI { - /// @dev may not be provided upon construction on some chains due to lack of availability - AggregatorV3Interface public LINK_ETH_FEED; /// @dev should always be available BlockhashStoreInterface public immutable BLOCKHASH_STORE; @@ -64,32 +61,13 @@ contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI { event RandomWordsFulfilled( uint256 indexed requestId, uint256 outputSeed, + uint256 indexed subID, uint96 payment, - bytes extraArgs, bool success ); - struct Config { - uint16 minimumRequestConfirmations; - uint32 maxGasLimit; - // stalenessSeconds is how long before we consider the feed price to be stale - // and fallback to fallbackWeiPerUnitLink. - uint32 stalenessSeconds; - // Gas to cover oracle payment after we calculate the payment. - // We make it configurable in case those operations are repriced. - // The recommended number is below, though it may vary slightly - // if certain chains do not implement certain EIP's. - // 21000 + // base cost of the transaction - // 100 + 5000 + // warm subscription balance read and update. See https://eips.ethereum.org/EIPS/eip-2929 - // 2*2100 + 5000 - // cold read oracle address and oracle balance and first time oracle balance update, note first time will be 20k, but 5k subsequently - // 4800 + // request delete refund (refunds happen after execution), note pre-london fork was 15k. See https://eips.ethereum.org/EIPS/eip-3529 - // 6685 + // Positive static costs of argument encoding etc. note that it varies by +/- x*12 for every x bytes of non-zero data in the proof. - // 21000 // cost of a cold storage write to update the request payments mapping. - // Total: 58,815 gas. - uint32 gasAfterPaymentCalculation; - } int256 public s_fallbackWeiPerUnitLink; - Config public s_config; + FeeConfig public s_feeConfig; struct FeeConfig { // Flat fee charged per fulfillment in millionths of link @@ -112,14 +90,6 @@ contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI { BLOCKHASH_STORE = BlockhashStoreInterface(blockhashStore); } - /** - * @notice set the link eth feed to be used by this coordinator - * @param linkEthFeed address of the link eth feed - */ - function setLinkEthFeed(address linkEthFeed) external onlyOwner { - LINK_ETH_FEED = AggregatorV3Interface(linkEthFeed); - } - /** * @notice Registers a proving key to an oracle. * @param oracle address of the oracle @@ -196,7 +166,8 @@ contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI { minimumRequestConfirmations: minimumRequestConfirmations, maxGasLimit: maxGasLimit, stalenessSeconds: stalenessSeconds, - gasAfterPaymentCalculation: gasAfterPaymentCalculation + gasAfterPaymentCalculation: gasAfterPaymentCalculation, + reentrancyLock: false }); s_feeConfig = feeConfig; s_fallbackWeiPerUnitLink = fallbackWeiPerUnitLink; @@ -375,9 +346,9 @@ contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI { } function getRandomnessFromProof( - Proof calldata proof, - RequestCommitment calldata rc - ) private view returns (Output memory) { + Proof memory proof, + RequestCommitment memory rc + ) internal view returns (Output memory) { bytes32 keyHash = hashOfKey(proof.pk); // Only registered proving keys are permitted. address oracle = s_provingKeys[keyHash]; @@ -417,10 +388,7 @@ contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI { * @return payment amount billed to the subscription * @dev simulated offchain to determine if sufficient balance is present to fulfill the request */ - function fulfillRandomWords( - Proof calldata proof, - RequestCommitment calldata rc - ) external nonReentrant returns (uint96) { + function fulfillRandomWords(Proof memory proof, RequestCommitment memory rc) external nonReentrant returns (uint96) { uint256 startGas = gasleft(); Output memory output = getRandomnessFromProof(proof, rc); @@ -438,11 +406,17 @@ contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI { // 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; + + // Increment the req count for the subscription. + uint64 reqCount = s_subscriptions[rc.subId].reqCount; + s_subscriptions[rc.subId].reqCount = reqCount + 1; // stack too deep error { - bool nativePayment = _fromBytes(rc.extraArgs).nativePayment; + 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. @@ -466,12 +440,9 @@ contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI { s_withdrawableTokens[s_provingKeys[output.keyHash]] += payment; } - bytes memory extraArgs = VRFV2PlusClient._argsToBytes( - VRFV2PlusClient.ExtraArgsV1({nativePayment: nativePayment}) - ); // 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, payment, extraArgs, success); + emit RandomWordsFulfilled(output.requestId, output.randomness, rc.subId, payment, success); return payment; } @@ -686,7 +657,7 @@ contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI { if (!isTargetRegistered(newCoordinator)) { revert CoordinatorNotRegistered(newCoordinator); } - (uint96 balance, uint96 ethBalance, address owner, address[] memory consumers) = getSubscription(subId); + (uint96 balance, uint96 ethBalance, , address owner, address[] memory consumers) = getSubscription(subId); require(owner == msg.sender, "Not subscription owner"); require(!pendingRequestExists(subId), "Pending request exists"); diff --git a/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol b/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol index b2453ec05e5..c8cba34ec5a 100644 --- a/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol +++ b/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; -import "../../ConfirmedOwner.sol"; +import "../../shared/access/ConfirmedOwner.sol"; import "../../interfaces/TypeAndVersionInterface.sol"; import "./VRFConsumerBaseV2Plus.sol"; -import "../../interfaces/LinkTokenInterface.sol"; +import "../../shared/interfaces/LinkTokenInterface.sol"; import "../../interfaces/AggregatorV3Interface.sol"; import "../interfaces/IVRFCoordinatorV2Plus.sol"; import "../interfaces/VRFV2PlusWrapperInterface.sol"; diff --git a/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapperConsumerBase.sol b/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapperConsumerBase.sol index 47c86dadc71..c9ddad2f778 100644 --- a/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapperConsumerBase.sol +++ b/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapperConsumerBase.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../interfaces/LinkTokenInterface.sol"; +import "../../shared/interfaces/LinkTokenInterface.sol"; import "../interfaces/VRFV2PlusWrapperInterface.sol"; /** diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2Plus.sol b/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2Plus.sol index c4ab099a777..82f4068112d 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2Plus.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2Plus.sol @@ -1,9 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.4; +import "../../../vrf/VRF.sol"; import {VRFCoordinatorV2Plus} from "../VRFCoordinatorV2Plus.sol"; +import "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; contract ExposedVRFCoordinatorV2Plus is VRFCoordinatorV2Plus { + using EnumerableSet for EnumerableSet.UintSet; + constructor(address blockhashStore) VRFCoordinatorV2Plus(blockhashStore) {} function computeRequestIdExternal( @@ -18,4 +22,15 @@ contract ExposedVRFCoordinatorV2Plus is VRFCoordinatorV2Plus { function isTargetRegisteredExternal(address target) external view returns (bool) { return isTargetRegistered(target); } + + function getRandomnessFromProofExternal( + Proof calldata proof, + RequestCommitment calldata rc + ) external view returns (Output memory) { + return getRandomnessFromProof(proof, rc); + } + + function getActiveSubscriptionIdsLength() external view returns (uint256) { + return s_subIds.length(); + } } diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFConsumerV2PlusUpgradeableExample.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFConsumerV2PlusUpgradeableExample.sol index 77e290ca80c..7b34f96e376 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFConsumerV2PlusUpgradeableExample.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFConsumerV2PlusUpgradeableExample.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../../interfaces/LinkTokenInterface.sol"; +import "../../../shared/interfaces/LinkTokenInterface.sol"; import "../../interfaces/IVRFCoordinatorV2Plus.sol"; import "../../VRFConsumerBaseV2Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable-4.7.3/proxy/utils/Initializable.sol"; diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2Plus_V2Example.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2Plus_V2Example.sol index c8029eb575f..b44a3e3190d 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2Plus_V2Example.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2Plus_V2Example.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.4; -import "../../../interfaces/LinkTokenInterface.sol"; +import "../../../shared/interfaces/LinkTokenInterface.sol"; import "../../interfaces/IVRFCoordinatorV2PlusMigration.sol"; import "../../interfaces/IVRFMigratableCoordinatorV2Plus.sol"; import "../VRFConsumerBaseV2Plus.sol"; diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFMaliciousConsumerV2Plus.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFMaliciousConsumerV2Plus.sol index 93f8186f168..11e899ae659 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFMaliciousConsumerV2Plus.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFMaliciousConsumerV2Plus.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../../interfaces/LinkTokenInterface.sol"; +import "../../../shared/interfaces/LinkTokenInterface.sol"; import "../../interfaces/IVRFCoordinatorV2Plus.sol"; import "../VRFConsumerBaseV2Plus.sol"; diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusConsumerExample.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusConsumerExample.sol index 8178704597e..ff9245b688e 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusConsumerExample.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusConsumerExample.sol @@ -1,11 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../../interfaces/LinkTokenInterface.sol"; +import "../../../shared/interfaces/LinkTokenInterface.sol"; import "../../interfaces/IVRFCoordinatorV2Plus.sol"; import "../VRFConsumerBaseV2Plus.sol"; -import "../../interfaces/IVRFCoordinatorV2Plus.sol"; -import "../../../ConfirmedOwner.sol"; +import "../../../shared/access/ConfirmedOwner.sol"; /// @notice This contract is used for testing only and should not be used for production. contract VRFV2PlusConsumerExample is ConfirmedOwner, VRFConsumerBaseV2Plus { @@ -33,19 +32,35 @@ contract VRFV2PlusConsumerExample is ConfirmedOwner, VRFConsumerBaseV2Plus { return resp.randomWords[idx]; } - function createSubscriptionAndFund(uint96 amount) external { + function subscribe() internal returns (uint256) { if (s_subId == 0) { s_subId = s_vrfCoordinatorApiV1.createSubscription(); s_vrfCoordinatorApiV1.addConsumer(s_subId, address(this)); } + return s_subId; + } + + function createSubscriptionAndFundNative() external payable { + subscribe(); + s_vrfCoordinatorApiV1.fundSubscriptionWithEth{value: msg.value}(s_subId); + } + + function createSubscriptionAndFund(uint96 amount) external { + subscribe(); // Approve the link transfer. s_linkToken.transferAndCall(address(s_vrfCoordinator), amount, abi.encode(s_subId)); } function topUpSubscription(uint96 amount) external { + require(s_subId != 0, "sub not set"); s_linkToken.transferAndCall(address(s_vrfCoordinator), amount, abi.encode(s_subId)); } + function topUpSubscriptionNative() external payable { + require(s_subId != 0, "sub not set"); + s_vrfCoordinatorApiV1.fundSubscriptionWithEth{value: msg.value}(s_subId); + } + function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override { require(requestId == s_recentRequestId, "request ID is incorrect"); s_requests[requestId].randomWords = randomWords; diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusExternalSubOwnerExample.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusExternalSubOwnerExample.sol index f83d256bc68..2b9ac5713cc 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusExternalSubOwnerExample.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusExternalSubOwnerExample.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../../interfaces/LinkTokenInterface.sol"; +import "../../../shared/interfaces/LinkTokenInterface.sol"; import "../../interfaces/IVRFCoordinatorV2Plus.sol"; import "../VRFConsumerBaseV2Plus.sol"; diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusRevertingExample.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusRevertingExample.sol index ae78b3aa8d1..36063533586 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusRevertingExample.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusRevertingExample.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../../interfaces/LinkTokenInterface.sol"; +import "../../../shared/interfaces/LinkTokenInterface.sol"; import "../../interfaces/IVRFCoordinatorV2Plus.sol"; import "../VRFConsumerBaseV2Plus.sol"; diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusSingleConsumerExample.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusSingleConsumerExample.sol index 68992b6f522..e4cd9ae29ad 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusSingleConsumerExample.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusSingleConsumerExample.sol @@ -2,7 +2,7 @@ // Example of a single consumer contract which owns the subscription. pragma solidity ^0.8.0; -import "../../../interfaces/LinkTokenInterface.sol"; +import "../../../shared/interfaces/LinkTokenInterface.sol"; import "../../interfaces/IVRFCoordinatorV2Plus.sol"; import "../VRFConsumerBaseV2Plus.sol"; diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusWrapperConsumerExample.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusWrapperConsumerExample.sol index 51fecb8430d..5851d2c5df7 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusWrapperConsumerExample.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusWrapperConsumerExample.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.6; import "../VRFV2PlusWrapperConsumerBase.sol"; -import "../../../ConfirmedOwner.sol"; +import "../../../shared/access/ConfirmedOwner.sol"; contract VRFV2PlusWrapperConsumerExample is VRFV2PlusWrapperConsumerBase, ConfirmedOwner { event WrappedRequestFulfilled(uint256 requestId, uint256[] randomWords, uint256 payment); diff --git a/contracts/src/v0.8/functions/dev/0_0_0/Functions.sol b/contracts/src/v0.8/functions/dev/0_0_0/Functions.sol index d5ff5f663e6..478149d8dda 100644 --- a/contracts/src/v0.8/functions/dev/0_0_0/Functions.sol +++ b/contracts/src/v0.8/functions/dev/0_0_0/Functions.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; -import {CBOR, Buffer} from "../../../shared/vendor/solidity-cborutils/v2.0.0/CBOR.sol"; +import {CBOR, Buffer} from "../../../vendor/solidity-cborutils/v2.0.0/CBOR.sol"; /** * @title Library for Chainlink Functions diff --git a/contracts/src/v0.8/functions/dev/0_0_0/FunctionsBillingRegistry.sol b/contracts/src/v0.8/functions/dev/0_0_0/FunctionsBillingRegistry.sol index 4c35c4232b9..3488af55cca 100644 --- a/contracts/src/v0.8/functions/dev/0_0_0/FunctionsBillingRegistry.sol +++ b/contracts/src/v0.8/functions/dev/0_0_0/FunctionsBillingRegistry.sol @@ -1,18 +1,18 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; -import {LinkTokenInterface} from "../../../interfaces/LinkTokenInterface.sol"; +import {LinkTokenInterface} from "../../../shared/interfaces/LinkTokenInterface.sol"; import {AggregatorV3Interface} from "../../../interfaces/AggregatorV3Interface.sol"; import {IFunctionsBillingRegistry} from "./interfaces/IFunctionsBillingRegistry.sol"; import {IFunctionsOracle} from "./interfaces/IFunctionsOracle.sol"; import {IFunctionsClient} from "./interfaces/IFunctionsClient.sol"; -import {ERC677ReceiverInterface} from "../../../interfaces/ERC677ReceiverInterface.sol"; +import {IERC677Receiver} from "../../../shared/interfaces/IERC677Receiver.sol"; import {IAuthorizedOriginReceiver} from "./accessControl/interfaces/IAuthorizedOriginReceiver.sol"; import {ConfirmedOwnerUpgradeable} from "./accessControl/ConfirmedOwnerUpgradeable.sol"; import {AuthorizedReceiver} from "./accessControl/AuthorizedReceiver.sol"; -import {SafeCast} from "../../../shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/utils/SafeCast.sol"; -import {PausableUpgradeable} from "../../../shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/security/PausableUpgradeable.sol"; -import {Initializable} from "../../../shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; +import {SafeCast} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/SafeCast.sol"; +import {PausableUpgradeable} from "../../../vendor/openzeppelin-contracts-upgradeable/v4.8.1/security/PausableUpgradeable.sol"; +import {Initializable} from "../../../vendor/openzeppelin-contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; /** * @title Functions Billing Registry contract @@ -24,7 +24,7 @@ contract FunctionsBillingRegistry is ConfirmedOwnerUpgradeable, PausableUpgradeable, IFunctionsBillingRegistry, - ERC677ReceiverInterface, + IERC677Receiver, AuthorizedReceiver { LinkTokenInterface private LINK; diff --git a/contracts/src/v0.8/functions/dev/0_0_0/FunctionsOracle.sol b/contracts/src/v0.8/functions/dev/0_0_0/FunctionsOracle.sol index e392e867903..b1233eeb526 100644 --- a/contracts/src/v0.8/functions/dev/0_0_0/FunctionsOracle.sol +++ b/contracts/src/v0.8/functions/dev/0_0_0/FunctionsOracle.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.6; import {IFunctionsOracle, IFunctionsBillingRegistry} from "./interfaces/IFunctionsOracle.sol"; import {OCR2BaseUpgradeable} from "./ocr/OCR2BaseUpgradeable.sol"; import {AuthorizedOriginReceiverUpgradeable} from "./accessControl/AuthorizedOriginReceiverUpgradeable.sol"; -import {Initializable} from "../../../shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; +import {Initializable} from "../../../vendor/openzeppelin-contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; /** * @title Functions Oracle contract diff --git a/contracts/src/v0.8/functions/dev/0_0_0/accessControl/AuthorizedOriginReceiver.sol b/contracts/src/v0.8/functions/dev/0_0_0/accessControl/AuthorizedOriginReceiver.sol index 655b32a03f2..16918072fba 100644 --- a/contracts/src/v0.8/functions/dev/0_0_0/accessControl/AuthorizedOriginReceiver.sol +++ b/contracts/src/v0.8/functions/dev/0_0_0/accessControl/AuthorizedOriginReceiver.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; -import {EnumerableSet} from "../../../../shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/utils/structs/EnumerableSet.sol"; +import {EnumerableSet} from "../../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/structs/EnumerableSet.sol"; import {IAuthorizedOriginReceiver} from "./interfaces/IAuthorizedOriginReceiver.sol"; /** diff --git a/contracts/src/v0.8/functions/dev/0_0_0/accessControl/AuthorizedOriginReceiverUpgradeable.sol b/contracts/src/v0.8/functions/dev/0_0_0/accessControl/AuthorizedOriginReceiverUpgradeable.sol index ec75452cccc..762bcb67b9f 100644 --- a/contracts/src/v0.8/functions/dev/0_0_0/accessControl/AuthorizedOriginReceiverUpgradeable.sol +++ b/contracts/src/v0.8/functions/dev/0_0_0/accessControl/AuthorizedOriginReceiverUpgradeable.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; -import {EnumerableSet} from "../../../../shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/utils/structs/EnumerableSet.sol"; -import {Initializable} from "../../../../shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; +import {EnumerableSet} from "../../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/structs/EnumerableSet.sol"; +import {Initializable} from "../../../../vendor/openzeppelin-contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; import {IAuthorizedOriginReceiver} from "./interfaces/IAuthorizedOriginReceiver.sol"; /** diff --git a/contracts/src/v0.8/functions/dev/0_0_0/accessControl/AuthorizedReceiver.sol b/contracts/src/v0.8/functions/dev/0_0_0/accessControl/AuthorizedReceiver.sol index 365dd24d567..92d8af6891d 100644 --- a/contracts/src/v0.8/functions/dev/0_0_0/accessControl/AuthorizedReceiver.sol +++ b/contracts/src/v0.8/functions/dev/0_0_0/accessControl/AuthorizedReceiver.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; -import {EnumerableSet} from "../../../../shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/utils/structs/EnumerableSet.sol"; +import {EnumerableSet} from "../../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/structs/EnumerableSet.sol"; import {IAuthorizedReceiver} from "./interfaces/IAuthorizedReceiver.sol"; abstract contract AuthorizedReceiver is IAuthorizedReceiver { diff --git a/contracts/src/v0.8/functions/dev/0_0_0/accessControl/ConfirmedOwnerUpgradeable.sol b/contracts/src/v0.8/functions/dev/0_0_0/accessControl/ConfirmedOwnerUpgradeable.sol index bf9165cc066..284c5637167 100644 --- a/contracts/src/v0.8/functions/dev/0_0_0/accessControl/ConfirmedOwnerUpgradeable.sol +++ b/contracts/src/v0.8/functions/dev/0_0_0/accessControl/ConfirmedOwnerUpgradeable.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; -import {OwnableInterface} from "../../../../interfaces/OwnableInterface.sol"; -import {Initializable} from "../../../../shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; +import {IOwnable} from "../../../../shared/interfaces/IOwnable.sol"; +import {Initializable} from "../../../../vendor/openzeppelin-contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; /** * @title The ConfirmedOwnerUpgradeable contract * @notice An upgrade compatible contract with helpers for basic contract ownership. */ -contract ConfirmedOwnerUpgradeable is Initializable, OwnableInterface { +contract ConfirmedOwnerUpgradeable is Initializable, IOwnable { address private s_owner; address private s_pendingOwner; diff --git a/contracts/src/v0.8/functions/dev/0_0_0/example/FunctionsClientExample.sol b/contracts/src/v0.8/functions/dev/0_0_0/example/FunctionsClientExample.sol index b95504c0e6e..2d118c6961a 100644 --- a/contracts/src/v0.8/functions/dev/0_0_0/example/FunctionsClientExample.sol +++ b/contracts/src/v0.8/functions/dev/0_0_0/example/FunctionsClientExample.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.6; import {FunctionsClient} from "../FunctionsClient.sol"; import {Functions} from "../Functions.sol"; -import {ConfirmedOwner} from "../../../../ConfirmedOwner.sol"; +import {ConfirmedOwner} from "../../../../shared/access/ConfirmedOwner.sol"; /** * @title Chainlink Functions example client contract implementation diff --git a/contracts/src/v0.8/functions/dev/0_0_0/ocr/OCR2Base.sol b/contracts/src/v0.8/functions/dev/0_0_0/ocr/OCR2Base.sol index f2b2e49e359..0814311248c 100644 --- a/contracts/src/v0.8/functions/dev/0_0_0/ocr/OCR2Base.sol +++ b/contracts/src/v0.8/functions/dev/0_0_0/ocr/OCR2Base.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {ConfirmedOwner} from "../../../../ConfirmedOwner.sol"; +import {ConfirmedOwner} from "../../../../shared/access/ConfirmedOwner.sol"; import {OCR2Abstract} from "./OCR2Abstract.sol"; /** diff --git a/contracts/src/v0.8/functions/dev/0_0_0/ocr/OCR2BaseUpgradeable.sol b/contracts/src/v0.8/functions/dev/0_0_0/ocr/OCR2BaseUpgradeable.sol index eeb966dd037..25481ceb73e 100644 --- a/contracts/src/v0.8/functions/dev/0_0_0/ocr/OCR2BaseUpgradeable.sol +++ b/contracts/src/v0.8/functions/dev/0_0_0/ocr/OCR2BaseUpgradeable.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import {ConfirmedOwnerUpgradeable} from "../accessControl/ConfirmedOwnerUpgradeable.sol"; import {OCR2Abstract} from "./OCR2Abstract.sol"; -import {Initializable} from "../../../../shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; +import {Initializable} from "../../../../vendor/openzeppelin-contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; /** * @notice Onchain verification of reports from the offchain reporting protocol diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FulfillResultCodes.sol b/contracts/src/v0.8/functions/dev/1_0_0/FulfillResultCodes.sol deleted file mode 100644 index 7ff5d0e0ad9..00000000000 --- a/contracts/src/v0.8/functions/dev/1_0_0/FulfillResultCodes.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -enum FulfillResult { - USER_SUCCESS, // 0 - USER_ERROR, // 1 - INVALID_REQUEST_ID, // 2 - INSUFFICIENT_GAS, // 3 - INSUFFICIENT_SUBSCRIPTION_BALANCE, // 4 - COST_EXCEEDS_COMMITMENT, // 5 - INTERNAL_ERROR // 6 -} diff --git a/contracts/src/v0.8/functions/dev/1_0_0/Functions.sol b/contracts/src/v0.8/functions/dev/1_0_0/Functions.sol deleted file mode 100644 index d6f9fc4efde..00000000000 --- a/contracts/src/v0.8/functions/dev/1_0_0/Functions.sol +++ /dev/null @@ -1,173 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import {CBOR, Buffer} from "../../../shared/vendor/solidity-cborutils/v2.0.0/CBOR.sol"; - -/** - * @title Library for Chainlink Functions - */ -library Functions { - uint16 public constant REQUEST_DATA_VERSION = 1; - uint256 internal constant DEFAULT_BUFFER_SIZE = 256; - - using CBOR for Buffer.buffer; - - enum Location { - Inline, - Remote, - DONHosted - } - - enum CodeLanguage { - JavaScript - // In future version we may add other languages - } - - struct Request { - Location codeLocation; - Location secretsLocation; // Only Remote secrets are supported - CodeLanguage language; - string source; // Source code for Location.Inline, url for Location.Remote or slot decimal number for Location.DONHosted - bytes encryptedSecretsReference; // Encrypted urls for Location.Remote or CBOR encoded slotid+version for Location.DONHosted, use addDONHostedSecrets() - string[] args; - bytes[] bytesArgs; - } - - error EmptySource(); - error EmptySecrets(); - error EmptyArgs(); - error NoInlineSecrets(); - - /** - * @notice Encodes a Request to CBOR encoded bytes - * @param self The request to encode - * @return CBOR encoded bytes - */ - function encodeCBOR(Request memory self) internal pure returns (bytes memory) { - CBOR.CBORBuffer memory buffer; - Buffer.init(buffer.buf, DEFAULT_BUFFER_SIZE); - - CBOR.writeString(buffer, "codeLocation"); - CBOR.writeUInt256(buffer, uint256(self.codeLocation)); - - CBOR.writeString(buffer, "language"); - CBOR.writeUInt256(buffer, uint256(self.language)); - - CBOR.writeString(buffer, "source"); - CBOR.writeString(buffer, self.source); - - if (self.args.length > 0) { - CBOR.writeString(buffer, "args"); - CBOR.startArray(buffer); - for (uint256 i = 0; i < self.args.length; i++) { - CBOR.writeString(buffer, self.args[i]); - } - CBOR.endSequence(buffer); - } - - if (self.encryptedSecretsReference.length > 0) { - if (self.secretsLocation == Location.Inline) { - revert NoInlineSecrets(); - } - CBOR.writeString(buffer, "secretsLocation"); - CBOR.writeUInt256(buffer, uint256(self.secretsLocation)); - CBOR.writeString(buffer, "secrets"); - CBOR.writeBytes(buffer, self.encryptedSecretsReference); - } - - if (self.bytesArgs.length > 0) { - CBOR.writeString(buffer, "bytesArgs"); - CBOR.startArray(buffer); - for (uint256 i = 0; i < self.bytesArgs.length; i++) { - CBOR.writeBytes(buffer, self.bytesArgs[i]); - } - CBOR.endSequence(buffer); - } - - return buffer.buf.buf; - } - - /** - * @notice Initializes a Chainlink Functions Request - * @dev Sets the codeLocation and code on the request - * @param self The uninitialized request - * @param codeLocation The user provided source code location - * @param language The programming language of the user code - * @param source The user provided source code or a url - */ - function initializeRequest( - Request memory self, - Location codeLocation, - CodeLanguage language, - string memory source - ) internal pure { - if (bytes(source).length == 0) revert EmptySource(); - - self.codeLocation = codeLocation; - self.language = language; - self.source = source; - } - - /** - * @notice Initializes a Chainlink Functions Request - * @dev Simplified version of initializeRequest for PoC - * @param self The uninitialized request - * @param javaScriptSource The user provided JS code (must not be empty) - */ - function initializeRequestForInlineJavaScript(Request memory self, string memory javaScriptSource) internal pure { - initializeRequest(self, Location.Inline, CodeLanguage.JavaScript, javaScriptSource); - } - - /** - * @notice Adds Remote user encrypted secrets to a Request - * @param self The initialized request - * @param encryptedSecretsReference Encrypted comma-separated string of URLs pointing to off-chain secrets - */ - function addSecretsReference(Request memory self, bytes memory encryptedSecretsReference) internal pure { - if (encryptedSecretsReference.length == 0) revert EmptySecrets(); - - self.secretsLocation = Location.Remote; - self.encryptedSecretsReference = encryptedSecretsReference; - } - - /** - * @notice Adds DON-hosted secrets reference to a Request - * @param self The initialized request - * @param slotID Slot ID of the user's secrets hosted on DON - * @param version User data version (for the slotID) - */ - function addDONHostedSecrets(Request memory self, uint8 slotID, uint64 version) internal pure { - CBOR.CBORBuffer memory buffer; - Buffer.init(buffer.buf, DEFAULT_BUFFER_SIZE); - - CBOR.writeString(buffer, "slotID"); - CBOR.writeUInt64(buffer, slotID); - CBOR.writeString(buffer, "version"); - CBOR.writeUInt64(buffer, version); - - self.secretsLocation = Location.DONHosted; - self.encryptedSecretsReference = buffer.buf.buf; - } - - /** - * @notice Adds args for the user run function - * @param self The initialized request - * @param args The array of string args (must not be empty) - */ - function addArgs(Request memory self, string[] memory args) internal pure { - if (args.length == 0) revert EmptyArgs(); - - self.args = args; - } - - /** - * @notice Adds bytes args for the user run function - * @param self The initialized request - * @param args The array of bytes args (must not be empty) - */ - function addBytesArgs(Request memory self, bytes[] memory args) internal pure { - if (args.length == 0) revert EmptyArgs(); - - self.bytesArgs = args; - } -} diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol index 6fbd4b6109c..efad1eab5e5 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol @@ -1,13 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -import {Routable} from "./Routable.sol"; -import {IFunctionsRouter} from "./interfaces/IFunctionsRouter.sol"; import {IFunctionsSubscriptions} from "./interfaces/IFunctionsSubscriptions.sol"; import {AggregatorV3Interface} from "../../../interfaces/AggregatorV3Interface.sol"; import {IFunctionsBilling} from "./interfaces/IFunctionsBilling.sol"; -import {FulfillResult} from "./FulfillResultCodes.sol"; -import {SafeCast} from "../../../shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/utils/SafeCast.sol"; + +import {Routable} from "./Routable.sol"; +import {FunctionsResponse} from "./libraries/FunctionsResponse.sol"; + +import {SafeCast} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/SafeCast.sol"; /** * @title Functions Billing contract @@ -15,68 +16,44 @@ import {SafeCast} from "../../../shared/vendor/openzeppelin-solidity/v.4.8.0/con * @dev THIS CONTRACT HAS NOT GONE THROUGH ANY SECURITY REVIEW. DO NOT USE IN PROD. */ abstract contract FunctionsBilling is Routable, IFunctionsBilling { - AggregatorV3Interface private LINK_TO_NATIVE_FEED; + using FunctionsResponse for FunctionsResponse.RequestMeta; + using FunctionsResponse for FunctionsResponse.Commitment; + using FunctionsResponse for FunctionsResponse.FulfillResult; + uint32 private constant REASONABLE_GAS_PRICE_CEILING = 1_000_000; // ================================================================ // | Request Commitment state | // ================================================================ - struct Commitment { - uint64 subscriptionId; - address client; - uint32 callbackGasLimit; - uint256 expectedGasPrice; - address don; - uint96 donFee; - uint96 adminFee; - uint96 estimatedTotalCostJuels; - uint256 gasOverhead; - uint256 timestamp; - } - mapping(bytes32 requestId => Commitment) private s_requestCommitments; - event RequestTimedOut(bytes32 indexed requestId); + mapping(bytes32 requestId => bytes32 commitmentHash) private s_requestCommitments; + + event CommitmentDeleted(bytes32 requestId); // ================================================================ // | Configuration state | // ================================================================ + struct Config { - // Maxiumum amount of gas that can be given to a request's client callback - uint32 maxCallbackGasLimit; - // feedStalenessSeconds is how long before we consider the feed price to be stale - // and fallback to fallbackNativePerUnitLink. - uint32 feedStalenessSeconds; - // Represents the average gas execution cost. Used in estimating cost beforehand. - uint32 gasOverheadBeforeCallback; - // Gas to cover transmitter oracle payment after we calculate the payment. - // We make it configurable in case those operations are repriced. - uint32 gasOverheadAfterCallback; - // how many seconds it takes before we consider a request to be timed out - uint32 requestTimeoutSeconds; - // additional flat fee (in Juels of LINK) that will be split between Node Operators - uint96 donFee; - // fallback NATIVE CURRENCY / LINK conversion rate if the data feed is stale - int256 fallbackNativePerUnitLink; - // The highest support request data version supported by the node - // All lower versions should also be supported - uint16 maxSupportedRequestDataVersion; + uint32 maxCallbackGasLimit; // ══════════════════╗ Maximum amount of gas that can be given to a request's client callback + uint32 feedStalenessSeconds; // ║ How long before we consider the feed price to be stale and fallback to fallbackNativePerUnitLink. + uint32 gasOverheadBeforeCallback; // ║ Represents the average gas execution cost before the fulfillment callback. This amount is always billed for every request. + uint32 gasOverheadAfterCallback; // ║ Represents the average gas execution cost after the fulfillment callback. This amount is always billed for every request. + uint32 requestTimeoutSeconds; // ║ How many seconds it takes before we consider a request to be timed out + uint72 donFee; // ║ Additional flat fee (in Juels of LINK) that will be split between Node Operators. Max value is 2^80 - 1 == 1.2m LINK. + uint16 maxSupportedRequestDataVersion; // ═══════╝ The highest support request data version supported by the node. All lower versions should also be supported. + uint32 fulfillmentGasPriceOverEstimationBP; // ══╗ Percentage of gas price overestimation to account for changes in gas price between request and response. Held as basis points (one hundredth of 1 percentage point) + uint224 fallbackNativePerUnitLink; // ═══════════╝ fallback NATIVE CURRENCY / LINK conversion rate if the data feed is stale } + Config private s_config; - event ConfigSet( - uint32 maxCallbackGasLimit, - uint32 feedStalenessSeconds, - uint32 gasOverheadBeforeCallback, - uint32 gasOverheadAfterCallback, - int256 fallbackNativePerUnitLink, - uint96 donFee, - uint16 maxSupportedRequestDataVersion - ); + + event ConfigUpdated(Config config); error UnsupportedRequestDataVersion(); error InsufficientBalance(); error InvalidSubscription(); error UnauthorizedSender(); error MustBeSubOwner(address owner); - error GasLimitTooBig(uint32 have, uint32 want); error InvalidLinkWeiPrice(int256 linkWei); error PaymentTooLarge(); error NoTransmittersSet(); @@ -85,254 +62,181 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { // ================================================================ // | Balance state | // ================================================================ + mapping(address transmitter => uint96 balanceJuelsLink) private s_withdrawableTokens; - // Pool together DON fees and disperse them on withdrawal - uint96 s_feePool; + // Pool together collected DON fees + // Disperse them on withdrawal or change in OCR configuration + uint96 internal s_feePool; - // ================================================================ - // | Cost Events | - // ================================================================ - event BillingStart(bytes32 indexed requestId, Commitment commitment); - event BillingEnd( - bytes32 indexed requestId, - uint64 subscriptionId, - uint96 signerPayment, - uint96 transmitterPayment, - uint96 totalCost, - FulfillResult result - ); + AggregatorV3Interface private s_linkToNativeFeed; // ================================================================ // | Initialization | // ================================================================ - constructor(address router, bytes memory config, address linkToNativeFeed) Routable(router, config) { - LINK_TO_NATIVE_FEED = AggregatorV3Interface(linkToNativeFeed); + constructor(address router, Config memory config, address linkToNativeFeed) Routable(router) { + s_linkToNativeFeed = AggregatorV3Interface(linkToNativeFeed); + + updateConfig(config); } // ================================================================ - // | Configuration Methods | + // | Configuration | // ================================================================ - /** - * @notice Sets the configuration of the Chainlink Functions billing registry - * @param config bytes of abi.encoded config data to set the following: - * See the content of the Config struct above - */ - function _setConfig(bytes memory config) internal override { - ( - uint32 maxCallbackGasLimit, - uint32 feedStalenessSeconds, - uint32 gasOverheadAfterCallback, - uint32 gasOverheadBeforeCallback, - int256 fallbackNativePerUnitLink, - uint32 requestTimeoutSeconds, - uint96 donFee, - uint16 maxSupportedRequestDataVersion - ) = abi.decode(config, (uint32, uint32, uint32, uint32, int256, uint32, uint96, uint16)); - - if (fallbackNativePerUnitLink <= 0) { - revert InvalidLinkWeiPrice(fallbackNativePerUnitLink); - } - s_config = Config({ - maxCallbackGasLimit: maxCallbackGasLimit, - feedStalenessSeconds: feedStalenessSeconds, - gasOverheadAfterCallback: gasOverheadAfterCallback, - gasOverheadBeforeCallback: gasOverheadBeforeCallback, - requestTimeoutSeconds: requestTimeoutSeconds, - donFee: donFee, - fallbackNativePerUnitLink: fallbackNativePerUnitLink, - maxSupportedRequestDataVersion: maxSupportedRequestDataVersion - }); - emit ConfigSet( - maxCallbackGasLimit, - feedStalenessSeconds, - gasOverheadBeforeCallback, - gasOverheadAfterCallback, - fallbackNativePerUnitLink, - donFee, - maxSupportedRequestDataVersion - ); + + // @notice Gets the Chainlink Coordinator's billing configuration + // @return config + function getConfig() external view returns (Config memory) { + return s_config; } - /** - * @inheritdoc IFunctionsBilling - */ - function getConfig() - external - view - override - returns ( - uint32 maxCallbackGasLimit, - uint32 feedStalenessSeconds, - uint256 gasOverheadAfterCallback, - int256 fallbackNativePerUnitLink, - uint32 gasOverheadBeforeCallback, - address linkPriceFeed, - uint16 maxSupportedRequestDataVersion - ) - { - return ( - s_config.maxCallbackGasLimit, - s_config.feedStalenessSeconds, - s_config.gasOverheadAfterCallback, - s_config.fallbackNativePerUnitLink, - s_config.gasOverheadBeforeCallback, - address(LINK_TO_NATIVE_FEED), - s_config.maxSupportedRequestDataVersion - ); + // @notice Sets the Chainlink Coordinator's billing configuration + // @param config - See the contents of the Config struct in IFunctionsBilling.Config for more information + function updateConfig(Config memory config) public { + _onlyOwner(); + + s_config = config; + emit ConfigUpdated(config); } // ================================================================ - // | Cost Calculation Methods | + // | Fee Calculation | // ================================================================ - /** - * @inheritdoc IFunctionsBilling - */ - function getDONFee( - bytes memory /* requestData */, - RequestBilling memory /* billing */ - ) public view override returns (uint96) { - // NOTE: Optionally, compute additional fee here + + // @inheritdoc IFunctionsBilling + function getDONFee(bytes memory /* requestData */) public view override returns (uint72) { return s_config.donFee; } - /** - * @inheritdoc IFunctionsBilling - */ - function getAdminFee( - bytes memory /* requestData */, - RequestBilling memory /* billing */ - ) public view override returns (uint96) { - // NOTE: Optionally, compute additional fee here - return IFunctionsRouter(address(s_router)).getAdminFee(); + // @inheritdoc IFunctionsBilling + function getAdminFee() public view override returns (uint72) { + return _getRouter().getAdminFee(); } - function getFeedData() public view returns (int256) { - uint32 feedStalenessSeconds = s_config.feedStalenessSeconds; - bool staleFallback = feedStalenessSeconds > 0; - (, int256 weiPerUnitLink, , uint256 timestamp, ) = LINK_TO_NATIVE_FEED.latestRoundData(); + // @inheritdoc IFunctionsBilling + function getWeiPerUnitLink() public view returns (uint256) { + Config memory config = s_config; + (, int256 weiPerUnitLink, , uint256 timestamp, ) = s_linkToNativeFeed.latestRoundData(); // solhint-disable-next-line not-rely-on-time - if (staleFallback && feedStalenessSeconds < block.timestamp - timestamp) { - weiPerUnitLink = s_config.fallbackNativePerUnitLink; + if (config.feedStalenessSeconds < block.timestamp - timestamp && config.feedStalenessSeconds > 0) { + return config.fallbackNativePerUnitLink; } - return weiPerUnitLink; + if (weiPerUnitLink <= 0) { + revert InvalidLinkWeiPrice(weiPerUnitLink); + } + return uint256(weiPerUnitLink); + } + + function _getJuelsPerGas(uint256 gasPriceGwei) private view returns (uint96) { + // (1e18 juels/link) * (wei/gas) / (wei/link) = juels per gas + // There are only 1e9*1e18 = 1e27 juels in existence, should not exceed uint96 (2^96 ~ 7e28) + return SafeCast.toUint96((1e18 * gasPriceGwei) / getWeiPerUnitLink()); } // ================================================================ - // | Cost Estimation Methods | + // | Cost Estimation | // ================================================================ - /** - * @inheritdoc IFunctionsBilling - */ + + // @inheritdoc IFunctionsBilling function estimateCost( uint64 subscriptionId, bytes calldata data, uint32 callbackGasLimit, - uint256 gasPrice + uint256 gasPriceGwei ) external view override returns (uint96) { + _getRouter().isValidCallbackGasLimit(subscriptionId, callbackGasLimit); // Reasonable ceilings to prevent integer overflows - if (callbackGasLimit > 30_000_000 /* London upgrade's 30M block max */) { - revert GasLimitTooBig(callbackGasLimit, s_config.maxCallbackGasLimit); - } - if (gasPrice > 1_000_000) { + if (gasPriceGwei > REASONABLE_GAS_PRICE_CEILING) { revert InvalidCalldata(); } - RequestBilling memory billing = RequestBilling(subscriptionId, msg.sender, callbackGasLimit, gasPrice); - uint96 donFee = getDONFee(data, billing); - uint96 adminFee = getAdminFee(data, billing); - return _calculateCostEstimate(callbackGasLimit, gasPrice, donFee, adminFee); + uint72 adminFee = getAdminFee(); + uint72 donFee = getDONFee(data); + return _calculateCostEstimate(callbackGasLimit, gasPriceGwei, donFee, adminFee); } - /** - * @notice Uses current price feed data to estimate a cost - */ + // @notice Estimate the cost in Juels of LINK + // that will be charged to a subscription to fulfill a Functions request + // Gas Price can be overestimated to account for flucuations between request and response time function _calculateCostEstimate( uint32 callbackGasLimit, - uint256 gasPrice, - uint96 donFee, - uint96 adminFee + uint256 gasPriceGwei, + uint72 donFee, + uint72 adminFee ) internal view returns (uint96) { - int256 weiPerUnitLink; - weiPerUnitLink = getFeedData(); - if (weiPerUnitLink <= 0) { - revert InvalidLinkWeiPrice(weiPerUnitLink); - } uint256 executionGas = s_config.gasOverheadBeforeCallback + s_config.gasOverheadAfterCallback + callbackGasLimit; - // (1e18 juels/link) (wei/gas * gas) / (wei/link) = juels - uint256 paymentNoFee = (1e18 * gasPrice * executionGas) / uint256(weiPerUnitLink); - uint256 fee = uint256(donFee) + uint256(adminFee); - if (paymentNoFee > (1e27 - fee)) { - revert PaymentTooLarge(); // Payment + fee cannot be more than all of the link in existence. - } - return uint96(paymentNoFee + fee); + + uint256 gasPriceWithOverestimation = gasPriceGwei + + ((gasPriceGwei * s_config.fulfillmentGasPriceOverEstimationBP) / 10_000); + // @NOTE: Basis Points are 1/100th of 1%, divide by 10_000 to bring back to original units + + uint96 juelsPerGas = _getJuelsPerGas(gasPriceWithOverestimation); + uint256 estimatedGasReimbursement = juelsPerGas * executionGas; + uint96 fees = uint96(donFee) + uint96(adminFee); + + return SafeCast.toUint96(estimatedGasReimbursement + fees); } // ================================================================ - // | Billing Methods | + // | Billing | // ================================================================ - /** - * @notice Initiate the billing process for an Functions request - * @dev Only callable by the Functions Router - * @param data - Encoded Chainlink Functions request data, use FunctionsClient API to encode a request - * @param requestDataVersion - Version number of the structure of the request data - * @param billing - Billing configuration for the request - * @return requestId - A unique identifier of the request. Can be used to match a request to a response in fulfillRequest. - * @return estimatedCost - The estimated cost in Juels of LINK that will be charged to the subscription if all callback gas is used - * @return gasOverheadAfterCallback - The amount of gas that will be used after the user's callback - * @return requestTimeoutSeconds - The number of seconds that this request can remain unfilled before being considered stale - */ + + // @notice Initiate the billing process for an Functions request + // @dev Only callable by the Functions Router + // @param data - Encoded Chainlink Functions request data, use FunctionsClient API to encode a request + // @param requestDataVersion - Version number of the structure of the request data + // @param billing - Billing configuration for the request + // @return commitment - The parameters of the request that must be held consistent at response time function _startBilling( - bytes memory data, - uint16 requestDataVersion, - RequestBilling memory billing - ) internal returns (bytes32, uint96, uint256, uint256) { + FunctionsResponse.RequestMeta memory request + ) internal returns (FunctionsResponse.Commitment memory commitment) { + Config memory config = s_config; + // Nodes should support all past versions of the structure - if (requestDataVersion > s_config.maxSupportedRequestDataVersion) { + if (request.dataVersion > config.maxSupportedRequestDataVersion) { revert UnsupportedRequestDataVersion(); } - // No lower bound on the requested gas limit. A user could request 0 - // and they would simply be billed for the gas and computation. - if (billing.callbackGasLimit > s_config.maxCallbackGasLimit) { - revert GasLimitTooBig(billing.callbackGasLimit, s_config.maxCallbackGasLimit); - } + uint72 donFee = getDONFee(request.data); + uint96 estimatedTotalCostJuels = _calculateCostEstimate( + request.callbackGasLimit, + tx.gasprice, + donFee, + request.adminFee + ); // Check that subscription can afford the estimated cost - uint96 donFee = getDONFee(data, billing); - uint96 adminFee = getAdminFee(data, billing); - uint96 estimatedCost = _calculateCostEstimate(billing.callbackGasLimit, billing.expectedGasPrice, donFee, adminFee); - IFunctionsSubscriptions subscriptions = IFunctionsSubscriptions(address(s_router)); - (uint96 balance, uint96 blockedBalance, , , ) = subscriptions.getSubscription(billing.subscriptionId); - (, uint64 initiatedRequests, ) = subscriptions.getConsumer(billing.client, billing.subscriptionId); - - if (balance - blockedBalance < estimatedCost) { + if ((request.availableBalance) < estimatedTotalCostJuels) { revert InsufficientBalance(); } - bytes32 requestId = computeRequestId(address(this), billing.client, billing.subscriptionId, initiatedRequests + 1); - - Commitment memory commitment = Commitment( - billing.subscriptionId, - billing.client, - billing.callbackGasLimit, - billing.expectedGasPrice, + bytes32 requestId = _computeRequestId( address(this), - donFee, - adminFee, - estimatedCost, - s_config.gasOverheadBeforeCallback + s_config.gasOverheadAfterCallback, - block.timestamp + request.requestingContract, + request.subscriptionId, + request.initiatedRequests + 1 ); - s_requestCommitments[requestId] = commitment; - emit BillingStart(requestId, commitment); + commitment = FunctionsResponse.Commitment({ + adminFee: request.adminFee, + coordinator: address(this), + client: request.requestingContract, + subscriptionId: request.subscriptionId, + callbackGasLimit: request.callbackGasLimit, + estimatedTotalCostJuels: estimatedTotalCostJuels, + timeoutTimestamp: uint32(block.timestamp + config.requestTimeoutSeconds), + requestId: requestId, + donFee: donFee, + gasOverheadBeforeCallback: config.gasOverheadBeforeCallback, + gasOverheadAfterCallback: config.gasOverheadAfterCallback + }); + + s_requestCommitments[requestId] = keccak256(abi.encode(commitment)); - return (requestId, estimatedCost, s_config.gasOverheadAfterCallback, s_config.requestTimeoutSeconds); + return commitment; } - /** - * @notice Generate a keccak hash request ID - */ - function computeRequestId( + // @notice Generate a keccak hash request ID + // @dev uses the number of requests that the consumer of a subscription has sent as a nonce + function _computeRequestId( address don, address client, uint64 subscriptionId, @@ -341,128 +245,137 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { return keccak256(abi.encode(don, client, subscriptionId, nonce)); } - /** - * @notice Finalize billing process for an Functions request by sending a callback to the Client contract and then charging the subscription - * @param requestId identifier for the request that was generated by the Registry in the beginBilling commitment - * @param response response data from DON consensus - * @param err error from DON consensus - * @return result fulfillment result - * @dev Only callable by a node that has been approved on the Coordinator - * @dev simulated offchain to determine if sufficient balance is present to fulfill the request - */ + // @notice Finalize billing process for an Functions request by sending a callback to the Client contract and then charging the subscription + // @param requestId identifier for the request that was generated by the Registry in the beginBilling commitment + // @param response response data from DON consensus + // @param err error from DON consensus + // @return result fulfillment result + // @dev Only callable by a node that has been approved on the Coordinator + // @dev simulated offchain to determine if sufficient balance is present to fulfill the request function _fulfillAndBill( bytes32 requestId, bytes memory response, - bytes memory err - ) - internal - returns ( - /* bytes calldata metadata, */ - FulfillResult - ) - { - Commitment memory commitment = s_requestCommitments[requestId]; - if (commitment.don == address(0)) { - return FulfillResult.INVALID_REQUEST_ID; + bytes memory err, + bytes memory onchainMetadata, + bytes memory /* offchainMetadata TODO: use in getDonFee() for dynamic billing */ + ) internal returns (FunctionsResponse.FulfillResult) { + FunctionsResponse.Commitment memory commitment = abi.decode(onchainMetadata, (FunctionsResponse.Commitment)); + + if (s_requestCommitments[requestId] != keccak256(abi.encode(commitment))) { + return FunctionsResponse.FulfillResult.INVALID_COMMITMENT; } - delete s_requestCommitments[requestId]; - int256 weiPerUnitLink; - weiPerUnitLink = getFeedData(); - if (weiPerUnitLink <= 0) { - revert InvalidLinkWeiPrice(weiPerUnitLink); + if (s_requestCommitments[requestId] == bytes32(0)) { + return FunctionsResponse.FulfillResult.INVALID_REQUEST_ID; } - // (1e18 juels/link) * (gas/wei) / (wei/link) = juels per wei - uint256 juelsPerGas = (1e18 * tx.gasprice) / uint256(weiPerUnitLink); + + uint96 juelsPerGas = _getJuelsPerGas(tx.gasprice); // Gas overhead without callback - uint96 gasOverheadJuels = uint96(juelsPerGas * commitment.gasOverhead); - uint96 costWithoutFulfillment = gasOverheadJuels + commitment.donFee; + uint96 gasOverheadJuels = juelsPerGas * + (commitment.gasOverheadBeforeCallback + commitment.gasOverheadAfterCallback); // The Functions Router will perform the callback to the client contract - IFunctionsRouter router = IFunctionsRouter(address(s_router)); - (uint8 result, uint96 callbackCostJuels) = router.fulfill( - requestId, + (FunctionsResponse.FulfillResult resultCode, uint96 callbackCostJuels) = _getRouter().fulfill( response, err, - uint96(juelsPerGas), - costWithoutFulfillment, - msg.sender + juelsPerGas, + gasOverheadJuels + commitment.donFee, // costWithoutFulfillment + msg.sender, + commitment ); - // Reimburse the transmitter for the fulfillment gas cost - s_withdrawableTokens[msg.sender] = gasOverheadJuels + callbackCostJuels; - // Put donFee into the pool of fees, to be split later - // Saves on storage writes that would otherwise be charged to the user - s_feePool += commitment.donFee; - - emit BillingEnd( - requestId, - commitment.subscriptionId, - commitment.donFee, - gasOverheadJuels + callbackCostJuels, - gasOverheadJuels + callbackCostJuels + commitment.donFee + commitment.adminFee, - FulfillResult(result) - ); + // The router will only pay the DON on successfully processing the fulfillment + // In these two fulfillment results the user has been charged + // Otherwise, the Coordinator should hold on to the request commitment + if ( + resultCode == FunctionsResponse.FulfillResult.FULFILLED || + resultCode == FunctionsResponse.FulfillResult.USER_CALLBACK_ERROR + ) { + delete s_requestCommitments[requestId]; + // Reimburse the transmitter for the fulfillment gas cost + s_withdrawableTokens[msg.sender] = gasOverheadJuels + callbackCostJuels; + // Put donFee into the pool of fees, to be split later + // Saves on storage writes that would otherwise be charged to the user + s_feePool += commitment.donFee; + } - return FulfillResult(result); + return resultCode; } // ================================================================ - // | Request Timeout Methods | + // | Request Timeout | // ================================================================ - /** - * @inheritdoc IFunctionsBilling - */ + + // @inheritdoc IFunctionsBilling + // @dev Only callable by the Router + // @dev Used by FunctionsRouter.sol during timeout of a request function deleteCommitment(bytes32 requestId) external override onlyRouter returns (bool) { - Commitment memory commitment = s_requestCommitments[requestId]; // Ensure that commitment exists - if (commitment.don == address(0)) { + if (s_requestCommitments[requestId] == bytes32(0)) { return false; } // Delete commitment delete s_requestCommitments[requestId]; - emit RequestTimedOut(requestId); + emit CommitmentDeleted(requestId); return true; } // ================================================================ - // | Node Operator methods | + // | Fund withdrawal | // ================================================================ - /* - * @notice Oracle withdraw LINK earned through fulfilling requests - * @notice If amount is 0 the full balance will be withdrawn - * @notice Both signing and transmitting wallets will have a balance to withdraw - * @param recipient where to send the funds - * @param amount amount to withdraw - */ + + // @inheritdoc IFunctionsBilling function oracleWithdraw(address recipient, uint96 amount) external { _disperseFeePool(); if (amount == 0) { amount = s_withdrawableTokens[msg.sender]; - } - if (s_withdrawableTokens[msg.sender] < amount) { + } else if (s_withdrawableTokens[msg.sender] < amount) { revert InsufficientBalance(); } s_withdrawableTokens[msg.sender] -= amount; - IFunctionsSubscriptions router = IFunctionsSubscriptions(address(s_router)); - router.oracleWithdraw(recipient, amount); + IFunctionsSubscriptions(address(_getRouter())).oracleWithdraw(recipient, amount); } + // @inheritdoc IFunctionsBilling + // @dev Only callable by the Coordinator owner + function oracleWithdrawAll() external { + _onlyOwner(); + _disperseFeePool(); + + address[] memory transmitters = _getTransmitters(); + + // Bounded by "maxNumOracles" on OCR2Abstract.sol + for (uint256 i = 0; i < transmitters.length; ++i) { + uint96 balance = s_withdrawableTokens[msg.sender]; + s_withdrawableTokens[msg.sender] = 0; + IFunctionsSubscriptions(address(_getRouter())).oracleWithdraw(transmitters[i], balance); + } + } + + // Overriden in FunctionsCoordinator, which has visibility into transmitters + function _getTransmitters() internal view virtual returns (address[] memory); + + // DON fees are collected into a pool s_feePool + // When OCR configuration changes, or any oracle withdraws, this must be dispersed function _disperseFeePool() internal { + if (s_feePool == 0) { + return; + } // All transmitters are assumed to also be observers // Pay out the DON fee to all transmitters - // Bounded by "maxNumOracles" on OCR2Abstract.sol address[] memory transmitters = _getTransmitters(); if (transmitters.length == 0) { revert NoTransmittersSet(); } uint96 feePoolShare = s_feePool / uint96(transmitters.length); - for (uint8 i = 0; i < transmitters.length; i++) { + // Bounded by "maxNumOracles" on OCR2Abstract.sol + for (uint256 i = 0; i < transmitters.length; ++i) { s_withdrawableTokens[transmitters[i]] += feePoolShare; } s_feePool -= feePoolShare * uint96(transmitters.length); } - function _getTransmitters() internal view virtual returns (address[] memory); + // Overriden in FunctionsCoordinator.sol + function _onlyOwner() internal view virtual; } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsClient.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsClient.sol index 05f8cab1c19..b7f676c2327 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsClient.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsClient.sol @@ -1,105 +1,61 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -import {Functions} from "./Functions.sol"; import {IFunctionsRouter} from "./interfaces/IFunctionsRouter.sol"; import {IFunctionsClient} from "./interfaces/IFunctionsClient.sol"; -import {IFunctionsCoordinator} from "./interfaces/IFunctionsCoordinator.sol"; -import {IFunctionsBilling} from "./interfaces/IFunctionsBilling.sol"; -/** - * @title The Chainlink Functions client contract - * @notice Contract writers can inherit this contract in order to create Chainlink Functions requests - */ +import {FunctionsRequest} from "./libraries/FunctionsRequest.sol"; + +// @title The Chainlink Functions client contract +// @notice Contract developers can inherit this contract in order to make Chainlink Functions requests abstract contract FunctionsClient is IFunctionsClient { - IFunctionsRouter internal s_router; + using FunctionsRequest for FunctionsRequest.Request; + + IFunctionsRouter internal immutable i_router; event RequestSent(bytes32 indexed id); event RequestFulfilled(bytes32 indexed id); - error OnlyRouterCanFufill(); + error OnlyRouterCanFulfill(); constructor(address router) { - setRouter(router); + i_router = IFunctionsRouter(router); } - /** - * @notice Sends a Chainlink Functions request to the stored oracle address - * @param req The initialized Functions.Request - * @param subscriptionId The subscription ID - * @param callbackGasLimit gas limit for the fulfillment callback - * @return requestId The generated request ID - */ + // @notice Sends a Chainlink Functions request + // @param data The CBOR encoded bytes data for a Functions request + // @param subscriptionId The subscription ID that will be charged to service the request + // @param callbackGasLimit the amount of gas that will be available for the fulfillment callback + // @return requestId The generated request ID for this request function _sendRequest( - Functions.Request memory req, - uint64 subscriptionId, - uint32 callbackGasLimit, - bytes32 donId - ) internal returns (bytes32 requestId) { - bytes memory requestData = Functions.encodeCBOR(req); - requestId = _sendRequestBytes(requestData, subscriptionId, callbackGasLimit, donId); - } - - /** - * @notice Sends a Chainlink Functions request to the stored oracle address - * @param data The initialized Functions request data - * @param subscriptionId The subscription ID - * @param callbackGasLimit gas limit for the fulfillment callback - * @return requestId The generated request ID - */ - function _sendRequestBytes( bytes memory data, uint64 subscriptionId, uint32 callbackGasLimit, bytes32 donId - ) internal returns (bytes32 requestId) { - requestId = s_router.sendRequest(subscriptionId, data, Functions.REQUEST_DATA_VERSION, callbackGasLimit, donId); + ) internal returns (bytes32) { + bytes32 requestId = i_router.sendRequest( + subscriptionId, + data, + FunctionsRequest.REQUEST_DATA_VERSION, + callbackGasLimit, + donId + ); emit RequestSent(requestId); + return requestId; } - /** - * @notice User defined function to handle a response - * @param requestId The request ID, returned by sendRequest() - * @param response Aggregated response from the user code - * @param err Aggregated error from the user code or from the execution pipeline - * Either response or error parameter will be set, but never both - */ + // @notice User defined function to handle a response from the DON + // @param requestId The request ID, returned by sendRequest() + // @param response Aggregated response from the execution of the user's source code + // @param err Aggregated error from the execution of the user code or from the execution pipeline + // @dev Either response or error parameter will be set, but never both function fulfillRequest(bytes32 requestId, bytes memory response, bytes memory err) internal virtual; - /** - * @inheritdoc IFunctionsClient - */ - function handleOracleFulfillment( - bytes32 requestId, - bytes memory response, - bytes memory err - ) external override onlyRouter { - fulfillRequest(requestId, response, err); - } - - /** - * @notice Sets the stored router address - * @param router The address of Functions router contract - */ - function setRouter(address router) internal { - s_router = IFunctionsRouter(router); - } - - /** - * @notice Gets the stored address of the router contract - * @return The address of the router contract - */ - function getRouter() internal view returns (address) { - return address(s_router); - } - - /** - * @dev Reverts if the request is not from the Router - */ - modifier onlyRouter() { - if (msg.sender != address(s_router)) { - revert OnlyRouterCanFufill(); + // @inheritdoc IFunctionsClient + function handleOracleFulfillment(bytes32 requestId, bytes memory response, bytes memory err) external override { + if (msg.sender != address(i_router)) { + revert OnlyRouterCanFulfill(); } - _; + fulfillRequest(requestId, response, err); } } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsCoordinator.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsCoordinator.sol index 5c875fd7698..46df61cd916 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsCoordinator.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsCoordinator.sol @@ -2,17 +2,24 @@ pragma solidity ^0.8.19; import {IFunctionsCoordinator} from "./interfaces/IFunctionsCoordinator.sol"; -import {IFunctionsBilling, FunctionsBilling} from "./FunctionsBilling.sol"; +import {IFunctionsBilling} from "./interfaces/IFunctionsBilling.sol"; +import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; + +import {FunctionsBilling} from "./FunctionsBilling.sol"; import {OCR2Base} from "./ocr/OCR2Base.sol"; -import {FulfillResult} from "./FulfillResultCodes.sol"; -import {ITypeAndVersion} from "./Routable.sol"; - -/** - * @title Functions Coordinator contract - * @notice Contract that nodes of a Decentralized Oracle Network (DON) interact with - * @dev THIS CONTRACT HAS NOT GONE THROUGH ANY SECURITY REVIEW. DO NOT USE IN PROD. - */ +import {FunctionsResponse} from "./libraries/FunctionsResponse.sol"; + +// @title Functions Coordinator contract +// @notice Contract that nodes of a Decentralized Oracle Network (DON) interact with +// @dev THIS CONTRACT HAS NOT GONE THROUGH ANY SECURITY REVIEW. DO NOT USE IN PROD. contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilling { + using FunctionsResponse for FunctionsResponse.RequestMeta; + using FunctionsResponse for FunctionsResponse.Commitment; + using FunctionsResponse for FunctionsResponse.FulfillResult; + + // @inheritdoc ITypeAndVersion + string public constant override typeAndVersion = "Functions Coordinator v1.0.0"; + event OracleRequest( bytes32 indexed requestId, address indexed requestingContract, @@ -20,14 +27,13 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli uint64 subscriptionId, address subscriptionOwner, bytes data, - uint16 dataVersion + uint16 dataVersion, + bytes32 flags, + uint64 callbackGasLimit, + FunctionsResponse.Commitment commitment ); event OracleResponse(bytes32 indexed requestId, address transmitter); - event InvalidRequestID(bytes32 indexed requestId); - event InsufficientGasProvided(bytes32 indexed requestId); - event CostExceedsCommitment(bytes32 indexed requestId); - error EmptyRequestData(); error InconsistentReportData(); error EmptyPublicKey(); error UnauthorizedPublicKeyChange(); @@ -38,20 +44,11 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli constructor( address router, - bytes memory config, + Config memory config, address linkToNativeFeed ) OCR2Base(true) FunctionsBilling(router, config, linkToNativeFeed) {} - /** - * @inheritdoc ITypeAndVersion - */ - function typeAndVersion() public pure override returns (string memory) { - return "Functions Coordinator v1"; - } - - /** - * @inheritdoc IFunctionsCoordinator - */ + // @inheritdoc IFunctionsCoordinator function getThresholdPublicKey() external view override returns (bytes memory) { if (s_thresholdPublicKey.length == 0) { revert EmptyPublicKey(); @@ -59,9 +56,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli return s_thresholdPublicKey; } - /** - * @inheritdoc IFunctionsCoordinator - */ + // @inheritdoc IFunctionsCoordinator function setThresholdPublicKey(bytes calldata thresholdPublicKey) external override onlyOwner { if (thresholdPublicKey.length == 0) { revert EmptyPublicKey(); @@ -69,9 +64,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli s_thresholdPublicKey = thresholdPublicKey; } - /** - * @inheritdoc IFunctionsCoordinator - */ + // @inheritdoc IFunctionsCoordinator function getDONPublicKey() external view override returns (bytes memory) { if (s_donPublicKey.length == 0) { revert EmptyPublicKey(); @@ -79,9 +72,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli return s_donPublicKey; } - /** - * @inheritdoc IFunctionsCoordinator - */ + // @inheritdoc IFunctionsCoordinator function setDONPublicKey(bytes calldata donPublicKey) external override onlyOwner { if (donPublicKey.length == 0) { revert EmptyPublicKey(); @@ -89,12 +80,11 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli s_donPublicKey = donPublicKey; } - /** - * @dev check if node is in current transmitter list - */ + // @dev check if node is in current transmitter list function _isTransmitter(address node) internal view returns (bool) { - address[] memory nodes = this.transmitters(); - for (uint256 i = 0; i < nodes.length; i++) { + address[] memory nodes = s_transmitters; + // Bounded by "maxNumOracles" on OCR2Abstract.sol + for (uint256 i = 0; i < nodes.length; ++i) { if (nodes[i] == node) { return true; } @@ -102,9 +92,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli return false; } - /** - * @inheritdoc IFunctionsCoordinator - */ + // @inheritdoc IFunctionsCoordinator function setNodePublicKey(address node, bytes calldata publicKey) external override { // Owner can set anything. Transmitters can set only their own key. if (!(msg.sender == owner() || (_isTransmitter(msg.sender) && msg.sender == node))) { @@ -113,131 +101,112 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli s_nodePublicKeys[node] = publicKey; } - /** - * @inheritdoc IFunctionsCoordinator - */ + // @inheritdoc IFunctionsCoordinator function deleteNodePublicKey(address node) external override { // Owner can delete anything. Others can delete only their own key. - if (!(msg.sender == owner() || msg.sender == node)) { + if (msg.sender != owner() && msg.sender != node) { revert UnauthorizedPublicKeyChange(); } delete s_nodePublicKeys[node]; } - /** - * @inheritdoc IFunctionsCoordinator - */ + // @inheritdoc IFunctionsCoordinator function getAllNodePublicKeys() external view override returns (address[] memory, bytes[] memory) { - address[] memory nodes = this.transmitters(); + address[] memory nodes = s_transmitters; bytes[] memory keys = new bytes[](nodes.length); - for (uint256 i = 0; i < nodes.length; i++) { - if (s_nodePublicKeys[nodes[i]].length == 0) { + // Bounded by "maxNumOracles" on OCR2Abstract.sol + for (uint256 i = 0; i < nodes.length; ++i) { + bytes memory nodePublicKey = s_nodePublicKeys[nodes[i]]; + if (nodePublicKey.length == 0) { revert EmptyPublicKey(); } - keys[i] = s_nodePublicKeys[nodes[i]]; + keys[i] = nodePublicKey; } return (nodes, keys); } - /** - * @inheritdoc IFunctionsCoordinator - */ - function sendRequest( - Request calldata request - ) - external - override - onlyRouter - returns (bytes32 requestId, uint96 estimatedCost, uint256 gasAfterPaymentCalculation, uint256 requestTimeoutSeconds) - { - if (request.data.length == 0) { - revert EmptyRequestData(); - } - - RequestBilling memory billing = IFunctionsBilling.RequestBilling( - request.subscriptionId, - request.caller, - request.callbackGasLimit, - tx.gasprice - ); - - (requestId, estimatedCost, gasAfterPaymentCalculation, requestTimeoutSeconds) = _startBilling( - request.data, - request.dataVersion, - billing - ); + // @inheritdoc IFunctionsCoordinator + function startRequest( + FunctionsResponse.RequestMeta calldata request + ) external override onlyRouter returns (FunctionsResponse.Commitment memory commitment) { + commitment = _startBilling(request); emit OracleRequest( - requestId, - request.caller, + commitment.requestId, + request.requestingContract, tx.origin, request.subscriptionId, request.subscriptionOwner, request.data, - request.dataVersion + request.dataVersion, + request.flags, + request.callbackGasLimit, + commitment ); + + return commitment; } + // DON fees are pooled together. If the OCR configuration is going to change, these need to be distributed. function _beforeSetConfig(uint8 /* _f */, bytes memory /* _onchainConfig */) internal override { if (_getTransmitters().length > 0) { _disperseFeePool(); } } - function _afterSetConfig(uint8 /* _f */, bytes memory /* _onchainConfig */) internal override {} - - function _validateReport( - bytes32 /* configDigest */, - uint40 /* epochAndRound */, - bytes memory /* report */ - ) internal pure override returns (bool) { - // validate within _report to save gas - return true; - } - + // Used by FunctionsBilling.sol function _getTransmitters() internal view override returns (address[] memory) { return s_transmitters; } + // Report hook called within OCR2Base.sol function _report( uint256 /*initialGas*/, address /*transmitter*/, uint8 /*signerCount*/, - address[maxNumOracles] memory /*signers*/, + address[MAX_NUM_ORACLES] memory /*signers*/, bytes calldata report ) internal override { bytes32[] memory requestIds; bytes[] memory results; bytes[] memory errors; - ( - requestIds, - results, - errors - /*metadata, TODO: usage metadata through report*/ - ) = abi.decode(report, (bytes32[], bytes[], bytes[])); - if (requestIds.length == 0 || requestIds.length != results.length || requestIds.length != errors.length) { + bytes[] memory onchainMetadata; + bytes[] memory offchainMetadata; + (requestIds, results, errors, onchainMetadata, offchainMetadata) = abi.decode( + report, + (bytes32[], bytes[], bytes[], bytes[], bytes[]) + ); + + if ( + requestIds.length == 0 || + requestIds.length != results.length || + requestIds.length != errors.length || + requestIds.length != onchainMetadata.length || + requestIds.length != offchainMetadata.length + ) { revert ReportInvalid(); } - for (uint256 i = 0; i < requestIds.length; i++) { - FulfillResult result = FulfillResult( - _fulfillAndBill( - requestIds[i], - results[i], - errors[i] - /* metadata[i], */ - ) + // Bounded by "MaxRequestBatchSize" on the Job's ReportingPluginConfig + for (uint256 i = 0; i < requestIds.length; ++i) { + FunctionsResponse.FulfillResult result = FunctionsResponse.FulfillResult( + _fulfillAndBill(requestIds[i], results[i], errors[i], onchainMetadata[i], offchainMetadata[i]) ); - if (result == FulfillResult.USER_SUCCESS || result == FulfillResult.USER_ERROR) { + // Emit on successfully processing the fulfillment + // In these two fulfillment results the user has been charged + // Otherwise, the DON will re-try + if ( + result == FunctionsResponse.FulfillResult.FULFILLED || + result == FunctionsResponse.FulfillResult.USER_CALLBACK_ERROR + ) { emit OracleResponse(requestIds[i], msg.sender); - } else if (result == FulfillResult.INVALID_REQUEST_ID) { - emit InvalidRequestID(requestIds[i]); - } else if (result == FulfillResult.INSUFFICIENT_GAS) { - emit InsufficientGasProvided(requestIds[i]); - } else if (result == FulfillResult.COST_EXCEEDS_COMMITMENT) { - emit CostExceedsCommitment(requestIds[i]); } } } + + // Used in FunctionsBilling.sol + function _onlyOwner() internal view override { + _validateOwnership(); + } } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol index 80a2f0037e8..46f6929fabc 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol @@ -1,14 +1,31 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -import {RouterBase, ITypeAndVersion} from "./RouterBase.sol"; +import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; import {IFunctionsRouter} from "./interfaces/IFunctionsRouter.sol"; import {IFunctionsCoordinator} from "./interfaces/IFunctionsCoordinator.sol"; +import {IAccessController} from "../../../shared/interfaces/IAccessController.sol"; + import {FunctionsSubscriptions} from "./FunctionsSubscriptions.sol"; -import {ITermsOfServiceAllowList} from "./accessControl/interfaces/ITermsOfServiceAllowList.sol"; -import {SafeCast} from "../../../shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/utils/SafeCast.sol"; +import {FunctionsResponse} from "./libraries/FunctionsResponse.sol"; +import {ConfirmedOwner} from "../../../shared/access/ConfirmedOwner.sol"; + +import {SafeCast} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/SafeCast.sol"; +import {Pausable} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/security/Pausable.sol"; + +contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, ITypeAndVersion, ConfirmedOwner { + using FunctionsResponse for FunctionsResponse.RequestMeta; + using FunctionsResponse for FunctionsResponse.Commitment; + using FunctionsResponse for FunctionsResponse.FulfillResult; + + string public constant override typeAndVersion = "Functions Router v1.0.0"; + + // We limit return data to a selector plus 4 words. This is to avoid + // malicious contracts from returning large amounts of data and causing + // repeated out-of-gas scenarios. + uint16 public constant MAX_CALLBACK_RETURN_BYTES = 4 + 4 * 32; + uint8 private constant MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX = 0; -contract FunctionsRouter is RouterBase, IFunctionsRouter, FunctionsSubscriptions { event RequestStart( bytes32 indexed requestId, bytes32 indexed donId, @@ -18,251 +35,343 @@ contract FunctionsRouter is RouterBase, IFunctionsRouter, FunctionsSubscriptions address requestInitiator, bytes data, uint16 dataVersion, - uint32 callbackGasLimit + uint32 callbackGasLimit, + uint96 estimatedTotalCostJuels ); - event RequestEnd( + event RequestProcessed( bytes32 indexed requestId, uint64 indexed subscriptionId, uint96 totalCostJuels, address transmitter, - uint8 resultCode, - bytes response + FunctionsResponse.FulfillResult resultCode, + bytes response, + bytes err, + bytes callbackReturnData + ); + + event RequestNotProcessed( + bytes32 indexed requestId, + address coordinator, + address transmitter, + FunctionsResponse.FulfillResult resultCode ); + error EmptyRequestData(); error OnlyCallableFromCoordinator(); error SenderMustAcceptTermsOfService(address sender); + error InvalidGasFlagValue(uint8 value); + error GasLimitTooBig(uint32 limit); struct CallbackResult { - bool success; - uint256 gasUsed; + bool success; // ══════╸ Whether the callback succeeded or not + uint256 gasUsed; // ═══╸ The amount of gas consumed during the callback + bytes returnData; // ══╸ The return of the callback function } + // ================================================================ + // | Route state | + // ================================================================ + + mapping(bytes32 id => address routableContract) private s_route; + + error RouteNotFound(bytes32 id); + // Identifier for the route to the Terms of Service Allow List - bytes32 private constant ALLOW_LIST_ID = keccak256("Functions Terms of Service Allow List"); + bytes32 private s_allowListId; // ================================================================ // | Configuration state | // ================================================================ struct Config { - // Flat fee (in Juels of LINK) that will be paid to the Router owner for operation of the network - uint96 adminFee; - // The function selector that is used when calling back to the Client contract - bytes4 handleOracleFulfillmentSelector; + uint16 maxConsumersPerSubscription; // ══════╗ Maximum number of consumers which can be added to a single subscription. This bound ensures we are able to loop over all subscription consumers as needed, without exceeding gas limits. Should a user require more consumers, they can use multiple subscriptions. + uint72 adminFee; // ║ Flat fee (in Juels of LINK) that will be paid to the Router owner for operation of the network + bytes4 handleOracleFulfillmentSelector; // ║ The function selector that is used when calling back to the Client contract + uint16 gasForCallExactCheck; // ═════════════╝ Used during calling back to the client. Ensures we have at least enough gas to be able to revert if gasAmount > 63//64*gas available. + uint32[] maxCallbackGasLimits; // ═══════════╸ List of max callback gas limits used by flag with GAS_FLAG_INDEX } + Config private s_config; - event ConfigSet(uint96 adminFee, bytes4 handleOracleFulfillmentSelector); - error OnlyCallableByRoute(); + event ConfigUpdated(Config); + + // ================================================================ + // | Proposal state | + // ================================================================ + + uint8 private constant MAX_PROPOSAL_SET_LENGTH = 8; + + struct ContractProposalSet { + bytes32[] ids; // ══╸ The IDs that key into the routes that will be modified if the update is applied + address[] to; // ═══╸ The address of the contracts that the route will point to if the updated is applied + } + ContractProposalSet private s_proposedContractSet; + + event ContractProposed( + bytes32 proposedContractSetId, + address proposedContractSetFromAddress, + address proposedContractSetToAddress + ); + + event ContractUpdated(bytes32 id, address from, address to); + + error InvalidProposal(); + error IdentifierIsReserved(bytes32 id); // ================================================================ // | Initialization | // ================================================================ + constructor( - uint16 timelockBlocks, - uint16 maximumTimelockBlocks, address linkToken, - bytes memory config - ) RouterBase(msg.sender, timelockBlocks, maximumTimelockBlocks, config) FunctionsSubscriptions(linkToken) {} + Config memory config + ) FunctionsSubscriptions(linkToken) ConfirmedOwner(msg.sender) Pausable() { + // Set the intial configuration + updateConfig(config); + } // ================================================================ - // | Getters | + // | Configuration | // ================================================================ - /** - * @inheritdoc ITypeAndVersion - */ - function typeAndVersion() public pure override returns (string memory) { - return "Functions Router v1"; + + // @notice The identifier of the route to retrieve the address of the access control contract + // The access control contract controls which accounts can manage subscriptions + // @return id - bytes32 id that can be passed to the "getContractById" of the Router + function getConfig() external view returns (Config memory) { + return s_config; + } + + // @notice The router configuration + function updateConfig(Config memory config) public onlyOwner { + s_config = config; + emit ConfigUpdated(config); } - /** - * @inheritdoc IFunctionsRouter - */ - function getAllowListId() external pure override returns (bytes32) { - return ALLOW_LIST_ID; + // @inheritdoc IFunctionsRouter + function isValidCallbackGasLimit(uint64 subscriptionId, uint32 callbackGasLimit) public view { + uint8 callbackGasLimitsIndexSelector = uint8(getFlags(subscriptionId)[MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX]); + if (callbackGasLimitsIndexSelector >= s_config.maxCallbackGasLimits.length) { + revert InvalidGasFlagValue(callbackGasLimitsIndexSelector); + } + uint32 maxCallbackGasLimit = s_config.maxCallbackGasLimits[callbackGasLimitsIndexSelector]; + if (callbackGasLimit > maxCallbackGasLimit) { + revert GasLimitTooBig(maxCallbackGasLimit); + } } - /** - * @inheritdoc IFunctionsRouter - */ - function getAdminFee() external view override returns (uint96) { + // @inheritdoc IFunctionsRouter + function getAdminFee() external view override returns (uint72) { return s_config.adminFee; } - // ================================================================ - // | Configuration methods | - // ================================================================ - /** - * @notice Sets the configuration for FunctionsRouter specific state - * @param config bytes of config data to set the following: - * - adminFee: fee that will be paid to the Router owner for operating the network - */ - function _setConfig(bytes memory config) internal override { - (uint96 adminFee, bytes4 handleOracleFulfillmentSelector) = abi.decode(config, (uint96, bytes4)); - s_config = Config({adminFee: adminFee, handleOracleFulfillmentSelector: handleOracleFulfillmentSelector}); - emit ConfigSet(adminFee, handleOracleFulfillmentSelector); + // @inheritdoc IFunctionsRouter + function getAllowListId() external view override returns (bytes32) { + return s_allowListId; + } + + // @inheritdoc IFunctionsRouter + function setAllowListId(bytes32 allowListId) external override onlyOwner { + s_allowListId = allowListId; + } + + // Used within FunctionsSubscriptions.sol + function _getMaxConsumers() internal view override returns (uint16) { + return s_config.maxConsumersPerSubscription; } // ================================================================ - // | Request methods | + // | Requests | // ================================================================ + // @inheritdoc IFunctionsRouter + function sendRequest( + uint64 subscriptionId, + bytes calldata data, + uint16 dataVersion, + uint32 callbackGasLimit, + bytes32 donId + ) external override returns (bytes32) { + IFunctionsCoordinator coordinator = IFunctionsCoordinator(getContractById(donId)); + return _sendRequest(donId, coordinator, subscriptionId, data, dataVersion, callbackGasLimit); + } + + // @inheritdoc IFunctionsRouter + function sendRequestToProposed( + uint64 subscriptionId, + bytes calldata data, + uint16 dataVersion, + uint32 callbackGasLimit, + bytes32 donId + ) external override returns (bytes32) { + IFunctionsCoordinator coordinator = IFunctionsCoordinator(getProposedContractById(donId)); + return _sendRequest(donId, coordinator, subscriptionId, data, dataVersion, callbackGasLimit); + } + function _sendRequest( bytes32 donId, - bool useProposed, + IFunctionsCoordinator coordinator, uint64 subscriptionId, bytes memory data, uint16 dataVersion, uint32 callbackGasLimit - ) private returns (bytes32 requestId) { - _isValidSubscription(subscriptionId); - _isValidConsumer(msg.sender, subscriptionId); + ) private returns (bytes32) { + _whenNotPaused(); + _isExistingSubscription(subscriptionId); + _isAllowedConsumer(msg.sender, subscriptionId); + isValidCallbackGasLimit(subscriptionId, callbackGasLimit); + + if (data.length == 0) { + revert EmptyRequestData(); + } - address coordinatorAddress = _getContractById(donId, useProposed); + Subscription memory subscription = getSubscription(subscriptionId); + Consumer memory consumer = getConsumer(msg.sender, subscriptionId); // Forward request to DON - uint96 estimatedCost; - uint256 gasAfterPaymentCalculation; // Used to ensure that the transmitter supplies enough gas - uint256 requestTimeoutSeconds; - ( - requestId, - estimatedCost, - gasAfterPaymentCalculation, // Used to ensure that the transmitter supplies enough gas - requestTimeoutSeconds - ) = IFunctionsCoordinator(coordinatorAddress).sendRequest( - IFunctionsCoordinator.Request( - subscriptionId, - data, - dataVersion, - callbackGasLimit, - msg.sender, - s_subscriptions[subscriptionId].owner - ) + FunctionsResponse.Commitment memory commitment = coordinator.startRequest( + FunctionsResponse.RequestMeta({ + requestingContract: msg.sender, + data: data, + subscriptionId: subscriptionId, + dataVersion: dataVersion, + flags: getFlags(subscriptionId), + callbackGasLimit: callbackGasLimit, + adminFee: s_config.adminFee, + initiatedRequests: consumer.initiatedRequests, + completedRequests: consumer.completedRequests, + availableBalance: subscription.balance - subscription.blockedBalance, + subscriptionOwner: subscription.owner + }) ); - _markRequestInFlight(msg.sender, subscriptionId, estimatedCost); - // Store a commitment about the request - s_requestCommitments[requestId] = Commitment( - coordinatorAddress, - msg.sender, - subscriptionId, - callbackGasLimit, - estimatedCost, - block.timestamp + requestTimeoutSeconds, - gasAfterPaymentCalculation, - s_config.adminFee - ); - - emit RequestStart( - requestId, - donId, - subscriptionId, - s_subscriptions[subscriptionId].owner, - msg.sender, - tx.origin, - data, - dataVersion, - callbackGasLimit + s_requestCommitments[commitment.requestId] = keccak256( + abi.encode( + FunctionsResponse.Commitment({ + adminFee: s_config.adminFee, + coordinator: address(coordinator), + client: msg.sender, + subscriptionId: subscriptionId, + callbackGasLimit: callbackGasLimit, + estimatedTotalCostJuels: commitment.estimatedTotalCostJuels, + timeoutTimestamp: commitment.timeoutTimestamp, + requestId: commitment.requestId, + donFee: commitment.donFee, + gasOverheadBeforeCallback: commitment.gasOverheadBeforeCallback, + gasOverheadAfterCallback: commitment.gasOverheadAfterCallback + }) + ) ); - return requestId; - } - - function _validateProposedContracts( - bytes32 donId, - bytes calldata data - ) internal override returns (bytes memory output) { - (uint64 subscriptionId, bytes memory reqData, uint16 reqDataVersion, uint32 callbackGasLimit) = abi.decode( - data, - (uint64, bytes, uint16, uint32) - ); - bytes32 requestId = _sendRequest(donId, true, subscriptionId, reqData, reqDataVersion, callbackGasLimit); - // Convert to bytes as a more generic return - output = new bytes(32); - for (uint256 i; i < 32; i++) { - output[i] = requestId[i]; - } + _markRequestInFlight(msg.sender, subscriptionId, commitment.estimatedTotalCostJuels); + + emit RequestStart({ + requestId: commitment.requestId, + donId: donId, + subscriptionId: subscriptionId, + subscriptionOwner: subscription.owner, + requestingContract: msg.sender, + requestInitiator: tx.origin, + data: data, + dataVersion: dataVersion, + callbackGasLimit: callbackGasLimit, + estimatedTotalCostJuels: commitment.estimatedTotalCostJuels + }); + + return commitment.requestId; } - /** - * @inheritdoc IFunctionsRouter - */ - function sendRequest( - uint64 subscriptionId, - bytes calldata data, - uint16 dataVersion, - uint32 callbackGasLimit, - bytes32 donId - ) external override nonReentrant whenNotPaused returns (bytes32) { - return _sendRequest(donId, false, subscriptionId, data, dataVersion, callbackGasLimit); - } + // ================================================================ + // | Responses | + // ================================================================ - /** - * @inheritdoc IFunctionsRouter - */ + // @inheritdoc IFunctionsRouter function fulfill( - bytes32 requestId, bytes memory response, bytes memory err, uint96 juelsPerGas, - uint96 costWithoutFulfillment, - address transmitter - ) external override nonReentrant returns (uint8 resultCode, uint96 callbackGasCostJuels) { - Commitment memory commitment = s_requestCommitments[requestId]; + uint96 costWithoutCallback, + address transmitter, + FunctionsResponse.Commitment memory commitment + ) external override returns (FunctionsResponse.FulfillResult resultCode, uint96) { + _whenNotPaused(); if (msg.sender != commitment.coordinator) { revert OnlyCallableFromCoordinator(); } - if (commitment.client == address(0)) { - resultCode = 2; // FulfillResult.INVALID_REQUEST_ID - return (resultCode, callbackGasCostJuels); + if (s_requestCommitments[commitment.requestId] == bytes32(0)) { + resultCode = FunctionsResponse.FulfillResult.INVALID_REQUEST_ID; + emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode); + return (resultCode, 0); + } + + if (keccak256(abi.encode(commitment)) != s_requestCommitments[commitment.requestId]) { + resultCode = FunctionsResponse.FulfillResult.INVALID_COMMITMENT; + emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode); + return (resultCode, 0); } // Check that the transmitter has supplied enough gas for the callback to succeed - if (gasleft() < commitment.callbackGasLimit + commitment.gasAfterPaymentCalculation) { - resultCode = 3; // IFunctionsRouter.FulfillResult.INSUFFICIENT_GAS; - return (resultCode, callbackGasCostJuels); + if (gasleft() < commitment.callbackGasLimit + commitment.gasOverheadAfterCallback) { + resultCode = FunctionsResponse.FulfillResult.INSUFFICIENT_GAS_PROVIDED; + emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode); + return (resultCode, 0); } - // Check that the cost has not exceeded the quoted cost - if ( - commitment.adminFee + costWithoutFulfillment + (juelsPerGas * SafeCast.toUint96(commitment.callbackGasLimit)) > - commitment.estimatedCost - ) { - resultCode = 4; // IFunctionsRouter.FulfillResult.COST_EXCEEDS_COMMITMENT - return (resultCode, callbackGasCostJuels); + { + uint96 callbackCost = juelsPerGas * SafeCast.toUint96(commitment.callbackGasLimit); + uint96 totalCostJuels = commitment.adminFee + costWithoutCallback + callbackCost; + + // Check that the subscription can still afford to fulfill the request + if (totalCostJuels > getSubscription(commitment.subscriptionId).balance) { + resultCode = FunctionsResponse.FulfillResult.SUBSCRIPTION_BALANCE_INVARIANT_VIOLATION; + emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode); + return (resultCode, 0); + } + + // Check that the cost has not exceeded the quoted cost + if (totalCostJuels > commitment.estimatedTotalCostJuels) { + resultCode = FunctionsResponse.FulfillResult.COST_EXCEEDS_COMMITMENT; + emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode); + return (resultCode, 0); + } } - // If checks pass, continue as default, 0 = USER_SUCCESS; - resultCode = 0; + delete s_requestCommitments[commitment.requestId]; - delete s_requestCommitments[requestId]; + CallbackResult memory result = _callback( + commitment.requestId, + response, + err, + commitment.callbackGasLimit, + commitment.client + ); - CallbackResult memory result = _callback(requestId, response, err, commitment.callbackGasLimit, commitment.client); resultCode = result.success - ? 0 // FulfillResult.USER_SUCCESS - : 1; // FulfillResult.USER_ERROR + ? FunctionsResponse.FulfillResult.FULFILLED + : FunctionsResponse.FulfillResult.USER_CALLBACK_ERROR; Receipt memory receipt = _pay( commitment.subscriptionId, - commitment.estimatedCost, + commitment.estimatedTotalCostJuels, commitment.client, commitment.adminFee, juelsPerGas, - result.gasUsed, - costWithoutFulfillment + SafeCast.toUint96(result.gasUsed), + costWithoutCallback ); - emit RequestEnd( - requestId, - commitment.subscriptionId, - receipt.totalCostJuels, - transmitter, - resultCode, - result.success ? response : err // TODO: handle more response data scenarios - ); + emit RequestProcessed({ + requestId: commitment.requestId, + subscriptionId: commitment.subscriptionId, + totalCostJuels: receipt.totalCostJuels, + transmitter: transmitter, + resultCode: resultCode, + response: response, + err: err, + callbackReturnData: result.returnData + }); return (resultCode, receipt.callbackGasCostJuels); } @@ -273,16 +382,16 @@ contract FunctionsRouter is RouterBase, IFunctionsRouter, FunctionsSubscriptions bytes memory err, uint32 callbackGasLimit, address client - ) private returns (CallbackResult memory result) { + ) private returns (CallbackResult memory) { bytes memory encodedCallback = abi.encodeWithSelector( s_config.handleOracleFulfillmentSelector, requestId, response, err ); - // Do not allow any non-view/non-pure coordinator functions to be called - // during the consumers callback code via reentrancyLock. - s_reentrancyLock = true; + + uint16 gasForCallExactCheck = s_config.gasForCallExactCheck; + // Call with explicitly the amount of callback gas requested // Important to not let them exhaust the gas budget and avoid payment. // NOTE: that callWithExactGas will revert if we do not have sufficient gas @@ -290,54 +399,169 @@ contract FunctionsRouter is RouterBase, IFunctionsRouter, FunctionsSubscriptions bool success; uint256 gasUsed; + // allocate return data memory ahead of time + bytes memory returnData = new bytes(MAX_CALLBACK_RETURN_BYTES); // solhint-disable-next-line no-inline-assembly assembly { + // solidity calls check that a contract actually exists at the destination, so we do the same + // Note we do this check prior to measuring gas so gasForCallExactCheck (our "cushion") + // doesn't need to account for it. + if iszero(extcodesize(client)) { + revert(0, 0) + } + let g := gas() - // GAS_FOR_CALL_EXACT_CHECK = 5000 - // Compute g -= GAS_FOR_CALL_EXACT_CHECK and check for underflow - // The gas actually passed to the callee is min(gasAmount, 63//64*gas available). + // Compute g -= gasForCallExactCheck and check for underflow + // The gas actually passed to the callee is _min(gasAmount, 63//64*gas available). // We want to ensure that we revert if gasAmount > 63//64*gas available // as we do not want to provide them with less, however that check itself costs - // gas. GAS_FOR_CALL_EXACT_CHECK ensures we have at least enough gas to be able + // gas. gasForCallExactCheck ensures we have at least enough gas to be able // to revert if gasAmount > 63//64*gas available. - if lt(g, 5000) { + if lt(g, gasForCallExactCheck) { revert(0, 0) } - g := sub(g, 5000) + g := sub(g, gasForCallExactCheck) // if g - g//64 <= gasAmount, revert // (we subtract g//64 because of EIP-150) if iszero(gt(sub(g, div(g, 64)), callbackGasLimit)) { revert(0, 0) } - // solidity calls check that a contract actually exists at the destination, so we do the same - if iszero(extcodesize(client)) { - revert(0, 0) - } - // call and return whether we succeeded. ignore return data + // call and report whether we succeeded // call(gas,addr,value,argsOffset,argsLength,retOffset,retLength) + let gasBeforeCall := gas() success := call(callbackGasLimit, client, 0, add(encodedCallback, 0x20), mload(encodedCallback), 0, 0) - gasUsed := sub(g, gas()) + gasUsed := sub(gasBeforeCall, gas()) + + // limit our copy to MAX_CALLBACK_RETURN_BYTES bytes + let toCopy := returndatasize() + if gt(toCopy, MAX_CALLBACK_RETURN_BYTES) { + toCopy := MAX_CALLBACK_RETURN_BYTES + } + // Store the length of the copied bytes + mstore(returnData, toCopy) + // copy the bytes from returnData[0:_toCopy] + returndatacopy(add(returnData, 0x20), 0, toCopy) } - s_reentrancyLock = false; + return CallbackResult({success: success, gasUsed: gasUsed, returnData: returnData}); + } + + // ================================================================ + // | Route methods | + // ================================================================ + + // @inheritdoc IRouterBase + function getContractById(bytes32 id) public view override returns (address) { + address currentImplementation = s_route[id]; + if (currentImplementation == address(0)) { + revert RouteNotFound(id); + } + return currentImplementation; + } + + // @inheritdoc IRouterBase + function getProposedContractById(bytes32 id) public view override returns (address) { + // Iterations will not exceed MAX_PROPOSAL_SET_LENGTH + for (uint8 i = 0; i < s_proposedContractSet.ids.length; ++i) { + if (id == s_proposedContractSet.ids[i]) { + return s_proposedContractSet.to[i]; + } + } + revert RouteNotFound(id); + } + + // ================================================================ + // | Contract Proposal methods | + // ================================================================ + + // @inheritdoc IRouterBase + function getProposedContractSet() external view override returns (bytes32[] memory, address[] memory) { + return (s_proposedContractSet.ids, s_proposedContractSet.to); + } + + // @inheritdoc IRouterBase + function proposeContractsUpdate( + bytes32[] memory proposedContractSetIds, + address[] memory proposedContractSetAddresses + ) external override onlyOwner { + // IDs and addresses arrays must be of equal length and must not exceed the max proposal length + uint256 idsArrayLength = proposedContractSetIds.length; + if (idsArrayLength != proposedContractSetAddresses.length || idsArrayLength > MAX_PROPOSAL_SET_LENGTH) { + revert InvalidProposal(); + } + + // NOTE: iterations of this loop will not exceed MAX_PROPOSAL_SET_LENGTH + for (uint256 i = 0; i < idsArrayLength; ++i) { + bytes32 id = proposedContractSetIds[i]; + address proposedContract = proposedContractSetAddresses[i]; + if ( + proposedContract == address(0) || // The Proposed address must be a valid address + s_route[id] == proposedContract // The Proposed address must point to a different address than what is currently set + ) { + revert InvalidProposal(); + } + } + + s_proposedContractSet = ContractProposalSet({ids: proposedContractSetIds, to: proposedContractSetAddresses}); - result = CallbackResult(success, gasUsed); + // NOTE: iterations of this loop will not exceed MAX_PROPOSAL_SET_LENGTH + for (uint256 i = 0; i < proposedContractSetIds.length; ++i) { + emit ContractProposed({ + proposedContractSetId: proposedContractSetIds[i], + proposedContractSetFromAddress: s_route[proposedContractSetIds[i]], + proposedContractSetToAddress: proposedContractSetAddresses[i] + }); + } + } + + // @inheritdoc IRouterBase + function updateContracts() external override onlyOwner { + // Iterations will not exceed MAX_PROPOSAL_SET_LENGTH + for (uint256 i = 0; i < s_proposedContractSet.ids.length; ++i) { + bytes32 id = s_proposedContractSet.ids[i]; + address to = s_proposedContractSet.to[i]; + emit ContractUpdated({id: id, from: s_route[id], to: to}); + s_route[id] = to; + } + + delete s_proposedContractSet; } // ================================================================ // | Modifiers | // ================================================================ + // Favoring internal functions over actual modifiers to reduce contract size + + // Used within FunctionsSubscriptions.sol + function _whenNotPaused() internal view override { + _requireNotPaused(); + } - modifier onlyRouterOwner() override { + // Used within FunctionsSubscriptions.sol + function _onlyRouterOwner() internal view override { _validateOwnership(); - _; } - modifier onlySenderThatAcceptedToS() override { - if (ITermsOfServiceAllowList(_getContractById(ALLOW_LIST_ID, false)).isAllowedSender(msg.sender) == false) { + // Used within FunctionsSubscriptions.sol + function _onlySenderThatAcceptedToS() internal view override { + address currentImplementation = s_route[s_allowListId]; + if (currentImplementation == address(0)) { + // If not set, ignore this check, allow all access + return; + } + if (!IAccessController(currentImplementation).hasAccess(msg.sender, new bytes(0))) { revert SenderMustAcceptTermsOfService(msg.sender); } - _; + } + + // @inheritdoc IRouterBase + function pause() external override onlyOwner { + _pause(); + } + + // @inheritdoc IRouterBase + function unpause() external override onlyOwner { + _unpause(); } } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol index 5e1d321230e..cabe8b0d284 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol @@ -2,38 +2,55 @@ pragma solidity ^0.8.19; import {IFunctionsSubscriptions} from "./interfaces/IFunctionsSubscriptions.sol"; -import {ERC677ReceiverInterface} from "../../../interfaces/ERC677ReceiverInterface.sol"; -import {LinkTokenInterface} from "../../../interfaces/LinkTokenInterface.sol"; +import {IERC677Receiver} from "../../../shared/interfaces/IERC677Receiver.sol"; +import {LinkTokenInterface} from "../../../shared/interfaces/LinkTokenInterface.sol"; import {IFunctionsBilling} from "./interfaces/IFunctionsBilling.sol"; -import {SafeCast} from "../../../shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/utils/SafeCast.sol"; - -/** - * @title Functions Subscriptions contract - * @notice Contract that coordinates payment from users to the nodes of the Decentralized Oracle Network (DON). - * @dev THIS CONTRACT HAS NOT GONE THROUGH ANY SECURITY REVIEW. DO NOT USE IN PROD. - */ -abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, ERC677ReceiverInterface { +import {IFunctionsRouter} from "./interfaces/IFunctionsRouter.sol"; + +import {FunctionsResponse} from "./libraries/FunctionsResponse.sol"; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol"; +import {SafeCast} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/SafeCast.sol"; + +// @title Functions Subscriptions contract +// @notice Contract that coordinates payment from users to the nodes of the Decentralized Oracle Network (DON). +// @dev THIS CONTRACT HAS NOT GONE THROUGH ANY SECURITY REVIEW. DO NOT USE IN PROD. +abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Receiver { + using SafeERC20 for IERC20; + using FunctionsResponse for FunctionsResponse.Commitment; + // ================================================================ - // | Subscription state | + // | Balance state | // ================================================================ + // link token address + address internal immutable i_linkToken; - // We make the sub count public so that its possible to - // get all the current subscriptions via getSubscription. - uint64 private s_currentsubscriptionId; - - // s_totalBalance tracks the total LINK sent to/from + // s_totalLinkBalance tracks the total LINK sent to/from // this contract through onTokenTransfer, cancelSubscription and oracleWithdraw. // A discrepancy with this contract's LINK balance indicates that someone // sent tokens using transfer and so we may need to use recoverFunds. - uint96 private s_totalBalance; + uint96 private s_totalLinkBalance; + + // @dev NOP balances are held as a single amount. The breakdown is held by the Coordinator. + mapping(address coordinator => uint96 balanceJuelsLink) private s_withdrawableTokens; - mapping(uint64 subscriptionId => IFunctionsSubscriptions.Subscription) internal s_subscriptions; + // ================================================================ + // | Subscription state | + // ================================================================ + // Keep a count of the number of subscriptions so that its possible to + // loop through all the current subscriptions via .getSubscription(). + uint64 private s_currentSubscriptionId; - // We need to maintain a list of addresses that can consume a subscription. - // This bound ensures we are able to loop over them as needed. - // Should a user require more consumers, they can use multiple subscriptions. - uint16 private constant MAX_CONSUMERS = 100; - mapping(address consumer => mapping(uint64 subscriptionId => IFunctionsSubscriptions.Consumer)) internal s_consumers; + mapping(uint64 subscriptionId => IFunctionsSubscriptions.Subscription) private s_subscriptions; + + // Maintains the list of keys in s_consumers. + // We do this for 2 reasons: + // 1. To be able to clean up all keys from s_consumers when canceling a subscription. + // 2. To be able to return the list of all consumers in getSubscription. + // Note that we need the s_consumers map to be able to directly check if a + // consumer is valid without reading all the consumers from storage. + mapping(address consumer => mapping(uint64 subscriptionId => IFunctionsSubscriptions.Consumer)) private s_consumers; event SubscriptionCreated(uint64 indexed subscriptionId, address owner); event SubscriptionFunded(uint64 indexed subscriptionId, uint256 oldBalance, uint256 newBalance); @@ -43,268 +60,173 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, ERC677Recei event SubscriptionOwnerTransferRequested(uint64 indexed subscriptionId, address from, address to); event SubscriptionOwnerTransferred(uint64 indexed subscriptionId, address from, address to); - error TooManyConsumers(); - error InsufficientBalance(); - error InvalidConsumer(uint64 subscriptionId, address consumer); - error ConsumerRequestsInFlight(); + error TooManyConsumers(uint16 maximumConsumers); + error InsufficientBalance(uint96 currentBalanceJuels); + error InvalidConsumer(); + error CannotRemoveWithPendingRequests(); error InvalidSubscription(); error OnlyCallableFromLink(); error InvalidCalldata(); - error MustBeSubOwner(address owner); - error PendingRequestExists(); - error MustBeRequestedOwner(address proposedOwner); - error BalanceInvariantViolated(uint256 internalBalance, uint256 externalBalance); // Should never happen + error MustBeSubscriptionOwner(); + error TimeoutNotExceeded(); + error MustBeProposedOwner(address proposedOwner); + error TotalBalanceInvariantViolated(uint256 totalBalance, uint256 deductionAttempt); // Should never happen event FundsRecovered(address to, uint256 amount); - // @dev NOP balances are held as a single amount. The breakdown is held by the Coordinator. - mapping(address coordinator => uint96 balanceJuelsLink) private s_withdrawableTokens; - // ================================================================ // | Request state | // ================================================================ - struct Commitment { - address coordinator; - address client; - uint64 subscriptionId; - uint32 callbackGasLimit; - uint96 estimatedCost; - uint256 timeoutTimestamp; - uint256 gasAfterPaymentCalculation; - uint96 adminFee; - } - - mapping(bytes32 requestId => Commitment) internal s_requestCommitments; + mapping(bytes32 requestId => bytes32 commitmentHash) internal s_requestCommitments; struct Receipt { uint96 callbackGasCostJuels; uint96 totalCostJuels; } - // ================================================================ - // | Other state | - // ================================================================ - // Reentrancy protection. - bool internal s_reentrancyLock; - error Reentrant(); - - LinkTokenInterface private LINK; + event RequestTimedOut(bytes32 indexed requestId); // ================================================================ // | Initialization | // ================================================================ constructor(address link) { - LINK = LinkTokenInterface(link); - } - - // ================================================================ - // | Getter methods | - // ================================================================ - /** - * @inheritdoc IFunctionsSubscriptions - */ - function getMaxConsumers() external pure override returns (uint16) { - return MAX_CONSUMERS; - } - - /** - * @inheritdoc IFunctionsSubscriptions - */ - function getTotalBalance() external view override returns (uint96) { - return s_totalBalance; - } - - /** - * @inheritdoc IFunctionsSubscriptions - */ - function getSubscriptionCount() external view override returns (uint64) { - return s_currentsubscriptionId; - } - - /** - * @inheritdoc IFunctionsSubscriptions - */ - function getSubscription( - uint64 subscriptionId - ) - external - view - override - returns (uint96 balance, uint96 blockedBalance, address owner, address requestedOwner, address[] memory consumers) - { - _isValidSubscription(subscriptionId); - - balance = s_subscriptions[subscriptionId].balance; - blockedBalance = s_subscriptions[subscriptionId].blockedBalance; - owner = s_subscriptions[subscriptionId].owner; - requestedOwner = s_subscriptions[subscriptionId].requestedOwner; - consumers = s_subscriptions[subscriptionId].consumers; - } - - /** - * @inheritdoc IFunctionsSubscriptions - */ - function getConsumer( - address client, - uint64 subscriptionId - ) external view override returns (bool allowed, uint64 initiatedRequests, uint64 completedRequests) { - allowed = s_consumers[client][subscriptionId].allowed; - initiatedRequests = s_consumers[client][subscriptionId].initiatedRequests; - completedRequests = s_consumers[client][subscriptionId].completedRequests; + i_linkToken = link; } // ================================================================ - // | Internal checks | + // | Request/Response | // ================================================================ - function _isValidSubscription(uint64 subscriptionId) internal view { - if (s_subscriptions[subscriptionId].owner == address(0)) { - revert InvalidSubscription(); - } - } - - function _isValidConsumer(address client, uint64 subscriptionId) internal view { - if (!s_consumers[client][subscriptionId].allowed) { - revert InvalidConsumer(subscriptionId, client); - } - } - - // ================================================================ - // | Internal Payment methods | - // ================================================================ - /** - * @notice Sets a request as in-flight - * @dev Only callable within the Router - * @param client - - * @param subscriptionId - - * @param estimatedCost - - */ - function _markRequestInFlight(address client, uint64 subscriptionId, uint96 estimatedCost) internal { + // @notice Sets a request as in-flight + // @dev Only callable within the Router + function _markRequestInFlight(address client, uint64 subscriptionId, uint96 estimatedTotalCostJuels) internal { // Earmark subscription funds - s_subscriptions[subscriptionId].blockedBalance += estimatedCost; + s_subscriptions[subscriptionId].blockedBalance += estimatedTotalCostJuels; // Increment sent requests s_consumers[client][subscriptionId].initiatedRequests += 1; } - /** - * @notice Moves funds from one subscription account to another. - * @dev Only callable by the Coordinator contract that is saved in the request commitment - * @param subscriptionId - - * @param estimatedCost - - * @param client - - * @param adminFee - - * @param juelsPerGas - - * @param gasUsed - - * @param costWithoutCallbackJuels - - */ + // @notice Moves funds from one subscription account to another. + // @dev Only callable by the Coordinator contract that is saved in the request commitment function _pay( uint64 subscriptionId, - uint96 estimatedCost, + uint96 estimatedTotalCostJuels, address client, uint96 adminFee, uint96 juelsPerGas, - uint256 gasUsed, + uint96 gasUsed, uint96 costWithoutCallbackJuels - ) internal returns (Receipt memory receipt) { - uint96 callbackGasCostJuels = juelsPerGas * SafeCast.toUint96(gasUsed); + ) internal returns (Receipt memory) { + uint96 callbackGasCostJuels = juelsPerGas * gasUsed; uint96 totalCostJuels = costWithoutCallbackJuels + adminFee + callbackGasCostJuels; - receipt = Receipt(callbackGasCostJuels, totalCostJuels); - // Charge the subscription + if (s_subscriptions[subscriptionId].balance < totalCostJuels) { + revert InsufficientBalance(s_subscriptions[subscriptionId].balance); + } s_subscriptions[subscriptionId].balance -= totalCostJuels; + // Unblock earmarked funds + if (s_subscriptions[subscriptionId].blockedBalance < estimatedTotalCostJuels) { + revert InsufficientBalance(s_subscriptions[subscriptionId].balance); + } + s_subscriptions[subscriptionId].blockedBalance -= estimatedTotalCostJuels; + // Pay the DON's fees and gas reimbursement s_withdrawableTokens[msg.sender] += costWithoutCallbackJuels + callbackGasCostJuels; // Pay out the administration fee s_withdrawableTokens[address(this)] += adminFee; - // Unblock earmarked funds - s_subscriptions[subscriptionId].blockedBalance -= estimatedCost; // Increment finished requests s_consumers[client][subscriptionId].completedRequests += 1; + + return Receipt({callbackGasCostJuels: callbackGasCostJuels, totalCostJuels: totalCostJuels}); } // ================================================================ // | Owner methods | // ================================================================ - /** - * @inheritdoc IFunctionsSubscriptions - */ - function ownerCancelSubscription(uint64 subscriptionId) external override onlyRouterOwner { - address owner = s_subscriptions[subscriptionId].owner; - if (owner == address(0)) { - revert InvalidSubscription(); - } - _cancelSubscriptionHelper(subscriptionId, owner); + + // @inheritdoc IFunctionsSubscriptions + function ownerCancelSubscription(uint64 subscriptionId) external override { + _onlyRouterOwner(); + _isExistingSubscription(subscriptionId); + _cancelSubscriptionHelper(subscriptionId, s_subscriptions[subscriptionId].owner); } - /** - * @inheritdoc IFunctionsSubscriptions - */ - function recoverFunds(address to) external override onlyRouterOwner { - uint256 externalBalance = LINK.balanceOf(address(this)); - uint256 internalBalance = uint256(s_totalBalance); - if (internalBalance > externalBalance) { - revert BalanceInvariantViolated(internalBalance, externalBalance); - } + // @inheritdoc IFunctionsSubscriptions + function recoverFunds(address to) external override { + _onlyRouterOwner(); + uint256 externalBalance = IERC20(i_linkToken).balanceOf(address(this)); + uint256 internalBalance = uint256(s_totalLinkBalance); if (internalBalance < externalBalance) { uint256 amount = externalBalance - internalBalance; - LINK.transfer(to, amount); + IERC20(i_linkToken).safeTransfer(to, amount); emit FundsRecovered(to, amount); } // If the balances are equal, nothing to be done. } - /** - * @notice Owner withdraw LINK earned through admin fees - * @notice If amount is 0 the full balance will be withdrawn - * @param recipient where to send the funds - * @param amount amount to withdraw - */ - function ownerWithdraw(address recipient, uint96 amount) internal nonReentrant onlyRouterOwner { + // ================================================================ + // | Fund withdrawal | + // ================================================================ + + // @inheritdoc IFunctionsSubscriptions + function oracleWithdraw(address recipient, uint96 amount) external override { + _whenNotPaused(); + if (amount == 0) { - amount = s_withdrawableTokens[address(this)]; + revert InvalidCalldata(); } - if (s_withdrawableTokens[address(this)] < amount) { - revert InsufficientBalance(); + uint96 currentBalance = s_withdrawableTokens[msg.sender]; + if (currentBalance < amount) { + revert InsufficientBalance(currentBalance); } - s_withdrawableTokens[address(this)] -= amount; - s_totalBalance -= amount; - if (!LINK.transfer(recipient, amount)) { - uint256 externalBalance = LINK.balanceOf(address(this)); - uint256 internalBalance = uint256(s_totalBalance); - revert BalanceInvariantViolated(internalBalance, externalBalance); + if (s_totalLinkBalance < amount) { + revert TotalBalanceInvariantViolated(s_totalLinkBalance, amount); } + s_withdrawableTokens[msg.sender] -= amount; + s_totalLinkBalance -= amount; + IERC20(i_linkToken).safeTransfer(recipient, amount); } - // ================================================================ - // | Coordinator methods | - // ================================================================ - /** - * @inheritdoc IFunctionsSubscriptions - */ - function oracleWithdraw(address recipient, uint96 amount) external override nonReentrant { + // @notice Owner withdraw LINK earned through admin fees + // @notice If amount is 0 the full balance will be withdrawn + // @param recipient where to send the funds + // @param amount amount to withdraw + function ownerWithdraw(address recipient, uint96 amount) external { + _onlyRouterOwner(); if (amount == 0) { - revert InvalidCalldata(); + amount = s_withdrawableTokens[address(this)]; } - if (s_withdrawableTokens[msg.sender] < amount) { - revert InsufficientBalance(); + uint96 currentBalance = s_withdrawableTokens[address(this)]; + if (currentBalance < amount) { + revert InsufficientBalance(currentBalance); } - s_withdrawableTokens[msg.sender] -= amount; - s_totalBalance -= amount; - if (!LINK.transfer(recipient, amount)) { - revert InsufficientBalance(); + if (s_totalLinkBalance < amount) { + revert TotalBalanceInvariantViolated(s_totalLinkBalance, amount); } + s_withdrawableTokens[address(this)] -= amount; + s_totalLinkBalance -= amount; + + IERC20(i_linkToken).safeTransfer(recipient, amount); } // ================================================================ - // | Deposit helper method | + // | TransferAndCall Deposit helper | // ================================================================ - function onTokenTransfer(address /* sender */, uint256 amount, bytes calldata data) external override nonReentrant { - if (msg.sender != address(LINK)) { + + // This function is to be invoked when using LINK.transferAndCall + // @dev Note to fund the subscription, use transferAndCall. For example + // @dev LINKTOKEN.transferAndCall( + // @dev address(ROUTER), + // @dev amount, + // @dev abi.encode(subscriptionId)); + function onTokenTransfer(address /* sender */, uint256 amount, bytes calldata data) external override { + _whenNotPaused(); + if (msg.sender != address(i_linkToken)) { revert OnlyCallableFromLink(); } if (data.length != 32) { @@ -318,89 +240,141 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, ERC677Recei // anyone can fund a subscription. uint256 oldBalance = s_subscriptions[subscriptionId].balance; s_subscriptions[subscriptionId].balance += uint96(amount); - s_totalBalance += uint96(amount); + s_totalLinkBalance += uint96(amount); emit SubscriptionFunded(subscriptionId, oldBalance, oldBalance + amount); } // ================================================================ - // | Subscription methods | + // | Subscription management | // ================================================================ - /** - * @inheritdoc IFunctionsSubscriptions - */ - function createSubscription() - external - override - nonReentrant - onlySenderThatAcceptedToS - returns (uint64 subscriptionId) - { - s_currentsubscriptionId++; - subscriptionId = s_currentsubscriptionId; + + // @inheritdoc IFunctionsSubscriptions + function getTotalBalance() external view override returns (uint96) { + return s_totalLinkBalance; + } + + // @inheritdoc IFunctionsSubscriptions + function getSubscriptionCount() external view override returns (uint64) { + return s_currentSubscriptionId; + } + + // @inheritdoc IFunctionsSubscriptions + function getSubscription(uint64 subscriptionId) public view override returns (Subscription memory) { + _isExistingSubscription(subscriptionId); + return s_subscriptions[subscriptionId]; + } + + // @inheritdoc IFunctionsSubscriptions + function getConsumer(address client, uint64 subscriptionId) public view override returns (Consumer memory) { + return s_consumers[client][subscriptionId]; + } + + // Used within this file & FunctionsRouter.sol + function _isExistingSubscription(uint64 subscriptionId) internal view { + if (s_subscriptions[subscriptionId].owner == address(0)) { + revert InvalidSubscription(); + } + } + + // Used within FunctionsRouter.sol + function _isAllowedConsumer(address client, uint64 subscriptionId) internal view { + if (!s_consumers[client][subscriptionId].allowed) { + revert InvalidConsumer(); + } + } + + // @inheritdoc IFunctionsSubscriptions + function createSubscription() external override returns (uint64 subscriptionId) { + _whenNotPaused(); + _onlySenderThatAcceptedToS(); + + subscriptionId = ++s_currentSubscriptionId; s_subscriptions[subscriptionId] = Subscription({ balance: 0, blockedBalance: 0, owner: msg.sender, - requestedOwner: address(0), - consumers: new address[](0) + proposedOwner: address(0), + consumers: new address[](0), + flags: bytes32(0) }); emit SubscriptionCreated(subscriptionId, msg.sender); + + return subscriptionId; } - /** - * @inheritdoc IFunctionsSubscriptions - */ - function requestSubscriptionOwnerTransfer( - uint64 subscriptionId, - address newOwner - ) external override onlySubscriptionOwner(subscriptionId) nonReentrant onlySenderThatAcceptedToS { - // Proposing to address(0) would never be claimable, so don't need to check. + // @inheritdoc IFunctionsSubscriptions + function createSubscriptionWithConsumer(address consumer) external override returns (uint64 subscriptionId) { + _whenNotPaused(); + _onlySenderThatAcceptedToS(); + + subscriptionId = ++s_currentSubscriptionId; + s_subscriptions[subscriptionId] = Subscription({ + balance: 0, + blockedBalance: 0, + owner: msg.sender, + proposedOwner: address(0), + consumers: new address[](0), + flags: bytes32(0) + }); + + s_subscriptions[subscriptionId].consumers.push(consumer); + s_consumers[consumer][subscriptionId].allowed = true; - if (s_subscriptions[subscriptionId].requestedOwner != newOwner) { - s_subscriptions[subscriptionId].requestedOwner = newOwner; - emit SubscriptionOwnerTransferRequested(subscriptionId, msg.sender, newOwner); + emit SubscriptionCreated(subscriptionId, msg.sender); + emit SubscriptionConsumerAdded(subscriptionId, consumer); + + return subscriptionId; + } + + // @inheritdoc IFunctionsSubscriptions + function proposeSubscriptionOwnerTransfer(uint64 subscriptionId, address newOwner) external override { + _whenNotPaused(); + _onlySubscriptionOwner(subscriptionId); + _onlySenderThatAcceptedToS(); + + if (newOwner == address(0) || s_subscriptions[subscriptionId].proposedOwner == newOwner) { + revert InvalidCalldata(); } + + s_subscriptions[subscriptionId].proposedOwner = newOwner; + emit SubscriptionOwnerTransferRequested(subscriptionId, msg.sender, newOwner); } - /** - * @inheritdoc IFunctionsSubscriptions - */ - function acceptSubscriptionOwnerTransfer( - uint64 subscriptionId - ) external override nonReentrant onlySenderThatAcceptedToS { + // @inheritdoc IFunctionsSubscriptions + function acceptSubscriptionOwnerTransfer(uint64 subscriptionId) external override { + _whenNotPaused(); + _onlySenderThatAcceptedToS(); + address previousOwner = s_subscriptions[subscriptionId].owner; - address nextOwner = s_subscriptions[subscriptionId].requestedOwner; - if (nextOwner != msg.sender) { - revert MustBeRequestedOwner(nextOwner); + address proposedOwner = s_subscriptions[subscriptionId].proposedOwner; + if (proposedOwner != msg.sender) { + revert MustBeProposedOwner(proposedOwner); } s_subscriptions[subscriptionId].owner = msg.sender; - s_subscriptions[subscriptionId].requestedOwner = address(0); + s_subscriptions[subscriptionId].proposedOwner = address(0); emit SubscriptionOwnerTransferred(subscriptionId, previousOwner, msg.sender); } - /** - * @inheritdoc IFunctionsSubscriptions - */ - function removeConsumer( - uint64 subscriptionId, - address consumer - ) external override onlySubscriptionOwner(subscriptionId) nonReentrant onlySenderThatAcceptedToS { + // @inheritdoc IFunctionsSubscriptions + function removeConsumer(uint64 subscriptionId, address consumer) external override { + _whenNotPaused(); + _onlySubscriptionOwner(subscriptionId); + _onlySenderThatAcceptedToS(); + Consumer memory consumerData = s_consumers[consumer][subscriptionId]; if (!consumerData.allowed) { - revert InvalidConsumer(subscriptionId, consumer); + revert InvalidConsumer(); } if (consumerData.initiatedRequests != consumerData.completedRequests) { - revert ConsumerRequestsInFlight(); + revert CannotRemoveWithPendingRequests(); } - // Note bounded by MAX_CONSUMERS + // Note bounded by config.maxConsumers address[] memory consumers = s_subscriptions[subscriptionId].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 - s_subscriptions[subscriptionId].consumers[i] = last; + s_subscriptions[subscriptionId].consumers[i] = consumers[consumers.length - 1]; // Storage remove last element s_subscriptions[subscriptionId].consumers.pop(); break; @@ -410,67 +384,66 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, ERC677Recei emit SubscriptionConsumerRemoved(subscriptionId, consumer); } - /** - * @inheritdoc IFunctionsSubscriptions - */ - function addConsumer( - uint64 subscriptionId, - address consumer - ) external override onlySubscriptionOwner(subscriptionId) nonReentrant onlySenderThatAcceptedToS { + // overriden in FunctionsRouter.sol + function _getMaxConsumers() internal view virtual returns (uint16); + + // @inheritdoc IFunctionsSubscriptions + function addConsumer(uint64 subscriptionId, address consumer) external override { + _whenNotPaused(); + _onlySubscriptionOwner(subscriptionId); + _onlySenderThatAcceptedToS(); + // Already maxed, cannot add any more consumers. - if (s_subscriptions[subscriptionId].consumers.length == MAX_CONSUMERS) { - revert TooManyConsumers(); + uint16 maximumConsumers = _getMaxConsumers(); + if (s_subscriptions[subscriptionId].consumers.length == maximumConsumers) { + revert TooManyConsumers(maximumConsumers); } if (s_consumers[consumer][subscriptionId].allowed) { // Idempotence - do nothing if already added. // Ensures uniqueness in s_subscriptions[subscriptionId].consumers. return; } + s_consumers[consumer][subscriptionId].allowed = true; s_subscriptions[subscriptionId].consumers.push(consumer); emit SubscriptionConsumerAdded(subscriptionId, consumer); } - /** - * @inheritdoc IFunctionsSubscriptions - */ - function cancelSubscription( - uint64 subscriptionId, - address to - ) external override onlySubscriptionOwner(subscriptionId) nonReentrant onlySenderThatAcceptedToS { - if (_pendingRequestExists(subscriptionId)) { - revert PendingRequestExists(); + // @inheritdoc IFunctionsSubscriptions + function cancelSubscription(uint64 subscriptionId, address to) external override { + _whenNotPaused(); + _onlySubscriptionOwner(subscriptionId); + _onlySenderThatAcceptedToS(); + + if (pendingRequestExists(subscriptionId)) { + revert CannotRemoveWithPendingRequests(); } + _cancelSubscriptionHelper(subscriptionId, to); } - function _cancelSubscriptionHelper(uint64 subscriptionId, address to) private nonReentrant { - Subscription memory sub = s_subscriptions[subscriptionId]; - uint96 balance = sub.balance; - // Note bounded by MAX_CONSUMERS; + function _cancelSubscriptionHelper(uint64 subscriptionId, address to) private { + Subscription memory subscription = s_subscriptions[subscriptionId]; + uint96 balance = subscription.balance; + // NOTE: loop iterations are bounded by config.maxConsumers // If no consumers, does nothing. - for (uint256 i = 0; i < sub.consumers.length; i++) { - delete s_consumers[sub.consumers[i]][subscriptionId]; + for (uint256 i = 0; i < subscription.consumers.length; ++i) { + delete s_consumers[subscription.consumers[i]][subscriptionId]; } delete s_subscriptions[subscriptionId]; - s_totalBalance -= balance; - if (!LINK.transfer(to, uint256(balance))) { - revert InsufficientBalance(); - } - emit SubscriptionCanceled(subscriptionId, to, balance); - } + s_totalLinkBalance -= balance; - /** - * @inheritdoc IFunctionsSubscriptions - */ - function pendingRequestExists(uint64 subscriptionId) external view override returns (bool) { - return _pendingRequestExists(subscriptionId); + IERC20(i_linkToken).safeTransfer(to, uint256(balance)); + + emit SubscriptionCanceled(subscriptionId, to, balance); } - function _pendingRequestExists(uint64 subscriptionId) internal view returns (bool) { + // @inheritdoc IFunctionsSubscriptions + function pendingRequestExists(uint64 subscriptionId) public view override returns (bool) { address[] memory consumers = s_subscriptions[subscriptionId].consumers; - for (uint256 i = 0; i < consumers.length; i++) { + // NOTE: loop iterations are bounded by config.maxConsumers + for (uint256 i = 0; i < consumers.length; ++i) { Consumer memory consumer = s_consumers[consumers[i]][subscriptionId]; if (consumer.initiatedRequests != consumer.completedRequests) { return true; @@ -479,68 +452,73 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, ERC677Recei return false; } + // @inheritdoc IFunctionsSubscriptions + function setFlags(uint64 subscriptionId, bytes32 flags) external override { + _onlyRouterOwner(); + _isExistingSubscription(subscriptionId); + s_subscriptions[subscriptionId].flags = flags; + } + + // @inheritdoc IFunctionsSubscriptions + function getFlags(uint64 subscriptionId) public view returns (bytes32) { + return s_subscriptions[subscriptionId].flags; + } + // ================================================================ - // | Request Timeout Methods | + // | Request Timeout | // ================================================================ - /** - * @inheritdoc IFunctionsSubscriptions - */ - function timeoutRequests(bytes32[] calldata requestIdsToTimeout) external override nonReentrant { - for (uint256 i = 0; i < requestIdsToTimeout.length; i++) { - bytes32 requestId = requestIdsToTimeout[i]; - Commitment memory request = s_requestCommitments[requestId]; + + // @inheritdoc IFunctionsSubscriptions + function timeoutRequests(FunctionsResponse.Commitment[] calldata requestsToTimeoutByCommitment) external override { + _whenNotPaused(); + + for (uint256 i = 0; i < requestsToTimeoutByCommitment.length; ++i) { + FunctionsResponse.Commitment memory request = requestsToTimeoutByCommitment[i]; + bytes32 requestId = request.requestId; uint64 subscriptionId = request.subscriptionId; - // Check that the message sender is the subscription owner - _isValidSubscription(subscriptionId); - address owner = s_subscriptions[subscriptionId].owner; - if (msg.sender != owner) { - revert MustBeSubOwner(owner); + // Check that request ID is valid + if (keccak256(abi.encode(request)) != s_requestCommitments[requestId]) { + revert InvalidCalldata(); } // Check that request has exceeded allowed request time if (block.timestamp < request.timeoutTimestamp) { - revert ConsumerRequestsInFlight(); + revert TimeoutNotExceeded(); } - IFunctionsBilling coordinator = IFunctionsBilling(request.coordinator); + // Notify the Coordinator that the request should no longer be fulfilled + IFunctionsBilling(request.coordinator).deleteCommitment(requestId); + // Release the subscription's balance that had been earmarked for the request + s_subscriptions[subscriptionId].blockedBalance -= request.estimatedTotalCostJuels; + s_consumers[request.client][subscriptionId].completedRequests += 1; + // Delete commitment within Router state + delete s_requestCommitments[requestId]; - if (coordinator.deleteCommitment(requestId)) { - // Release blocked balance - s_subscriptions[subscriptionId].blockedBalance -= request.estimatedCost; - s_consumers[request.client][subscriptionId].completedRequests += 1; - // Delete commitment - delete s_requestCommitments[requestId]; - } + emit RequestTimedOut(requestId); } } // ================================================================ // | Modifiers | // ================================================================ - modifier onlySubscriptionOwner(uint64 subscriptionId) { + + function _onlySubscriptionOwner(uint64 subscriptionId) internal view { address owner = s_subscriptions[subscriptionId].owner; if (owner == address(0)) { revert InvalidSubscription(); } if (msg.sender != owner) { - revert MustBeSubOwner(owner); + revert MustBeSubscriptionOwner(); } - _; } - modifier nonReentrant() { - if (s_reentrancyLock) { - revert Reentrant(); - } - _; - } + // Overriden in FunctionsRouter.sol + function _onlySenderThatAcceptedToS() internal virtual; - modifier onlySenderThatAcceptedToS() virtual { - _; - } + // Overriden in FunctionsRouter.sol + function _onlyRouterOwner() internal virtual; - modifier onlyRouterOwner() virtual { - _; - } + // Overriden in FunctionsRouter.sol + function _whenNotPaused() internal virtual; } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/Routable.sol b/contracts/src/v0.8/functions/dev/1_0_0/Routable.sol index f5a9ac1a477..8c09eba5d79 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/Routable.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/Routable.sol @@ -1,69 +1,43 @@ // SPDX-License-Identifier: MIT - pragma solidity ^0.8.19; -import {IConfigurable} from "./interfaces/IConfigurable.sol"; import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; -import {IRouterBase} from "./interfaces/IRouterBase.sol"; -import {IOwnable} from "../../../shared/interfaces/IOwnable.sol"; - -abstract contract Routable is ITypeAndVersion, IConfigurable { - bytes32 internal s_config_hash; +import {IOwnableFunctionsRouter} from "./interfaces/IOwnableFunctionsRouter.sol"; - IRouterBase internal s_router; +// @title This abstract should be inherited by contracts that will be used +// as the destinations to a route (id=>contract) on the Router. +// It provides a Router getter and modifiers +abstract contract Routable is ITypeAndVersion { + IOwnableFunctionsRouter private immutable i_router; error RouterMustBeSet(); error OnlyCallableByRouter(); error OnlyCallableByRouterOwner(); - /** - * @dev Initializes the contract. - */ - constructor(address router, bytes memory config) { + // @dev Initializes the contract. + constructor(address router) { if (router == address(0)) { revert RouterMustBeSet(); } - s_router = IRouterBase(router); - _setConfig(config); - s_config_hash = keccak256(config); + i_router = IOwnableFunctionsRouter(router); } - /** - * @inheritdoc IConfigurable - */ - function getConfigHash() external view override returns (bytes32 config) { - return s_config_hash; - } - - /** - * @dev Must be implemented by inheriting contract - * Use to set configuration state - */ - function _setConfig(bytes memory config) internal virtual; - - /** - * @inheritdoc IConfigurable - */ - function setConfig(bytes memory config) external override onlyRouter { - _setConfig(config); - s_config_hash = keccak256(config); + // @notice Return the Router + function _getRouter() internal view returns (IOwnableFunctionsRouter router) { + return i_router; } - /** - * @notice Reverts if called by anyone other than the router. - */ + // @notice Reverts if called by anyone other than the router. modifier onlyRouter() { - if (msg.sender != address(s_router)) { + if (msg.sender != address(i_router)) { revert OnlyCallableByRouter(); } _; } - /** - * @notice Reverts if called by anyone other than the router owner. - */ + // @notice Reverts if called by anyone other than the router owner. modifier onlyRouterOwner() { - if (msg.sender != IOwnable(address(s_router)).owner()) { + if (msg.sender != i_router.owner()) { revert OnlyCallableByRouterOwner(); } _; diff --git a/contracts/src/v0.8/functions/dev/1_0_0/RouterBase.sol b/contracts/src/v0.8/functions/dev/1_0_0/RouterBase.sol deleted file mode 100644 index 6e6176aaa30..00000000000 --- a/contracts/src/v0.8/functions/dev/1_0_0/RouterBase.sol +++ /dev/null @@ -1,340 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import {IRouterBase} from "./interfaces/IRouterBase.sol"; -import {ConfirmedOwnerWithProposal} from "../../../ConfirmedOwnerWithProposal.sol"; -import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; -import {Pausable} from "../../../shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/security/Pausable.sol"; -import {IConfigurable} from "./interfaces/IConfigurable.sol"; - -abstract contract RouterBase is IRouterBase, Pausable, ITypeAndVersion, ConfirmedOwnerWithProposal { - // ================================================================ - // | Version state | - // ================================================================ - uint16 internal constant s_majorVersion = 1; - uint16 internal s_minorVersion = 0; - uint16 internal s_patchVersion = 0; - - // ================================================================ - // | Route state | - // ================================================================ - mapping(bytes32 id => address routableContract) internal s_route; - error RouteNotFound(bytes32 id); - // Use empty bytes to self-identify, since it does not have an id - bytes32 internal constant routerId = bytes32(0); - - // ================================================================ - // | Proposal state | - // ================================================================ - uint8 internal constant MAX_PROPOSAL_SET_LENGTH = 8; - - struct ContractProposalSet { - bytes32[] ids; - address[] to; - uint256 timelockEndBlock; - } - ContractProposalSet internal s_proposedContractSet; - - event ContractProposed( - bytes32 proposedContractSetId, - address proposedContractSetFromAddress, - address proposedContractSetToAddress, - uint256 timelockEndBlock - ); - event ContractUpdated( - bytes32 proposedContractSetId, - address proposedContractSetFromAddress, - address proposedContractSetToAddress, - uint16 major, - uint16 minor, - uint16 patch - ); - - struct ConfigProposal { - bytes32 fromHash; - bytes to; - uint256 timelockEndBlock; - } - mapping(bytes32 id => ConfigProposal) internal s_proposedConfig; - event ConfigProposed(bytes32 id, bytes32 fromHash, bytes toBytes); - event ConfigUpdated(bytes32 id, bytes32 fromHash, bytes toBytes); - error InvalidProposal(); - error IdentifierIsReserved(bytes32 id); - - // ================================================================ - // | Timelock state | - // ================================================================ - uint16 internal MAXIMUM_TIMELOCK_BLOCKS; - uint16 internal s_timelockBlocks; - struct TimeLockProposal { - uint16 from; - uint16 to; - uint256 timelockEndBlock; - } - TimeLockProposal s_timelockProposal; - event TimeLockProposed(uint16 from, uint16 to); - event TimeLockUpdated(uint16 from, uint16 to); - error ProposedTimelockAboveMaximum(); - error TimelockInEffect(); - - // ================================================================ - // | Config state | - // ================================================================ - bytes32 internal s_config_hash; - - error InvalidConfigData(); - - // ================================================================ - // | Initialization | - // ================================================================ - constructor( - address newOwner, - uint16 timelockBlocks, - uint16 maximumTimelockBlocks, - bytes memory selfConfig - ) ConfirmedOwnerWithProposal(newOwner, address(0)) Pausable() { - // Set initial value for the number of blocks of the timelock - s_timelockBlocks = timelockBlocks; - // Set maximum number of blocks that the timelock can be - // NOTE: this cannot be later modified - MAXIMUM_TIMELOCK_BLOCKS = maximumTimelockBlocks; - // Set the initial configuration for the Router - s_route[routerId] = address(this); - _setConfig(selfConfig); - s_config_hash = keccak256(selfConfig); - } - - // ================================================================ - // | Version methods | - // ================================================================ - - /** - * @inheritdoc IRouterBase - */ - function version() external view override returns (uint16, uint16, uint16) { - return (s_majorVersion, s_minorVersion, s_patchVersion); - } - - // ================================================================ - // | Route methods | - // ================================================================ - - function _getContractById(bytes32 id, bool useProposed) internal view returns (address) { - if (!useProposed) { - address currentImplementation = s_route[id]; - if (currentImplementation != address(0)) { - return currentImplementation; - } - } else { - for (uint8 i = 0; i < s_proposedContractSet.ids.length; i++) { - if (id == s_proposedContractSet.ids[i]) { - // NOTE: proposals can be used immediately - return s_proposedContractSet.to[i]; - } - } - } - revert RouteNotFound(id); - } - - /** - * @inheritdoc IRouterBase - */ - function getContractById(bytes32 id) external view override returns (address routeDestination) { - routeDestination = _getContractById(id, false); - } - - /** - * @inheritdoc IRouterBase - */ - function getContractById(bytes32 id, bool useProposed) external view override returns (address routeDestination) { - routeDestination = _getContractById(id, useProposed); - } - - // ================================================================ - // | Contract Proposal methods | - // ================================================================ - /** - * @inheritdoc IRouterBase - */ - function getProposedContractSet() external view override returns (uint256, bytes32[] memory, address[] memory) { - return (s_proposedContractSet.timelockEndBlock, s_proposedContractSet.ids, s_proposedContractSet.to); - } - - /** - * @inheritdoc IRouterBase - */ - function proposeContractsUpdate( - bytes32[] memory proposedContractSetIds, - address[] memory proposedContractSetAddresses - ) external override onlyOwner { - // All arrays must be of equal length and not must not exceed the max length - uint256 idsArrayLength = proposedContractSetIds.length; - if (idsArrayLength != proposedContractSetAddresses.length || idsArrayLength > MAX_PROPOSAL_SET_LENGTH) { - revert InvalidProposal(); - } - // Iterations will not exceed MAX_PROPOSAL_SET_LENGTH - for (uint8 i = 0; i < idsArrayLength; i++) { - bytes32 id = proposedContractSetIds[i]; - address proposedContract = proposedContractSetAddresses[i]; - if ( - proposedContract == address(0) || // The Proposed address must be a valid address - s_route[id] == proposedContract // The Proposed address must point to a different address than what is currently set - ) { - revert InvalidProposal(); - } - // Reserved ids cannot be set - if (id == routerId) { - revert IdentifierIsReserved(id); - } - } - - uint256 timelockEndBlock = block.number + s_timelockBlocks; - - s_proposedContractSet = ContractProposalSet(proposedContractSetIds, proposedContractSetAddresses, timelockEndBlock); - - // Iterations will not exceed MAX_PROPOSAL_SET_LENGTH - for (uint8 i = 0; i < proposedContractSetIds.length; i++) { - emit ContractProposed( - proposedContractSetIds[i], - s_route[proposedContractSetIds[i]], - proposedContractSetAddresses[i], - timelockEndBlock - ); - } - } - - /** - * @inheritdoc IRouterBase - */ - function validateProposedContracts(bytes32 id, bytes calldata data) external override returns (bytes memory) { - return _validateProposedContracts(id, data); - } - - /** - * @dev Must be implemented by the inheriting contract - * Use to test an end to end request through the system - */ - function _validateProposedContracts(bytes32 id, bytes calldata data) internal virtual returns (bytes memory); - - /** - * @inheritdoc IRouterBase - */ - function updateContracts() external override onlyOwner { - if (block.number < s_proposedContractSet.timelockEndBlock) { - revert TimelockInEffect(); - } - s_minorVersion = s_minorVersion + 1; - if (s_patchVersion != 0) s_patchVersion = 0; - for (uint8 i = 0; i < s_proposedContractSet.ids.length; i++) { - bytes32 id = s_proposedContractSet.ids[i]; - address from = s_route[id]; - address to = s_proposedContractSet.to[i]; - s_route[id] = to; - emit ContractUpdated(id, from, to, s_majorVersion, s_minorVersion, s_patchVersion); - } - } - - // ================================================================ - // | Config Proposal methods | - // ================================================================ - /** - * @notice Get the hash of the Router's current configuration - * @return config hash of config bytes - */ - function getConfigHash() external view returns (bytes32 config) { - return s_config_hash; - } - - /** - * @dev Must be implemented by inheriting contract - * Use to set configuration state of the Router - */ - function _setConfig(bytes memory config) internal virtual; - - /** - * @inheritdoc IRouterBase - */ - function proposeConfigUpdate(bytes32 id, bytes calldata config) external override onlyOwner { - address implAddr = _getContractById(id, false); - bytes32 currentConfigHash; - if (implAddr == address(this)) { - currentConfigHash = s_config_hash; - } else { - currentConfigHash = IConfigurable(implAddr).getConfigHash(); - } - if (currentConfigHash == keccak256(config)) { - revert InvalidProposal(); - } - s_proposedConfig[id] = ConfigProposal(currentConfigHash, config, block.number + s_timelockBlocks); - emit ConfigProposed(id, currentConfigHash, config); - } - - /** - * @inheritdoc IRouterBase - */ - function updateConfig(bytes32 id) external override onlyOwner { - ConfigProposal memory proposal = s_proposedConfig[id]; - if (block.number < proposal.timelockEndBlock) { - revert TimelockInEffect(); - } - if (id == routerId) { - _setConfig(proposal.to); - s_config_hash = keccak256(proposal.to); - } else { - try IConfigurable(_getContractById(id, false)).setConfig(proposal.to) {} catch { - revert InvalidConfigData(); - } - } - s_patchVersion = s_patchVersion + 1; - emit ConfigUpdated(id, proposal.fromHash, proposal.to); - } - - // ================================================================ - // | Timelock methods | - // ================================================================ - - /** - * @inheritdoc IRouterBase - */ - function proposeTimelockBlocks(uint16 blocks) external override onlyOwner { - if (s_timelockBlocks == blocks) { - revert InvalidProposal(); - } - if (blocks > MAXIMUM_TIMELOCK_BLOCKS) { - revert ProposedTimelockAboveMaximum(); - } - s_timelockProposal = TimeLockProposal(s_timelockBlocks, blocks, block.number + s_timelockBlocks); - } - - /** - * @inheritdoc IRouterBase - */ - function updateTimelockBlocks() external override onlyOwner { - if (block.number < s_timelockProposal.timelockEndBlock) { - revert TimelockInEffect(); - } - s_timelockBlocks = s_timelockProposal.to; - } - - // ================================================================ - // | Pausable methods | - // ================================================================ - - /** - * @inheritdoc IRouterBase - */ - function isPaused() external view override returns (bool) { - return Pausable.paused(); - } - - /** - * @inheritdoc IRouterBase - */ - function togglePaused() external override onlyOwner { - if (Pausable.paused()) { - _unpause(); - } else { - _pause(); - } - } -} diff --git a/contracts/src/v0.8/functions/dev/1_0_0/accessControl/TermsOfServiceAllowList.sol b/contracts/src/v0.8/functions/dev/1_0_0/accessControl/TermsOfServiceAllowList.sol index aa44b0b421a..2ce107c9861 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/accessControl/TermsOfServiceAllowList.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/accessControl/TermsOfServiceAllowList.sol @@ -1,191 +1,142 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -import {EnumerableSet} from "../../../../shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/utils/structs/EnumerableSet.sol"; import {ITermsOfServiceAllowList} from "./interfaces/ITermsOfServiceAllowList.sol"; -import {Routable, ITypeAndVersion} from "../Routable.sol"; -import {IOwnable} from "../../../../shared/interfaces/IOwnable.sol"; +import {IAccessController} from "../../../../shared/interfaces/IAccessController.sol"; +import {ITypeAndVersion} from "../../../../shared/interfaces/ITypeAndVersion.sol"; -/** - * @notice A contract to handle access control of subscription management dependent on signing a Terms of Service - */ +import {ConfirmedOwner} from "../../../../shared/access/ConfirmedOwner.sol"; -contract TermsOfServiceAllowList is Routable, ITermsOfServiceAllowList { +import {Address} from "../../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Address.sol"; +import {EnumerableSet} from "../../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/structs/EnumerableSet.sol"; + +// @notice A contract to handle access control of subscription management dependent on signing a Terms of Service +contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController, ITypeAndVersion, ConfirmedOwner { + using Address for address; using EnumerableSet for EnumerableSet.AddressSet; + // @inheritdoc ITypeAndVersion + string public constant override typeAndVersion = "Functions Terms of Service Allow List v1.0.0"; + EnumerableSet.AddressSet private s_allowedSenders; - EnumerableSet.AddressSet private s_blockedSenders; + mapping(address => bool) private s_blockedSenders; + + event AddedAccess(address user); + event BlockedAccess(address user); + event UnblockedAccess(address user); - error InvalidProof(); + error InvalidSignature(); + error InvalidUsage(); error RecipientIsBlocked(); + // ================================================================ // | Configuration state | // ================================================================ struct Config { - bool enabled; - address proofSignerPublicKey; + bool enabled; // ═════════════╗ When enabled, access will be checked against s_allowedSenders. When disabled, all access will be allowed. + address signerPublicKey; // ══╝ The key pair that needs to sign the acceptance data } + Config private s_config; - event ConfigSet(bool enabled); + + event ConfigUpdated(Config config); // ================================================================ // | Initialization | // ================================================================ - constructor(address router, bytes memory config) Routable(router, config) {} + + constructor(Config memory config) ConfirmedOwner(msg.sender) { + updateConfig(config); + } // ================================================================ - // | Configuration methods | + // | Configuration | // ================================================================ - /** - * @notice Sets the configuration - * @param config bytes of config data to set the following: - * - enabled: boolean representing if the allow list is active, when disabled all usage will be allowed - * - proofSignerPublicKey: public key of the signer of the proof - */ - function _setConfig(bytes memory config) internal override { - (bool enabled, address proofSignerPublicKey) = abi.decode(config, (bool, address)); - s_config = Config({enabled: enabled, proofSignerPublicKey: proofSignerPublicKey}); - emit ConfigSet(enabled); + + // @notice Gets the contracts's configuration + // @return config + function getConfig() external view returns (Config memory) { + return s_config; } - /** - * @inheritdoc ITypeAndVersion - */ - function typeAndVersion() public pure override returns (string memory) { - return "Functions Terms of Service Allow List v1"; + // @notice Sets the contracts's configuration + // @param config - See the contents of the TermsOfServiceAllowList.Config struct for more information + function updateConfig(Config memory config) public onlyOwner { + s_config = config; + emit ConfigUpdated(config); } // ================================================================ - // | Terms of Service methods | + // | Allow methods | // ================================================================ - /** - * @inheritdoc ITermsOfServiceAllowList - */ - function getMessageHash(address acceptor, address recipient) public pure override returns (bytes32) { - return keccak256(abi.encodePacked(acceptor, recipient)); - } - /** - * @inheritdoc ITermsOfServiceAllowList - */ - function getEthSignedMessageHash(bytes32 messageHash) public pure override returns (bytes32) { - return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", messageHash)); + // @inheritdoc ITermsOfServiceAllowList + function getMessage(address acceptor, address recipient) public pure override returns (bytes32) { + return keccak256(abi.encodePacked(acceptor, recipient)); } - /** - * @inheritdoc ITermsOfServiceAllowList - */ - function acceptTermsOfService(address acceptor, address recipient, bytes calldata proof) external override { - if (s_blockedSenders.contains(recipient)) { + // @inheritdoc ITermsOfServiceAllowList + function acceptTermsOfService(address acceptor, address recipient, bytes32 r, bytes32 s, uint8 v) external override { + if (s_blockedSenders[recipient]) { revert RecipientIsBlocked(); } - // Validate that the proof is correct and has been signed - bytes32 messageHash = getMessageHash(acceptor, recipient); - bytes32 ethSignedMessageHash = getEthSignedMessageHash(messageHash); - address proofSigner = _getSigner(ethSignedMessageHash, proof); - if (proofSigner != s_config.proofSignerPublicKey) { - revert InvalidProof(); - } - - // Check if msg.sender is an EoA or contract - bool callerIsContractAccount = _isContract(msg.sender); - // If EoA, validate that msg.sender == acceptor == recipient - // This is to prevent EoAs from accepting for other EoAs - if (callerIsContractAccount == false && (msg.sender != acceptor || msg.sender != recipient)) { - revert InvalidProof(); + // Validate that the signature is correct and the correct data has been signed + bytes32 prefixedMessage = keccak256( + abi.encodePacked("\x19Ethereum Signed Message:\n32", getMessage(acceptor, recipient)) + ); + if (ecrecover(prefixedMessage, v, r, s) != s_config.signerPublicKey) { + revert InvalidSignature(); } // If contract, validate that msg.sender == recipient // This is to prevent EoAs from claiming contracts that they are not in control of - if (callerIsContractAccount && msg.sender != recipient) { - revert InvalidProof(); + // If EoA, validate that msg.sender == acceptor == recipient + // This is to prevent EoAs from accepting for other EoAs + if (msg.sender != recipient || (msg.sender != acceptor && !msg.sender.isContract())) { + revert InvalidUsage(); } // Add recipient to the allow list s_allowedSenders.add(recipient); + emit AddedAccess(recipient); } - /** - * @inheritdoc ITermsOfServiceAllowList - */ - function isAllowedSender(address sender) public view override returns (bool) { - if (s_config.enabled == false) { - return true; - } - return s_allowedSenders.contains(sender); + // @inheritdoc ITermsOfServiceAllowList + function getAllAllowedSenders() external view override returns (address[] memory) { + return s_allowedSenders.values(); } - /** - * @inheritdoc ITermsOfServiceAllowList - */ - function isBlockedSender(address sender) public view override returns (bool) { - if (s_config.enabled == false) { - return false; + // @inheritdoc IAccessController + function hasAccess(address user, bytes calldata /* data */) external view override returns (bool) { + if (!s_config.enabled) { + return true; } - return s_blockedSenders.contains(sender); + return s_allowedSenders.contains(user); } // ================================================================ - // | Owner methods | + // | Block methods | // ================================================================ - /** - /** - * @inheritdoc ITermsOfServiceAllowList - */ - function blockSender(address sender) external override onlyRouterOwner { - s_allowedSenders.remove(sender); - s_blockedSenders.add(sender); - } - - /** - * @inheritdoc ITermsOfServiceAllowList - */ - function unblockSender(address sender) external override onlyRouterOwner { - s_blockedSenders.remove(sender); - } - - // ================================================================ - // | Internal helpers | - // ================================================================ - - // NOTE: a contract account can appear to be an EoA if called during its constructor - // This is not a risk, because they will fail in acceptTermsOfService during acceptor == recipient - function _isContract(address _addr) private view returns (bool isContract) { - uint32 size; - // solhint-disable-next-line no-inline-assembly - assembly { - size := extcodesize(_addr) + // @inheritdoc ITermsOfServiceAllowList + function isBlockedSender(address sender) external view override returns (bool) { + if (!s_config.enabled) { + return false; } - return (size > 0); + return s_blockedSenders[sender]; } - function _getSigner(bytes32 _ethSignedMessageHash, bytes memory signature) private pure returns (address) { - (bytes32 r, bytes32 s, uint8 v) = _splitSignature(signature); - return ecrecover(_ethSignedMessageHash, v, r, s); + // @inheritdoc ITermsOfServiceAllowList + function blockSender(address sender) external override onlyOwner { + s_allowedSenders.remove(sender); + s_blockedSenders[sender] = true; + emit BlockedAccess(sender); } - function _splitSignature(bytes memory sig) private pure returns (bytes32 r, bytes32 s, uint8 v) { - if (sig.length != 65) { - revert InvalidProof(); - } - // solhint-disable-next-line no-inline-assembly - assembly { - /*/ - First 32 bytes stores the length of the signature - - add(sig, 32) = pointer of sig + 32 - effectively, skips first 32 bytes of signature - - mload(p) loads next 32 bytes starting at the memory address p into memory - */ - // first 32 bytes, after the length prefix - r := mload(add(sig, 32)) - // second 32 bytes - s := mload(add(sig, 64)) - // final byte (first byte of the next 32 bytes) - v := byte(0, mload(add(sig, 96))) - } + // @inheritdoc ITermsOfServiceAllowList + function unblockSender(address sender) external override onlyOwner { + s_blockedSenders[sender] = false; + emit UnblockedAccess(sender); } } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/accessControl/interfaces/ITermsOfServiceAllowList.sol b/contracts/src/v0.8/functions/dev/1_0_0/accessControl/interfaces/ITermsOfServiceAllowList.sol index ff7ee47d7e5..b83375ee01f 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/accessControl/interfaces/ITermsOfServiceAllowList.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/accessControl/interfaces/ITermsOfServiceAllowList.sol @@ -1,57 +1,40 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -/** - * @notice A contract to handle access control of subscription management dependent on signing a Terms of Service - */ - +// @notice A contract to handle access control of subscription management dependent on signing a Terms of Service interface ITermsOfServiceAllowList { - /** - * @notice Return the message data for the proof given to accept the Terms of Service - * @param acceptor - The wallet address that has accepted the Terms of Service on the UI - * @param recipient - The recipient address that the acceptor is taking responsibility for - * @return Hash of the message data - */ - function getMessageHash(address acceptor, address recipient) external pure returns (bytes32); - - /** - * @notice Wrap a bytes32 message as an ethereum signed message - * @param messageHash - Message hash produced from "getMessageHash" - * @return Hash of the message data packed as "\x19Ethereum Signed Message\n" + len(msg) + msg - */ - function getEthSignedMessageHash(bytes32 messageHash) external pure returns (bytes32); - - /** - * @notice Check if the address is authorized for usage - * @param sender The transaction sender's address - * @return True or false - */ - function isAllowedSender(address sender) external returns (bool); - - /** - * @notice Check if the address is blocked for usage - * @param sender The transaction sender's address - * @return True or false - */ + // @notice Return the message data for the proof given to accept the Terms of Service + // @param acceptor - The wallet address that has accepted the Terms of Service on the UI + // @param recipient - The recipient address that the acceptor is taking responsibility for + // @return Hash of the message data + function getMessage(address acceptor, address recipient) external pure returns (bytes32); + + // @notice Check if the address is blocked for usage + // @param sender The transaction sender's address + // @return True or false function isBlockedSender(address sender) external returns (bool); - /** - * @notice Allows access to the sender based on acceptance of the Terms of Service - * @param acceptor - The wallet address that has accepted the Terms of Service on the UI - * @param recipient - The recipient address that the acceptor is taking responsibility for - * @param proof - Signed data produced by the Chainlink Functions Subscription UI - */ - function acceptTermsOfService(address acceptor, address recipient, bytes calldata proof) external; - - /** - * @notice Removes a sender's access if already authorized, and disallows re-acceptiong the Terms of Service - * @param sender - Address of the sender to block - */ + // @notice Get a list of all allowed senders + // @dev WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + // to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + // this function has an unbounded cost, and using it as part of a state-changing function may render the function + // uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. + // @return addresses - all allowed addresses + function getAllAllowedSenders() external view returns (address[] memory); + + // @notice Allows access to the sender based on acceptance of the Terms of Service + // @param acceptor - The wallet address that has accepted the Terms of Service on the UI + // @param recipient - The recipient address that the acceptor is taking responsibility for + // @param r - ECDSA signature r data produced by the Chainlink Functions Subscription UI + // @param s - ECDSA signature s produced by the Chainlink Functions Subscription UI + // @param v - ECDSA signature v produced by the Chainlink Functions Subscription UI + function acceptTermsOfService(address acceptor, address recipient, bytes32 r, bytes32 s, uint8 v) external; + + // @notice Removes a sender's access if already authorized, and disallows re-accepting the Terms of Service + // @param sender - Address of the sender to block function blockSender(address sender) external; - /** - * @notice Re-allows a previosly blocked sender to accept the Terms of Service - * @param sender - Address of the sender to unblock - */ + // @notice Re-allows a previously blocked sender to accept the Terms of Service + // @param sender - Address of the sender to unblock function unblockSender(address sender) external; } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/example/FunctionsClientExample.sol b/contracts/src/v0.8/functions/dev/1_0_0/example/FunctionsClientExample.sol index c183579b975..5feee704ef5 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/example/FunctionsClientExample.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/example/FunctionsClientExample.sol @@ -2,22 +2,22 @@ pragma solidity ^0.8.19; import {FunctionsClient} from "../FunctionsClient.sol"; -import {Functions} from "../Functions.sol"; -import {ConfirmedOwner} from "../../../../ConfirmedOwner.sol"; +import {ConfirmedOwner} from "../../../../shared/access/ConfirmedOwner.sol"; +import {FunctionsRequest} from "../libraries/FunctionsRequest.sol"; /** - * @title Chainlink Functions example client contract implementation + * @title Chainlink Functions example Client contract implementation */ contract FunctionsClientExample is FunctionsClient, ConfirmedOwner { - using Functions for Functions.Request; + using FunctionsRequest for FunctionsRequest.Request; uint32 public constant MAX_CALLBACK_GAS = 70_000; - bytes32 public lastRequestId; - bytes32 public lastResponse; - bytes32 public lastError; - uint32 public lastResponseLength; - uint32 public lastErrorLength; + bytes32 public s_lastRequestId; + bytes32 public s_lastResponse; + bytes32 public s_lastError; + uint32 public s_lastResponseLength; + uint32 public s_lastErrorLength; error UnexpectedRequestID(bytes32 requestId); @@ -37,11 +37,11 @@ contract FunctionsClientExample is FunctionsClient, ConfirmedOwner { uint64 subscriptionId, bytes32 jobId ) external onlyOwner { - Functions.Request memory req; + FunctionsRequest.Request memory req; req.initializeRequestForInlineJavaScript(source); if (encryptedSecretsReferences.length > 0) req.addSecretsReference(encryptedSecretsReferences); - if (args.length > 0) req.addArgs(args); - lastRequestId = _sendRequest(req, subscriptionId, MAX_CALLBACK_GAS, jobId); + if (args.length > 0) req.setArgs(args); + s_lastRequestId = _sendRequest(req.encodeCBOR(), subscriptionId, MAX_CALLBACK_GAS, jobId); } /** @@ -52,23 +52,22 @@ contract FunctionsClientExample is FunctionsClient, ConfirmedOwner { * Either response or error parameter will be set, but never both */ function fulfillRequest(bytes32 requestId, bytes memory response, bytes memory err) internal override { - if (lastRequestId != requestId) { + if (s_lastRequestId != requestId) { revert UnexpectedRequestID(requestId); } - // Save only the first 32 bytes of reponse/error to always fit within MAX_CALLBACK_GAS - lastResponse = bytesToBytes32(response); - lastResponseLength = uint32(response.length); - lastError = bytesToBytes32(err); - lastErrorLength = uint32(err.length); + // Save only the first 32 bytes of response/error to always fit within MAX_CALLBACK_GAS + s_lastResponse = bytesToBytes32(response); + s_lastResponseLength = uint32(response.length); + s_lastError = bytesToBytes32(err); + s_lastErrorLength = uint32(err.length); } - function bytesToBytes32(bytes memory b) private pure returns (bytes32) { - bytes32 out; + function bytesToBytes32(bytes memory b) private pure returns (bytes32 out) { uint256 maxLen = 32; if (b.length < 32) { maxLen = b.length; } - for (uint256 i = 0; i < maxLen; i++) { + for (uint256 i = 0; i < maxLen; ++i) { out |= bytes32(b[i]) >> (i * 8); } return out; diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IConfigurable.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IConfigurable.sol deleted file mode 100644 index 836f888f584..00000000000 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IConfigurable.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -/** - * @title Configurable contract interface. - */ -interface IConfigurable { - /** - * @notice Get the hash of the current configuration - * @return config hash of config bytes - */ - function getConfigHash() external returns (bytes32 config); - - /** - * @notice Set the contract's configuration - * @dev Only callable by the Router - * @param config bytes containing config data - */ - function setConfig(bytes calldata config) external; -} diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol index f16ef26bfb1..00ff17ee14d 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol @@ -1,80 +1,44 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -/** - * @title Chainlink Functions billing subscription registry interface. - */ +// @title Chainlink Functions DON billing interface. interface IFunctionsBilling { - struct RequestBilling { - // a unique subscription ID allocated by billing system, - uint64 subscriptionId; - // the client contract that initiated the request to the DON - // to use the subscription it must be added as a consumer on the subscription - address client; - // customer specified gas limit for the fulfillment callback - uint32 callbackGasLimit; - // the expected gas price used to execute the transaction - uint256 expectedGasPrice; - } + // @notice Return the current conversion from WEI of ETH to LINK from the configured Chainlink data feed + // @return weiPerUnitLink - The amount of WEI in one LINK + function getWeiPerUnitLink() external view returns (uint256); - /** - * @notice Gets the configuration of the Chainlink Functions billing registry - * @return maxGasLimit global max for request gas limit - * @return stalenessSeconds if the eth/link feed is more stale then this, use the fallback price - * @return gasAfterPaymentCalculation gas used in doing accounting after completing the gas measurement - * @return fallbackWeiPerUnitLink fallback eth/link price in the case of a stale feed - * @return gasOverhead average gas execution cost used in estimating total cost - * @return linkPriceFeed address of contract for a conversion price between LINK token and native token - * @return maxSupportedRequestDataVersion The highest support request data version supported by the node - */ - function getConfig() - external - view - returns ( - uint32 maxGasLimit, - uint32 stalenessSeconds, - uint256 gasAfterPaymentCalculation, - int256 fallbackWeiPerUnitLink, - uint32 gasOverhead, - address linkPriceFeed, - uint16 maxSupportedRequestDataVersion - ); + // @notice Determine the fee that will be split between Node Operators for servicing a request + // @param requestCBOR - CBOR encoded Chainlink Functions request data, use FunctionsRequest library to encode a request + // @return fee - Cost in Juels (1e18) of LINK + function getDONFee(bytes memory requestCBOR) external view returns (uint72); - /** - * @notice Determine the fee that will be split between Node Operators for servicing a request - * @param requestData Encoded Chainlink Functions request data, use FunctionsClient API to encode a request - * @param billing The request's billing configuration - * @return fee Cost in Juels (1e18) of LINK - */ - function getDONFee(bytes memory requestData, RequestBilling memory billing) external view returns (uint96); + // @notice Determine the fee that will be paid to the Router owner for operating the network + // @return fee - Cost in Juels (1e18) of LINK + function getAdminFee() external view returns (uint72); - /** - * @notice Determine the fee that will be paid to the Router owner for operating the network - * @param requestData Encoded Chainlink Functions request data, use FunctionsClient API to encode a request - * @param billing The request's billing configuration - * @return fee Cost in Juels (1e18) of LINK - */ - function getAdminFee(bytes memory requestData, RequestBilling memory billing) external view returns (uint96); - - /** - * @notice Estimate the total cost that will be charged to a subscription to make a request: gas re-imbursement, plus DON fee, plus Registry fee - * @param subscriptionId An identifier of the billing account - * @param data Encoded Chainlink Functions request data, use FunctionsClient API to encode a request - * @param callbackGasLimit Gas limit for the fulfillment callback - * @param gasPrice The blockchain's gas price to estimate with - * @return billedCost Cost in Juels (1e18) of LINK - */ + // @notice Estimate the total cost that will be charged to a subscription to make a request: transmitter gas re-reimbursement, plus DON fee, plus Registry fee + // @param - subscriptionId An identifier of the billing account + // @param - data Encoded Chainlink Functions request data, use FunctionsClient API to encode a request + // @param - callbackGasLimit Gas limit for the fulfillment callback + // @param - gasPriceGwei The blockchain's gas price to estimate with + // @return - billedCost Cost in Juels (1e18) of LINK function estimateCost( uint64 subscriptionId, bytes calldata data, uint32 callbackGasLimit, - uint256 gasPrice + uint256 gasPriceGwei ) external view returns (uint96); - /** - * @notice Remove a request comittment that the Router has determined to be stale - * @dev Only callable by the Router - * @param requestId - The request ID to remove - */ + // @notice Remove a request commitment that the Router has determined to be stale + // @param requestId - The request ID to remove function deleteCommitment(bytes32 requestId) external returns (bool); + + // @notice Oracle withdraw LINK earned through fulfilling requests + // @notice If amount is 0 the full balance will be withdrawn + // @param recipient where to send the funds + // @param amount amount to withdraw + function oracleWithdraw(address recipient, uint96 amount) external; + + // @notice Withdraw all LINK earned by Oracles through fulfilling requests + function oracleWithdrawAll() external; } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsClient.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsClient.sol index 4423ec6dcca..5fbee58274e 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsClient.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsClient.sol @@ -1,16 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -/** - * @title Chainlink Functions client interface. - */ +// @title Chainlink Functions client interface. interface IFunctionsClient { - /** - * @notice Chainlink Functions response handler called by the designated transmitter node in an OCR round. - * @param requestId The requestId returned by FunctionsClient.sendRequest(). - * @param response Aggregated response from the user code. - * @param err Aggregated error either from the user code or from the execution pipeline. - * Either response or error parameter will be set, but never both. - */ + // @notice Chainlink Functions response handler called by the Functions Router + // during fullilment from the designated transmitter node in an OCR round. + // @param requestId The requestId returned by FunctionsClient.sendRequest(). + // @param response Aggregated response from the request's source code. + // @param err Aggregated error either from the request's source code or from the execution pipeline. + // @dev Either response or error parameter will be set, but never both. function handleOracleFulfillment(bytes32 requestId, bytes memory response, bytes memory err) external; } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsCoordinator.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsCoordinator.sol index 309a2d5de04..63571786eb8 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsCoordinator.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsCoordinator.sol @@ -1,78 +1,52 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -/** - * @title Chainlink Functions oracle interface. - */ -interface IFunctionsCoordinator { - struct Request { - uint64 subscriptionId; // Identifier of the subscription that will be charged for the request - bytes data; // Encoded Chainlink Functions request data, use FunctionsClient API to encode a request - uint16 dataVersion; // The version of the structure of the encoded data - uint32 callbackGasLimit; // The amount of gas that the callback to the consuming contract can utilize - address caller; // The client contract that is sending the request - address subscriptionOwner; // The owner of the subscription - } +import {FunctionsResponse} from "../libraries/FunctionsResponse.sol"; - /** - * @notice Returns the DON's threshold encryption public key used to encrypt secrets - * @dev All nodes on the DON have separate key shares of the threshold decryption key - * and nodes must participate in a threshold decryption OCR round to decrypt secrets - * @return thresholdPublicKey the DON's threshold encryption public key - */ +// @title Chainlink Functions DON Coordinator interface. +interface IFunctionsCoordinator { + // @notice Returns the DON's threshold encryption public key used to encrypt secrets + // @dev All nodes on the DON have separate key shares of the threshold decryption key + // and nodes must participate in a threshold decryption OCR round to decrypt secrets + // @return thresholdPublicKey the DON's threshold encryption public key function getThresholdPublicKey() external view returns (bytes memory); - /** - * @notice Sets the DON's threshold encryption public key used to encrypt secrets - * @dev Used to rotate the key - * @param thresholdPublicKey The new public key - */ + // @notice Sets the DON's threshold encryption public key used to encrypt secrets + // @dev Used to rotate the key + // @param thresholdPublicKey The new public key function setThresholdPublicKey(bytes calldata thresholdPublicKey) external; - /** - * @notice Returns the DON's secp256k1 public key that is used to encrypt secrets - * @dev All nodes on the DON have the corresponding private key - * needed to decrypt the secrets encrypted with the public key - * @return publicKey the DON's public key - */ + // @notice Returns the DON's secp256k1 public key that is used to encrypt secrets + // @dev All nodes on the DON have the corresponding private key + // needed to decrypt the secrets encrypted with the public key + // @return publicKey the DON's public key function getDONPublicKey() external view returns (bytes memory); - /** - * @notice Sets DON's secp256k1 public key used to encrypt secrets - * @dev Used to rotate the key - * @param donPublicKey The new public key - */ + // @notice Sets DON's secp256k1 public key used to encrypt secrets + // @dev Used to rotate the key + // @param donPublicKey The new public key function setDONPublicKey(bytes calldata donPublicKey) external; - /** - * @notice Sets a per-node secp256k1 public key used to encrypt secrets for that node - * @dev Callable only by contract owner and DON members - * @param node node's address - * @param publicKey node's public key - */ + // @notice Sets a per-node secp256k1 public key used to encrypt secrets for that node + // @dev Callable only by contract owner and DON members + // @param node node's address + // @param publicKey node's public key function setNodePublicKey(address node, bytes calldata publicKey) external; - /** - * @notice Deletes node's public key - * @dev Callable only by contract owner or the node itself - * @param node node's address - */ + // @notice Deletes node's public key + // @dev Callable only by contract owner or the node itself + // @param node node's address function deleteNodePublicKey(address node) external; - /** - * @notice Return two arrays of equal size containing DON members' addresses and their corresponding - * public keys (or empty byte arrays if per-node key is not defined) - */ + // @notice Return two arrays of equal size containing DON members' addresses and their corresponding + // public keys (or empty byte arrays if per-node key is not defined) function getAllNodePublicKeys() external view returns (address[] memory, bytes[] memory); - /** - * @notice Sends a request (encoded as data) using the provided subscriptionId - * @dev Callable only by the Router - * @param request The request information, @dev see the struct for field descriptions - * @return requestId A unique request identifier (unique per DON) - * @return estimatedCost The cost in Juels of LINK that the request is estimated to charge if market conditions were to stay the same - * @return gasAfterPaymentCalculation The amount of gas overhead that will be used after balances have already been changed - * @return requestTimeoutSeconds The amount of time in seconds before this request is considered stale - */ - function sendRequest(Request calldata request) external returns (bytes32, uint96, uint256, uint256); + // @notice Receives a request to be emitted to the DON for processing + // @param request The request metadata + // @dev see the struct for field descriptions + // @return commitment - The parameters of the request that must be held consistent at response time + function startRequest( + FunctionsResponse.RequestMeta calldata request + ) external returns (FunctionsResponse.Commitment memory commitment); } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsRouter.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsRouter.sol index 932f34d0c6b..ebc1dbd4538 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsRouter.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsRouter.sol @@ -1,35 +1,31 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -import {IRouterBase} from "./IRouterBase.sol"; - -/** - * @title Chainlink Functions Router interface. - */ -interface IFunctionsRouter is IRouterBase { - /** - * @notice The identifier of the route to retrieve the address of the access control contract - * The access control contract controls which accounts can manage subscriptions - * @return id - bytes32 id that can be passed to the "getContractById" of the Router - */ - function getAllowListId() external pure returns (bytes32); - - /** - * @notice The fee that will be paid to the Router owner for operating the network - * @return fee Cost in Juels (1e18) of LINK - */ - function getAdminFee() external view returns (uint96); - - /** - * @notice Sends a request (encoded as data) using the provided subscriptionId - * @param subscriptionId A unique subscription ID allocated by billing system, - * a client can make requests from different contracts referencing the same subscription - * @param data Encoded Chainlink Functions request data, use FunctionsClient API to encode a request - * @param dataVersion Gas limit for the fulfillment callback - * @param callbackGasLimit Gas limit for the fulfillment callback - * @param donId An identifier used to determine which route to send the request along - * @return requestId A unique request identifier - */ +import {FunctionsResponse} from "../libraries/FunctionsResponse.sol"; + +// @title Chainlink Functions Router interface. +interface IFunctionsRouter { + // @notice The identifier of the route to retrieve the address of the access control contract + // The access control contract controls which accounts can manage subscriptions + // @return id - bytes32 id that can be passed to the "getContractById" of the Router + function getAllowListId() external view returns (bytes32); + + // @notice Set the identifier of the route to retrieve the address of the access control contract + // The access control contract controls which accounts can manage subscriptions + function setAllowListId(bytes32 allowListId) external; + + // @notice Get the flat fee (in Juels of LINK) that will be paid to the Router owner for operation of the network + // @return adminFee + function getAdminFee() external view returns (uint72 adminFee); + + // @notice Sends a request using the provided subscriptionId + // @param subscriptionId - A unique subscription ID allocated by billing system, + // a client can make requests from different contracts referencing the same subscription + // @param data - CBOR encoded Chainlink Functions request data, use FunctionsClient API to encode a request + // @param dataVersion - Gas limit for the fulfillment callback + // @param callbackGasLimit - Gas limit for the fulfillment callback + // @param donId - An identifier used to determine which route to send the request along + // @return requestId - A unique request identifier function sendRequest( uint64 subscriptionId, bytes calldata data, @@ -38,26 +34,76 @@ interface IFunctionsRouter is IRouterBase { bytes32 donId ) external returns (bytes32); - /** - * @notice Fulfill the request by: - * - calling back the data that the Oracle returned to the client contract - * - pay the DON for processing the request - * @dev Only callable by the Coordinator contract that is saved in the commitment - * @param requestId The identifier for the request - * @param response response data from DON consensus - * @param err error from DON consensus - * @param juelsPerGas - - * @param costWithoutFulfillment - - * @param transmitter - - * @return fulfillResult - - * @return callbackGasCostJuels - - */ + // @notice Sends a request to the proposed contracts + // @param subscriptionId - A unique subscription ID allocated by billing system, + // a client can make requests from different contracts referencing the same subscription + // @param data - CBOR encoded Chainlink Functions request data, use FunctionsClient API to encode a request + // @param dataVersion - Gas limit for the fulfillment callback + // @param callbackGasLimit - Gas limit for the fulfillment callback + // @param donId - An identifier used to determine which route to send the request along + // @return requestId - A unique request identifier + function sendRequestToProposed( + uint64 subscriptionId, + bytes calldata data, + uint16 dataVersion, + uint32 callbackGasLimit, + bytes32 donId + ) external returns (bytes32); + + // @notice Fulfill the request by: + // - calling back the data that the Oracle returned to the client contract + // - pay the DON for processing the request + // @dev Only callable by the Coordinator contract that is saved in the commitment + // @param response response data from DON consensus + // @param err error from DON consensus + // @param juelsPerGas - current rate of juels/gas + // @param costWithoutFulfillment - The cost of processing the request (in Juels of LINK ), without fulfillment + // @param transmitter - The Node that transmitted the OCR report + // @param commitment - The parameters of the request that must be held consistent between request and response time + // @return fulfillResult - + // @return callbackGasCostJuels - function fulfill( - bytes32 requestId, bytes memory response, bytes memory err, uint96 juelsPerGas, uint96 costWithoutFulfillment, - address transmitter - ) external returns (uint8, uint96); + address transmitter, + FunctionsResponse.Commitment memory commitment + ) external returns (FunctionsResponse.FulfillResult, uint96); + + // @notice Validate requested gas limit is below the subscription max. + // @param subscriptionId subscription ID + // @param callbackGasLimit desired callback gas limit + function isValidCallbackGasLimit(uint64 subscriptionId, uint32 callbackGasLimit) external view; + + // @notice Get the current contract given an ID + // @param id A bytes32 identifier for the route + // @return contract The current contract address + function getContractById(bytes32 id) external view returns (address); + + // @notice Get the proposed next contract given an ID + // @param id A bytes32 identifier for the route + // @return contract The current or proposed contract address + function getProposedContractById(bytes32 id) external view returns (address); + + // @notice Return the latest proprosal set + // @return ids The identifiers of the contracts to update + // @return to The addresses of the contracts that will be updated to + function getProposedContractSet() external view returns (bytes32[] memory, address[] memory); + + // @notice Proposes one or more updates to the contract routes + // @dev Only callable by owner + function proposeContractsUpdate(bytes32[] memory proposalSetIds, address[] memory proposalSetAddresses) external; + + // @notice Updates the current contract routes to the proposed contracts + // @dev Only callable by owner + function updateContracts() external; + + // @dev Puts the system into an emergency stopped state. + // @dev Only callable by owner + function pause() external; + + // @dev Takes the system out of an emergency stopped state. + // @dev Only callable by owner + function unpause() external; } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsSubscriptions.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsSubscriptions.sol index 7582764a3e1..4072307edb8 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsSubscriptions.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsSubscriptions.sol @@ -1,169 +1,133 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -/** - * @title Chainlink Functions Subscription interface. - */ +import {FunctionsResponse} from "../libraries/FunctionsResponse.sol"; + +// @title Chainlink Functions Subscription interface. interface IFunctionsSubscriptions { struct Subscription { - // There are only 1e9*1e18 = 1e27 juels in existence, so the balance can fit in uint96 (2^96 ~ 7e28) - uint96 balance; // Common LINK balance that is controlled by the Registry to be used for all consumer requests. - uint96 blockedBalance; // LINK balance that is reserved to pay for pending consumer requests. - address owner; // Owner can fund/withdraw/cancel the sub. - address requestedOwner; // For safely transferring sub ownership. - // Maintains the list of keys in s_consumers. - // We do this for 2 reasons: - // 1. To be able to clean up all keys from s_consumers when canceling a subscription. - // 2. To be able to return the list of all consumers in getSubscription. - // Note that we need the s_consumers map to be able to directly check if a - // consumer is valid without reading all the consumers from storage. - address[] consumers; + uint96 balance; // ═════════╗ Common LINK balance that is controlled by the Router to be used for all consumer requests. + address owner; // ══════════╝ The owner can fund/withdraw/cancel the subscription. + uint96 blockedBalance; // ══╗ LINK balance that is reserved to pay for pending consumer requests. + address proposedOwner; // ══╝ For safely transferring sub ownership. + address[] consumers; // ════╸ Client contracts that can use the subscription + bytes32 flags; // ══════════╸ Per-subscription flags } struct Consumer { - bool allowed; // Owner can fund/withdraw/cancel the sub. - uint64 initiatedRequests; // The number of requests that have been started - uint64 completedRequests; // The number of requests that have successfully completed or timed out + bool allowed; // ══════════════╗ Owner can fund/withdraw/cancel the sub. + uint64 initiatedRequests; // ║ The number of requests that have been started + uint64 completedRequests; // ══╝ The number of requests that have successfully completed or timed out } - /** - * @notice Get details about a subscription. - * @param subscriptionId - ID of the subscription - * @return balance - LINK balance of the subscription in juels. - * @return blockedBalance - amount of LINK balance of the subscription in juels that is blocked for an in flight request. - * @return owner - owner of the subscription. - * @return requestedOwner - proposed owner to move ownership of the subscription to. - * @return consumers - list of consumer address which are able to use this subscription. - */ - function getSubscription( - uint64 subscriptionId - ) - external - view - returns (uint96 balance, uint96 blockedBalance, address owner, address requestedOwner, address[] memory consumers); - - /** - * @notice Get details about a consumer of a subscription. - * @dev Only callable by a route - * @param client - the consumer contract that initiated the request - * @param subscriptionId - ID of the subscription - * @return allowed - amount of LINK balance of the subscription in juels that is blocked for an in flight request. - * @return initiatedRequests - owner of the subscription. - * @return completedRequests - list of consumer address which are able to use this subscription. - */ - function getConsumer( - address client, - uint64 subscriptionId - ) external view returns (bool allowed, uint64 initiatedRequests, uint64 completedRequests); - - /** - * @notice Get the maximum number of consumers that can be added to one subscription - * @return maxConsumers - maximum number of consumers that can be added to one subscription - */ - function getMaxConsumers() external view returns (uint16); - - /** - * @notice Get details about the total amount of LINK within the system - * @return totalBalance - total Juels of LINK held by the contract - */ + // @notice Get details about a subscription. + // @param subscriptionId - the ID of the subscription + // @return subscription - see IFunctionsSubscriptions.Subscription for more information on the structure + function getSubscription(uint64 subscriptionId) external view returns (Subscription memory); + + // @notice Get details about a consumer of a subscription. + // @param client - the consumer contract address + // @param subscriptionId - the ID of the subscription + // @return consumer - see IFunctionsSubscriptions.Consumer for more information on the structure + function getConsumer(address client, uint64 subscriptionId) external view returns (Consumer memory); + + // @notice Get details about the total amount of LINK within the system + // @return totalBalance - total Juels of LINK held by the contract function getTotalBalance() external view returns (uint96); - /** - * @notice Get details about the total number of subscription accounts - * @return count - total number of subscriptions in the system - */ + // @notice Get details about the total number of subscription accounts + // @return count - total number of subscriptions in the system function getSubscriptionCount() external view returns (uint64); - /** - * @notice Time out all expired requests: unlocks funds and removes the ability for the request to be fulfilled - * @param requestIdsToTimeout - A list of request IDs to time out - */ - function timeoutRequests(bytes32[] calldata requestIdsToTimeout) external; - - /** - * @notice Oracle withdraw LINK earned through fulfilling requests - * @dev Must be called by the Coordinator contract - * @notice If amount is 0 the full balance will be withdrawn - * @notice Both signing and transmitting wallets will have a balance to withdraw - * @param recipient where to send the funds - * @param amount amount to withdraw - */ + // @notice Time out all expired requests: unlocks funds and removes the ability for the request to be fulfilled + // @param requestsToTimeoutByCommitment - A list of request commitments to time out + // @dev The commitment can be found on the "OracleRequest" event created when sending the request. + function timeoutRequests(FunctionsResponse.Commitment[] calldata requestsToTimeoutByCommitment) external; + + // @notice Oracle withdraw LINK earned through fulfilling requests + // @notice If amount is 0 the full balance will be withdrawn + // @notice Both signing and transmitting wallets will have a balance to withdraw + // @param recipient where to send the funds + // @param amount amount to withdraw function oracleWithdraw(address recipient, uint96 amount) external; - /** - * @notice Owner cancel subscription, sends remaining link directly to the subscription owner. - * @dev Only callable by the Router Owner - * @param subscriptionId subscription id - * @dev notably can be called even if there are pending requests, outstanding ones may fail onchain - */ + // @notice Owner cancel subscription, sends remaining link directly to the subscription owner. + // @dev Only callable by the Router Owner + // @param subscriptionId subscription id + // @dev notably can be called even if there are pending requests, outstanding ones may fail onchain function ownerCancelSubscription(uint64 subscriptionId) external; - /** - * @notice Recover link sent with transfer instead of transferAndCall. - * @dev Only callable by the Router Owner - * @param to address to send link to - */ + // @notice Recover link sent with transfer instead of transferAndCall. + // @dev Only callable by the Router Owner + // @param to address to send link to function recoverFunds(address to) external; - /** - * @notice Create a new subscription. - * @return subscriptionId - A unique subscription id. - * @dev You can manage the consumer set dynamically with addConsumer/removeConsumer. - * @dev Note to fund the subscription, use transferAndCall. For example - * @dev LINKTOKEN.transferAndCall( - * @dev address(REGISTRY), - * @dev amount, - * @dev abi.encode(subscriptionId)); - */ + // @notice Create a new subscription. + // @return subscriptionId - A unique subscription id. + // @dev You can manage the consumer set dynamically with addConsumer/removeConsumer. + // @dev Note to fund the subscription, use transferAndCall. For example + // @dev LINKTOKEN.transferAndCall( + // @dev address(ROUTER), + // @dev amount, + // @dev abi.encode(subscriptionId)); function createSubscription() external returns (uint64); - /** - * @notice Request subscription owner transfer. - * @dev Only callable by the Subscription's owner - * @param subscriptionId - ID of the subscription - * @param newOwner - proposed new owner of the subscription - */ - function requestSubscriptionOwnerTransfer(uint64 subscriptionId, address newOwner) external; - - /** - * @notice Request subscription owner transfer. - * @param subscriptionId - ID of the subscription - * @dev will revert if original owner of subscriptionId has - * not requested that msg.sender become the new owner. - */ + // @notice Create a new subscription and add a consumer. + // @return subscriptionId - A unique subscription id. + // @dev You can manage the consumer set dynamically with addConsumer/removeConsumer. + // @dev Note to fund the subscription, use transferAndCall. For example + // @dev LINKTOKEN.transferAndCall( + // @dev address(ROUTER), + // @dev amount, + // @dev abi.encode(subscriptionId)); + function createSubscriptionWithConsumer(address consumer) external returns (uint64 subscriptionId); + + // @notice Propose a new owner for a subscription. + // @dev Only callable by the Subscription's owner + // @param subscriptionId - ID of the subscription + // @param newOwner - proposed new owner of the subscription + function proposeSubscriptionOwnerTransfer(uint64 subscriptionId, address newOwner) external; + + // @notice Accept an ownership transfer. + // @param subscriptionId - ID of the subscription + // @dev will revert if original owner of subscriptionId has + // not requested that msg.sender become the new owner. function acceptSubscriptionOwnerTransfer(uint64 subscriptionId) external; - /** - * @notice Remove a consumer from a Chainlink Functions subscription. - * @dev Only callable by the Subscription's owner - * @param subscriptionId - ID of the subscription - * @param consumer - Consumer to remove from the subscription - */ + // @notice Remove a consumer from a Chainlink Functions subscription. + // @dev Only callable by the Subscription's owner + // @param subscriptionId - ID of the subscription + // @param consumer - Consumer to remove from the subscription function removeConsumer(uint64 subscriptionId, address consumer) external; - /** - * @notice Add a consumer to a Chainlink Functions subscription. - * @dev Only callable by the Subscription's owner - * @param subscriptionId - ID of the subscription - * @param consumer - New consumer which can use the subscription - */ + // @notice Add a consumer to a Chainlink Functions subscription. + // @dev Only callable by the Subscription's owner + // @param subscriptionId - ID of the subscription + // @param consumer - New consumer which can use the subscription function addConsumer(uint64 subscriptionId, address consumer) external; - /** - * @notice Cancel a subscription - * @dev Only callable by the Subscription's owner - * @param subscriptionId - ID of the subscription - * @param to - Where to send the remaining LINK to - */ + // @notice Cancel a subscription + // @dev Only callable by the Subscription's owner + // @param subscriptionId - ID of the subscription + // @param to - Where to send the remaining LINK to function cancelSubscription(uint64 subscriptionId, address to) external; - /** - * @notice Check to see if there exists a request commitment for all consumers for a given sub. - * @param subscriptionId - 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 DONs). - * @dev Used to disable subscription canceling while outstanding request are present. - */ + // @notice Check to see if there exists a request commitment for all consumers for a given sub. + // @param subscriptionId - 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 DONs). + // @dev Used to disable subscription canceling while outstanding request are present. function pendingRequestExists(uint64 subscriptionId) external view returns (bool); + + // @notice Set subscription specific flags for a subscription. + // Each byte of the flag is used to represent a resource tier that the subscription can utilize. + // @param subscriptionId - ID of the subscription + // @param flags - desired flag values + function setFlags(uint64 subscriptionId, bytes32 flags) external; + + // @notice Get flags for a given subscription. + // @param subscriptionId - ID of the subscription + // @return flags - current flag values + function getFlags(uint64 subscriptionId) external view returns (bytes32); } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IOwnableFunctionsRouter.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IOwnableFunctionsRouter.sol new file mode 100644 index 00000000000..5a2f85fd32e --- /dev/null +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IOwnableFunctionsRouter.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {IFunctionsRouter} from "./IFunctionsRouter.sol"; +import {IOwnable} from "../../../../shared/interfaces/IOwnable.sol"; + +// @title Chainlink Functions Router interface with Ownability. +interface IOwnableFunctionsRouter is IOwnable, IFunctionsRouter { + +} diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IRouterBase.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IRouterBase.sol deleted file mode 100644 index a88a8b12598..00000000000 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IRouterBase.sol +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -/** - * @title Chainlink base Router interface. - */ -interface IRouterBase { - /** - * @notice Returns the latest semantic version of the system - * @dev See https://semver.org/ for more details - * @return major The current major version number - * @return minor The current minor version number - * @return patch The current patch version number - */ - function version() external view returns (uint16 major, uint16 minor, uint16 patch); - - /** - * @notice Get the current contract given an ID - * @param id A bytes32 identifier for the route - * @return contract The current contract address - */ - function getContractById(bytes32 id) external view returns (address); - - /** - * @notice Get the proposed next contract given an ID - * @param id A bytes32 identifier for the route - * @return contract The current or proposed contract address - */ - function getContractById(bytes32 id, bool useProposed) external view returns (address); - - /** - * @notice Return the latest proprosal set - * @return timelockEndBlock The block number that the proposal is able to be merged at - * @return ids The identifiers of the contracts to update - * @return to The addresses of the contracts that will be updated to - */ - function getProposedContractSet() external view returns (uint, bytes32[] memory, address[] memory); - - /** - * @notice Proposes one or more updates to the contract routes - * @dev Only callable by owner - */ - function proposeContractsUpdate(bytes32[] memory proposalSetIds, address[] memory proposalSetAddresses) external; - - /** - * @notice Tests a proposal for the ability to make a successful upgrade - */ - function validateProposedContracts(bytes32 id, bytes calldata data) external returns (bytes memory); - - /** - * @notice Updates the current contract routes to the proposed contracts - * @dev Only callable once timelock has passed - * @dev Only callable by owner - */ - function updateContracts() external; - - /** - * @notice Proposes new configuration data for the current (not proposed) contract - * @dev Only callable by owner - */ - function proposeConfigUpdate(bytes32 id, bytes calldata config) external; - - /** - * @notice Sends new configuration data to the contract along a route route - * @dev Only callable once timelock has passed - * @dev Only callable by owner - */ - function updateConfig(bytes32 id) external; - - /** - * @notice Propose a change to the amount of blocks of the timelock - * (the amount of blocks that are required to pass before a change can be applied) - * @dev Only callable by owner - */ - function proposeTimelockBlocks(uint16 blocks) external; - - /** - * @notice Apply a proposed change to the amount of blocks required for the timelock - * (the amount of blocks that are required to pass before a change can be applied) - * @dev Only callable after the timelock blocks proposal has gone through the timelock itself - * @dev Only callable by owner - */ - function updateTimelockBlocks() external; - - /** - * @dev Returns true if the contract is paused, and false otherwise. - */ - function isPaused() external view returns (bool); - - /** - * @dev Toggles the stopped state. - * @dev Only callable by owner - */ - function togglePaused() external; -} diff --git a/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsRequest.sol b/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsRequest.sol new file mode 100644 index 00000000000..0a669588ed0 --- /dev/null +++ b/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsRequest.sol @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {CBOR} from "../../../../vendor/solidity-cborutils/v2.0.0/CBOR.sol"; + +// @title Library for encoding the input data of a Functions request into CBOR +library FunctionsRequest { + using CBOR for CBOR.CBORBuffer; + + uint16 public constant REQUEST_DATA_VERSION = 1; + uint256 internal constant DEFAULT_BUFFER_SIZE = 256; + + enum Location { + Inline, // Provided within the Request + Remote, // Hosted through remote location that can be accessed through a provided URL + DONHosted // Hosted on the DON's storage + } + + enum CodeLanguage { + JavaScript + // In future version we may add other languages + } + + struct Request { + Location codeLocation; // ════════════╸ The location of the source code that will be executed on each node in the DON + Location secretsLocation; // ═════════╸ The location of secrets that will be passed into the source code. *Only Remote secrets are supported + CodeLanguage language; // ════════════╸ The coding language that the source code is written in + string source; // ════════════════════╸ Raw source code for Request.codeLocation of Location.Inline, URL for Request.codeLocation of Location.Remote, or slot decimal number for Request.codeLocation of Location.DONHosted + bytes encryptedSecretsReference; // ══╸ Encrypted URLs for Request.secretsLocation of Location.Remote (use addSecretsReference()), or CBOR encoded slotid+version for Request.secretsLocation of Location.DONHosted (use addDONHostedSecrets()) + bytes requestSignature; // ═══════════╸ Signature generated by the subscription owner's EOA + string[] args; // ════════════════════╸ String arguments that will be passed into the source code + bytes[] bytesArgs; // ════════════════╸ Bytes arguments that will be passed into the source code + } + + error EmptySource(); + error EmptySecrets(); + error EmptyArgs(); + error NoInlineSecrets(); + + // @notice Encodes a Request to CBOR encoded bytes + // @param self The request to encode + // @return CBOR encoded bytes + function encodeCBOR(Request memory self) internal pure returns (bytes memory) { + CBOR.CBORBuffer memory buffer = CBOR.create(DEFAULT_BUFFER_SIZE); + + buffer.writeString("codeLocation"); + buffer.writeUInt256(uint256(self.codeLocation)); + + buffer.writeString("language"); + buffer.writeUInt256(uint256(self.language)); + + buffer.writeString("source"); + buffer.writeString(self.source); + + if (self.requestSignature.length > 0) { + buffer.writeString("requestSignature"); + buffer.writeBytes(self.requestSignature); + } + + if (self.args.length > 0) { + buffer.writeString("args"); + buffer.startArray(); + for (uint256 i = 0; i < self.args.length; ++i) { + buffer.writeString(self.args[i]); + } + buffer.endSequence(); + } + + if (self.encryptedSecretsReference.length > 0) { + if (self.secretsLocation == Location.Inline) { + revert NoInlineSecrets(); + } + buffer.writeString("secretsLocation"); + buffer.writeUInt256(uint256(self.secretsLocation)); + buffer.writeString("secrets"); + buffer.writeBytes(self.encryptedSecretsReference); + } + + if (self.bytesArgs.length > 0) { + buffer.writeString("bytesArgs"); + buffer.startArray(); + for (uint256 i = 0; i < self.bytesArgs.length; ++i) { + buffer.writeBytes(self.bytesArgs[i]); + } + buffer.endSequence(); + } + + return buffer.buf.buf; + } + + // @notice Initializes a Chainlink Functions Request + // @dev Sets the codeLocation and code on the request + // @param self The uninitialized request + // @param codeLocation The user provided source code location + // @param language The programming language of the user code + // @param source The user provided source code or a url + function initializeRequest( + Request memory self, + Location codeLocation, + CodeLanguage language, + string memory source + ) internal pure { + if (bytes(source).length == 0) revert EmptySource(); + + self.codeLocation = codeLocation; + self.language = language; + self.source = source; + } + + // @notice Initializes a Chainlink Functions Request + // @dev Simplified version of initializeRequest for PoC + // @param self The uninitialized request + // @param javaScriptSource The user provided JS code (must not be empty) + function initializeRequestForInlineJavaScript(Request memory self, string memory javaScriptSource) internal pure { + initializeRequest(self, Location.Inline, CodeLanguage.JavaScript, javaScriptSource); + } + + // @notice Adds Remote user encrypted secrets to a Request + // @param self The initialized request + // @param encryptedSecretsReference Encrypted comma-separated string of URLs pointing to off-chain secrets + function addSecretsReference(Request memory self, bytes memory encryptedSecretsReference) internal pure { + if (encryptedSecretsReference.length == 0) revert EmptySecrets(); + + self.secretsLocation = Location.Remote; + self.encryptedSecretsReference = encryptedSecretsReference; + } + + // @notice Adds DON-hosted secrets reference to a Request + // @param self The initialized request + // @param slotID Slot ID of the user's secrets hosted on DON + // @param version User data version (for the slotID) + function addDONHostedSecrets(Request memory self, uint8 slotID, uint64 version) internal pure { + CBOR.CBORBuffer memory buffer = CBOR.create(DEFAULT_BUFFER_SIZE); + + buffer.writeString("slotID"); + buffer.writeUInt64(slotID); + buffer.writeString("version"); + buffer.writeUInt64(version); + + self.secretsLocation = Location.DONHosted; + self.encryptedSecretsReference = buffer.buf.buf; + } + + // @notice Sets args for the user run function + // @param self The initialized request + // @param args The array of string args (must not be empty) + function setArgs(Request memory self, string[] memory args) internal pure { + if (args.length == 0) revert EmptyArgs(); + + self.args = args; + } + + // @notice Sets bytes args for the user run function + // @param self The initialized request + // @param args The array of bytes args (must not be empty) + function setBytesArgs(Request memory self, bytes[] memory args) internal pure { + if (args.length == 0) revert EmptyArgs(); + + self.bytesArgs = args; + } +} diff --git a/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsResponse.sol b/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsResponse.sol new file mode 100644 index 00000000000..71e731b2e33 --- /dev/null +++ b/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsResponse.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {IFunctionsSubscriptions} from "../interfaces/IFunctionsSubscriptions.sol"; + +// @title Library of types that are used for fulfillment of a Functions request +library FunctionsResponse { + // Used to send request information from the Router to the Coordinator + struct RequestMeta { + bytes data; // ══════════════════╸ CBOR encoded Chainlink Functions request data, use FunctionsRequest library to encode a request + bytes32 flags; // ═══════════════╸ Per-subscription flags + address requestingContract; // ══╗ The client contract that is sending the request + uint96 availableBalance; // ═════╝ Common LINK balance of the subscription that is controlled by the Router to be used for all consumer requests. + uint72 adminFee; // ═════════════╗ Flat fee (in Juels of LINK) that will be paid to the Router Owner for operation of the network + uint64 subscriptionId; // ║ Identifier of the billing subscription that will be charged for the request + uint64 initiatedRequests; // ║ The number of requests that have been started + uint32 callbackGasLimit; // ║ The amount of gas that the callback to the consuming contract will be given + uint16 dataVersion; // ══════════╝ The version of the structure of the CBOR encoded request data + uint64 completedRequests; // ════╗ The number of requests that have successfully completed or timed out + address subscriptionOwner; // ═══╝ The owner of the billing subscription + } + + enum FulfillResult { + FULFILLED, // 0 + USER_CALLBACK_ERROR, // 1 + INVALID_REQUEST_ID, // 2 + COST_EXCEEDS_COMMITMENT, // 3 + INSUFFICIENT_GAS_PROVIDED, // 4 + SUBSCRIPTION_BALANCE_INVARIANT_VIOLATION, // 5 + INVALID_COMMITMENT // 6 + } + + struct Commitment { + bytes32 requestId; // ═════════════════╸ A unique identifier for a Chainlink Functions request + address coordinator; // ═══════════════╗ The Coordinator contract that manages the DON that is servicing a request + uint96 estimatedTotalCostJuels; // ════╝ The maximum cost in Juels (1e18) of LINK that will be charged to fulfill a request + address client; // ════════════════════╗ The client contract that sent the request + uint64 subscriptionId; // ║ Identifier of the billing subscription that will be charged for the request + uint32 callbackGasLimit; // ═══════════╝ The amount of gas that the callback to the consuming contract will be given + uint72 adminFee; // ═══════════════════╗ Flat fee (in Juels of LINK) that will be paid to the Router Owner for operation of the network + uint72 donFee; // ║ Fee (in Juels of LINK) that will be split between Node Operators for servicing a request + uint40 gasOverheadBeforeCallback; // ║ Represents the average gas execution cost before the fulfillment callback. + uint40 gasOverheadAfterCallback; // ║ Represents the average gas execution cost after the fulfillment callback. + uint32 timeoutTimestamp; // ═══════════╝ The timestamp at which a request will be eligible to be timed out + } +} diff --git a/contracts/src/v0.8/functions/dev/1_0_0/ocr/OCR2Abstract.sol b/contracts/src/v0.8/functions/dev/1_0_0/ocr/OCR2Abstract.sol index ecfa75158c5..ea4503a8b7d 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/ocr/OCR2Abstract.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/ocr/OCR2Abstract.sol @@ -5,7 +5,7 @@ import {ITypeAndVersion} from "../../../../shared/interfaces/ITypeAndVersion.sol abstract contract OCR2Abstract is ITypeAndVersion { // Maximum number of oracles the offchain reporting protocol is designed for - uint256 internal constant maxNumOracles = 31; + uint256 internal constant MAX_NUM_ORACLES = 31; /** * @notice triggers a new run of the offchain reporting protocol @@ -19,7 +19,7 @@ abstract contract OCR2Abstract is ITypeAndVersion { * @param offchainConfigVersion version of the serialization format used for "offchainConfig" parameter * @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract */ - event OCRConfigSet( + event ConfigSet( uint32 previousConfigBlockNumber, bytes32 configDigest, uint64 configCount, diff --git a/contracts/src/v0.8/functions/dev/1_0_0/ocr/OCR2Base.sol b/contracts/src/v0.8/functions/dev/1_0_0/ocr/OCR2Base.sol index 3a9872bf60e..013cefe82b9 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/ocr/OCR2Base.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/ocr/OCR2Base.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {ConfirmedOwner} from "../../../../ConfirmedOwner.sol"; +import {ConfirmedOwner} from "../../../../shared/access/ConfirmedOwner.sol"; import {OCR2Abstract} from "./OCR2Abstract.sol"; /** @@ -16,6 +16,7 @@ import {OCR2Abstract} from "./OCR2Abstract.sol"; */ abstract contract OCR2Base is ConfirmedOwner, OCR2Abstract { error ReportInvalid(); + error InvalidConfig(string message); bool internal immutable i_uniqueReports; @@ -25,6 +26,12 @@ abstract contract OCR2Base is ConfirmedOwner, OCR2Abstract { uint256 private constant maxUint32 = (1 << 32) - 1; + // incremented each time a new config is posted. This count is incorporated + // into the config digest, to prevent replay attacks. + uint32 internal s_configCount; + uint32 internal s_latestConfigBlockNumber; // makes it easier for offchain systems + // to extract config from logs. + // Storing these fields used on the hot path in a ConfigInfo variable reduces the // retrieval of all of them to a single SLOAD. If any further fields are // added, make sure that storage of the struct still takes at most 32 bytes. @@ -35,12 +42,6 @@ abstract contract OCR2Base is ConfirmedOwner, OCR2Abstract { } ConfigInfo internal s_configInfo; - // incremented each time a new config is posted. This count is incorporated - // into the config digest, to prevent replay attacks. - uint32 internal s_configCount; - uint32 internal s_latestConfigBlockNumber; // makes it easier for offchain systems - // to extract config from logs. - // Used for s_oracles[a].role, where a is an address, to track the purpose // of the address, or to indicate that the address is unset. enum Role { @@ -75,14 +76,14 @@ abstract contract OCR2Base is ConfirmedOwner, OCR2Abstract { // Reverts transaction if config args are invalid modifier checkConfigValid( - uint256 _numSigners, - uint256 _numTransmitters, - uint256 _f + uint256 numSigners, + uint256 numTransmitters, + uint256 f ) { - require(_numSigners <= maxNumOracles, "too many signers"); - require(_f > 0, "f must be positive"); - require(_numSigners == _numTransmitters, "oracle addresses out of registration"); - require(_numSigners > 3 * _f, "faulty-oracle f too high"); + if (numSigners > MAX_NUM_ORACLES) revert InvalidConfig("too many signers"); + if (f == 0) revert InvalidConfig("f must be positive"); + if (numSigners != numTransmitters) revert InvalidConfig("oracle addresses out of registration"); + if (numSigners <= 3 * f) revert InvalidConfig("faulty-oracle f too high"); _; } @@ -145,7 +146,8 @@ abstract contract OCR2Base is ConfirmedOwner, OCR2Abstract { s_transmitters.pop(); } - for (uint256 i = 0; i < args.signers.length; ++i) { + // Bounded by MAX_NUM_ORACLES in OCR2Abstract.sol + for (uint256 i = 0; i < args.signers.length; i++) { // add new signer/transmitter addresses require(s_oracles[args.signers[i]].role == Role.Unset, "repeated signer address"); s_oracles[args.signers[i]] = Oracle(uint8(i), Role.Signer); @@ -173,7 +175,7 @@ abstract contract OCR2Base is ConfirmedOwner, OCR2Abstract { } s_configInfo.n = uint8(args.signers.length); - emit OCRConfigSet( + emit ConfigSet( previousConfigBlockNumber, s_configInfo.latestConfigDigest, s_configCount, @@ -184,8 +186,6 @@ abstract contract OCR2Base is ConfirmedOwner, OCR2Abstract { args.offchainConfigVersion, args.offchainConfig ); - - _afterSetConfig(args.f, args.onchainConfig); } function configDigestFromConfigData( @@ -244,20 +244,6 @@ abstract contract OCR2Base is ConfirmedOwner, OCR2Abstract { function _beforeSetConfig(uint8 _f, bytes memory _onchainConfig) internal virtual; - function _afterSetConfig(uint8 _f, bytes memory _onchainConfig) internal virtual; - - /** - * @dev hook to allow additional validation of the report by the extending contract - * @param configDigest separation tag for current config (see configDigestFromConfigData) - * @param epochAndRound 27 byte padding, 4-byte epoch and 1-byte round - * @param report serialized report - */ - function _validateReport( - bytes32 configDigest, - uint40 epochAndRound, - bytes memory report - ) internal virtual returns (bool); - /** * @dev hook called after the report has been fully validated * for the extending contract to handle additional logic, such as oracle payment @@ -270,7 +256,7 @@ abstract contract OCR2Base is ConfirmedOwner, OCR2Abstract { uint256 initialGas, address transmitter, uint8 signerCount, - address[maxNumOracles] memory signers, + address[MAX_NUM_ORACLES] memory signers, bytes calldata report ) internal virtual; @@ -332,10 +318,6 @@ abstract contract OCR2Base is ConfirmedOwner, OCR2Abstract { bytes32 configDigest = reportContext[0]; uint32 epochAndRound = uint32(uint256(reportContext[1])); - if (!_validateReport(configDigest, epochAndRound, report)) { - revert ReportInvalid(); - } - emit Transmitted(configDigest, uint32(epochAndRound >> 8)); ConfigInfo memory configInfo = s_configInfo; @@ -360,7 +342,7 @@ abstract contract OCR2Base is ConfirmedOwner, OCR2Abstract { ); } - address[maxNumOracles] memory signed; + address[MAX_NUM_ORACLES] memory signed; uint8 signerCount = 0; { @@ -368,6 +350,7 @@ abstract contract OCR2Base is ConfirmedOwner, OCR2Abstract { bytes32 h = keccak256(abi.encodePacked(keccak256(report), reportContext)); Oracle memory o; + // Bounded by MAX_NUM_ORACLES in OCR2Abstract.sol for (uint256 i = 0; i < rs.length; ++i) { address signer = ecrecover(h, uint8(rawVs[i]) + 27, rs[i], ss[i]); o = s_oracles[signer]; diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/AuthorizedOriginReceiverUpgradeable.sol b/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/AuthorizedOriginReceiverUpgradeable.sol index fe26965d729..4c963e46c86 100644 --- a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/AuthorizedOriginReceiverUpgradeable.sol +++ b/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/AuthorizedOriginReceiverUpgradeable.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; -import {EnumerableSet} from "../../../../../shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/utils/structs/EnumerableSet.sol"; -import {Initializable} from "../../../../../shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; +import {EnumerableSet} from "../../../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/structs/EnumerableSet.sol"; +import {Initializable} from "../../../../../vendor/openzeppelin-contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; import {AuthorizedOriginReceiverInterface} from "./AuthorizedOriginReceiverInterface.sol"; /** diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/AuthorizedReceiver.sol b/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/AuthorizedReceiver.sol index 27df650b8af..52078ff6447 100644 --- a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/AuthorizedReceiver.sol +++ b/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/AuthorizedReceiver.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; -import {EnumerableSet} from "../../../../../shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/utils/structs/EnumerableSet.sol"; +import {EnumerableSet} from "../../../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/structs/EnumerableSet.sol"; import {AuthorizedReceiverInterface} from "./AuthorizedReceiverInterface.sol"; abstract contract AuthorizedReceiver is AuthorizedReceiverInterface { diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/ConfirmedOwnerUpgradeable.sol b/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/ConfirmedOwnerUpgradeable.sol index a03e2b583de..ebe2e4c14f7 100644 --- a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/ConfirmedOwnerUpgradeable.sol +++ b/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/ConfirmedOwnerUpgradeable.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; -import {OwnableInterface} from "../../../../../interfaces/OwnableInterface.sol"; -import {Initializable} from "../../../../../shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; +import {IOwnable} from "../../../../../shared/interfaces/IOwnable.sol"; +import {Initializable} from "../../../../../vendor/openzeppelin-contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; /** * @title The ConfirmedOwnerUpgradeable contract * @notice An upgrade compatible contract with helpers for basic contract ownership. */ -contract ConfirmedOwnerUpgradeable is Initializable, OwnableInterface { +contract ConfirmedOwnerUpgradeable is Initializable, IOwnable { address private s_owner; address private s_pendingOwner; diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsBillingRegistryMigration.sol b/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsBillingRegistryMigration.sol index a3b31e6c35e..f9e6649d026 100644 --- a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsBillingRegistryMigration.sol +++ b/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsBillingRegistryMigration.sol @@ -1,19 +1,19 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; -import {LinkTokenInterface} from "../../../../../interfaces/LinkTokenInterface.sol"; +import {LinkTokenInterface} from "../../../../../shared/interfaces/LinkTokenInterface.sol"; import {AggregatorV3Interface} from "../../../../../interfaces/AggregatorV3Interface.sol"; import {FunctionsBillingRegistryInterface} from "./FunctionsBillingRegistryInterface.sol"; import {FunctionsOracleInterface} from "./FunctionsOracleInterface.sol"; import {FunctionsClientInterface} from "./FunctionsClientInterface.sol"; import {TypeAndVersionInterface} from "../../../../../interfaces/TypeAndVersionInterface.sol"; -import {ERC677ReceiverInterface} from "../../../../../interfaces/ERC677ReceiverInterface.sol"; +import {IERC677Receiver} from "../../../../../shared/interfaces/IERC677Receiver.sol"; import {AuthorizedOriginReceiverInterface} from "./AuthorizedOriginReceiverInterface.sol"; import {ConfirmedOwnerUpgradeable} from "./ConfirmedOwnerUpgradeable.sol"; import {AuthorizedReceiver} from "./AuthorizedReceiver.sol"; -import {SafeCast} from "../../../../../shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/utils/SafeCast.sol"; -import {PausableUpgradeable} from "../../../../../shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/security/PausableUpgradeable.sol"; -import {Initializable} from "../../../../../shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; +import {SafeCast} from "../../../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/SafeCast.sol"; +import {PausableUpgradeable} from "../../../../../vendor/openzeppelin-contracts-upgradeable/v4.8.1/security/PausableUpgradeable.sol"; +import {Initializable} from "../../../../../vendor/openzeppelin-contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; /** * @title Functions Billing Registry contract @@ -25,7 +25,7 @@ contract FunctionsBillingRegistryMigration is ConfirmedOwnerUpgradeable, PausableUpgradeable, FunctionsBillingRegistryInterface, - ERC677ReceiverInterface, + IERC677Receiver, AuthorizedReceiver { LinkTokenInterface public LINK; diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsBillingRegistryOriginal.sol b/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsBillingRegistryOriginal.sol index 54bef1d0a66..39bff270401 100644 --- a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsBillingRegistryOriginal.sol +++ b/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsBillingRegistryOriginal.sol @@ -1,19 +1,19 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; -import {LinkTokenInterface} from "../../../../../interfaces/LinkTokenInterface.sol"; +import {LinkTokenInterface} from "../../../../../shared/interfaces/LinkTokenInterface.sol"; import {AggregatorV3Interface} from "../../../../../interfaces/AggregatorV3Interface.sol"; import {FunctionsOracleInterface} from "./FunctionsOracleInterface.sol"; import {FunctionsBillingRegistryInterface} from "./FunctionsBillingRegistryInterface.sol"; import {FunctionsClientInterface} from "./FunctionsClientInterface.sol"; import {TypeAndVersionInterface} from "../../../../../interfaces/TypeAndVersionInterface.sol"; -import {ERC677ReceiverInterface} from "../../../../../interfaces/ERC677ReceiverInterface.sol"; +import {IERC677Receiver} from "../../../../../shared/interfaces/IERC677Receiver.sol"; import {AuthorizedOriginReceiverInterface} from "./AuthorizedOriginReceiverInterface.sol"; import {ConfirmedOwnerUpgradeable} from "./ConfirmedOwnerUpgradeable.sol"; import {AuthorizedReceiver} from "./AuthorizedReceiver.sol"; -import {SafeCast} from "../../../../../shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/utils/SafeCast.sol"; -import {PausableUpgradeable} from "../../../../../shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/security/PausableUpgradeable.sol"; -import {Initializable} from "../../../../../shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; +import {SafeCast} from "../../../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/SafeCast.sol"; +import {PausableUpgradeable} from "../../../../../vendor/openzeppelin-contracts-upgradeable/v4.8.1/security/PausableUpgradeable.sol"; +import {Initializable} from "../../../../../vendor/openzeppelin-contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; /** * @title Functions Billing Registry contract @@ -25,7 +25,7 @@ contract FunctionsBillingRegistryOriginal is ConfirmedOwnerUpgradeable, PausableUpgradeable, FunctionsBillingRegistryInterface, - ERC677ReceiverInterface, + IERC677Receiver, AuthorizedReceiver { LinkTokenInterface public LINK; diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsOracleMigration.sol b/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsOracleMigration.sol index 0c3c85a4330..ccc65007842 100644 --- a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsOracleMigration.sol +++ b/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsOracleMigration.sol @@ -5,7 +5,7 @@ import {FunctionsOracleInterface} from "./FunctionsOracleInterface.sol"; import {FunctionsBillingRegistryInterface} from "./FunctionsBillingRegistryInterface.sol"; import {OCR2BaseUpgradeable} from "./OCR2BaseUpgradeable.sol"; import {AuthorizedOriginReceiverUpgradeable} from "./AuthorizedOriginReceiverUpgradeable.sol"; -import {Initializable} from "../../../../../shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; +import {Initializable} from "../../../../../vendor/openzeppelin-contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; /** * @title Functions Oracle contract diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsOracleOriginal.sol b/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsOracleOriginal.sol index 0b0417ca18b..0ff5ad1b6cc 100644 --- a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsOracleOriginal.sol +++ b/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsOracleOriginal.sol @@ -5,7 +5,7 @@ import {FunctionsOracleInterface} from "./FunctionsOracleInterface.sol"; import {FunctionsBillingRegistryInterface} from "./FunctionsBillingRegistryInterface.sol"; import {OCR2BaseUpgradeable} from "./OCR2BaseUpgradeable.sol"; import {AuthorizedOriginReceiverUpgradeable} from "./AuthorizedOriginReceiverUpgradeable.sol"; -import {Initializable} from "../../../../../shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; +import {Initializable} from "../../../../../vendor/openzeppelin-contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; /** * @title Functions Oracle contract diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/OCR2BaseUpgradeable.sol b/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/OCR2BaseUpgradeable.sol index e852740deb0..b768d716583 100644 --- a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/OCR2BaseUpgradeable.sol +++ b/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/OCR2BaseUpgradeable.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import {ConfirmedOwnerUpgradeable} from "./ConfirmedOwnerUpgradeable.sol"; import {OCR2Abstract} from "./OCR2Abstract.sol"; -import {Initializable} from "../../../../../shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; +import {Initializable} from "../../../../../vendor/openzeppelin-contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol"; /** * @notice Onchain verification of reports from the offchain reporting protocol diff --git a/contracts/src/v0.8/functions/tests/1_0_0/BaseTest.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/BaseTest.t.sol index 51faad52666..13994f88f71 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/BaseTest.t.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/BaseTest.t.sol @@ -4,14 +4,18 @@ import {Test} from "forge-std/Test.sol"; contract BaseTest is Test { bool private s_baseTestInitialized; - address internal constant OWNER = 0x00007e64E1fB0C487F25dd6D3601ff6aF8d32e4e; + + uint256 internal OWNER_PRIVATE_KEY = 0x1; + address internal OWNER_ADDRESS = vm.addr(OWNER_PRIVATE_KEY); + + uint256 internal STRANGER_PRIVATE_KEY = 0x2; + address internal STRANGER_ADDRESS = vm.addr(STRANGER_PRIVATE_KEY); function setUp() public virtual { // BaseTest.setUp is often called multiple times from tests' setUp due to inheritance. if (s_baseTestInitialized) return; s_baseTestInitialized = true; - - // Set msg.sender to OWNER until changePrank or stopPrank is called - vm.startPrank(OWNER); + // Set msg.sender to OWNER until stopPrank is called + vm.startPrank(OWNER_ADDRESS); } } diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsClient.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsClient.t.sol new file mode 100644 index 00000000000..b2740b7e297 --- /dev/null +++ b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsClient.t.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +/// @notice #constructor +contract FunctionsClient_Constructor { + +} + +/// @notice #_sendRequest +contract FunctionsClient__SendRequest { + +} + +/// @notice #fulfillRequest +contract FunctionsClient_FulfillRequest { + +} + +/// @notice #handleOracleFulfillment +contract FunctionsClient_HandleOracleFulfillment { + +} diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsCoordinator.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsCoordinator.t.sol new file mode 100644 index 00000000000..c6d560fffc6 --- /dev/null +++ b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsCoordinator.t.sol @@ -0,0 +1,219 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// ================================================================ +// | Functions Coordinator | +// ================================================================ + +/// @notice #constructor +contract FunctionsCoordinator_Constructor { + +} + +/// @notice #getThresholdPublicKey +contract FunctionsCoordinator_GetThresholdPublicKey { + +} + +/// @notice #setThresholdPublicKey +contract FunctionsCoordinator_SetThresholdPublicKey { + +} + +/// @notice #getDONPublicKey +contract FunctionsCoordinator_GetDONPublicKey { + +} + +/// @notice #setDONPublicKey +contract FunctionsCoordinator__SetDONPublicKey { + +} + +/// @notice #_isTransmitter +contract FunctionsCoordinator_IsTransmitter { + +} + +/// @notice #setNodePublicKey +contract FunctionsCoordinator_SetNodePublicKey { + +} + +/// @notice #deleteNodePublicKey +contract FunctionsCoordinator_DeleteNodePublicKey { + +} + +/// @notice #getAllNodePublicKeys +contract FunctionsCoordinator_GetAllNodePublicKeys { + +} + +/// @notice #startRequest +contract FunctionsCoordinator_StartRequest { + +} + +/// @notice #_beforeSetConfig +contract FunctionsCoordinator__BeforeSetConfig { + +} + +/// @notice #_getTransmitters +contract FunctionsCoordinator__GetTransmitters { + +} + +/// @notice #_report +contract FunctionsCoordinator__Report { + +} + +/// @notice #_onlyOwner +contract FunctionsCoordinator__OnlyOwner { + +} + +// ================================================================ +// | Functions Billing | +// ================================================================ + +/// @notice #constructor +contract FunctionsBilling_Constructor { + +} + +/// @notice #getConfig +contract FunctionsBilling_GetConfig { + +} + +/// @notice #updateConfig +contract FunctionsBilling_UpdateConfig { + +} + +/// @notice #getDONFee +contract FunctionsBilling_GetDONFee { + +} + +/// @notice #getAdminFee +contract FunctionsBilling_GetAdminFee { + +} + +/// @notice #getWeiPerUnitLink +contract FunctionsBilling_GetWeiPerUnitLink { + +} + +/// @notice #_getJuelsPerGas +contract FunctionsBilling__GetJuelsPerGas { + +} + +/// @notice #estimateCost +contract FunctionsBilling_EstimateCost { + +} + +/// @notice #_calculateCostEstimate +contract FunctionsBilling__CalculateCostEstimate { + +} + +/// @notice #_startBilling +contract FunctionsBilling__StartBilling { + +} + +/// @notice #_computeRequestId +contract FunctionsBilling__ComputeRequestId { + +} + +/// @notice #_fulfillAndBill +contract FunctionsBilling__FulfillAndBill { + +} + +/// @notice #deleteCommitment +contract FunctionsBilling_DeleteCommitment { + +} + +/// @notice #oracleWithdraw +contract FunctionsBilling_OracleWithdraw { + +} + +/// @notice #oracleWithdrawAll +contract FunctionsBilling_OracleWithdrawAll { + +} + +/// @notice #_getTransmitters +contract FunctionsBilling__GetTransmitters { + +} + +/// @notice #_disperseFeePool +contract FunctionsBilling__DisperseFeePool { + +} + +// ================================================================ +// | OCR2Base | +// ================================================================ + +/// @notice #constructor +contract OCR2Base_Constructor { + +} + +/// @notice #checkConfigValid +contract OCR2Base_CheckConfigValid { + +} + +/// @notice #latestConfigDigestAndEpoch +contract OCR2Base_LatestConfigDigestAndEpoch { + +} + +/// @notice #setConfig +contract OCR2Base_SetConfig { + +} + +/// @notice #configDigestFromConfigData +contract OCR2Base_ConfigDigestFromConfigData { + +} + +/// @notice #latestConfigDetails +contract OCR2Base_LatestConfigDetails { + +} + +/// @notice #transmitters +contract OCR2Base_Transmitters { + +} + +/// @notice #_report +contract OCR2Base__Report { + +} + +/// @notice #requireExpectedMsgDataLength +contract OCR2Base_RequireExpectedMsgDataLength { + +} + +/// @notice #transmit +contract OCR2Base_Transmit { + +} diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRequest.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRequest.t.sol new file mode 100644 index 00000000000..a274bbe8cfc --- /dev/null +++ b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRequest.t.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +/// @notice #REQUEST_DATA_VERSION +contract FunctionsRequest_REQUEST_DATA_VERSION { + +} + +/// @notice #DEFAULT_BUFFER_SIZE +contract FunctionsRequest_DEFAULT_BUFFER_SIZE { + +} + +/// @notice #encodeCBOR +contract FunctionsRequest_EncodeCBOR { + +} + +/// @notice #initializeRequest +contract FunctionsRequest_InitializeRequest { + +} + +/// @notice #initializeRequestForInlineJavaScript +contract FunctionsRequest_InitializeRequestForInlineJavaScript { + +} + +/// @notice #addSecretsReference +contract FunctionsRequest_AddSecretsReference { + +} + +/// @notice #addDONHostedSecrets +contract FunctionsRequest_AddDONHostedSecrets { + +} + +/// @notice #setArgs +contract FunctionsRequest_SetArgs { + +} + +/// @notice #setBytesArgs +contract FunctionsRequest_SetBytesArgs { + +} diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol new file mode 100644 index 00000000000..649c06f9eed --- /dev/null +++ b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {FunctionsRouter} from "../../dev/1_0_0/FunctionsRouter.sol"; +import {FunctionsSubscriptions} from "../../dev/1_0_0/FunctionsSubscriptions.sol"; + +import {FunctionsRouterSetup, FunctionsOwnerAcceptTermsOfService} from "./Setup.t.sol"; + +// ================================================================ +// | Functions Router | +// ================================================================ + +/// @notice #constructor +contract FunctionsRouter_Constructor { + +} + +/// @notice #getConfig +contract FunctionsRouter_GetConfig { + +} + +/// @notice #updateConfig +contract FunctionsRouter_UpdateConfig { + +} + +/// @notice #isValidCallbackGasLimit +contract FunctionsRouter_IsValidCallbackGasLimit { + +} + +/// @notice #getAdminFee +contract FunctionsRouter_GetAdminFee { + +} + +/// @notice #getAllowListId +contract FunctionsRouter_GetAllowListId { + +} + +/// @notice #setAllowListId +contract FunctionsRouter_SetAllowListId { + +} + +/// @notice #_getMaxConsumers +contract FunctionsRouter__GetMaxConsumers { + +} + +/// @notice #sendRequest +contract FunctionsRouter_SendRequest { + +} + +/// @notice #sendRequestToProposed +contract FunctionsRouter_SendRequestToProposed { + +} + +/// @notice #_sendRequest +contract FunctionsRouter__SendRequest { + +} + +/// @notice #fulfill +contract FunctionsRouter_Fulfill { + +} + +/// @notice #_callback +contract FunctionsRouter__Callback { + +} + +/// @notice #getContractById +contract FunctionsRouter_GetContractById { + +} + +/// @notice #getProposedContractById +contract FunctionsRouter_GetProposedContractById { + +} + +/// @notice #getProposedContractSet +contract FunctionsRouter_GetProposedContractSet { + +} + +/// @notice #proposeContractsUpdate +contract FunctionsRouter_ProposeContractsUpdate { + +} + +/// @notice #updateContracts +contract FunctionsRouter_UpdateContracts { + +} + +/// @notice #_whenNotPaused +contract FunctionsRouter__WhenNotPaused { + +} + +/// @notice #_onlyRouterOwner +contract FunctionsRouter__OnlyRouterOwner { + +} + +/// @notice #_onlySenderThatAcceptedToS +contract FunctionsRouter__OnlySenderThatAcceptedToS { + +} + +/// @notice #pause +contract FunctionsRouter_Pause is FunctionsRouterSetup { + function setUp() public virtual override { + FunctionsRouterSetup.setUp(); + } + + event Paused(address account); + + function test_Pause_RevertIfNotOwner() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + vm.expectRevert("Only callable by owner"); + s_functionsRouter.pause(); + } + + function test_Pause_Success() public { + // topic0 (always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + vm.expectEmit(false, false, false, true); + emit Paused(OWNER_ADDRESS); + + s_functionsRouter.pause(); + + bool isPaused = s_functionsRouter.paused(); + assertEq(isPaused, true); + + vm.expectRevert("Pausable: paused"); + s_functionsRouter.createSubscription(); + } +} + +/// @notice #unpause +contract FunctionsRouter_Unpause is FunctionsRouterSetup { + function setUp() public virtual override { + FunctionsRouterSetup.setUp(); + s_functionsRouter.pause(); + } + + event Unpaused(address account); + + function test_Unpause_RevertIfNotOwner() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + vm.expectRevert("Only callable by owner"); + s_functionsRouter.unpause(); + } + + function test_Unpause_Success() public { + // topic0 (always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true). + vm.expectEmit(false, false, false, true); + emit Unpaused(OWNER_ADDRESS); + + s_functionsRouter.unpause(); + + bool isPaused = s_functionsRouter.paused(); + assertEq(isPaused, false); + + s_functionsRouter.createSubscription(); + } +} diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsSubscriptions.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsSubscriptions.t.sol new file mode 100644 index 00000000000..ab77a33691d --- /dev/null +++ b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsSubscriptions.t.sol @@ -0,0 +1,188 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {FunctionsRouter} from "../../dev/1_0_0/FunctionsRouter.sol"; +import {FunctionsSubscriptions} from "../../dev/1_0_0/FunctionsSubscriptions.sol"; + +import {FunctionsRouterSetup, FunctionsOwnerAcceptTermsOfService} from "./Setup.t.sol"; + +// ================================================================ +// | Functions Subscriptions | +// ================================================================ + +/// @notice #constructor +contract FunctionsSubscriptions_Constructor { + +} + +/// @notice #_markRequestInFlight +contract FunctionsSubscriptions__MarkRequestInFlight { + +} + +/// @notice #_pay +contract FunctionsSubscriptions__Pay { + +} + +/// @notice #ownerCancelSubscription +contract FunctionsSubscriptions_OwnerCancelSubscription { + +} + +/// @notice #recoverFunds +contract FunctionsSubscriptions_RecoverFunds { + +} + +/// @notice #oracleWithdraw +contract FunctionsSubscriptions_OracleWithdraw { + +} + +/// @notice #ownerWithdraw +contract FunctionsSubscriptions_OwnerWithdraw { + +} + +/// @notice #onTokenTransfer +contract FunctionsSubscriptions_OnTokenTransfer { + +} + +/// @notice #getTotalBalance +contract FunctionsSubscriptions_GetTotalBalance { + +} + +/// @notice #getSubscriptionCount +contract FunctionsSubscriptions_GetSubscriptionCount { + +} + +/// @notice #getSubscription +contract FunctionsSubscriptions_GetSubscription { + +} + +/// @notice #getConsumer +contract FunctionsSubscriptions_GetConsumer { + +} + +/// @notice #_isExistingSubscription +contract FunctionsSubscriptions__IsExistingSubscription { + +} + +/// @notice #_isAllowedConsumer +contract FunctionsSubscriptions__IsAllowedConsumer { + +} + +/// @notice #createSubscription +contract FunctionsSubscriptions_createSubscription is FunctionsOwnerAcceptTermsOfService { + function setUp() public virtual override { + FunctionsOwnerAcceptTermsOfService.setUp(); + } + + event SubscriptionCreated(uint64 indexed subscriptionId, address owner); + + function test_CreateSubscription_Success() public { + vm.expectEmit(true, false, false, true); + emit SubscriptionCreated(1, OWNER_ADDRESS); + uint64 firstCallSubscriptionId = s_functionsRouter.createSubscription(); + assertEq(firstCallSubscriptionId, 1); + + vm.expectEmit(true, false, false, true); + emit SubscriptionCreated(2, OWNER_ADDRESS); + uint64 secondCallSubscriptionId = s_functionsRouter.createSubscription(); + assertEq(secondCallSubscriptionId, 2); + + vm.expectEmit(true, false, false, true); + emit SubscriptionCreated(3, OWNER_ADDRESS); + uint64 thirdCallSubscriptionId = s_functionsRouter.createSubscription(); + assertEq(thirdCallSubscriptionId, 3); + } + + function test_CreateSubscription_RevertIfPaused() public { + s_functionsRouter.pause(); + + vm.expectRevert("Pausable: paused"); + s_functionsRouter.createSubscription(); + } + + function test_CreateSubscription_RevertIfNotAllowedSender() public { + // Send as stranger, who has not accepted Terms of Service + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.SenderMustAcceptTermsOfService.selector, STRANGER_ADDRESS)); + s_functionsRouter.createSubscription(); + } +} + +/// @notice #createSubscriptionWithConsumer +contract FunctionsSubscriptions_CreateSubscriptionWithConsumer { + +} + +/// @notice #proposeSubscriptionOwnerTransfer +contract FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer { + +} + +/// @notice #acceptSubscriptionOwnerTransfer +contract FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer { + +} + +/// @notice #removeConsumer +contract FunctionsSubscriptions_RemoveConsumer { + +} + +/// @notice #_getMaxConsumers +contract FunctionsSubscriptions__GetMaxConsumers { + +} + +/// @notice #addConsumer +contract FunctionsSubscriptions_AddConsumer { + +} + +/// @notice #cancelSubscription +contract FunctionsSubscriptions_CancelSubscription { + +} + +/// @notice #_cancelSubscriptionHelper +contract FunctionsSubscriptions__CancelSubscriptionHelper { + +} + +/// @notice #pendingRequestExists +contract FunctionsSubscriptions_PendingRequestExists { + +} + +/// @notice #setFlags +contract FunctionsSubscriptions_SetFlags { + +} + +/// @notice #getFlags +contract FunctionsSubscriptions_GetFlags { + +} + +/// @notice #timeoutRequests +contract FunctionsSubscriptions_TimeoutRequests { + +} + +/// @notice #_onlySubscriptionOwner +contract FunctionsSubscriptions__OnlySubscriptionOwner { + +} diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsTermsOfServiceAllowList.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsTermsOfServiceAllowList.t.sol new file mode 100644 index 00000000000..af6fa6dcca5 --- /dev/null +++ b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsTermsOfServiceAllowList.t.sol @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +/// @notice #constructor +contract FunctionsTermsOfServiceAllowList_Constructor { + +} + +/// @notice #getConfig +contract FunctionsTermsOfServiceAllowList_GetConfig { + +} + +/// @notice #updateConfig +contract FunctionsTermsOfServiceAllowList_UpdateConfig { + +} + +/// @notice #getMessage +contract FunctionsTermsOfServiceAllowList_GetMessage { + +} + +/// @notice #acceptTermsOfService +contract FunctionsTermsOfServiceAllowList_AcceptTermsOfService { + +} + +/// @notice #getAllAllowedSenders +contract FunctionsTermsOfServiceAllowList_GetAllAllowedSenders { + +} + +/// @notice #hasAccess +contract FunctionsTermsOfServiceAllowList_HasAccess { + +} + +/// @notice #isBlockedSender +contract FunctionsTermsOfServiceAllowList_IsBlockedSender { + +} + +/// @notice #blockSender +contract FunctionsTermsOfServiceAllowList_BlockSender { + +} + +/// @notice #unblockSender +contract FunctionsTermsOfServiceAllowList_UnblockSender { + +} diff --git a/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol new file mode 100644 index 00000000000..56addcabd79 --- /dev/null +++ b/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {BaseTest} from "./BaseTest.t.sol"; +import {FunctionsRouter} from "../../dev/1_0_0/FunctionsRouter.sol"; +import {FunctionsCoordinator} from "../../dev/1_0_0/FunctionsCoordinator.sol"; +import {FunctionsBilling} from "../../dev/1_0_0/FunctionsBilling.sol"; +import {MockV3Aggregator} from "../../../tests/MockV3Aggregator.sol"; +import {TermsOfServiceAllowList} from "../../dev/1_0_0/accessControl/TermsOfServiceAllowList.sol"; + +contract FunctionsRouterSetup is BaseTest { + FunctionsRouter internal s_functionsRouter; + FunctionsCoordinator internal s_functionsCoordinator; + MockV3Aggregator internal s_linkEthFeed; + TermsOfServiceAllowList internal s_termsOfServiceAllowList; + + uint16 internal s_maxConsumersPerSubscription = 100; + uint72 internal s_adminFee = 100; + bytes4 internal s_handleOracleFulfillmentSelector = 0x0ca76175; + + address internal s_linkToken = 0x01BE23585060835E02B77ef475b0Cc51aA1e0709; + + int256 internal LINK_ETH_RATE = 6000000000000000; + + uint256 internal TOS_SIGNER_PRIVATE_KEY = 0x3; + address internal TOS_SIGNER = vm.addr(TOS_SIGNER_PRIVATE_KEY); + + function setUp() public virtual override { + BaseTest.setUp(); + s_functionsRouter = new FunctionsRouter(s_linkToken, getRouterConfig()); + s_linkEthFeed = new MockV3Aggregator(0, LINK_ETH_RATE); + s_functionsCoordinator = new FunctionsCoordinator( + address(s_functionsRouter), + getCoordinatorConfig(), + address(s_linkEthFeed) + ); + s_termsOfServiceAllowList = new TermsOfServiceAllowList(getTermsOfServiceConfig()); + } + + function getRouterConfig() public view returns (FunctionsRouter.Config memory) { + uint32[] memory maxCallbackGasLimits = new uint32[](3); + maxCallbackGasLimits[0] = 300_000; + maxCallbackGasLimits[1] = 500_000; + maxCallbackGasLimits[2] = 1_000_000; + + return + FunctionsRouter.Config({ + maxConsumersPerSubscription: s_maxConsumersPerSubscription, + adminFee: s_adminFee, + handleOracleFulfillmentSelector: s_handleOracleFulfillmentSelector, + maxCallbackGasLimits: maxCallbackGasLimits, + gasForCallExactCheck: 5000 + }); + } + + function getCoordinatorConfig() public pure returns (FunctionsBilling.Config memory) { + return + FunctionsBilling.Config({ + maxCallbackGasLimit: 0, // NOTE: unused , TODO: remove + feedStalenessSeconds: 24 * 60 * 60, // 1 day + gasOverheadAfterCallback: 44_615, // TODO: update + gasOverheadBeforeCallback: 44_615, // TODO: update + requestTimeoutSeconds: 60 * 5, // 5 minutes + donFee: 100, + maxSupportedRequestDataVersion: 1, + fulfillmentGasPriceOverEstimationBP: 5000, + fallbackNativePerUnitLink: 5000000000000000 + }); + } + + function getTermsOfServiceConfig() public view returns (TermsOfServiceAllowList.Config memory) { + return TermsOfServiceAllowList.Config({enabled: true, signerPublicKey: TOS_SIGNER}); + } +} + +contract FunctionsSetupRoutes is FunctionsRouterSetup { + function setUp() public virtual override { + FunctionsRouterSetup.setUp(); + + bytes32 allowListId = s_functionsRouter.getAllowListId(); + bytes32[] memory proposedContractSetIds = new bytes32[](2); + proposedContractSetIds[0] = bytes32("1"); + proposedContractSetIds[1] = allowListId; + address[] memory proposedContractSetAddresses = new address[](2); + proposedContractSetAddresses[0] = address(s_functionsCoordinator); + proposedContractSetAddresses[1] = address(s_termsOfServiceAllowList); + + s_functionsRouter.proposeContractsUpdate(proposedContractSetIds, proposedContractSetAddresses); + s_functionsRouter.updateContracts(); + } +} + +contract FunctionsOwnerAcceptTermsOfService is FunctionsSetupRoutes { + function setUp() public virtual override { + FunctionsSetupRoutes.setUp(); + + bytes32 message = s_termsOfServiceAllowList.getMessage(OWNER_ADDRESS, OWNER_ADDRESS); + bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage); + s_termsOfServiceAllowList.acceptTermsOfService(OWNER_ADDRESS, OWNER_ADDRESS, r, s, v); + } +} diff --git a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsClientTestHelper.sol b/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsClientTestHelper.sol index ceaff7b4c19..92255e0b572 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsClientTestHelper.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsClientTestHelper.sol @@ -1,29 +1,38 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; -import {FunctionsClient, Functions} from "../../../dev/1_0_0/FunctionsClient.sol"; import {ITermsOfServiceAllowList} from "../../../dev/1_0_0/accessControl/interfaces/ITermsOfServiceAllowList.sol"; +import {IFunctionsSubscriptions} from "../../../dev/1_0_0/interfaces/IFunctionsSubscriptions.sol"; + +import {FunctionsRequest} from "../../../dev/1_0_0/libraries/FunctionsRequest.sol"; +import {FunctionsClient} from "../../../dev/1_0_0/FunctionsClient.sol"; contract FunctionsClientTestHelper is FunctionsClient { - using Functions for Functions.Request; + using FunctionsRequest for FunctionsRequest.Request; event SendRequestInvoked(bytes32 requestId, string sourceCode, uint64 subscriptionId); event FulfillRequestInvoked(bytes32 requestId, bytes response, bytes err); bool private s_revertFulfillRequest; bool private s_doInvalidOperation; + bool private s_doInvalidReentrantOperation; + bool private s_doValidReentrantOperation; + + uint64 private s_subscriptionId; + bytes32 private s_donId; constructor(address router) FunctionsClient(router) {} function sendSimpleRequestWithJavaScript( string memory sourceCode, uint64 subscriptionId, - bytes32 donId + bytes32 donId, + uint32 callbackGasLimit ) public returns (bytes32 requestId) { - Functions.Request memory request; - uint32 callbackGasLimit = 20_000; + FunctionsRequest.Request memory request; request.initializeRequestForInlineJavaScript(sourceCode); - requestId = _sendRequest(request, subscriptionId, callbackGasLimit, donId); + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + requestId = _sendRequest(requestData, subscriptionId, callbackGasLimit, donId); emit SendRequestInvoked(requestId, sourceCode, subscriptionId); } @@ -32,24 +41,29 @@ contract FunctionsClientTestHelper is FunctionsClient { uint64 subscriptionId, bytes32 donId ) public returns (bytes32 requestId) { - Functions.Request memory request; + FunctionsRequest.Request memory request; uint32 callbackGasLimit = 20_000; request.initializeRequestForInlineJavaScript(sourceCode); - bytes memory requestData = Functions.encodeCBOR(request); - requestId = bytes32( - s_router.validateProposedContracts( - donId, - abi.encode(subscriptionId, requestData, Functions.REQUEST_DATA_VERSION, callbackGasLimit) - ) + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + requestId = i_router.sendRequestToProposed( + subscriptionId, + requestData, + FunctionsRequest.REQUEST_DATA_VERSION, + callbackGasLimit, + donId ); emit RequestSent(requestId); emit SendRequestInvoked(requestId, sourceCode, subscriptionId); } - function acceptTermsOfService(address acceptor, address recipient, bytes calldata proof) external { - bytes32 allowListId = s_router.getAllowListId(); - ITermsOfServiceAllowList allowList = ITermsOfServiceAllowList(s_router.getContractById(allowListId)); - allowList.acceptTermsOfService(acceptor, recipient, proof); + function acceptTermsOfService(address acceptor, address recipient, bytes32 r, bytes32 s, uint8 v) external { + bytes32 allowListId = i_router.getAllowListId(); + ITermsOfServiceAllowList allowList = ITermsOfServiceAllowList(i_router.getContractById(allowListId)); + allowList.acceptTermsOfService(acceptor, recipient, r, s, v); + } + + function acceptSubscriptionOwnerTransfer(uint64 subscriptionId) external { + IFunctionsSubscriptions(address(i_router)).acceptSubscriptionOwnerTransfer(subscriptionId); } function fulfillRequest(bytes32 requestId, bytes memory response, bytes memory err) internal override { @@ -61,6 +75,12 @@ contract FunctionsClientTestHelper is FunctionsClient { uint256 y = 0; x = x / y; } + if (s_doValidReentrantOperation) { + sendSimpleRequestWithJavaScript("somedata", s_subscriptionId, s_donId, 20_000); + } + if (s_doInvalidReentrantOperation) { + IFunctionsSubscriptions(address(i_router)).cancelSubscription(s_subscriptionId, msg.sender); + } emit FulfillRequestInvoked(requestId, response, err); } @@ -71,4 +91,15 @@ contract FunctionsClientTestHelper is FunctionsClient { function setDoInvalidOperation(bool on) external { s_doInvalidOperation = on; } + + function setDoInvalidReentrantOperation(bool on, uint64 subscriptionId) external { + s_doInvalidReentrantOperation = on; + s_subscriptionId = subscriptionId; + } + + function setDoValidReentrantOperation(bool on, uint64 subscriptionId, bytes32 donId) external { + s_doValidReentrantOperation = on; + s_subscriptionId = subscriptionId; + s_donId = donId; + } } diff --git a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsClientWithEmptyCallback.sol b/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsClientWithEmptyCallback.sol new file mode 100644 index 00000000000..4878290b6eb --- /dev/null +++ b/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsClientWithEmptyCallback.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.6; + +import {FunctionsRequest} from "../../../dev/1_0_0/libraries/FunctionsRequest.sol"; +import {FunctionsClient} from "../../../dev/1_0_0/FunctionsClient.sol"; + +contract FunctionsClientWithEmptyCallback is FunctionsClient { + using FunctionsRequest for FunctionsRequest.Request; + + event SendRequestInvoked(bytes32 requestId, string sourceCode, uint64 subscriptionId); + event FulfillRequestInvoked(bytes32 requestId, bytes response, bytes err); + + constructor(address router) FunctionsClient(router) {} + + function sendSimpleRequestWithJavaScript( + string memory sourceCode, + uint64 subscriptionId, + bytes32 donId, + uint32 callbackGasLimit + ) public returns (bytes32 requestId) { + FunctionsRequest.Request memory request; + request.initializeRequestForInlineJavaScript(sourceCode); + bytes memory requestData = FunctionsRequest.encodeCBOR(request); + requestId = _sendRequest(requestData, subscriptionId, callbackGasLimit, donId); + emit SendRequestInvoked(requestId, sourceCode, subscriptionId); + } + + function fulfillRequest(bytes32 /*requestId*/, bytes memory /*response*/, bytes memory /*err*/) internal override { + // Do nothing + } +} diff --git a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsCoordinatorTestHelper.sol b/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsCoordinatorTestHelper.sol index 0aa46ee8fcb..0bf7adb7a25 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsCoordinatorTestHelper.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsCoordinatorTestHelper.sol @@ -2,28 +2,23 @@ pragma solidity ^0.8.6; import {FunctionsCoordinator} from "../../../dev/1_0_0/FunctionsCoordinator.sol"; +import {FunctionsBilling} from "../../../dev/1_0_0/FunctionsBilling.sol"; contract FunctionsCoordinatorTestHelper is FunctionsCoordinator { constructor( address router, - bytes memory config, + FunctionsBilling.Config memory config, address linkToNativeFeed ) FunctionsCoordinator(router, config, linkToNativeFeed) {} - function callValidateReport(bytes calldata report) external pure returns (bool isValid) { - bytes32 configDigest; - uint40 epochAndRound; - isValid = _validateReport(configDigest, epochAndRound, report); - } - function callReport(bytes calldata report) external { - address[maxNumOracles] memory signers; + address[MAX_NUM_ORACLES] memory signers; signers[0] = msg.sender; _report(gasleft(), msg.sender, 1, signers, report); } function callReportMultipleSigners(bytes calldata report, address secondSigner) external { - address[maxNumOracles] memory signers; + address[MAX_NUM_ORACLES] memory signers; signers[0] = msg.sender; signers[1] = secondSigner; _report(gasleft(), msg.sender, 2, signers, report); diff --git a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsLoadTestClient.sol b/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsLoadTestClient.sol new file mode 100644 index 00000000000..7aa46e9ba06 --- /dev/null +++ b/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsLoadTestClient.sol @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {FunctionsClient} from "../../../dev/1_0_0/FunctionsClient.sol"; +import {ConfirmedOwner} from "../../../../shared/access/ConfirmedOwner.sol"; +import {FunctionsRequest} from "../../../dev/1_0_0/libraries/FunctionsRequest.sol"; + +/** + * @title Chainlink Functions load test client implementation + */ +contract FunctionsLoadTestClient is FunctionsClient, ConfirmedOwner { + using FunctionsRequest for FunctionsRequest.Request; + + uint32 public constant MAX_CALLBACK_GAS = 70_000; + + bytes32 public s_lastRequestId; + bytes32 public s_lastResponse; + bytes32 public s_lastError; + uint32 public s_lastResponseLength; + uint32 public s_lastErrorLength; + + constructor(address router) FunctionsClient(router) ConfirmedOwner(msg.sender) {} + + /** + * @notice Send a simple request + * @param source JavaScript source code + * @param encryptedSecretsReferences Encrypted secrets payload + * @param args List of arguments accessible from within the source code + * @param subscriptionId Billing ID + */ + function sendRequest( + string calldata source, + bytes calldata encryptedSecretsReferences, + string[] calldata args, + uint64 subscriptionId, + bytes32 jobId + ) external onlyOwner { + FunctionsRequest.Request memory req; + req.initializeRequestForInlineJavaScript(source); + if (encryptedSecretsReferences.length > 0) req.addSecretsReference(encryptedSecretsReferences); + if (args.length > 0) req.setArgs(args); + s_lastRequestId = _sendRequest(req.encodeCBOR(), subscriptionId, MAX_CALLBACK_GAS, jobId); + } + + /** + * @notice Store latest result/error + * @param requestId The request ID, returned by sendRequest() + * @param response Aggregated response from the user code + * @param err Aggregated error from the user code or from the execution pipeline + * Either response or error parameter will be set, but never both + */ + function fulfillRequest(bytes32 requestId, bytes memory response, bytes memory err) internal override { + // Save only the first 32 bytes of response/error to always fit within MAX_CALLBACK_GAS + s_lastRequestId = requestId; + s_lastResponse = bytesToBytes32(response); + s_lastResponseLength = uint32(response.length); + s_lastError = bytesToBytes32(err); + s_lastErrorLength = uint32(err.length); + } + + function bytesToBytes32(bytes memory b) private pure returns (bytes32 out) { + uint256 maxLen = 32; + if (b.length < 32) { + maxLen = b.length; + } + for (uint256 i = 0; i < maxLen; ++i) { + out |= bytes32(b[i]) >> (i * 8); + } + return out; + } +} diff --git a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsTestHelper.sol b/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsTestHelper.sol index 782f3bb4e22..57ae6e0bbad 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsTestHelper.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsTestHelper.sol @@ -1,12 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; -import {Functions} from "../../../dev/1_0_0/Functions.sol"; +import {FunctionsRequest} from "../../../dev/1_0_0/libraries/FunctionsRequest.sol"; contract FunctionsTestHelper { - using Functions for Functions.Request; + using FunctionsRequest for FunctionsRequest.Request; - Functions.Request private s_req; + FunctionsRequest.Request private s_req; event RequestData(bytes data); @@ -15,38 +15,45 @@ contract FunctionsTestHelper { } function initializeRequestForInlineJavaScript(string memory sourceCode) public { - Functions.Request memory r; + FunctionsRequest.Request memory r; r.initializeRequestForInlineJavaScript(sourceCode); storeRequest(r); } function addSecretsReference(bytes memory secrets) public { - Functions.Request memory r = s_req; + FunctionsRequest.Request memory r = s_req; r.addSecretsReference(secrets); storeRequest(r); } function addEmptyArgs() public pure { - Functions.Request memory r; + FunctionsRequest.Request memory r; string[] memory args; - r.addArgs(args); + r.setArgs(args); } function addTwoArgs(string memory arg1, string memory arg2) public { string[] memory args = new string[](2); args[0] = arg1; args[1] = arg2; - Functions.Request memory r = s_req; - r.addArgs(args); + FunctionsRequest.Request memory r = s_req; + r.setArgs(args); storeRequest(r); } - function storeRequest(Functions.Request memory r) private { + function addSignature(bytes memory signature) public { + FunctionsRequest.Request memory r = s_req; + r.requestSignature = signature; + storeRequest(r); + } + + function storeRequest(FunctionsRequest.Request memory r) private { s_req.codeLocation = r.codeLocation; s_req.language = r.language; s_req.source = r.source; s_req.args = r.args; s_req.secretsLocation = r.secretsLocation; s_req.encryptedSecretsReference = r.encryptedSecretsReference; + s_req.requestSignature = r.requestSignature; } } diff --git a/contracts/src/v0.8/interfaces/OwnableInterface.sol b/contracts/src/v0.8/interfaces/OwnableInterface.sol deleted file mode 100644 index a24cbee504c..00000000000 --- a/contracts/src/v0.8/interfaces/OwnableInterface.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -interface OwnableInterface { - function owner() external returns (address); - - function transferOwnership(address recipient) external; - - function acceptOwnership() external; -} diff --git a/contracts/src/v0.8/libraries/ByteUtil.sol b/contracts/src/v0.8/libraries/ByteUtil.sol new file mode 100644 index 00000000000..906fef3fa77 --- /dev/null +++ b/contracts/src/v0.8/libraries/ByteUtil.sol @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.16; + +/* + * @title ByteUtil + * @author Michael Fletcher + * @notice Byte utility functions for efficiently parsing and manipulating packed byte data + */ +library ByteUtil { + // Error message when an offset is out of bounds + error MalformedData(); + + /** + * @dev Reads a uint256 from a position within a byte array. + * @param data Byte array to read from. + * @param offset Position to start reading from. + * @return result The uint256 read from the byte array. + */ + function readUint256(bytes memory data, uint256 offset) internal pure returns (uint256 result) { + //bounds check + if (offset + 32 > data.length) revert MalformedData(); + + assembly { + //load 32 byte word accounting for 32 bit length and offset + result := mload(add(add(data, 32), offset)) + } + } + + /** + * @dev Reads a uint192 from a position within a byte array. + * @param data Byte array to read from. + * @param offset Position to start reading from. + * @return result The uint192 read from the byte array. + */ + function readUint192(bytes memory data, uint256 offset) internal pure returns (uint256 result) { + //bounds check + if (offset + 24 > data.length) revert MalformedData(); + + assembly { + //load 32 byte word accounting for 32 bit length and offset + result := mload(add(add(data, 32), offset)) + //shift the result right 64 bits + result := shr(64, result) + } + } + + /** + * @dev Reads a uint32 from a position within a byte array. + * @param data Byte array to read from. + * @param offset Position to start reading from. + * @return result The uint32 read from the byte array. + */ + function readUint32(bytes memory data, uint256 offset) internal pure returns (uint256 result) { + //bounds check + if (offset + 4 > data.length) revert MalformedData(); + + assembly { + //load 32 byte word accounting for 32 bit length and offset + result := mload(add(add(data, 32), offset)) + //shift the result right 224 bits + result := shr(224, result) + } + } + + /** + * @dev Reads an address from a position within a byte array. + * @param data Byte array to read from. + * @param offset Position to start reading from. + * @return result The uint32 read from the byte array. + */ + function readAddress(bytes memory data, uint256 offset) internal pure returns (address result) { + //bounds check + if (offset + 20 > data.length) revert MalformedData(); + + assembly { + //load 32 byte word accounting for 32 bit length and offset + let word := mload(add(add(data, 32), offset)) + //address is the last 20 bytes of the word, so shift right + result := shr(96, word) + } + } +} diff --git a/contracts/src/v0.8/libraries/Common.sol b/contracts/src/v0.8/libraries/Common.sol new file mode 100644 index 00000000000..2df1e5c94e6 --- /dev/null +++ b/contracts/src/v0.8/libraries/Common.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.16; + +/* + * @title Common + * @author Michael Fletcher + * @notice Common functions and structs + */ +library Common { + // @notice The asset struct to hold the address of an asset and amount + struct Asset { + address assetAddress; + uint256 amount; + } + + // @notice Struct to hold the address and its associated weight + struct AddressAndWeight { + address addr; + uint256 weight; + } + + /** + * @notice Checks if an array of AddressAndWeight has duplicate addresses + * @param recipients The array of AddressAndWeight to check + * @return bool True if there are duplicates, false otherwise + */ + function hasDuplicateAddresses(Common.AddressAndWeight[] memory recipients) internal pure returns (bool) { + for (uint256 i = 0; i < recipients.length; ) { + for (uint256 j = i + 1; j < recipients.length; ) { + if (recipients[i].addr == recipients[j].addr) { + return true; + } + unchecked { + ++j; + } + } + unchecked { + ++i; + } + } + return false; + } +} diff --git a/contracts/src/v0.8/libraries/test/ByteUtilTest.t.sol b/contracts/src/v0.8/libraries/test/ByteUtilTest.t.sol new file mode 100644 index 00000000000..eabae4f5729 --- /dev/null +++ b/contracts/src/v0.8/libraries/test/ByteUtilTest.t.sol @@ -0,0 +1,177 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.16; + +import {Test} from "forge-std/Test.sol"; +import {ByteUtil} from "../ByteUtil.sol"; + +contract ByteUtilTest is Test { + using ByteUtil for bytes; + + bytes internal constant B_512 = + hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000"; + bytes internal constant B_128 = hex"ffffffffffffffffffffffffffffffff"; + bytes internal constant B_16 = hex"ffff"; + bytes internal constant B_EMPTY = new bytes(0); + + bytes4 internal constant MALFORMED_ERROR_SELECTOR = bytes4(keccak256("MalformedData()")); + + function test_readUint256Max() public { + //read the first 32 bytes + uint256 result = B_512.readUint256(0); + + //the result should be the max value of a uint256 + assertEq(result, type(uint256).max); + } + + function test_readUint192Max() public { + //read the first 24 bytes + uint256 result = B_512.readUint192(0); + + //the result should be the max value of a uint192 + assertEq(result, type(uint192).max); + } + + function test_readUint32Max() public { + //read the first 4 bytes + uint256 result = B_512.readUint32(0); + + //the result should be the max value of a uint32 + assertEq(result, type(uint32).max); + } + + function test_readUint256Min() public { + //read the second 32 bytes + uint256 result = B_512.readUint256(32); + + //the result should be the min value of a uint256 + assertEq(result, type(uint256).min); + } + + function test_readUint192Min() public { + //read the second 24 bytes + uint256 result = B_512.readUint192(32); + + //the result should be the min value of a uint192 + assertEq(result, type(uint192).min); + } + + function test_readUint32Min() public { + //read the second 4 bytes + uint256 result = B_512.readUint32(32); + + //the result should be the min value of a uint32 + assertEq(result, type(uint32).min); + } + + function test_readUint256MultiWord() public { + //read the first 32 bytes + uint256 result = B_512.readUint256(31); + + //the result should be the last byte from the first word (ff), and 31 bytes from the second word (0000) (0xFF...0000) + assertEq(result, type(uint256).max << 248); + } + + function test_readUint192MultiWord() public { + //read the first 24 bytes + uint256 result = B_512.readUint192(31); + + //the result should be the last byte from the first word (ff), and 23 bytes from the second word (0000) (0xFF...0000) + assertEq(result, type(uint192).max << 184); + } + + function test_readUint32MultiWord() public { + //read the first 4 bytes + uint256 result = B_512.readUint32(31); + + //the result should be the last byte from the first word (ff), and 3 bytes from the second word (0000) (0xFF...0000) + assertEq(result, type(uint32).max << 24); + } + + function test_readUint256WithNotEnoughBytes() public { + //should revert if there's not enough bytes + vm.expectRevert(MALFORMED_ERROR_SELECTOR); + + //try and read 32 bytes from a 16 byte number + B_128.readUint256(0); + } + + function test_readUint192WithNotEnoughBytes() public { + //should revert if there's not enough bytes + vm.expectRevert(MALFORMED_ERROR_SELECTOR); + + //try and read 24 bytes from a 16 byte number + B_128.readUint192(0); + } + + function test_readUint32WithNotEnoughBytes() public { + //should revert if there's not enough bytes + vm.expectRevert(MALFORMED_ERROR_SELECTOR); + + //try and read 4 bytes from a 2 byte number + B_16.readUint32(0); + } + + function test_readUint256WithEmptyArray() public { + //should revert if there's not enough bytes + vm.expectRevert(MALFORMED_ERROR_SELECTOR); + + //read 20 bytes from an empty array + B_EMPTY.readUint256(0); + } + + function test_readUint192WithEmptyArray() public { + //should revert if there's not enough bytes + vm.expectRevert(MALFORMED_ERROR_SELECTOR); + + //read 20 bytes from an empty array + B_EMPTY.readUint192(0); + } + + function test_readUint32WithEmptyArray() public { + //should revert if there's not enough bytes + vm.expectRevert(MALFORMED_ERROR_SELECTOR); + + //read 20 bytes from an empty array + B_EMPTY.readUint32(0); + } + + function test_readAddress() public { + //read the first 20 bytes + address result = B_512.readAddress(0); + + //the result should be the max value of a uint256 + assertEq(result, address(type(uint160).max)); + } + + function test_readZeroAddress() public { + //read the first 32 bytes after the first word + address result = B_512.readAddress(32); + + //the result should be 0x00...0 + assertEq(result, address(type(uint160).min)); + } + + function test_readAddressMultiWord() public { + //read the first 20 bytes after byte 13 + address result = B_512.readAddress(13); + + //the result should be the value last 19 bytes of the first word (ffff..) and the first byte of the second word (00) (0xFFFF..00) + assertEq(result, address(type(uint160).max << 8)); + } + + function test_readAddressWithNotEnoughBytes() public { + //should revert if there's not enough bytes + vm.expectRevert(MALFORMED_ERROR_SELECTOR); + + //read 20 bytes from a 16 byte array + B_128.readAddress(0); + } + + function test_readAddressWithEmptyArray() public { + //should revert if there's not enough bytes + vm.expectRevert(MALFORMED_ERROR_SELECTOR); + + //read the first 20 bytes of an empty array + B_EMPTY.readAddress(0); + } +} diff --git a/contracts/src/v0.8/llo-feeds/Verifier.sol b/contracts/src/v0.8/llo-feeds/Verifier.sol index e8b002df883..0bc2dee18c8 100644 --- a/contracts/src/v0.8/llo-feeds/Verifier.sol +++ b/contracts/src/v0.8/llo-feeds/Verifier.sol @@ -1,20 +1,21 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.16; -import {ConfirmedOwner} from "../ConfirmedOwner.sol"; +import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol"; import {IVerifier} from "./interfaces/IVerifier.sol"; import {IVerifierProxy} from "./interfaces/IVerifierProxy.sol"; import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol"; -import {IERC165} from "../shared/vendor/IERC165.sol"; +import {IERC165} from "../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol"; +import {Common} from "../libraries/Common.sol"; // OCR2 standard uint256 constant MAX_NUM_ORACLES = 31; /* * The verifier contract is used to verify offchain reports signed - * by DONs. A report consists of a price, block number and feed Id. It + * by DONs. A report consists of a price, block number and feed Id. It * represents the observed price of an asset at a specified block number for - * a feed. The verifier contract is used to verify that such reports have + * a feed. The verifier contract is used to verify that such reports have * been signed by the correct signers. **/ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { @@ -148,10 +149,12 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { /// @param ssLength The number of s signature components error MismatchedSignatures(uint256 rsLength, uint256 ssLength); - /// @notice This error is thrown whenever a report has a duplicate - /// signature + /// @notice This error is thrown whenever setting a config with duplicate signatures error NonUniqueSignatures(); + /// @notice This error is thrown whenever a report fails to verify due to bad or duplicate signatures + error BadVerification(); + /// @notice This error is thrown whenever the admin tries to deactivate /// the latest config digest /// @param feedId The feed ID in the signed report @@ -178,6 +181,13 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { i_verifierProxyAddr = verifierProxyAddr; } + modifier checkConfigValid(uint256 numSigners, uint256 f) { + if (f == 0) revert FaultToleranceMustBePositive(); + if (numSigners > MAX_NUM_ORACLES) revert ExcessSigners(numSigners, MAX_NUM_ORACLES); + if (numSigners <= 3 * f) revert InsufficientSigners(numSigners, 3 * f + 1); + _; + } + /// @inheritdoc IERC165 function supportsInterface(bytes4 interfaceId) external pure override returns (bool isVerifier) { return interfaceId == this.verify.selector; @@ -185,7 +195,7 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { /// @inheritdoc TypeAndVersionInterface function typeAndVersion() external pure override returns (string memory) { - return "Verifier 1.0.0"; + return "Verifier 1.1.0"; } /// @inheritdoc IVerifier @@ -223,6 +233,7 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { _verifySignatures(hashedReport, reportContext, rs, ss, rawVs, s_config); emit ReportVerified(feedId, sender); + return reportData; } @@ -285,126 +296,90 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { for (uint256 i; i < numSigners; ++i) { signerAddress = ecrecover(h, uint8(rawVs[i]) + 27, rs[i], ss[i]); o = s_config.oracles[signerAddress]; - if (o.role != Role.Signer) revert AccessForbidden(); + if (o.role != Role.Signer) revert BadVerification(); unchecked { signedCount += 1 << (8 * o.index); } } - if (signedCount & ORACLE_MASK != signedCount) revert NonUniqueSignatures(); + if (signedCount & ORACLE_MASK != signedCount) revert BadVerification(); } - /// @notice Generates the config digest from config data - /// @param configCount ordinal number of this config setting among all config settings over the life of this contract - /// @param signers ith element is address ith oracle uses to sign a report - /// @param offchainTransmitters ith element is address ith oracle used to transmit reports (in this case used for flexible additional field, such as CSA pub keys) - /// @param f maximum number of faulty/dishonest oracles the protocol can tolerate while still working correctly - /// @param onchainConfig serialized configuration used by the contract (and possibly oracles) - /// @param offchainConfigVersion version of the serialization format used for "offchainConfig" parameter - /// @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract - /// @dev This function is a modified version of the method from OCR2Abstract - function _configDigestFromConfigData( + /// @inheritdoc IVerifier + function setConfig( bytes32 feedId, - uint64 configCount, address[] memory signers, bytes32[] memory offchainTransmitters, uint8 f, bytes memory onchainConfig, uint64 offchainConfigVersion, - bytes memory offchainConfig - ) internal view returns (bytes32) { - uint256 h = uint256( - keccak256( - abi.encode( - feedId, - block.chainid, // chainId - address(this), // contractAddress - configCount, - signers, - offchainTransmitters, - f, - onchainConfig, - offchainConfigVersion, - offchainConfig - ) - ) + bytes memory offchainConfig, + Common.AddressAndWeight[] memory recipientAddressesAndWeights + ) external override checkConfigValid(signers.length, f) onlyOwner { + _setConfig( + feedId, + block.chainid, + address(this), + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig, + recipientAddressesAndWeights ); - uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 - // 0x0006 corresponds to ConfigDigestPrefixMercuryV02 in libocr - uint256 prefix = 0x0006 << (256 - 16); // 0x000600..00 - return bytes32((prefix & prefixMask) | (h & ~prefixMask)); } - /// @notice Deactivates the configuration for a config digest - /// @param feedId Feed ID to deactivate config for - /// @param configDigest The config digest to deactivate - /// @dev This function can be called by the contract admin to deactivate an incorrect configuration. - function deactivateConfig(bytes32 feedId, bytes32 configDigest) external onlyOwner { - VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; - - if (configDigest == bytes32("")) revert DigestEmpty(); - if (feedVerifierState.s_verificationDataConfigs[configDigest].f == 0) revert DigestNotSet(feedId, configDigest); - if (configDigest == feedVerifierState.latestConfigDigest) revert CannotDeactivateLatestConfig(feedId, configDigest); - feedVerifierState.s_verificationDataConfigs[configDigest].isActive = false; - emit ConfigDeactivated(feedId, configDigest); - } - - /// @notice Activates the configuration for a config digest - /// @param feedId Feed ID to activate config for - /// @param configDigest The config digest to activate - /// @dev This function can be called by the contract admin to activate a configuration. - function activateConfig(bytes32 feedId, bytes32 configDigest) external onlyOwner { - VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; - - if (configDigest == bytes32("")) revert DigestEmpty(); - if (feedVerifierState.s_verificationDataConfigs[configDigest].f == 0) revert DigestNotSet(feedId, configDigest); - feedVerifierState.s_verificationDataConfigs[configDigest].isActive = true; - emit ConfigActivated(feedId, configDigest); - } - - /// @notice Activates the given feed - /// @param feedId Feed ID to activated - /// @dev This function can be called by the contract admin to activate a feed - function activateFeed(bytes32 feedId) external onlyOwner { - VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; - - if (feedVerifierState.configCount == 0) revert InvalidFeed(feedId); - feedVerifierState.isDeactivated = false; - emit FeedActivated(feedId); - } - - /// @notice Deactivates the given feed - /// @param feedId Feed ID to deactivated - /// @dev This function can be called by the contract admin to deactivate a feed - function deactivateFeed(bytes32 feedId) external onlyOwner { - VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; - - if (feedVerifierState.configCount == 0) revert InvalidFeed(feedId); - feedVerifierState.isDeactivated = true; - emit FeedDeactivated(feedId); - } - - //***************************// - // Repurposed OCR2 Functions // - //***************************// - - // Reverts transaction if config args are invalid - modifier checkConfigValid(uint256 numSigners, uint256 f) { - if (f == 0) revert FaultToleranceMustBePositive(); - if (numSigners > MAX_NUM_ORACLES) revert ExcessSigners(numSigners, MAX_NUM_ORACLES); - if (numSigners <= 3 * f) revert InsufficientSigners(numSigners, 3 * f + 1); - _; + /// @inheritdoc IVerifier + function setConfigFromSource( + bytes32 feedId, + uint256 sourceChainId, + address sourceAddress, + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig, + Common.AddressAndWeight[] memory recipientAddressesAndWeights + ) external override checkConfigValid(signers.length, f) onlyOwner { + _setConfig( + feedId, + sourceChainId, + sourceAddress, + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig, + recipientAddressesAndWeights + ); } - function setConfig( + /// @notice Sets config based on the given arguments + /// @param feedId Feed ID to set config for + /// @param sourceChainId Chain ID of source config + /// @param sourceAddress Address of source config Verifier + /// @param signers addresses with which oracles sign the reports + /// @param offchainTransmitters CSA key for the ith Oracle + /// @param f number of faulty oracles the system can tolerate + /// @param onchainConfig serialized configuration used by the contract (and possibly oracles) + /// @param offchainConfigVersion version number for offchainEncoding schema + /// @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract + /// @param recipientAddressesAndWeights the addresses and weights of all the recipients to receive rewards + function _setConfig( bytes32 feedId, + uint256 sourceChainId, + address sourceAddress, address[] memory signers, bytes32[] memory offchainTransmitters, uint8 f, bytes memory onchainConfig, uint64 offchainConfigVersion, - bytes memory offchainConfig - ) external override checkConfigValid(signers.length, f) onlyOwner { + bytes memory offchainConfig, + Common.AddressAndWeight[] memory recipientAddressesAndWeights + ) internal { VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; // Increment the number of times a config has been set first @@ -412,6 +387,8 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { bytes32 configDigest = _configDigestFromConfigData( feedId, + sourceChainId, + sourceAddress, feedVerifierState.configCount, signers, offchainTransmitters, @@ -440,7 +417,11 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { }); } - IVerifierProxy(i_verifierProxyAddr).setVerifier(feedVerifierState.latestConfigDigest, configDigest); + IVerifierProxy(i_verifierProxyAddr).setVerifier( + feedVerifierState.latestConfigDigest, + configDigest, + recipientAddressesAndWeights + ); emit ConfigSet( feedId, @@ -460,6 +441,94 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { feedVerifierState.latestConfigDigest = configDigest; } + /// @notice Generates the config digest from config data + /// @param feedId Feed ID to set config for + /// @param sourceChainId Chain ID of source config + /// @param sourceAddress Address of source config Verifier + /// @param configCount ordinal number of this config setting among all config settings over the life of this contract + /// @param signers ith element is address ith oracle uses to sign a report + /// @param offchainTransmitters ith element is address ith oracle used to transmit reports (in this case used for flexible additional field, such as CSA pub keys) + /// @param f maximum number of faulty/dishonest oracles the protocol can tolerate while still working correctly + /// @param onchainConfig serialized configuration used by the contract (and possibly oracles) + /// @param offchainConfigVersion version of the serialization format used for "offchainConfig" parameter + /// @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract + /// @dev This function is a modified version of the method from OCR2Abstract + function _configDigestFromConfigData( + bytes32 feedId, + uint256 sourceChainId, + address sourceAddress, + uint64 configCount, + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) internal pure returns (bytes32) { + uint256 h = uint256( + keccak256( + abi.encode( + feedId, + sourceChainId, + sourceAddress, + configCount, + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ) + ) + ); + uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 + // 0x0006 corresponds to ConfigDigestPrefixMercuryV02 in libocr + uint256 prefix = 0x0006 << (256 - 16); // 0x000600..00 + return bytes32((prefix & prefixMask) | (h & ~prefixMask)); + } + + /// @inheritdoc IVerifier + function activateConfig(bytes32 feedId, bytes32 configDigest) external onlyOwner { + VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; + + if (configDigest == bytes32("")) revert DigestEmpty(); + if (feedVerifierState.s_verificationDataConfigs[configDigest].f == 0) revert DigestNotSet(feedId, configDigest); + feedVerifierState.s_verificationDataConfigs[configDigest].isActive = true; + emit ConfigActivated(feedId, configDigest); + } + + /// @inheritdoc IVerifier + function deactivateConfig(bytes32 feedId, bytes32 configDigest) external onlyOwner { + VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; + + if (configDigest == bytes32("")) revert DigestEmpty(); + if (feedVerifierState.s_verificationDataConfigs[configDigest].f == 0) revert DigestNotSet(feedId, configDigest); + if (configDigest == feedVerifierState.latestConfigDigest) { + revert CannotDeactivateLatestConfig(feedId, configDigest); + } + feedVerifierState.s_verificationDataConfigs[configDigest].isActive = false; + emit ConfigDeactivated(feedId, configDigest); + } + + /// @inheritdoc IVerifier + function activateFeed(bytes32 feedId) external onlyOwner { + VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; + + if (feedVerifierState.configCount == 0) revert InvalidFeed(feedId); + feedVerifierState.isDeactivated = false; + emit FeedActivated(feedId); + } + + /// @inheritdoc IVerifier + function deactivateFeed(bytes32 feedId) external onlyOwner { + VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; + + if (feedVerifierState.configCount == 0) revert InvalidFeed(feedId); + feedVerifierState.isDeactivated = true; + emit FeedDeactivated(feedId); + } + + /// @inheritdoc IVerifier function latestConfigDigestAndEpoch( bytes32 feedId ) external view override returns (bool scanLogs, bytes32 configDigest, uint32 epoch) { @@ -467,6 +536,7 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { return (false, feedVerifierState.latestConfigDigest, feedVerifierState.latestEpoch); } + /// @inheritdoc IVerifier function latestConfigDetails( bytes32 feedId ) external view override returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest) { diff --git a/contracts/src/v0.8/llo-feeds/VerifierProxy.sol b/contracts/src/v0.8/llo-feeds/VerifierProxy.sol index 60ad52b1810..41907432a31 100644 --- a/contracts/src/v0.8/llo-feeds/VerifierProxy.sol +++ b/contracts/src/v0.8/llo-feeds/VerifierProxy.sol @@ -1,12 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.16; -import {ConfirmedOwner} from "../ConfirmedOwner.sol"; +import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol"; import {IVerifierProxy} from "./interfaces/IVerifierProxy.sol"; import {IVerifier} from "./interfaces/IVerifier.sol"; import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol"; import {AccessControllerInterface} from "../interfaces/AccessControllerInterface.sol"; -import {IERC165} from "../shared/vendor/IERC165.sol"; +import {IERC165} from "../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol"; +import {IVerifierFeeManager} from "./interfaces/IVerifierFeeManager.sol"; +import {Common} from "../libraries/Common.sol"; /** * The verifier proxy contract is the gateway for all report verification requests @@ -37,6 +39,11 @@ contract VerifierProxy is IVerifierProxy, ConfirmedOwner, TypeAndVersionInterfac /// @param newAccessController The new access controller address event AccessControllerSet(address oldAccessController, address newAccessController); + /// @notice This event is emitted when a new fee manager is set + /// @param oldFeeManager The old fee manager address + /// @param newFeeManager The new fee manager address + event FeeManagerSet(address oldFeeManager, address newFeeManager); + /// @notice This error is thrown whenever an address tries /// to exeecute a transaction that it is not authorized to do so error AccessForbidden(); @@ -62,6 +69,9 @@ contract VerifierProxy is IVerifierProxy, ConfirmedOwner, TypeAndVersionInterfac /// @param configDigest The digest for which a verifier is not found error VerifierNotFound(bytes32 configDigest); + /// @notice This error is thrown whenever billing fails. + error BadVerification(); + /// @notice Mapping of authorized verifiers mapping(address => bool) private s_initializedVerifiers; @@ -69,20 +79,21 @@ contract VerifierProxy is IVerifierProxy, ConfirmedOwner, TypeAndVersionInterfac mapping(bytes32 => address) private s_verifiersByConfig; /// @notice The contract to control addresses that are allowed to verify reports - AccessControllerInterface private s_accessController; + AccessControllerInterface public s_accessController; + + /// @notice The contract to control fees for report verification + IVerifierFeeManager public s_feeManager; constructor(AccessControllerInterface accessController) ConfirmedOwner(msg.sender) { s_accessController = accessController; } - /// @dev reverts if the caller does not have access by the accessController contract or is the contract itself. modifier checkAccess() { AccessControllerInterface ac = s_accessController; if (address(ac) != address(0) && !ac.hasAccess(msg.sender, msg.data)) revert AccessForbidden(); _; } - /// @dev only allow verified addresses to call this function modifier onlyInitializedVerifier() { if (!s_initializedVerifiers[msg.sender]) revert AccessForbidden(); _; @@ -94,8 +105,6 @@ contract VerifierProxy is IVerifierProxy, ConfirmedOwner, TypeAndVersionInterfac _; } - /// @notice Reverts if the config digest has already been assigned - /// a verifier modifier onlyUnsetConfigDigest(bytes32 configDigest) { address configDigestVerifier = s_verifiersByConfig[configDigest]; if (configDigestVerifier != address(0)) revert ConfigDigestAlreadySet(configDigest, configDigestVerifier); @@ -104,44 +113,26 @@ contract VerifierProxy is IVerifierProxy, ConfirmedOwner, TypeAndVersionInterfac /// @inheritdoc TypeAndVersionInterface function typeAndVersion() external pure override returns (string memory) { - return "VerifierProxy 1.0.0"; + return "VerifierProxy 1.1.0"; } - //***************************// - // Admin Functions // - //***************************// - - /// @notice This function can be called by the contract admin to set - /// the proxy's access controller contract - /// @param accessController The new access controller to set - /// @dev The access controller can be set to the zero address to allow - /// all addresses to verify reports - function setAccessController(AccessControllerInterface accessController) external onlyOwner { - address oldAccessController = address(s_accessController); - s_accessController = accessController; - emit AccessControllerSet(oldAccessController, address(accessController)); - } - - /// @notice Returns the current access controller - /// @return accessController The current access controller contract - /// the proxy is using to gate access - function getAccessController() external view returns (AccessControllerInterface accessController) { - return s_accessController; - } - - //***************************// - // Verification Functions // - //***************************// - /// @inheritdoc IVerifierProxy - /// @dev Contract skips checking whether or not the current verifier - /// is valid as it checks this before a new verifier is set. - function verify(bytes calldata signedReport) external override checkAccess returns (bytes memory verifierResponse) { - // First 32 bytes of the signed report is the config digest. - bytes32 configDigest = bytes32(signedReport); + function verify( + bytes calldata payload + ) external payable override checkAccess returns (bytes memory verifierResponse) { + // First 32 bytes of the signed report is the config digest + bytes32 configDigest = bytes32(payload); address verifierAddress = s_verifiersByConfig[configDigest]; if (verifierAddress == address(0)) revert VerifierNotFound(configDigest); - return IVerifier(verifierAddress).verify(signedReport, msg.sender); + + IVerifierFeeManager feeManager = s_feeManager; + + // Bill the verifier + if (address(feeManager) != address(0)) { + feeManager.processFee{value: msg.value}(payload, msg.sender); + } + + return IVerifier(verifierAddress).verify(payload, msg.sender); } /// @inheritdoc IVerifierProxy @@ -155,9 +146,20 @@ contract VerifierProxy is IVerifierProxy, ConfirmedOwner, TypeAndVersionInterfac /// @inheritdoc IVerifierProxy function setVerifier( bytes32 currentConfigDigest, - bytes32 newConfigDigest + bytes32 newConfigDigest, + Common.AddressAndWeight[] calldata addressesAndWeights ) external override onlyUnsetConfigDigest(newConfigDigest) onlyInitializedVerifier { s_verifiersByConfig[newConfigDigest] = msg.sender; + + // Empty recipients array will be ignored and must be set off chain + if (addressesAndWeights.length > 0) { + if (address(s_feeManager) == address(0)) { + revert ZeroAddress(); + } + + s_feeManager.setFeeRecipients(newConfigDigest, addressesAndWeights); + } + emit VerifierSet(currentConfigDigest, newConfigDigest, msg.sender); } @@ -170,7 +172,23 @@ contract VerifierProxy is IVerifierProxy, ConfirmedOwner, TypeAndVersionInterfac } /// @inheritdoc IVerifierProxy - function getVerifier(bytes32 configDigest) external view override returns (address) { + function getVerifier(bytes32 configDigest) external view override returns (address verifierAddress) { return s_verifiersByConfig[configDigest]; } + + /// @inheritdoc IVerifierProxy + function setAccessController(AccessControllerInterface accessController) external onlyOwner { + address oldAccessController = address(s_accessController); + s_accessController = accessController; + emit AccessControllerSet(oldAccessController, address(accessController)); + } + + /// @inheritdoc IVerifierProxy + function setFeeManager(IVerifierFeeManager feeManager) external onlyOwner { + if (address(feeManager) == address(0)) revert ZeroAddress(); + + address oldFeeManager = address(s_feeManager); + s_feeManager = IVerifierFeeManager(feeManager); + emit FeeManagerSet(oldFeeManager, address(feeManager)); + } } diff --git a/contracts/src/v0.8/llo-feeds/dev/FeeManager.sol b/contracts/src/v0.8/llo-feeds/dev/FeeManager.sol new file mode 100644 index 00000000000..2d3376cd67a --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/dev/FeeManager.sol @@ -0,0 +1,368 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.16; + +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; +import {IFeeManager} from "./interfaces/IFeeManager.sol"; +import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; +import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol"; +import {Common} from "../../libraries/Common.sol"; +import {IRewardManager} from "./interfaces/IRewardManager.sol"; +import {IWERC20} from "../../shared/interfaces/IWERC20.sol"; +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC20.sol"; +import {Math} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/Math.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol"; + +/** + * @title FeeManager + * @author Michael Fletcher + * @author Austin Born + * @notice This contract is used for the handling of fees required for users verifying reports. + */ +contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { + using SafeERC20 for IERC20; + + /// @notice list of subscribers and their discounts subscriberDiscounts[subscriber][feedId][token] + mapping(address => mapping(bytes32 => mapping(address => uint256))) public s_subscriberDiscounts; + + /// @notice keep track of any subsidised link that is owed to the reward manager. + mapping(bytes32 => uint256) public s_linkDeficit; + + /// @notice the total discount that can be applied to a fee, 1e18 = 100% discount + uint256 private constant PERCENTAGE_SCALAR = 1e18; + + /// @notice the LINK token address + address private immutable i_linkAddress; + + /// @notice the native token address + address private immutable i_nativeAddress; + + /// @notice the proxy address + address private immutable i_proxyAddress; + + /// @notice the reward manager address + IRewardManager private immutable i_rewardManager; + + // @notice the mask to apply to get the report version + bytes32 private constant REPORT_VERSION_MASK = 0xffff000000000000000000000000000000000000000000000000000000000000; + + // @notice the different report versions + bytes32 private constant REPORT_V1 = 0x0001000000000000000000000000000000000000000000000000000000000000; + + /// @notice the surcharge fee to be paid if paying in native + uint256 public s_nativeSurcharge; + + /// @notice the error thrown if the discount or surcharge is invalid + error InvalidSurcharge(); + + /// @notice the error thrown if the token is invalid + error InvalidToken(); + + /// @notice the error thrown if the discount is invalid + error InvalidDiscount(); + + /// @notice the error thrown if the address is invalid + error InvalidAddress(); + + /// @notice thrown if msg.value is supplied with a bad quote + error InvalidDeposit(); + + /// @notice thrown if a report has expired + error ExpiredReport(); + + /// @notice thrown if a report has no quote + error InvalidQuote(); + + // @notice thrown when the caller is not authorized + error Unauthorized(); + + // @notice thrown when trying to clear a zero deficit + error ZeroDeficit(); + + /// @notice Emitted whenever a subscriber's discount is updated + /// @param subscriber address of the subscriber to update discounts for + /// @param feedId Feed ID for the discount + /// @param token Token address for the discount + /// @param discount Discount to apply, in relation to the PERCENTAGE_SCALAR + event SubscriberDiscountUpdated(address indexed subscriber, bytes32 indexed feedId, address token, uint256 discount); + + /// @notice Emitted when updating the native surcharge + /// @param newSurcharge Surcharge amount to apply relative to PERCENTAGE_SCALAR + event NativeSurchargeUpdated(uint256 newSurcharge); + + /// @notice Emits when this contract does not have enough LINK to send to the reward manager when paying in native + /// @param configDigest Config digest of the report + /// @param linkQuantity Amount of LINK required to pay the reward + /// @param nativeQuantity Amount of native required to pay the reward + event InsufficientLink(bytes32 indexed configDigest, uint256 linkQuantity, uint256 nativeQuantity); + + /// @notice Emitted when funds are withdrawn + /// @param assetAddress Address of the asset withdrawn + /// @param quantity Amount of the asset withdrawn + event Withdraw(address adminAddress, address assetAddress, uint256 quantity); + + /// @notice Emits when a deficit has been cleared for a particular config digest + /// @param configDigest Config digest of the deficit cleared + /// @param linkQuantity Amount of LINK required to pay the deficit + event LinkDeficitCleared(bytes32 indexed configDigest, uint256 linkQuantity); + + /** + * @notice Construct the FeeManager contract + * @param _linkAddress The address of the LINK token + * @param _nativeAddress The address of the wrapped ERC-20 version of the native token (represents fee in native or wrapped) + * @param _proxyAddress The address of the proxy contract + * @param _rewardManagerAddress The address of the reward manager contract + */ + constructor( + address _linkAddress, + address _nativeAddress, + address _proxyAddress, + address _rewardManagerAddress + ) ConfirmedOwner(msg.sender) { + if ( + _linkAddress == address(0) || + _nativeAddress == address(0) || + _proxyAddress == address(0) || + _rewardManagerAddress == address(0) + ) revert InvalidAddress(); + + i_linkAddress = _linkAddress; + i_nativeAddress = _nativeAddress; + i_proxyAddress = _proxyAddress; + i_rewardManager = IRewardManager(_rewardManagerAddress); + + IERC20(i_linkAddress).approve(address(i_rewardManager), type(uint256).max); + } + + modifier onlyOwnerOrProxy() { + if (msg.sender != owner() && msg.sender != i_proxyAddress) revert Unauthorized(); + _; + } + + /// @inheritdoc TypeAndVersionInterface + function typeAndVersion() external pure override returns (string memory) { + return "FeeManager 0.0.1"; + } + + /// @inheritdoc IERC165 + function supportsInterface(bytes4 interfaceId) external pure override returns (bool) { + return interfaceId == this.processFee.selector; + } + + /// @inheritdoc IFeeManager + function processFee(bytes calldata payload, address subscriber) external payable onlyOwnerOrProxy { + if (subscriber == address(this)) revert InvalidAddress(); + + //decode the report from the payload + (, bytes memory report) = abi.decode(payload, (bytes32[3], bytes)); + + //get the feedId from the report + bytes32 feedId = bytes32(report); + + //v2 doesn't need a quote payload, so skip the decoding if the report is a v1 report + Quote memory quote; + if (_getReportVersion(feedId) != REPORT_V1) { + //all reports greater than v1 should have a quote payload + (, , , , , bytes memory quoteBytes) = abi.decode( + payload, + (bytes32[3], bytes, bytes32[], bytes32[], bytes32, bytes) + ); + + //decode the quote from the bytes + (quote) = abi.decode(quoteBytes, (Quote)); + } + + //decode the fee, it will always be native or LINK + (Common.Asset memory fee, Common.Asset memory reward) = getFeeAndReward(msg.sender, report, quote); + + //keep track of change in case of any over payment + uint256 change; + + //wrap the amount required to pay the fee + if (msg.value != 0) { + //quote must be in native with enough to cover the fee + if (fee.assetAddress != i_nativeAddress) revert InvalidDeposit(); + if (fee.amount > msg.value) revert InvalidDeposit(); + + //wrap the amount required to pay the fee & approve + IWERC20(i_nativeAddress).deposit{value: fee.amount}(); + + unchecked { + //msg.value is always >= to fee.amount + change = msg.value - fee.amount; + } + } + + //get the config digest which is the first 32 bytes of the payload + bytes32 configDigest = bytes32(payload); + + //some users might not be billed + if (fee.amount != 0) { + //if the fee is in LINK, transfer directly from the subscriber to the reward manager + if (fee.assetAddress == i_linkAddress) { + //distributes the fee + i_rewardManager.onFeePaid(configDigest, subscriber, reward.amount); + } else { + //if the fee is in native wrapped, transfer to this contract in exchange for the equivalent amount of LINK excluding the surcharge + if (msg.value == 0) { + IERC20(fee.assetAddress).safeTransferFrom(subscriber, address(this), fee.amount); + } + + //check that the contract has enough LINK before paying the fee + if (reward.amount > IERC20(i_linkAddress).balanceOf(address(this))) { + // If not enough LINK on this contract to forward for rewards, tally the deficit to be paid by out-of-band LINK + s_linkDeficit[configDigest] += reward.amount; + emit InsufficientLink(configDigest, reward.amount, fee.amount); + } else { + //bill the payee and distribute the fee using the config digest as the key + i_rewardManager.onFeePaid(configDigest, address(this), reward.amount); + } + } + } + + // a refund may be needed if the payee has paid in excess of the fee + if (change != 0) { + payable(subscriber).transfer(change); + } + } + + /// @inheritdoc IFeeManager + function getFeeAndReward( + address subscriber, + bytes memory report, + Quote memory quote + ) public view returns (Common.Asset memory, Common.Asset memory) { + Common.Asset memory fee; + Common.Asset memory reward; + + //get the feedId from the report + bytes32 feedId = bytes32(report); + + //the report needs to be a support version + bytes32 reportVersion = _getReportVersion(feedId); + + //version 1 of the reports don't require quotes, so the fee will be 0 + if (reportVersion == REPORT_V1) { + fee.assetAddress = i_nativeAddress; + reward.assetAddress = i_linkAddress; + return (fee, reward); + } + + //verify the quote payload is a supported token + if (quote.quoteAddress != i_nativeAddress && quote.quoteAddress != i_linkAddress) { + revert InvalidQuote(); + } + + //decode the report depending on the version + uint256 linkQuantity; + uint256 nativeQuantity; + uint256 expiresAt; + (, , , , linkQuantity, nativeQuantity, expiresAt) = abi.decode( + report, + (bytes32, uint32, uint32, int192, uint192, uint192, uint32) + ); + + //read the timestamp bytes from the report data and verify it has not expired + if (expiresAt < block.timestamp) { + revert ExpiredReport(); + } + + //the reward is always set in LINK + reward.assetAddress = i_linkAddress; + reward.amount = linkQuantity; + + //calculate either the LINK fee or native fee if it's within the report + if (quote.quoteAddress == i_linkAddress) { + fee.assetAddress = reward.assetAddress; + fee.amount = reward.amount; + } else { + fee.assetAddress = i_nativeAddress; + fee.amount = Math.ceilDiv(nativeQuantity * (PERCENTAGE_SCALAR + s_nativeSurcharge), PERCENTAGE_SCALAR); + } + + //get the discount being applied + uint256 discount = s_subscriberDiscounts[subscriber][feedId][quote.quoteAddress]; + + //apply the discount to the fee, rounding up + fee.amount = fee.amount - ((fee.amount * discount) / PERCENTAGE_SCALAR); + + //apply the discount to the reward, rounding down + reward.amount = reward.amount - Math.ceilDiv(reward.amount * discount, PERCENTAGE_SCALAR); + + //return the fee + return (fee, reward); + } + + /// @inheritdoc IFeeManager + function setFeeRecipients( + bytes32 configDigest, + Common.AddressAndWeight[] calldata rewardRecipientAndWeights + ) external onlyOwnerOrProxy { + i_rewardManager.setRewardRecipients(configDigest, rewardRecipientAndWeights); + } + + /// @inheritdoc IFeeManager + function setNativeSurcharge(uint256 surcharge) external onlyOwner { + if (surcharge > PERCENTAGE_SCALAR) revert InvalidSurcharge(); + + s_nativeSurcharge = surcharge; + + emit NativeSurchargeUpdated(surcharge); + } + + /// @inheritdoc IFeeManager + function updateSubscriberDiscount( + address subscriber, + bytes32 feedId, + address token, + uint256 discount + ) external onlyOwner { + //make sure the discount is not greater than the total discount that can be applied + if (discount > PERCENTAGE_SCALAR) revert InvalidDiscount(); + //make sure the token is either LINK or native + if (token != i_linkAddress && token != i_nativeAddress) revert InvalidAddress(); + + s_subscriberDiscounts[subscriber][feedId][token] = discount; + + emit SubscriberDiscountUpdated(subscriber, feedId, token, discount); + } + + /// @inheritdoc IFeeManager + function withdraw(address assetAddress, uint256 quantity) external onlyOwner { + //address 0 is used to withdraw native in the context of withdrawing + if (assetAddress == address(0)) { + payable(owner()).transfer(quantity); + return; + } + + //withdraw the requested asset + IERC20(assetAddress).safeTransfer(owner(), quantity); + + //emit event when funds are withdrawn + emit Withdraw(msg.sender, assetAddress, quantity); + } + + /// @inheritdoc IFeeManager + function linkAvailableForPayment() external view returns (uint256) { + //return the amount of LINK this contact has available to pay rewards + return IERC20(i_linkAddress).balanceOf(address(this)); + } + + /** + * @notice Gets the current version of the report that is encoded as the last two bytes of the feed + * @param feedId feed id to get the report version for + */ + function _getReportVersion(bytes32 feedId) internal pure returns (bytes32) { + return REPORT_VERSION_MASK & feedId; + } + + /// @inheritdoc IFeeManager + function payLinkDeficit(bytes32 configDigest) external onlyOwner { + uint256 deficit = s_linkDeficit[configDigest]; + if (deficit == 0) revert ZeroDeficit(); + + delete s_linkDeficit[configDigest]; + i_rewardManager.onFeePaid(configDigest, address(this), deficit); + + emit LinkDeficitCleared(configDigest, deficit); + } +} diff --git a/contracts/src/v0.8/llo-feeds/dev/RewardManager.sol b/contracts/src/v0.8/llo-feeds/dev/RewardManager.sol new file mode 100644 index 00000000000..fbe072cacab --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/dev/RewardManager.sol @@ -0,0 +1,311 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.16; + +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; +import {IRewardManager} from "./interfaces/IRewardManager.sol"; +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC20.sol"; +import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; +import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol"; +import {Common} from "../../libraries/Common.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol"; + +/** + * @title FeeManager + * @author Michael Fletcher + * @author Austin Born + * @notice This contract will be used to reward any configured recipients within a pool. Recipients will receive a share of their pool relative to their configured weight. + */ +contract RewardManager is IRewardManager, ConfirmedOwner, TypeAndVersionInterface { + using SafeERC20 for IERC20; + + // @dev The mapping of total fees collected for a particular pot: s_totalRewardRecipientFees[poolId] + mapping(bytes32 => uint256) public s_totalRewardRecipientFees; + + // @dev The mapping of fee balances for each pot last time the recipient claimed: s_totalRewardRecipientFeesLastClaimedAmounts[poolId][recipient] + mapping(bytes32 => mapping(address => uint256)) private s_totalRewardRecipientFeesLastClaimedAmounts; + + // @dev The mapping of RewardRecipient weights for a particular poolId: s_rewardRecipientWeights[poolId][rewardRecipient]. + mapping(bytes32 => mapping(address => uint256)) public s_rewardRecipientWeights; + + // @dev Keep track of the reward recipient weights that have been set to prevent duplicates + mapping(bytes32 => bool) private s_rewardRecipientWeightsSet; + + // @dev Store a list of pool ids that have been registered, to make off chain lookups easier + bytes32[] public s_registeredPoolIds; + + // @dev The address for the LINK contract + address private immutable i_linkAddress; + + // The total weight of all RewardRecipients. 1e18 = 100% of the pool fees + uint256 private constant PERCENTAGE_SCALAR = 1e18; + + // The fee manager address + address public s_feeManagerAddress; + + // @notice Thrown whenever the RewardRecipient weights are invalid + error InvalidWeights(); + + // @notice Thrown when any given address is invalid + error InvalidAddress(); + + // @notice Thrown when the pool id is invalid + error InvalidPoolId(); + + // @notice Thrown when the calling contract is not within the authorized contracts + error Unauthorized(); + + // Events emitted upon state change + event RewardRecipientsUpdated(bytes32 indexed poolId, Common.AddressAndWeight[] newRewardRecipients); + event RewardsClaimed(bytes32 indexed poolId, address indexed recipient, uint256 quantity); + event FeeManagerUpdated(address newFeeManagerAddress); + event FeePaid(bytes32 poolId, address payee, uint256 quantity); + + /** + * @notice Constructor + * @param linkAddress address of the wrapped LINK token + */ + constructor(address linkAddress) ConfirmedOwner(msg.sender) { + //ensure that the address ia not zero + if (linkAddress == address(0)) revert InvalidAddress(); + + i_linkAddress = linkAddress; + } + + // @inheritdoc TypeAndVersionInterface + function typeAndVersion() external pure override returns (string memory) { + return "RewardManager 0.0.1"; + } + + // @inheritdoc IERC165 + function supportsInterface(bytes4 interfaceId) external pure override returns (bool) { + return interfaceId == this.onFeePaid.selector; + } + + modifier onlyOwnerOrFeeManager() { + if (msg.sender != owner() && msg.sender != s_feeManagerAddress) revert Unauthorized(); + _; + } + + modifier onlyOwnerOrRecipientInPool(bytes32 poolId) { + if (msg.sender != owner() && s_rewardRecipientWeights[poolId][msg.sender] == 0) revert Unauthorized(); + _; + } + + /// @inheritdoc IRewardManager + function onFeePaid(bytes32 poolId, address payee, uint256 amount) external override onlyOwnerOrFeeManager { + //update the total fees collected for this pot + unchecked { + //the total amount for any ERC20 asset cannot exceed 2^256 - 1 + s_totalRewardRecipientFees[poolId] += amount; + } + + //transfer the fee to this contract + IERC20(i_linkAddress).safeTransferFrom(payee, address(this), amount); + + emit FeePaid(poolId, payee, amount); + } + + /// @inheritdoc IRewardManager + function claimRewards(bytes32[] memory poolIds) external override { + _claimRewards(msg.sender, poolIds); + } + + // wrapper impl for claimRewards + function _claimRewards(address recipient, bytes32[] memory poolIds) internal returns (uint256) { + //get the total amount claimable for this recipient + uint256 claimAmount; + + //loop and claim all the rewards in the poolId pot + for (uint256 i; i < poolIds.length; ++i) { + //get the poolId to be claimed + bytes32 poolId = poolIds[i]; + + //get the total fees for the pot + uint256 totalFeesInPot = s_totalRewardRecipientFees[poolId]; + + unchecked { + //get the claimable amount for this recipient, this calculation will never exceed the amount in the pot + uint256 claimableAmount = totalFeesInPot - s_totalRewardRecipientFeesLastClaimedAmounts[poolId][recipient]; + + //calculate the recipients share of the fees, which is their weighted share of the difference between the last amount they claimed and the current amount in the pot. This can never be more than the total amount in existence + uint256 recipientShare = (claimableAmount * s_rewardRecipientWeights[poolId][recipient]) / PERCENTAGE_SCALAR; + + //if there's no fees to claim, continue as there's nothing to update + if (recipientShare == 0) continue; + + //keep track of the total amount claimable, this can never be more than the total amount in existence + claimAmount += recipientShare; + + //set the current total amount of fees in the pot as it's used to calculate future claims + s_totalRewardRecipientFeesLastClaimedAmounts[poolId][recipient] = totalFeesInPot; + + //emit event if the recipient has rewards to claim + emit RewardsClaimed(poolIds[i], recipient, recipientShare); + } + } + + //check if there's any rewards to claim in the given poolId + if (claimAmount != 0) { + //transfer the reward to the recipient + IERC20(i_linkAddress).safeTransfer(recipient, claimAmount); + } + + return claimAmount; + } + + /// @inheritdoc IRewardManager + function setRewardRecipients( + bytes32 poolId, + Common.AddressAndWeight[] calldata rewardRecipientAndWeights + ) external override onlyOwnerOrFeeManager { + //revert if there are no recipients to set + if (rewardRecipientAndWeights.length == 0) revert InvalidAddress(); + + //check that the weights have not been previously set + if (s_rewardRecipientWeightsSet[poolId]) revert InvalidPoolId(); + + //keep track of the registered poolIds to make off chain lookups easier + s_registeredPoolIds.push(poolId); + + //keep track of which pools have had their reward recipients set + s_rewardRecipientWeightsSet[poolId] = true; + + //set the reward recipients, this will only be called once and contain the full set of RewardRecipients with a total weight of 100% + _setRewardRecipientWeights(poolId, rewardRecipientAndWeights, PERCENTAGE_SCALAR); + + emit RewardRecipientsUpdated(poolId, rewardRecipientAndWeights); + } + + function _setRewardRecipientWeights( + bytes32 poolId, + Common.AddressAndWeight[] calldata rewardRecipientAndWeights, + uint256 expectedWeight + ) internal { + //we can't update the weights if it contains duplicates + if (Common.hasDuplicateAddresses(rewardRecipientAndWeights)) revert InvalidAddress(); + + //loop all the reward recipients and validate the weight and address + uint256 totalWeight; + for (uint256 i; i < rewardRecipientAndWeights.length; ++i) { + //get the weight + uint256 recipientWeight = rewardRecipientAndWeights[i].weight; + //get the address + address recipientAddress = rewardRecipientAndWeights[i].addr; + + //ensure the reward recipient address is not zero + if (recipientAddress == address(0)) revert InvalidAddress(); + //ensure the weight is not zero + if (recipientWeight == 0) revert InvalidWeights(); + + //save/overwrite the weight for the reward recipient + s_rewardRecipientWeights[poolId][recipientAddress] = recipientWeight; + + unchecked { + //keep track of the cumulative weight, this cannot overflow as the total weight is restricted at 1e18 + totalWeight += recipientWeight; + } + } + + //if total weight is not met, the fees will either be under or over distributed + if (totalWeight != expectedWeight) revert InvalidWeights(); + } + + /// @inheritdoc IRewardManager + function updateRewardRecipients( + bytes32 poolId, + Common.AddressAndWeight[] calldata newRewardRecipients + ) external override onlyOwner { + //create an array of poolIds to pass to _claimRewards if required + bytes32[] memory poolIds = new bytes32[](1); + poolIds[0] = poolId; + + //loop all the reward recipients and claim their rewards before updating their weights + uint256 existingTotalWeight; + for (uint256 i; i < newRewardRecipients.length; ) { + //get the address + address recipientAddress = newRewardRecipients[i].addr; + //get the existing weight + uint256 existingWeight = s_rewardRecipientWeights[poolId][recipientAddress]; + + //if the existing weight is 0, the recipient isn't part of this configuration + if (existingWeight == 0) revert InvalidAddress(); + + //if a recipient is updated, the rewards must be claimed first as they can't claim previous fees at the new weight + _claimRewards(newRewardRecipients[i].addr, poolIds); + + unchecked { + //keep tally of the weights so that the expected collective weight is known + existingTotalWeight += existingWeight; + //there will never be enough reward recipients for i to overflow + ++i; + } + } + + //update the reward recipients, if the new collective weight isn't equal to the previous collective weight, the fees will either be under or over distributed + _setRewardRecipientWeights(poolId, newRewardRecipients, existingTotalWeight); + + //emit event + emit RewardRecipientsUpdated(poolId, newRewardRecipients); + } + + /// @inheritdoc IRewardManager + function payRecipients(bytes32 poolId, address[] calldata recipients) external onlyOwnerOrRecipientInPool(poolId) { + //convert poolIds to an array to match the interface of _claimRewards + bytes32[] memory poolIdsArray = new bytes32[](1); + poolIdsArray[0] = poolId; + + //loop each recipient and claim the rewards for each of the pools and assets + for (uint256 i; i < recipients.length; ) { + _claimRewards(recipients[i], poolIdsArray); + + unchecked { + //there will never be enough recipients for i to overflow + ++i; + } + } + } + + /// @inheritdoc IRewardManager + function setFeeManager(address newFeeManagerAddress) external onlyOwner { + if (newFeeManagerAddress == address(0)) revert InvalidAddress(); + + s_feeManagerAddress = newFeeManagerAddress; + + emit FeeManagerUpdated(newFeeManagerAddress); + } + + /// @inheritdoc IRewardManager + function getAvailableRewardPoolIds(address recipient) external view returns (bytes32[] memory) { + //get the length of the pool ids which we will loop through and potentially return + uint256 registeredPoolIdsLength = s_registeredPoolIds.length; + + //create a new array with the maximum amount of potential pool ids + bytes32[] memory claimablePoolIds = new bytes32[](registeredPoolIdsLength); + //we want the pools which a recipient has funds for to be sequential, so we need to keep track of the index + uint256 poolIdArrayIndex; + + //loop all the pool ids, and check if the recipient has a registered weight and a claimable amount + for (uint256 i; i < registeredPoolIdsLength; ) { + //get the poolId + bytes32 poolId = s_registeredPoolIds[i]; + //if the recipient has a weight, they are a recipient of this poolId + if (s_rewardRecipientWeights[poolId][recipient] != 0) { + //if the recipient has any LINK, then add the poolId to the array + if (s_totalRewardRecipientFees[poolId] != 0) { + claimablePoolIds[poolIdArrayIndex] = poolId; + unchecked { + //there will never be enough pool ids for i to overflow + ++poolIdArrayIndex; + } + } + } + + unchecked { + //there will never be enough poolIds for i to overflow + ++i; + } + } + + return claimablePoolIds; + } +} diff --git a/contracts/src/v0.8/llo-feeds/dev/interfaces/IFeeManager.sol b/contracts/src/v0.8/llo-feeds/dev/interfaces/IFeeManager.sol new file mode 100644 index 00000000000..e045b961c3e --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/dev/interfaces/IFeeManager.sol @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.16; + +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol"; +import {Common} from "../../../libraries/Common.sol"; +import {IVerifierFeeManager} from "../../interfaces/IVerifierFeeManager.sol"; + +interface IFeeManager is IERC165, IVerifierFeeManager { + struct Quote { + address quoteAddress; + } + + /** + * @notice Processes the fee for a report, billing the subscriber and paying the reward manager + * @param payload report and quote data to process the fee for + * @param subscriber address of the user to process fee for + */ + function processFee(bytes calldata payload, address subscriber) external payable; + + /** + * @notice Calculate the applied fee and the reward from a report. If the sender is a subscriber, they will receive a discount. + * @param subscriber address trying to verify + * @param report report to calculate the fee for + * @param quote any metadata required to fetch the fee + * @return (fee, reward) fee and the reward data + */ + function getFeeAndReward( + address subscriber, + bytes memory report, + Quote memory quote + ) external returns (Common.Asset memory, Common.Asset memory); + + /** + * @notice Sets the fee recipients within the reward manager + * @param configDigest digest of the configuration + * @param rewardRecipientAndWeights the address and weights of all the recipients to receive rewards + */ + function setFeeRecipients( + bytes32 configDigest, + Common.AddressAndWeight[] calldata rewardRecipientAndWeights + ) external; + + /** + * @notice Sets the native surcharge + * @param surcharge surcharge to be paid if paying in native + */ + function setNativeSurcharge(uint256 surcharge) external; + + /** + * @notice Adds a subscriber to the fee manager + * @param subscriber address of the subscriber + * @param feedId feed id to apply the discount to + * @param token token to apply the discount to + * @param discount discount to be applied to the fee + */ + function updateSubscriberDiscount(address subscriber, bytes32 feedId, address token, uint256 discount) external; + + /** + * @notice Withdraws any native rewards to the owner address + * @param quantity quantity of native tokens to withdraw, address(0) is native + * @param quantity quantity to withdraw + */ + function withdraw(address assetAddress, uint256 quantity) external; + + /** + * @notice Returns the link balance of the fee manager + * @return link balance of the fee manager + */ + function linkAvailableForPayment() external returns (uint256); + + /** + * @notice Admin function to pay the LINK deficit for a given config digest + * @param configDigest the config digest to pay the deficit for + */ + function payLinkDeficit(bytes32 configDigest) external; +} diff --git a/contracts/src/v0.8/llo-feeds/dev/interfaces/IRewardManager.sol b/contracts/src/v0.8/llo-feeds/dev/interfaces/IRewardManager.sol new file mode 100644 index 00000000000..b560b8efb61 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/dev/interfaces/IRewardManager.sol @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.16; + +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol"; +import {Common} from "../../../libraries/Common.sol"; + +interface IRewardManager is IERC165 { + /** + * @notice Record the fee received for a particular pool + * @param poolId poolId of the report being verified + * @param payee the user the funds should be deposited from + * @param amount the amount to be paid into the pool + */ + function onFeePaid(bytes32 poolId, address payee, uint256 amount) external; + + /** + * @notice Claims the rewards in a specific pool + * @param poolIds array of poolIds to claim rewards for + */ + function claimRewards(bytes32[] calldata poolIds) external; + + /** + * @notice Set the RewardRecipients and weights for a specific pool. This should only be called once per pool Id. Else updateRewardRecipients should be used. + * @param poolId poolId to set RewardRecipients and weights for + * @param rewardRecipientAndWeights array of each RewardRecipient and associated weight + */ + function setRewardRecipients(bytes32 poolId, Common.AddressAndWeight[] calldata rewardRecipientAndWeights) external; + + /** + * @notice Updates a subset the reward recipients for a specific poolId. The collective weight of the recipients should add up to the recipients existing weights. Any recipients with a weight of 0 will be removed. + * @param poolId the poolId to update + * @param newRewardRecipients array of new reward recipients + */ + function updateRewardRecipients(bytes32 poolId, Common.AddressAndWeight[] calldata newRewardRecipients) external; + + /** + * @notice Pays all the recipients for each of the pool ids + * @param poolId the pool id to pay recipients for + * @param recipients array of recipients to pay within the pool + */ + function payRecipients(bytes32 poolId, address[] calldata recipients) external; + + /** + * @notice Sets the fee manager. This needs to be done post construction to prevent a circular dependency. + * @param newFeeManager address of the new verifier proxy + */ + function setFeeManager(address newFeeManager) external; + + /** + * @notice Gets a list of pool ids which have reward for a specific recipient. + * @param recipient address of the recipient to get pool ids for + */ + function getAvailableRewardPoolIds(address recipient) external view returns (bytes32[] memory); +} diff --git a/contracts/src/v0.8/llo-feeds/interfaces/IVerifier.sol b/contracts/src/v0.8/llo-feeds/interfaces/IVerifier.sol index 53dd6c6f3e5..181bf9ad716 100644 --- a/contracts/src/v0.8/llo-feeds/interfaces/IVerifier.sol +++ b/contracts/src/v0.8/llo-feeds/interfaces/IVerifier.sol @@ -1,21 +1,22 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.16; -import {IERC165} from "../../shared/vendor/IERC165.sol"; +import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol"; +import {Common} from "../../libraries/Common.sol"; interface IVerifier is IERC165 { /** * @notice Verifies that the data encoded has been signed * correctly by routing to the correct verifier. * @param signedReport The encoded data to be verified. - * @param requester The original address that requested to verify the contract. + * @param sender The address that requested to verify the contract. * This is only used for logging purposes. * @dev Verification is typically only done through the proxy contract so * we can't just use msg.sender to log the requester as the msg.sender * contract will always be the proxy. * @return response The encoded verified response. */ - function verify(bytes memory signedReport, address requester) external returns (bytes memory response); + function verify(bytes calldata signedReport, address sender) external returns (bytes memory response); /** * @notice sets offchain reporting protocol configuration incl. participating oracles @@ -26,6 +27,7 @@ interface IVerifier is IERC165 { * @param onchainConfig serialized configuration used by the contract (and possibly oracles) * @param offchainConfigVersion version number for offchainEncoding schema * @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract + * @param recipientAddressesAndWeights the addresses and weights of all the recipients to receive rewards */ function setConfig( bytes32 feedId, @@ -34,9 +36,66 @@ interface IVerifier is IERC165 { uint8 f, bytes memory onchainConfig, uint64 offchainConfigVersion, - bytes memory offchainConfig + bytes memory offchainConfig, + Common.AddressAndWeight[] memory recipientAddressesAndWeights ) external; + /** + * @notice identical to `setConfig` except with args for sourceChainId and sourceAddress + * @param feedId Feed ID to set config for + * @param sourceChainId Chain ID of source config + * @param sourceAddress Address of source config Verifier + * @param signers addresses with which oracles sign the reports + * @param offchainTransmitters CSA key for the ith Oracle + * @param f number of faulty oracles the system can tolerate + * @param onchainConfig serialized configuration used by the contract (and possibly oracles) + * @param offchainConfigVersion version number for offchainEncoding schema + * @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract + * @param recipientAddressesAndWeights the addresses and weights of all the recipients to receive rewards + */ + function setConfigFromSource( + bytes32 feedId, + uint256 sourceChainId, + address sourceAddress, + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig, + Common.AddressAndWeight[] memory recipientAddressesAndWeights + ) external; + + /** + * @notice Activates the configuration for a config digest + * @param feedId Feed ID to activate config for + * @param configDigest The config digest to activate + * @dev This function can be called by the contract admin to activate a configuration. + */ + function activateConfig(bytes32 feedId, bytes32 configDigest) external; + + /** + * @notice Deactivates the configuration for a config digest + * @param feedId Feed ID to deactivate config for + * @param configDigest The config digest to deactivate + * @dev This function can be called by the contract admin to deactivate an incorrect configuration. + */ + function deactivateConfig(bytes32 feedId, bytes32 configDigest) external; + + /** + * @notice Activates the given feed + * @param feedId Feed ID to activated + * @dev This function can be called by the contract admin to activate a feed + */ + function activateFeed(bytes32 feedId) external; + + /** + * @notice Deactivates the given feed + * @param feedId Feed ID to deactivated + * @dev This function can be called by the contract admin to deactivate a feed + */ + function deactivateFeed(bytes32 feedId) external; + /** * @notice returns the latest config digest and epoch for a feed * @param feedId Feed ID to fetch data for diff --git a/contracts/src/v0.8/llo-feeds/interfaces/IVerifierFeeManager.sol b/contracts/src/v0.8/llo-feeds/interfaces/IVerifierFeeManager.sol new file mode 100644 index 00000000000..345122eb50b --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/interfaces/IVerifierFeeManager.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.16; + +import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol"; +import {Common} from "../../libraries/Common.sol"; + +interface IVerifierFeeManager is IERC165 { + /** + * @notice Handles fees for a report from the subscriber and manages rewards + * @param payload report and quote to process the fee for + * @param subscriber address of the fee will be applied + */ + function processFee(bytes calldata payload, address subscriber) external payable; + + /** + * @notice Sets the fee recipients according to the fee manager + * @param configDigest digest of the configuration + * @param rewardRecipientAndWeights the address and weights of all the recipients to receive rewards + */ + function setFeeRecipients( + bytes32 configDigest, + Common.AddressAndWeight[] calldata rewardRecipientAndWeights + ) external; +} diff --git a/contracts/src/v0.8/llo-feeds/interfaces/IVerifierProxy.sol b/contracts/src/v0.8/llo-feeds/interfaces/IVerifierProxy.sol index 66db64f3e13..d128b5090fa 100644 --- a/contracts/src/v0.8/llo-feeds/interfaces/IVerifierProxy.sol +++ b/contracts/src/v0.8/llo-feeds/interfaces/IVerifierProxy.sol @@ -1,31 +1,41 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.16; +import {Common} from "../../libraries/Common.sol"; +import {AccessControllerInterface} from "../../interfaces/AccessControllerInterface.sol"; +import {IVerifierFeeManager} from "./IVerifierFeeManager.sol"; + interface IVerifierProxy { /** * @notice Verifies that the data encoded has been signed - * correctly by routing to the correct verifier. - * @param signedReport The encoded data to be verified. - * @return verifierResponse The encoded response from the verifier. + * correctly by routing to the correct verifier, and bills the user if applicable. + * @param payload The encoded data to be verified, including the signed + * report and any metadata for billing. + * @return verifiedReport The encoded report from the verifier. + */ + function verify(bytes calldata payload) external payable returns (bytes memory verifiedReport); + + /** + * @notice Sets the verifier address initially, allowing `setVerifier` to be set by this Verifier in the future + * @param verifierAddress The address of the verifier contract to initialize */ - function verify(bytes memory signedReport) external returns (bytes memory verifierResponse); + function initializeVerifier(address verifierAddress) external; /** * @notice Sets a new verifier for a config digest * @param currentConfigDigest The current config digest * @param newConfigDigest The config digest to set + * @param addressesAndWeights The addresses and weights of reward recipients * reports for a given config digest. */ - function setVerifier(bytes32 currentConfigDigest, bytes32 newConfigDigest) external; - - /** - * @notice Sets the verifier address to initialized - * @param verifierAddr The address of the verifier contract that we want to initialize - */ - function initializeVerifier(address verifierAddr) external; + function setVerifier( + bytes32 currentConfigDigest, + bytes32 newConfigDigest, + Common.AddressAndWeight[] memory addressesAndWeights + ) external; /** - * @notice Removes a verifier + * @notice Removes a verifier for a given config digest * @param configDigest The config digest of the verifier to remove */ function unsetVerifier(bytes32 configDigest) external; @@ -34,8 +44,20 @@ interface IVerifierProxy { * @notice Retrieves the verifier address that verifies reports * for a config digest. * @param configDigest The config digest to query for - * @return verifierAddr The address of the verifier contract that verifies + * @return verifierAddress The address of the verifier contract that verifies * reports for a given config digest. */ - function getVerifier(bytes32 configDigest) external view returns (address verifierAddr); + function getVerifier(bytes32 configDigest) external view returns (address verifierAddress); + + /** + * @notice Called by the admin to set an access controller contract + * @param accessController The new access controller to set + */ + function setAccessController(AccessControllerInterface accessController) external; + + /** + * @notice Updates the fee manager + * @param feeManager The new fee manager + */ + function setFeeManager(IVerifierFeeManager feeManager) external; } diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/BaseFeeManager.t.sol b/contracts/src/v0.8/llo-feeds/test/fee-manager/BaseFeeManager.t.sol new file mode 100644 index 00000000000..b17679d1490 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/test/fee-manager/BaseFeeManager.t.sol @@ -0,0 +1,361 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.16; + +import {Test} from "forge-std/Test.sol"; +import {FeeManager} from "../../dev/FeeManager.sol"; +import {IFeeManager} from "../../dev/interfaces/IFeeManager.sol"; +import {RewardManager} from "../../dev/RewardManager.sol"; +import {Common} from "../../../libraries/Common.sol"; +import {ERC20Mock} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/mocks/ERC20Mock.sol"; +import {WERC20Mock} from "../../../shared/mocks/WERC20Mock.sol"; + +/** + * @title BaseFeeManagerTest + * @author Michael Fletcher + * @notice Base class for all feeManager tests + * @dev This contract is intended to be inherited from and not used directly. It contains functionality to setup the feeManager + */ +contract BaseFeeManagerTest is Test { + //contracts + FeeManager internal feeManager; + RewardManager internal rewardManager; + + ERC20Mock internal link; + WERC20Mock internal native; + + //erc20 config + uint256 internal constant DEFAULT_LINK_MINT_QUANTITY = 100 ether; + uint256 internal constant DEFAULT_NATIVE_MINT_QUANTITY = 100 ether; + + //contract owner + address internal constant INVALID_ADDRESS = address(0); + address internal constant ADMIN = address(uint160(uint256(keccak256("ADMIN")))); + address internal constant USER = address(uint160(uint256(keccak256("USER")))); + address internal constant PROXY = address(uint160(uint256(keccak256("PROXY")))); + + //version masks + bytes32 internal constant V_MASK = 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; + bytes32 internal constant V1_BITMASK = 0x0001000000000000000000000000000000000000000000000000000000000000; + bytes32 internal constant V2_BITMASK = 0x0002000000000000000000000000000000000000000000000000000000000000; + bytes32 internal constant V3_BITMASK = 0x0003000000000000000000000000000000000000000000000000000000000000; + + //feed ids & config digests + bytes32 internal constant DEFAULT_FEED_1_V1 = (keccak256("ETH-USD") & V_MASK) | V1_BITMASK; + bytes32 internal constant DEFAULT_FEED_1_V2 = (keccak256("ETH-USD") & V_MASK) | V2_BITMASK; + bytes32 internal constant DEFAULT_FEED_1_V3 = (keccak256("ETH-USD") & V_MASK) | V3_BITMASK; + + bytes32 internal constant DEFAULT_FEED_2_V3 = (keccak256("LINK-USD") & V_MASK) | V3_BITMASK; + bytes32 internal constant DEFAULT_CONFIG_DIGEST = keccak256("DEFAULT_CONFIG_DIGEST"); + + //report + uint256 internal constant DEFAULT_REPORT_LINK_FEE = 1e10; + uint256 internal constant DEFAULT_REPORT_NATIVE_FEE = 1e12; + + //rewards + uint256 internal constant FEE_SCALAR = 1e18; + + address internal constant NATIVE_WITHDRAW_ADDRESS = address(0); + + //the selector for each error + bytes4 internal immutable INVALID_DISCOUNT_ERROR = FeeManager.InvalidDiscount.selector; + bytes4 internal immutable INVALID_ADDRESS_ERROR = FeeManager.InvalidAddress.selector; + bytes4 internal immutable INVALID_SURCHARGE_ERROR = FeeManager.InvalidSurcharge.selector; + bytes4 internal immutable EXPIRED_REPORT_ERROR = FeeManager.ExpiredReport.selector; + bytes4 internal immutable INVALID_DEPOSIT_ERROR = FeeManager.InvalidDeposit.selector; + bytes4 internal immutable INVALID_QUOTE_ERROR = FeeManager.InvalidQuote.selector; + bytes4 internal immutable UNAUTHORIZED_ERROR = FeeManager.Unauthorized.selector; + bytes internal constant ONLY_CALLABLE_BY_OWNER_ERROR = "Only callable by owner"; + bytes internal constant INSUFFICIENT_ALLOWANCE_ERROR = "ERC20: insufficient allowance"; + bytes4 internal immutable ZERO_DEFICIT = FeeManager.ZeroDeficit.selector; + + //events emitted + event SubscriberDiscountUpdated(address indexed subscriber, bytes32 indexed feedId, address token, uint256 discount); + event NativeSurchargeUpdated(uint256 newSurcharge); + event InsufficientLink(bytes32 indexed configDigest, uint256 linkQuantity, uint256 nativeQuantity); + event Withdraw(address adminAddress, address assetAddress, uint256 quantity); + event LinkDeficitCleared(bytes32 indexed configDigest, uint256 linkQuantity); + + function setUp() public virtual { + //change to admin user + vm.startPrank(ADMIN); + + //init required contracts + _initializeContracts(); + } + + function _initializeContracts() internal { + link = new ERC20Mock("LINK", "LINK", ADMIN, 0); + native = new WERC20Mock(); + + rewardManager = new RewardManager(getLinkAddress()); + feeManager = new FeeManager(getLinkAddress(), getNativeAddress(), PROXY, address(rewardManager)); + + //link the feeManager to the reward manager + rewardManager.setFeeManager(address(feeManager)); + + //mint some tokens to the admin + link.mint(ADMIN, DEFAULT_LINK_MINT_QUANTITY); + native.mint(ADMIN, DEFAULT_NATIVE_MINT_QUANTITY); + vm.deal(ADMIN, DEFAULT_NATIVE_MINT_QUANTITY); + + //mint some tokens to the user + link.mint(USER, DEFAULT_LINK_MINT_QUANTITY); + native.mint(USER, DEFAULT_NATIVE_MINT_QUANTITY); + vm.deal(USER, DEFAULT_NATIVE_MINT_QUANTITY); + + //mint some tokens to the proxy + link.mint(PROXY, DEFAULT_LINK_MINT_QUANTITY); + native.mint(PROXY, DEFAULT_NATIVE_MINT_QUANTITY); + vm.deal(PROXY, DEFAULT_NATIVE_MINT_QUANTITY); + } + + function setSubscriberDiscount( + address subscriber, + bytes32 feedId, + address token, + uint256 discount, + address sender + ) internal { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //set the discount + feeManager.updateSubscriberDiscount(subscriber, feedId, token, discount); + + //change back to the original address + changePrank(originalAddr); + } + + function setNativeSurcharge(uint256 surcharge, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //set the surcharge + feeManager.setNativeSurcharge(surcharge); + + //change back to the original address + changePrank(originalAddr); + } + + // solium-disable-next-line no-unused-vars + function getFee( + bytes memory report, + IFeeManager.Quote memory quote, + address subscriber + ) public view returns (Common.Asset memory) { + //get the fee + (Common.Asset memory fee, ) = feeManager.getFeeAndReward(subscriber, report, quote); + + return fee; + } + + function getReward( + bytes memory report, + IFeeManager.Quote memory quote, + address subscriber + ) public view returns (Common.Asset memory) { + //get the reward + (, Common.Asset memory reward) = feeManager.getFeeAndReward(subscriber, report, quote); + + return reward; + } + + function getV0Report(bytes32 feedId) public pure returns (bytes memory) { + return abi.encode(feedId, uint32(0), int192(0), int192(0), int192(0), uint64(0), bytes32(0), uint64(0), uint64(0)); + } + + function getV1Report(bytes32 feedId) public view returns (bytes memory) { + return + abi.encode( + feedId, + uint32(0), + uint32(0), + int192(0), + uint192(DEFAULT_REPORT_LINK_FEE), + uint192(DEFAULT_REPORT_NATIVE_FEE), + uint32(block.timestamp) + ); + } + + function getV1ReportWithExpiryAndFee( + bytes32 feedId, + uint256 expiry, + uint256 linkFee, + uint256 nativeFee + ) public pure returns (bytes memory) { + return abi.encode(feedId, uint32(0), uint32(0), int192(0), uint192(linkFee), uint192(nativeFee), uint32(expiry)); + } + + function getV2Report(bytes32 feedId) public view returns (bytes memory) { + return + abi.encode( + feedId, + uint32(0), + uint32(0), + int192(0), + uint192(DEFAULT_REPORT_LINK_FEE), + uint192(DEFAULT_REPORT_NATIVE_FEE), + uint32(block.timestamp), + int192(0), + int192(0) + ); + } + + function getV2ReportWithCustomExpiryAndFee( + bytes32 feedId, + uint256 expiry, + uint256 linkFee, + uint256 nativeFee + ) public pure returns (bytes memory) { + return + abi.encode( + feedId, + uint32(0), + uint32(0), + int192(0), + uint192(linkFee), + uint192(nativeFee), + uint32(expiry), + int192(0), + int192(0) + ); + } + + function getLinkQuote() public view returns (IFeeManager.Quote memory) { + return IFeeManager.Quote(getLinkAddress()); + } + + function getNativeQuote() public view returns (IFeeManager.Quote memory) { + return IFeeManager.Quote(getNativeAddress()); + } + + function withdraw(address assetAddress, uint256 amount, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //set the surcharge + feeManager.withdraw(assetAddress, amount); + + //change back to the original address + changePrank(originalAddr); + } + + function getLinkBalance(address balanceAddress) public view returns (uint256) { + return link.balanceOf(balanceAddress); + } + + function getNativeBalance(address balanceAddress) public view returns (uint256) { + return native.balanceOf(balanceAddress); + } + + function getNativeUnwrappedBalance(address balanceAddress) public view returns (uint256) { + return balanceAddress.balance; + } + + function mintLink(address recipient, uint256 amount) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(ADMIN); + + //mint the link to the recipient + link.mint(recipient, amount); + + //change back to the original address + changePrank(originalAddr); + } + + function mintNative(address recipient, uint256 amount, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //mint the native to the recipient + native.mint(recipient, amount); + + //change back to the original address + changePrank(originalAddr); + } + + function issueUnwrappedNative(address recipient, uint256 quantity) public { + vm.deal(recipient, quantity); + } + + function processFee(bytes memory payload, address subscriber, uint256 wrappedNativeValue, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //process the fee + feeManager.processFee{value: wrappedNativeValue}(payload, subscriber); + + //change back to the original address + changePrank(originalAddr); + } + + function getPayload(bytes memory reportPayload, bytes memory quotePayload) public pure returns (bytes memory) { + return + abi.encode( + [DEFAULT_CONFIG_DIGEST, 0, 0], + reportPayload, + new bytes32[](1), + new bytes32[](1), + bytes32(""), + quotePayload + ); + } + + function getQuotePayload(address quoteAddress) public pure returns (bytes memory) { + return abi.encode(quoteAddress); + } + + function approveLink(address spender, uint256 quantity, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //approve the link to be transferred + link.approve(spender, quantity); + + //change back to the original address + changePrank(originalAddr); + } + + function approveNative(address spender, uint256 quantity, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //approve the link to be transferred + native.approve(spender, quantity); + + //change back to the original address + changePrank(originalAddr); + } + + function getLinkAddress() public view returns (address) { + return address(link); + } + + function getNativeAddress() public view returns (address) { + return address(native); + } + + function payLinkDeficit(bytes32 configDigest, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //approve the link to be transferred + feeManager.payLinkDeficit(configDigest); + + //change back to the original address + changePrank(originalAddr); + } + + function getLinkDeficit(bytes32 configDigest) public view returns (uint256) { + return feeManager.s_linkDeficit(configDigest); + } +} diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.general.t.sol b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.general.t.sol new file mode 100644 index 00000000000..0c8c9dd9ee4 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.general.t.sol @@ -0,0 +1,236 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.16; + +import {Test} from "forge-std/Test.sol"; +import {FeeManager} from "../../dev/FeeManager.sol"; +import {Common} from "../../../libraries/Common.sol"; +import "./BaseFeeManager.t.sol"; + +/** + * @title BaseFeeManagerTest + * @author Michael Fletcher + * @notice This contract will test the setup functionality of the feemanager + */ +contract FeeManagerProcessFeeTest is BaseFeeManagerTest { + function setUp() public override { + super.setUp(); + } + + function test_WithdrawERC20() public { + //simulate a fee + mintLink(address(feeManager), DEFAULT_LINK_MINT_QUANTITY); + + //get the balances to ne used for comparison + uint256 contractBalance = getLinkBalance(address(feeManager)); + uint256 adminBalance = getLinkBalance(ADMIN); + + //the amount to withdraw + uint256 withdrawAmount = contractBalance / 2; + + //withdraw some balance + withdraw(getLinkAddress(), withdrawAmount, ADMIN); + + //check the balance has been reduced + uint256 newContractBalance = getLinkBalance(address(feeManager)); + uint256 newAdminBalance = getLinkBalance(ADMIN); + + //check the balance is greater than zero + assertGt(newContractBalance, 0); + //check the balance has been reduced by the correct amount + assertEq(newContractBalance, contractBalance - withdrawAmount); + //check the admin balance has increased by the correct amount + assertEq(newAdminBalance, adminBalance + withdrawAmount); + } + + function test_WithdrawUnwrappedNative() public { + //issue funds straight to the contract to bypass the lack of fallback function + issueUnwrappedNative(address(feeManager), DEFAULT_NATIVE_MINT_QUANTITY); + + //get the balances to be used for comparison + uint256 contractBalance = getNativeUnwrappedBalance(address(feeManager)); + uint256 adminBalance = getNativeUnwrappedBalance(ADMIN); + + //the amount to withdraw + uint256 withdrawAmount = contractBalance / 2; + + //withdraw some balance + withdraw(NATIVE_WITHDRAW_ADDRESS, withdrawAmount, ADMIN); + + //check the balance has been reduced + uint256 newContractBalance = getNativeUnwrappedBalance(address(feeManager)); + uint256 newAdminBalance = getNativeUnwrappedBalance(ADMIN); + + //check the balance is greater than zero + assertGt(newContractBalance, 0); + //check the balance has been reduced by the correct amount + assertEq(newContractBalance, contractBalance - withdrawAmount); + //check the admin balance has increased by the correct amount + assertEq(newAdminBalance, adminBalance + withdrawAmount); + } + + function test_WithdrawNonAdminAddr() public { + //simulate a fee + mintLink(address(feeManager), DEFAULT_LINK_MINT_QUANTITY); + + //should revert if not admin + vm.expectRevert(ONLY_CALLABLE_BY_OWNER_ERROR); + + //withdraw some balance + withdraw(getLinkAddress(), DEFAULT_LINK_MINT_QUANTITY, USER); + } + + function test_eventIsEmittedAfterSurchargeIsSet() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 5; + + //expect an emit + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit NativeSurchargeUpdated(nativeSurcharge); + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + } + + function test_subscriberDiscountEventIsEmittedOnUpdate() public { + //native surcharge + uint256 discount = FEE_SCALAR / 3; + + //an event should be emitted + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit SubscriberDiscountUpdated(USER, DEFAULT_FEED_1_V3, getNativeAddress(), discount); + + //set the surcharge + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), discount, ADMIN); + } + + function test_eventIsEmittedUponWithdraw() public { + //simulate a fee + mintLink(address(feeManager), DEFAULT_LINK_MINT_QUANTITY); + + //the amount to withdraw + uint256 withdrawAmount = 1; + + //expect an emit + vm.expectEmit(); + + //the event to be emitted + emit Withdraw(ADMIN, getLinkAddress(), withdrawAmount); + + //withdraw some balance + withdraw(getLinkAddress(), withdrawAmount, ADMIN); + } + + function test_linkAvailableForPaymentReturnsLinkBalance() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //check there's a balance + assertGt(getLinkBalance(address(feeManager)), 0); + + //check the link available for payment is the link balance + assertEq(feeManager.linkAvailableForPayment(), getLinkBalance(address(feeManager))); + } + + function test_payLinkDeficit() public { + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getNativeAddress())); + + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + + //not enough funds in the reward pool should trigger an insufficient link event + vm.expectEmit(); + emit InsufficientLink(DEFAULT_CONFIG_DIGEST, DEFAULT_REPORT_LINK_FEE, DEFAULT_REPORT_NATIVE_FEE); + + //process the fee + processFee(payload, USER, 0, ADMIN); + + //double check the rewardManager balance is 0 + assertEq(getLinkBalance(address(rewardManager)), 0); + + //simulate a deposit of link to cover the deficit + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + vm.expectEmit(); + emit LinkDeficitCleared(DEFAULT_CONFIG_DIGEST, DEFAULT_REPORT_LINK_FEE); + + //pay the deficit which will transfer link from the rewardManager to the rewardManager + payLinkDeficit(DEFAULT_CONFIG_DIGEST, ADMIN); + + //check the rewardManager received the link + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + } + + function test_payLinkDeficitTwice() public { + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getNativeAddress())); + + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + + //not enough funds in the reward pool should trigger an insufficient link event + vm.expectEmit(); + emit InsufficientLink(DEFAULT_CONFIG_DIGEST, DEFAULT_REPORT_LINK_FEE, DEFAULT_REPORT_NATIVE_FEE); + + //process the fee + processFee(payload, USER, 0, ADMIN); + + //double check the rewardManager balance is 0 + assertEq(getLinkBalance(address(rewardManager)), 0); + + //simulate a deposit of link to cover the deficit + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + vm.expectEmit(); + emit LinkDeficitCleared(DEFAULT_CONFIG_DIGEST, DEFAULT_REPORT_LINK_FEE); + + //pay the deficit which will transfer link from the rewardManager to the rewardManager + payLinkDeficit(DEFAULT_CONFIG_DIGEST, ADMIN); + + //check the rewardManager received the link + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //paying again should revert with 0 + vm.expectRevert(ZERO_DEFICIT); + + payLinkDeficit(DEFAULT_CONFIG_DIGEST, ADMIN); + } + + function test_payLinkDeficitPaysAllFeesProcessed() public { + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getNativeAddress())); + + //approve the native to be transferred from the user + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE * 2, USER); + + //processing the fee will transfer the native from the user to the feeManager + processFee(payload, USER, 0, ADMIN); + processFee(payload, USER, 0, ADMIN); + + //check the deficit has been increased twice + assertEq(getLinkDeficit(DEFAULT_CONFIG_DIGEST), DEFAULT_REPORT_LINK_FEE * 2); + + //double check the rewardManager balance is 0 + assertEq(getLinkBalance(address(rewardManager)), 0); + + //simulate a deposit of link to cover the deficit + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE * 2); + + vm.expectEmit(); + emit LinkDeficitCleared(DEFAULT_CONFIG_DIGEST, DEFAULT_REPORT_LINK_FEE * 2); + + //pay the deficit which will transfer link from the rewardManager to the rewardManager + payLinkDeficit(DEFAULT_CONFIG_DIGEST, ADMIN); + + //check the rewardManager received the link + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * 2); + } + + function test_payLinkDeficitOnlyCallableByAdmin() public { + vm.expectRevert(ONLY_CALLABLE_BY_OWNER_ERROR); + + payLinkDeficit(DEFAULT_CONFIG_DIGEST, USER); + } +} diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.getFeeAndReward.t.sol b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.getFeeAndReward.t.sol new file mode 100644 index 00000000000..0baf8dee084 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.getFeeAndReward.t.sol @@ -0,0 +1,569 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.16; + +import {Test} from "forge-std/Test.sol"; +import {FeeManager} from "../../dev/FeeManager.sol"; +import {IFeeManager} from "../../dev/interfaces/IFeeManager.sol"; +import {Common} from "../../../libraries/Common.sol"; +import "./BaseFeeManager.t.sol"; + +/** + * @title BaseFeeManagerTest + * @author Michael Fletcher + * @notice This contract will test the functionality of the feeManager's getFeeAndReward + */ +contract FeeManagerProcessFeeTest is BaseFeeManagerTest { + function test_baseFeeIsAppliedForNative() public { + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be the default + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE); + } + + function test_baseFeeIsAppliedForLink() public { + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be the default + assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE); + } + + function test_discountAIsNotAppliedWhenSetForOtherUsers() public { + //set the subscriber discount for another user + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getLinkAddress(), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), INVALID_ADDRESS); + + //fee should be the default + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE); + } + + function test_discountIsNotAppliedForInvalidTokenAddress() public { + //should revert with invalid address as it's not a configured token + vm.expectRevert(INVALID_ADDRESS_ERROR); + + //set the subscriber discount for another user + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, INVALID_ADDRESS, FEE_SCALAR / 2, ADMIN); + } + + function test_discountIsAppliedForLink() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getLinkAddress(), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be half the default + assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE / 2); + } + + function test_DiscountIsAppliedForNative() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be half the default + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE / 2); + } + + function test_discountIsNoLongerAppliedAfterRemoving() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getLinkAddress(), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be half the default + assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE / 2); + + //remove the discount + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getLinkAddress(), 0, ADMIN); + + //get the fee required by the feeManager + fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be the default + assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE); + } + + function test_surchargeIsApplied() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 5; + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected surcharge + uint256 expectedSurcharge = ((DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR); + + //expected fee should the base fee offset by the surcharge and discount + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE + expectedSurcharge); + } + + function test_surchargeIsNotAppliedForLinkFee() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 5; + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be the default + assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE); + } + + function test_surchargeIsNoLongerAppliedAfterRemoving() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 5; + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected surcharge + uint256 expectedSurcharge = ((DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR); + + //expected fee should be the base fee offset by the surcharge and discount + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE + expectedSurcharge); + + //remove the surcharge + setNativeSurcharge(0, ADMIN); + + //get the fee required by the feeManager + fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be the default + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE); + } + + function test_feeIsUpdatedAfterNewSurchargeIsApplied() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 5; + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected surcharge + uint256 expectedSurcharge = ((DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR); + + //expected fee should the base fee offset by the surcharge and discount + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE + expectedSurcharge); + + //change the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected surcharge + expectedSurcharge = ((DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR); + + //expected fee should the base fee offset by the surcharge and discount + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE + expectedSurcharge); + } + + function test_surchargeIsAppliedForNativeFeeWithDiscount() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 5; + + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 2, ADMIN); + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected surcharge quantity + uint256 expectedSurcharge = ((DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR); + + //calculate the expected discount quantity + uint256 expectedDiscount = ((DEFAULT_REPORT_NATIVE_FEE + expectedSurcharge) / 2); + + //expected fee should the base fee offset by the surcharge and discount + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE + expectedSurcharge - expectedDiscount); + } + + function test_emptyQuoteRevertsWithError() public { + //expect a revert + vm.expectRevert(INVALID_QUOTE_ERROR); + + //get the fee required by the feeManager + getFee(getV2Report(DEFAULT_FEED_1_V3), IFeeManager.Quote(address(0)), USER); + } + + function test_nativeSurcharge100Percent() public { + //set the surcharge + setNativeSurcharge(FEE_SCALAR, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be twice the base fee + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE * 2); + } + + function test_nativeSurcharge0Percent() public { + //set the surcharge + setNativeSurcharge(0, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should base fee + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE); + } + + function test_nativeSurchargeCannotExceed100Percent() public { + //should revert if surcharge is greater than 100% + vm.expectRevert(INVALID_SURCHARGE_ERROR); + + //set the surcharge above the max + setNativeSurcharge(FEE_SCALAR + 1, ADMIN); + } + + function test_discountIsAppliedWith100PercentSurcharge() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 2, ADMIN); + + //set the surcharge + setNativeSurcharge(FEE_SCALAR, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected discount quantity + uint256 expectedDiscount = DEFAULT_REPORT_NATIVE_FEE; + + //fee should be twice the surcharge minus the discount + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE * 2 - expectedDiscount); + } + + function test_feeIsZeroWith100PercentDiscount() public { + //set the subscriber discount to 100% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be zero + assertEq(fee.amount, 0); + } + + function test_feeIsUpdatedAfterDiscountIsRemoved() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected discount quantity + uint256 expectedDiscount = DEFAULT_REPORT_NATIVE_FEE / 2; + + //fee should be 50% of the base fee + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE - expectedDiscount); + + //remove the discount + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), 0, ADMIN); + + //get the fee required by the feeManager + fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be the base fee + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE); + } + + function test_feeIsUpdatedAfterNewDiscountIsApplied() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected discount quantity + uint256 expectedDiscount = DEFAULT_REPORT_NATIVE_FEE / 2; + + //fee should be 50% of the base fee + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE - expectedDiscount); + + //change the discount to 25% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 4, ADMIN); + + //get the fee required by the feeManager + fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //expected discount is now 25% + expectedDiscount = DEFAULT_REPORT_NATIVE_FEE / 4; + + //fee should be the base fee minus the expected discount + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE - expectedDiscount); + } + + function test_setDiscountOver100Percent() public { + //should revert with invalid discount + vm.expectRevert(INVALID_DISCOUNT_ERROR); + + //set the subscriber discount to over 100% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR + 1, ADMIN); + } + + function test_surchargeIsNotAppliedWith100PercentDiscount() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 5; + + //set the subscriber discount to 100% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR, ADMIN); + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be zero + assertEq(fee.amount, 0); + } + + function test_nonAdminUserCanNotSetDiscount() public { + //should revert with unauthorized + vm.expectRevert(ONLY_CALLABLE_BY_OWNER_ERROR); + + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR, USER); + } + + function test_surchargeFeeRoundsUpWhenUneven() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 3; + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected surcharge quantity + uint256 expectedSurcharge = (DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR; + + //expected fee should the base fee offset by the expected surcharge + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE + expectedSurcharge + 1); + } + + function test_discountFeeRoundsDownWhenUneven() public { + //native surcharge + uint256 discount = FEE_SCALAR / 3; + + //set the subscriber discount to 33.333% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), discount, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected quantity + uint256 expectedDiscount = ((DEFAULT_REPORT_NATIVE_FEE * discount) / FEE_SCALAR); + + //expected fee should the base fee offset by the expected surcharge + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE - expectedDiscount); + } + + function test_reportWithNoExpiryOrFeeReturnsZero() public { + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV0Report(DEFAULT_FEED_1_V1), getNativeQuote(), USER); + + //fee should be zero + assertEq(fee.amount, 0); + } + + function test_correctDiscountIsAppliedWhenBothTokensAreDiscounted() public { + //set the subscriber and native discounts + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getLinkAddress(), FEE_SCALAR / 4, ADMIN); + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager for both tokens + Common.Asset memory linkFee = getFee(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + Common.Asset memory nativeFee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected discount quantity for each token + uint256 expectedDiscountLink = (DEFAULT_REPORT_LINK_FEE * FEE_SCALAR) / 4 / FEE_SCALAR; + uint256 expectedDiscountNative = (DEFAULT_REPORT_NATIVE_FEE * FEE_SCALAR) / 2 / FEE_SCALAR; + + //check the fee calculation for each token + assertEq(linkFee.amount, DEFAULT_REPORT_LINK_FEE - expectedDiscountLink); + assertEq(nativeFee.amount, DEFAULT_REPORT_NATIVE_FEE - expectedDiscountNative); + } + + function test_discountIsNotAppliedToOtherFeeds() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_2_V3), getNativeQuote(), USER); + + //fee should be the base fee + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE); + } + + function test_noFeeIsAppliedWhenReportHasZeroFee() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee( + getV2ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, uint32(block.timestamp), 0, 0), + getNativeQuote(), + USER + ); + + //fee should be zero + assertEq(fee.amount, 0); + } + + function test_noFeeIsAppliedWhenReportHasZeroFeeAndDiscountAndSurchargeIsSet() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 2, ADMIN); + + //set the surcharge + setNativeSurcharge(FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee( + getV2ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, uint32(block.timestamp), 0, 0), + getNativeQuote(), + USER + ); + + //fee should be zero + assertEq(fee.amount, 0); + } + + function test_nativeSurchargeEventIsEmittedOnUpdate() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 3; + + //an event should be emitted + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit NativeSurchargeUpdated(nativeSurcharge); + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + } + + function test_getBaseRewardWithLinkQuote() public { + //get the fee required by the feeManager + Common.Asset memory fee = getReward(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //the reward should equal the base fee + assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE); + } + + function test_getRewardWithLinkQuoteAndLinkDiscount() public { + //set the link discount + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getLinkAddress(), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getReward(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //the reward should equal the discounted base fee + assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE / 2); + } + + function test_getRewardWithNativeQuote() public { + //get the fee required by the feeManager + Common.Asset memory fee = getReward(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //the reward should equal the base fee in link + assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE); + } + + function test_getRewardWithNativeQuoteAndSurcharge() public { + //set the native surcharge + setNativeSurcharge(FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getReward(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //the reward should equal the base fee in link regardless of the surcharge + assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE); + } + + function test_getRewardWithLinkDiscount() public { + //set the link discount + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getLinkAddress(), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getReward(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //the reward should equal the discounted base fee + assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE / 2); + } + + function test_getLinkFeeIsRoundedUp() public { + //set the link discount + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getLinkAddress(), FEE_SCALAR / 3, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //the reward should equal .66% + 1 of the base fee due to a 33% discount rounded up + assertEq(fee.amount, (DEFAULT_REPORT_LINK_FEE * 2) / 3 + 1); + } + + function test_getLinkRewardIsRoundedDown() public { + //set the link discount + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getLinkAddress(), FEE_SCALAR / 3, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getReward(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //the reward should equal .66% of the base fee due to a 33% discount rounded down + assertEq(fee.amount, (DEFAULT_REPORT_LINK_FEE * 2) / 3); + } + + function test_getLinkRewardWithNativeQuoteAndSurchargeWithLinkDiscount() public { + //set the native surcharge + setNativeSurcharge(FEE_SCALAR / 2, ADMIN); + + //set the link discount + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getLinkAddress(), FEE_SCALAR / 3, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getReward(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //the reward should equal the base fee in link regardless of the surcharge + assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE); + } + + function test_testRevertIfReportHasExpired() public { + //expect a revert + vm.expectRevert(EXPIRED_REPORT_ERROR); + + //get the fee required by the feeManager + getFee( + getV2ReportWithCustomExpiryAndFee( + DEFAULT_FEED_1_V3, + block.timestamp - 1, + DEFAULT_REPORT_LINK_FEE, + DEFAULT_REPORT_NATIVE_FEE + ), + getNativeQuote(), + USER + ); + } +} diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFee.t.sol b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFee.t.sol new file mode 100644 index 00000000000..4ba54bb5fdb --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFee.t.sol @@ -0,0 +1,330 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.16; + +import {Test} from "forge-std/Test.sol"; +import {FeeManager} from "../../dev/FeeManager.sol"; +import {Common} from "../../../libraries/Common.sol"; +import "./BaseFeeManager.t.sol"; + +/** + * @title BaseFeeManagerTest + * @author Michael Fletcher + * @notice This contract will test the functionality of the feeManager processFee + */ +contract FeeManagerProcessFeeTest is BaseFeeManagerTest { + function setUp() public override { + super.setUp(); + } + + function test_nonAdminProxyUserCannotProcessFee() public { + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getLinkAddress())); + + //should revert as the user is not the owner + vm.expectRevert(UNAUTHORIZED_ERROR); + + //process the fee + processFee(payload, USER, 0, USER); + } + + function test_processFeeAsProxy() public { + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getLinkAddress())); + + //approve the link to be transferred from the from the subscriber to the rewardManager + approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + + //processing the fee will transfer the link from the user to the rewardManager + processFee(payload, USER, 0, PROXY); + + //check the link has been transferred + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the user has had the link fee deducted + assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE); + } + + function test_processFeeIfSubscriberIsSelf() public { + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getLinkAddress())); + + //expect a revert due to funds being unapproved + vm.expectRevert(INVALID_ADDRESS_ERROR); + + //process the fee will attempt to transfer link from the contract to the rewardManager, which won't be approved + processFee(payload, address(feeManager), 0, ADMIN); + } + + function test_processFeeWithWithEmptyQuotePayload() public { + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), bytes("")); + + //expect a revert as the quote is invalid + vm.expectRevert(); + + //processing the fee will transfer the link by default + processFee(payload, USER, 0, ADMIN); + } + + function test_processFeeWithWithZeroQuotePayload() public { + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(INVALID_ADDRESS)); + + //expect a revert as the quote is invalid + vm.expectRevert(INVALID_QUOTE_ERROR); + + //processing the fee will transfer the link by default + processFee(payload, USER, 0, ADMIN); + } + + function test_processFeeWithWithCorruptQuotePayload() public { + //get the default payload + bytes memory payload = abi.encode( + [DEFAULT_CONFIG_DIGEST, 0, 0], + getV2Report(DEFAULT_FEED_1_V3), + new bytes32[](1), + new bytes32[](1), + bytes32("") + ); + + //expect an evm revert as the quote is corrupt + vm.expectRevert(); + + //processing the fee will not withdraw anything as there is no fee to collect + processFee(payload, USER, 0, ADMIN); + } + + function test_processFeeDefaultReportsStillVerifiesWithEmptyQuote() public { + //get the default payload + bytes memory payload = getPayload(getV0Report(DEFAULT_FEED_1_V1), bytes("")); + + //processing the fee will transfer the link from the user to the rewardManager + processFee(payload, USER, 0, PROXY); + } + + function test_processFeeWithDefaultReportPayloadAndQuoteStillVerifies() public { + //get the default payload + bytes memory payload = getPayload(getV0Report(DEFAULT_FEED_1_V1), getQuotePayload(getLinkAddress())); + + //processing the fee will not withdraw anything as there is no fee to collect + processFee(payload, USER, 0, ADMIN); + } + + function test_processFeeNative() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getNativeAddress())); + + //approve the native to be transferred from the user + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + + //processing the fee will transfer the native from the user to the feeManager + processFee(payload, USER, 0, ADMIN); + + //check the native has been transferred + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE); + + //check the link has been transferred to the rewardManager + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the feeManager has had the link deducted, the remaining balance should be 0 + assertEq(getLinkBalance(address(feeManager)), 0); + + //check the subscriber has had the native deducted + assertEq(getNativeBalance(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + } + + function test_processFeeEmitsEventIfNotEnoughLink() public { + //simulate a deposit of half the link required for the fee + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE / 2); + + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getNativeAddress())); + + //approve the native to be transferred from the user + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + + //expect an emit as there's not enough link + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit InsufficientLink(DEFAULT_CONFIG_DIGEST, DEFAULT_REPORT_LINK_FEE, DEFAULT_REPORT_NATIVE_FEE); + + //processing the fee will transfer the native from the user to the feeManager + processFee(payload, USER, 0, ADMIN); + + //check the native has been transferred + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE); + + //check no link has been transferred to the rewardManager + assertEq(getLinkBalance(address(rewardManager)), 0); + assertEq(getLinkBalance(address(feeManager)), DEFAULT_REPORT_LINK_FEE / 2); + + //check the subscriber has had the native deducted + assertEq(getNativeBalance(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + } + + function test_processFeeWithUnwrappedNative() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getNativeAddress())); + + //only the proxy or admin can call processFee, they will pass in the native value on the users behalf + processFee(payload, USER, DEFAULT_REPORT_NATIVE_FEE, PROXY); + + //check the native has been transferred and converted to wrapped native + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE); + assertEq(getNativeUnwrappedBalance(address(feeManager)), 0); + + //check the link has been transferred to the rewardManager + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the feeManager has had the link deducted, the remaining balance should be 0 + assertEq(getLinkBalance(address(feeManager)), 0); + + //check the subscriber has had the native deducted + assertEq(getNativeUnwrappedBalance(PROXY), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + } + + function test_processFeeWithUnwrappedNativeShortFunds() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getNativeAddress())); + + //expect a revert as not enough funds + vm.expectRevert(INVALID_DEPOSIT_ERROR); + + //only the proxy or admin can call processFee, they will pass in the native value on the users behalf + processFee(payload, USER, DEFAULT_REPORT_NATIVE_FEE - 1, PROXY); + } + + function test_processFeeWithUnwrappedNativeLinkAddress() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getLinkAddress())); + + //expect a revert as not enough funds + vm.expectRevert(INVALID_DEPOSIT_ERROR); + + //only the proxy or admin can call processFee, they will pass in the native value on the users behalf + processFee(payload, USER, DEFAULT_REPORT_NATIVE_FEE - 1, PROXY); + } + + function test_processFeeWithUnwrappedNativeWithExcessiveFee() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getNativeAddress())); + + //call processFee from the proxy to test whether the funds are returned to the subscriber. In reality, the funds would be returned to the caller of the proxy. + processFee(payload, PROXY, DEFAULT_REPORT_NATIVE_FEE * 2, PROXY); + + //check the native has been transferred and converted to wrapped native + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE); + assertEq(getNativeUnwrappedBalance(address(feeManager)), 0); + + //check the link has been transferred to the rewardManager + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the feeManager has had the link deducted, the remaining balance should be 0 + assertEq(getLinkBalance(address(feeManager)), 0); + + //check the subscriber has had the native deducted + assertEq(getNativeUnwrappedBalance(PROXY), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + } + + function test_processFeeUsesCorrectDigest() public { + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getLinkAddress())); + + //approve the link to be transferred from the from the subscriber to the rewardManager + approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + + //processing the fee will transfer the link from the user to the rewardManager + processFee(payload, USER, 0, PROXY); + + //check the link has been transferred + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the user has had the link fee deducted + assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE); + + //check funds have been paid to the reward manager + assertEq(rewardManager.s_totalRewardRecipientFees(DEFAULT_CONFIG_DIGEST), DEFAULT_REPORT_LINK_FEE); + } + + function test_V1PayloadVerifies() public { + //replicate a default payload + bytes memory payload = abi.encode( + [DEFAULT_CONFIG_DIGEST, 0, 0], + getV1Report(DEFAULT_FEED_1_V1), + new bytes32[](1), + new bytes32[](1), + bytes32("") + ); + + //processing the fee will transfer the link from the user to the rewardManager + processFee(payload, USER, 0, PROXY); + } + + function test_V2PayloadVerifies() public { + //get the default payload + bytes memory payload = getPayload(getV1Report(DEFAULT_FEED_1_V2), getQuotePayload(getLinkAddress())); + + //approve the link to be transferred from the from the subscriber to the rewardManager + approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + + //processing the fee will transfer the link from the user to the rewardManager + processFee(payload, USER, 0, ADMIN); + + //check the link has been transferred + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the user has had the link fee deducted + assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE); + } + + function test_V2PayloadWithoutQuoteFails() public { + //get the default payload + bytes memory payload = getPayload(getV1Report(DEFAULT_FEED_1_V2), bytes("")); + + //expect a revert as the quote is invalid + vm.expectRevert(); + + //processing the fee will transfer the link from the user to the rewardManager + processFee(payload, USER, 0, ADMIN); + } + + function test_V2PayloadWithoutZeroFee() public { + //get the default payload + bytes memory payload = getPayload(getV1Report(DEFAULT_FEED_1_V2), getQuotePayload(getLinkAddress())); + + //expect a revert as the quote is invalid + vm.expectRevert(); + + //processing the fee will transfer the link from the user to the rewardManager + processFee(payload, USER, 0, ADMIN); + } + + function test_processFeeWithInvalidReportVersionFailsToDecode() public { + bytes memory data = abi.encode(0x0000100000000000000000000000000000000000000000000000000000000000); + + //get the default payload + bytes memory payload = getPayload(data, getQuotePayload(getLinkAddress())); + + //serialization will fail as there is no report to decode + vm.expectRevert(); + + //processing the fee will not withdraw anything as there is no fee to collect + processFee(payload, USER, 0, ADMIN); + } +} diff --git a/contracts/src/v0.8/llo-feeds/test/gas/Gas_VerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/test/gas/Gas_VerifierTest.t.sol index 48e8689e6e4..e3764fce0a6 100644 --- a/contracts/src/v0.8/llo-feeds/test/gas/Gas_VerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/gas/Gas_VerifierTest.t.sol @@ -1,9 +1,10 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.16; -import {BaseTest, BaseTestWithConfiguredVerifier} from "../BaseVerifierTest.t.sol"; +import {BaseTest, BaseTestWithConfiguredVerifierAndFeeManager} from "../verifier/BaseVerifierTest.t.sol"; import {Verifier} from "../../Verifier.sol"; import {SimpleWriteAccessController} from "../../../SimpleWriteAccessController.sol"; +import {Common} from "../../../libraries/Common.sol"; contract Verifier_setConfig is BaseTest { address[] internal s_signerAddrs; @@ -23,18 +24,76 @@ contract Verifier_setConfig is BaseTest { FAULT_TOLERANCE, bytes(""), VERIFIER_VERSION, - bytes("") + bytes(""), + new Common.AddressAndWeight[](0) ); } } -contract Verifier_verify is BaseTestWithConfiguredVerifier { +contract Verifier_verifyWithFee is BaseTestWithConfiguredVerifierAndFeeManager { + uint256 internal constant DEFAULT_LINK_MINT_QUANTITY = 100 ether; + uint256 internal constant DEFAULT_NATIVE_MINT_QUANTITY = 100 ether; + + function setUp() public virtual override { + super.setUp(); + + //mint some link and eth to warm the storage + link.mint(address(rewardManager), DEFAULT_LINK_MINT_QUANTITY); + native.mint(address(feeManager), DEFAULT_NATIVE_MINT_QUANTITY); + + //warm the rewardManager + link.mint(address(this), DEFAULT_NATIVE_MINT_QUANTITY); + _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, address(this)); + (, , bytes32 latestConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); + + //mint some tokens to the user + link.mint(USER, DEFAULT_LINK_MINT_QUANTITY); + native.mint(USER, DEFAULT_NATIVE_MINT_QUANTITY); + vm.deal(USER, DEFAULT_NATIVE_MINT_QUANTITY); + + //mint some link tokens to the feeManager pool + link.mint(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //approve funds prior to test + _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + _approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + + changePrank(address(feeManager)); + rewardManager.onFeePaid(latestConfigDigest, address(this), DEFAULT_REPORT_LINK_FEE); + + changePrank(USER); + } + + function testVerifyProxyWithLinkFeeSuccess_gas() public { + bytes memory signedLinkPayload = _generateEncodedBlobWithQuote( + _generateV2Report(), + _generateReportContext(FEED_ID_V3), + _getSigners(FAULT_TOLERANCE + 1), + _generateQuote(address(link)) + ); + + s_verifierProxy.verify(signedLinkPayload); + } + + function testVerifyProxyWithNativeFeeSuccess_gas() public { + bytes memory signedNativePayload = _generateEncodedBlobWithQuote( + _generateV2Report(), + _generateReportContext(FEED_ID_V3), + _getSigners(FAULT_TOLERANCE + 1), + _generateQuote(address(native)) + ); + + s_verifierProxy.verify(signedNativePayload); + } +} + +contract Verifier_verify is BaseTestWithConfiguredVerifierAndFeeManager { bytes internal s_signedReport; bytes32 internal s_configDigest; function setUp() public override { - BaseTestWithConfiguredVerifier.setUp(); - BaseTest.Report memory s_testReportOne = _createReport( + BaseTestWithConfiguredVerifierAndFeeManager.setUp(); + BaseTest.V0Report memory s_testReportOne = _createV0Report( FEED_ID, OBSERVATIONS_TIMESTAMP, MEDIAN, @@ -42,7 +101,8 @@ contract Verifier_verify is BaseTestWithConfiguredVerifier { ASK, BLOCKNUMBER_UPPER_BOUND, blockhash(BLOCKNUMBER_UPPER_BOUND), - BLOCKNUMBER_LOWER_BOUND + BLOCKNUMBER_LOWER_BOUND, + uint32(block.timestamp) ); (, , s_configDigest) = s_verifier.latestConfigDetails(FEED_ID); bytes32[3] memory reportContext; @@ -53,6 +113,7 @@ contract Verifier_verify is BaseTestWithConfiguredVerifier { function testVerifySuccess_gas() public { changePrank(address(s_verifierProxy)); + s_verifier.verify(s_signedReport, msg.sender); } @@ -61,7 +122,7 @@ contract Verifier_verify is BaseTestWithConfiguredVerifier { } } -contract Verifier_accessControlledVerify is BaseTestWithConfiguredVerifier { +contract Verifier_accessControlledVerify is BaseTestWithConfiguredVerifierAndFeeManager { bytes internal s_signedReport; bytes32 internal s_configDigest; SimpleWriteAccessController s_accessController; @@ -70,8 +131,8 @@ contract Verifier_accessControlledVerify is BaseTestWithConfiguredVerifier { address internal constant ACCESS_CONTROLLER_ADDR = address(10000); function setUp() public override { - BaseTestWithConfiguredVerifier.setUp(); - BaseTest.Report memory s_testReportOne = _createReport( + BaseTestWithConfiguredVerifierAndFeeManager.setUp(); + BaseTest.V0Report memory s_testReportOne = _createV0Report( FEED_ID, OBSERVATIONS_TIMESTAMP, MEDIAN, @@ -79,7 +140,8 @@ contract Verifier_accessControlledVerify is BaseTestWithConfiguredVerifier { ASK, BLOCKNUMBER_UPPER_BOUND, blockhash(BLOCKNUMBER_UPPER_BOUND), - BLOCKNUMBER_LOWER_BOUND + BLOCKNUMBER_LOWER_BOUND, + uint32(block.timestamp) ); (, , s_configDigest) = s_verifier.latestConfigDetails(FEED_ID); bytes32[3] memory reportContext; diff --git a/contracts/src/v0.8/llo-feeds/test/mocks/ErroredVerifier.sol b/contracts/src/v0.8/llo-feeds/test/mocks/ErroredVerifier.sol index e58421415b8..23ef7c85802 100644 --- a/contracts/src/v0.8/llo-feeds/test/mocks/ErroredVerifier.sol +++ b/contracts/src/v0.8/llo-feeds/test/mocks/ErroredVerifier.sol @@ -2,13 +2,30 @@ pragma solidity 0.8.16; import {IVerifier} from "../../interfaces/IVerifier.sol"; +import {Common} from "../../../libraries/Common.sol"; contract ErroredVerifier is IVerifier { function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { return interfaceId == this.verify.selector; } - function verify(bytes memory /**signedReport**/, address /**sender**/) external pure override returns (bytes memory) { + function verify( + bytes memory, + /** + * signedReport* + */ + address + ) + external + pure + override + returns ( + /** + * sender* + */ + bytes memory + ) + { revert("Failed to verify"); } @@ -19,11 +36,43 @@ contract ErroredVerifier is IVerifier { uint8, bytes memory, uint64, - bytes memory + bytes memory, + Common.AddressAndWeight[] memory ) external pure override { revert("Failed to set config"); } + function setConfigFromSource( + bytes32, + uint256, + address, + address[] memory, + bytes32[] memory, + uint8, + bytes memory, + uint64, + bytes memory, + Common.AddressAndWeight[] memory + ) external pure override { + revert("Failed to set config"); + } + + function activateConfig(bytes32, bytes32) external pure { + revert("Failed to activate config"); + } + + function deactivateConfig(bytes32, bytes32) external pure { + revert("Failed to deactivate config"); + } + + function activateFeed(bytes32) external pure { + revert("Failed to activate feed"); + } + + function deactivateFeed(bytes32) external pure { + revert("Failed to deactivate feed"); + } + function latestConfigDigestAndEpoch(bytes32) external pure override returns (bool, bytes32, uint32) { revert("Failed to get latest config digest and epoch"); } diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/BaseRewardManager.t.sol b/contracts/src/v0.8/llo-feeds/test/reward-manager/BaseRewardManager.t.sol new file mode 100644 index 00000000000..7d7aa6aac38 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/test/reward-manager/BaseRewardManager.t.sol @@ -0,0 +1,248 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.16; + +import {Test} from "forge-std/Test.sol"; +import {ERC20Mock} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/mocks/ERC20Mock.sol"; +import {RewardManager} from "../../dev/RewardManager.sol"; +import {Common} from "../../../libraries/Common.sol"; + +/** + * @title BaseRewardManagerTest + * @author Michael Fletcher + * @notice Base class for all reward manager tests + * @dev This contract is intended to be inherited from and not used directly. It contains functionality to setup a primary and secondary pool + */ +contract BaseRewardManagerTest is Test { + //contracts + ERC20Mock internal asset; + ERC20Mock internal unsupported; + RewardManager internal rewardManager; + + //default address for unregistered recipient + address internal constant INVALID_ADDRESS = address(0); + //contract owner + address internal constant ADMIN = address(uint160(uint256(keccak256("ADMIN")))); + //address to represent verifier contract + address internal constant FEE_MANAGER = address(uint160(uint256(keccak256("FEE_MANAGER")))); + //a general user + address internal constant USER = address(uint160(uint256(keccak256("USER")))); + + //default recipients configured in reward manager + address internal constant DEFAULT_RECIPIENT_1 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_1")))); + address internal constant DEFAULT_RECIPIENT_2 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_2")))); + address internal constant DEFAULT_RECIPIENT_3 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_3")))); + address internal constant DEFAULT_RECIPIENT_4 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_4")))); + address internal constant DEFAULT_RECIPIENT_5 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_5")))); + address internal constant DEFAULT_RECIPIENT_6 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_6")))); + address internal constant DEFAULT_RECIPIENT_7 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_7")))); + + //additional recipients not in the reward manager + address internal constant DEFAULT_RECIPIENT_8 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_8")))); + address internal constant DEFAULT_RECIPIENT_9 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_9")))); + + //two pools should be enough to test all edge cases + bytes32 internal constant PRIMARY_POOL_ID = keccak256("primary_pool"); + bytes32 internal constant SECONDARY_POOL_ID = keccak256("secondary_pool"); + bytes32 internal constant INVALID_POOL_ID = keccak256("invalid_pool"); + bytes32 internal constant ZERO_POOL_ID = bytes32(0); + + //convenience arrays of all pool combinations used for testing + bytes32[] internal PRIMARY_POOL_ARRAY = [PRIMARY_POOL_ID]; + bytes32[] internal SECONDARY_POOL_ARRAY = [SECONDARY_POOL_ID]; + bytes32[] internal ALL_POOLS = [PRIMARY_POOL_ID, SECONDARY_POOL_ID]; + + //erc20 config + uint256 internal constant DEFAULT_MINT_QUANTITY = 100 ether; + + //reward scalar (this should match the const in the contract) + uint256 internal constant POOL_SCALAR = 1e18; + uint256 internal constant ONE_PERCENT = POOL_SCALAR / 100; + uint256 internal constant FIFTY_PERCENT = POOL_SCALAR / 2; + uint256 internal constant TEN_PERCENT = POOL_SCALAR / 10; + + //the selector for each error + bytes4 internal immutable UNAUTHORIZED_ERROR_SELECTOR = RewardManager.Unauthorized.selector; + bytes4 internal immutable INVALID_ADDRESS_ERROR_SELECTOR = RewardManager.InvalidAddress.selector; + bytes4 internal immutable INVALID_WEIGHT_ERROR_SELECTOR = RewardManager.InvalidWeights.selector; + bytes4 internal immutable INVALID_POOL_ID_ERROR_SELECTOR = RewardManager.InvalidPoolId.selector; + bytes internal constant ONLY_CALLABLE_BY_OWNER_ERROR = "Only callable by owner"; + + // Events emitted within the reward manager + event RewardRecipientsUpdated(bytes32 indexed poolId, Common.AddressAndWeight[] newRewardRecipients); + event RewardsClaimed(bytes32 indexed poolId, address indexed recipient, uint256 quantity); + event FeeManagerUpdated(address newProxyAddress); + event FeePaid(bytes32 poolId, address payee, uint256 quantity); + + function setUp() public virtual { + //change to admin user + vm.startPrank(ADMIN); + + //init required contracts + _initializeERC20Contracts(); + _initializeRewardManager(); + } + + function _initializeERC20Contracts() internal { + //create the contracts + asset = new ERC20Mock("ASSET", "AST", ADMIN, 0); + unsupported = new ERC20Mock("UNSUPPORTED", "UNS", ADMIN, 0); + + //mint some tokens to the admin + asset.mint(ADMIN, DEFAULT_MINT_QUANTITY); + unsupported.mint(ADMIN, DEFAULT_MINT_QUANTITY); + + //mint some tokens to the user + asset.mint(FEE_MANAGER, DEFAULT_MINT_QUANTITY); + unsupported.mint(FEE_MANAGER, DEFAULT_MINT_QUANTITY); + } + + function _initializeRewardManager() internal { + //create the contract + rewardManager = new RewardManager(address(asset)); + + rewardManager.setFeeManager(FEE_MANAGER); + } + + function createPrimaryPool() public { + rewardManager.setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients()); + } + + function createSecondaryPool() public { + rewardManager.setRewardRecipients(SECONDARY_POOL_ID, getSecondaryRecipients()); + } + + //override this to test variations of different recipients. changing this function will require existing tests to be updated as constants are hardcoded to be explicit + function getPrimaryRecipients() public virtual returns (Common.AddressAndWeight[] memory) { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + + //init each recipient with even weights. 2500 = 25% of pool + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, POOL_SCALAR / 4); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, POOL_SCALAR / 4); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, POOL_SCALAR / 4); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, POOL_SCALAR / 4); + + return recipients; + } + + function getPrimaryRecipientAddresses() public pure returns (address[] memory) { + //array of recipients + address[] memory recipients = new address[](4); + + recipients[0] = DEFAULT_RECIPIENT_1; + recipients[1] = DEFAULT_RECIPIENT_2; + recipients[2] = DEFAULT_RECIPIENT_3; + recipients[3] = DEFAULT_RECIPIENT_4; + + return recipients; + } + + //override this to test variations of different recipients. + function getSecondaryRecipients() public virtual returns (Common.AddressAndWeight[] memory) { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + + //init each recipient with even weights. 2500 = 25% of pool + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, POOL_SCALAR / 4); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, POOL_SCALAR / 4); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, POOL_SCALAR / 4); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_7, POOL_SCALAR / 4); + + return recipients; + } + + function getSecondaryRecipientAddresses() public pure returns (address[] memory) { + //array of recipients + address[] memory recipients = new address[](4); + + recipients[0] = DEFAULT_RECIPIENT_1; + recipients[1] = DEFAULT_RECIPIENT_5; + recipients[2] = DEFAULT_RECIPIENT_6; + recipients[3] = DEFAULT_RECIPIENT_7; + + return recipients; + } + + function addFundsToPool(bytes32 poolId, Common.Asset memory amount, address sender) public { + //record the current address and switch to the sender + address originalAddr = msg.sender; + changePrank(sender); + + //approve the amount being paid into the pool + ERC20Mock(amount.assetAddress).approve(address(rewardManager), amount.amount); + + //this represents the verifier adding some funds to the pool + rewardManager.onFeePaid(poolId, sender, amount.amount); + + //change back to the original address + changePrank(originalAddr); + } + + function getAsset(uint256 quantity) public view returns (Common.Asset memory) { + return Common.Asset(address(asset), quantity); + } + + function getAssetBalance(address addr) public view returns (uint256) { + return asset.balanceOf(addr); + } + + function claimRewards(bytes32[] memory poolIds, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //claim the rewards + rewardManager.claimRewards(poolIds); + + //change back to the original address + changePrank(originalAddr); + } + + function payRecipients(bytes32 poolId, address[] memory recipients, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //pay the recipients + rewardManager.payRecipients(poolId, recipients); + + //change back to the original address + changePrank(originalAddr); + } + + function setRewardRecipients(bytes32 poolId, Common.AddressAndWeight[] memory recipients, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //pay the recipients + rewardManager.setRewardRecipients(poolId, recipients); + + //change back to the original address + changePrank(originalAddr); + } + + function setFeeManager(address feeManager, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //update the proxy + rewardManager.setFeeManager(feeManager); + + //change back to the original address + changePrank(originalAddr); + } + + function updateRewardRecipients(bytes32 poolId, Common.AddressAndWeight[] memory recipients, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //pay the recipients + rewardManager.updateRewardRecipients(poolId, recipients); + + //change back to the original address + changePrank(originalAddr); + } +} diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.claim.t.sol b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.claim.t.sol new file mode 100644 index 00000000000..358ffeee40c --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.claim.t.sol @@ -0,0 +1,740 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.16; + +import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol"; +import {Common} from "../../../libraries/Common.sol"; + +/** + * @title BaseRewardManagerTest + * @author Michael Fletcher + * @notice This contract will test the claim functionality of the RewardManager contract. + */ +contract RewardManagerClaimTest is BaseRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //create a single pool for these tests + createPrimaryPool(); + + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function test_claimAllRecipients() public { + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + } + + function test_claimRewardsWithDuplicatPoolIdsDoesNotPayoutTwice() public { + //add funds to a different pool to ensure they're not claimed + addFundsToPool(SECONDARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //create an array containing duplicate poolIds + bytes32[] memory poolIds = new bytes32[](2); + poolIds[0] = PRIMARY_POOL_ID; + poolIds[1] = PRIMARY_POOL_ID; + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(poolIds, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //the pool should still have the remaining + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_claimSingleRecipient() public { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[0]; + + //claim the individual rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check the recipients balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT - expectedRecipientAmount); + } + + function test_claimMultipleRecipients() public { + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, getPrimaryRecipients()[0].addr); + claimRewards(PRIMARY_POOL_ARRAY, getPrimaryRecipients()[1].addr); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check the recipients balance matches the ratio the recipient should have received + assertEq(getAssetBalance(getPrimaryRecipients()[0].addr), expectedRecipientAmount); + assertEq(getAssetBalance(getPrimaryRecipients()[1].addr), expectedRecipientAmount); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT - (expectedRecipientAmount * 2)); + } + + function test_claimUnregisteredRecipient() public { + //claim the rewards for a recipient who isn't in this pool + claimRewards(PRIMARY_POOL_ARRAY, getSecondaryRecipients()[1].addr); + + //check the recipients didn't receive any fees from this pool + assertEq(getAssetBalance(getSecondaryRecipients()[1].addr), 0); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_claimUnevenAmountRoundsDown() public { + //adding 1 to the pool should leave 1 wei worth of dust, which the contract doesn't handle due to it being economically infeasible + addFundsToPool(PRIMARY_POOL_ID, getAsset(1), FEE_MANAGER); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //check the rewardManager has the remaining quantity equals 1 wei + assertEq(getAssetBalance(address(rewardManager)), 1); + } + + function test_claimUnregisteredPoolId() public { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[0]; + + //claim the individual rewards for this recipient + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //check the recipients balance is still 0 as there's no pool to receive fees from + assertEq(getAssetBalance(recipient.addr), 0); + + //check the rewardManager has the full amount + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_singleRecipientClaimMultipleDeposits() public { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[0]; + + //claim the individual rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check the recipients balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + + //check the rewardManager has the remaining quantity, which is 3/4 of the initial deposit + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT - expectedRecipientAmount); + + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //claim the individual rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the recipients balance matches the ratio the recipient should have received, which is 1/4 of each deposit + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount * 2); + + //check the rewardManager has the remaining quantity, which is now 3/4 of both deposits + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT * 2 - (expectedRecipientAmount * 2)); + } + + function test_recipientsClaimMultipleDeposits() public { + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //the reward manager balance should be 0 as all of the funds have been claimed + assertEq(getAssetBalance(address(rewardManager)), 0); + + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //expected recipient amount is 1/4 of the pool deposit + expectedRecipientAmount = (POOL_DEPOSIT_AMOUNT / 4) * 2; + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //the reward manager balance should again be 0 as all of the funds have been claimed + assertEq(getAssetBalance(address(rewardManager)), 0); + } + + function test_eventIsEmittedUponClaim() public { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[0]; + + //expect an emit + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit RewardsClaimed(PRIMARY_POOL_ID, recipient.addr, POOL_DEPOSIT_AMOUNT / 4); + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + } + + function test_eventIsNotEmittedUponUnsuccessfulClaim() public { + //record logs to check no events were emitted + vm.recordLogs(); + + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[0]; + + //claim the individual rewards for each recipient + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //no logs should have been emitted + assertEq(vm.getRecordedLogs().length, 0); + } +} + +contract RewardManagerRecipientClaimMultiplePoolsTest is BaseRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //create a two pools + createPrimaryPool(); + createSecondaryPool(); + + //add funds to each of the pools to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + addFundsToPool(SECONDARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function test_claimAllRecipientsSinglePool() public { + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //check the pool balance is still equal to DEPOSIT_AMOUNT as the test only claims for one of the pools + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_claimMultipleRecipientsSinglePool() public { + //claim the individual rewards for each recipient + claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[0].addr); + claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[1].addr); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check the recipients balance matches the ratio the recipient should have received + assertEq(getAssetBalance(getSecondaryRecipients()[0].addr), expectedRecipientAmount); + assertEq(getAssetBalance(getSecondaryRecipients()[1].addr), expectedRecipientAmount); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT * 2 - (expectedRecipientAmount * 2)); + } + + function test_claimMultipleRecipientsMultiplePools() public { + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, getPrimaryRecipients()[0].addr); + claimRewards(PRIMARY_POOL_ARRAY, getPrimaryRecipients()[1].addr); + claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[0].addr); + claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[1].addr); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check the recipients balance matches the ratio the recipient should have received. The first recipient is shared across both pools so should receive 1/4 of each pool + assertEq(getAssetBalance(getPrimaryRecipients()[0].addr), expectedRecipientAmount * 2); + assertEq(getAssetBalance(getPrimaryRecipients()[1].addr), expectedRecipientAmount); + assertEq(getAssetBalance(getSecondaryRecipients()[1].addr), expectedRecipientAmount); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_claimAllRecipientsMultiplePools() public { + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim funds for each recipient within the pool + for (uint256 i = 1; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //claim funds for each recipient within the pool + for (uint256 i = 1; i < getSecondaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory secondaryRecipient = getSecondaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(SECONDARY_POOL_ARRAY, secondaryRecipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(secondaryRecipient.addr), expectedRecipientAmount); + } + + //special case to handle the first recipient of each pool as they're the same address + Common.AddressAndWeight memory commonRecipient = getPrimaryRecipients()[0]; + + //claim the individual rewards for each pool + claimRewards(PRIMARY_POOL_ARRAY, commonRecipient.addr); + claimRewards(SECONDARY_POOL_ARRAY, commonRecipient.addr); + + //check the balance matches the ratio the recipient should have received, which is 1/4 of each deposit for each pool + assertEq(getAssetBalance(commonRecipient.addr), expectedRecipientAmount * 2); + } + + function test_claimSingleUniqueRecipient() public { + //the first recipient of the secondary pool is in both pools, so take the second recipient which is unique + Common.AddressAndWeight memory recipient = getSecondaryRecipients()[1]; + + //claim the individual rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //the recipient should have received 1/4 of the deposit amount + uint256 recipientExpectedAmount = POOL_DEPOSIT_AMOUNT / 4; + + //the recipient should have received 1/4 of the deposit amount + assertEq(getAssetBalance(recipient.addr), recipientExpectedAmount); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT * 2 - recipientExpectedAmount); + } + + function test_claimSingleRecipientMultiplePools() public { + //the first recipient of the secondary pool is in both pools + Common.AddressAndWeight memory recipient = getSecondaryRecipients()[0]; + + //claim the individual rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //the recipient should have received 1/4 of the deposit amount for each pool + uint256 recipientExpectedAmount = (POOL_DEPOSIT_AMOUNT / 4) * 2; + + //this recipient belongs in both pools so should have received 1/4 of each + assertEq(getAssetBalance(recipient.addr), recipientExpectedAmount); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT * 2 - recipientExpectedAmount); + } + + function test_claimUnregisteredRecipient() public { + //claim the individual rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, getSecondaryRecipients()[1].addr); + claimRewards(SECONDARY_POOL_ARRAY, getPrimaryRecipients()[1].addr); + + //check the recipients didn't receive any fees from this pool + assertEq(getAssetBalance(getSecondaryRecipients()[1].addr), 0); + assertEq(getAssetBalance(getPrimaryRecipients()[1].addr), 0); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT * 2); + } + + function test_claimUnevenAmountRoundsDown() public { + //adding an uneven amount of dust to each pool, this should round down to the nearest whole number with 4 remaining in the contract + addFundsToPool(PRIMARY_POOL_ID, getAsset(3), FEE_MANAGER); + addFundsToPool(SECONDARY_POOL_ID, getAsset(1), FEE_MANAGER); + + //the recipient should have received 1/4 of the deposit amount for each pool + uint256 recipientExpectedAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), recipientExpectedAmount); + } + + //special case to handle the first recipient of each pool as they're the same address + claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[0].addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(getSecondaryRecipients()[0].addr), recipientExpectedAmount * 2); + + //claim funds for each recipient of the secondary pool except the first + for (uint256 i = 1; i < getSecondaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getSecondaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), recipientExpectedAmount); + } + + //contract should have 4 remaining + assertEq(getAssetBalance(address(rewardManager)), 4); + } + + function test_singleRecipientClaimMultipleDeposits() public { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getSecondaryRecipients()[0]; + + //claim the individual rewards for this recipient + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //the recipient should have received 1/4 of the deposit amount + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check the recipients balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + + //check the rewardManager has the remaining quantity, which is 3/4 of the initial deposit plus the deposit from the second pool + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT * 2 - expectedRecipientAmount); + + //add funds to the pool to be split among the recipients + addFundsToPool(SECONDARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //claim the individual rewards for this recipient + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //the recipient should have received 1/4 of the next deposit amount + expectedRecipientAmount += POOL_DEPOSIT_AMOUNT / 4; + + //check the recipients balance matches the ratio the recipient should have received, which is 1/4 of each deposit + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + + //check the rewardManager has the remaining quantity, which is now 3/4 of both deposits + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT * 3 - expectedRecipientAmount); + } + + function test_recipientsClaimMultipleDeposits() public { + //the recipient should have received 1/4 of the deposit amount + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim funds for each recipient within the pool + for (uint256 i; i < getSecondaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getSecondaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //the reward manager balance should contain only the funds of the secondary pool + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + + //add funds to the pool to be split among the recipients + addFundsToPool(SECONDARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //special case to handle the first recipient of each pool as they're the same address + claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[0].addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(getSecondaryRecipients()[0].addr), expectedRecipientAmount * 2); + + //claim funds for each recipient within the pool except the first + for (uint256 i = 1; i < getSecondaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getSecondaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount * 2); + } + + //the reward manager balance should again be the balance of the secondary pool as the primary pool has been emptied twice + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_claimEmptyPoolWhenSecondPoolContainsFunds() public { + //the recipient should have received 1/4 of the deposit amount + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim all rewards for each recipient in the primary pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //claim all the rewards again for the first recipient as that address is a member of both pools + claimRewards(PRIMARY_POOL_ARRAY, getSecondaryRecipients()[0].addr); + + //check the balance + assertEq(getAssetBalance(getSecondaryRecipients()[0].addr), expectedRecipientAmount); + } + + function test_getRewardsAvailableToRecipientInBothPools() public { + //get index 0 as this recipient is in both default pools + bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(getPrimaryRecipients()[0].addr); + + //check the recipient is in both pools + assertEq(poolIds[0], PRIMARY_POOL_ID); + assertEq(poolIds[1], SECONDARY_POOL_ID); + } + + function test_getRewardsAvailableToRecipientInSinglePool() public { + //get index 0 as this recipient is in both default pools + bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(getPrimaryRecipients()[1].addr); + + //check the recipient is in both pools + assertEq(poolIds[0], PRIMARY_POOL_ID); + assertEq(poolIds[1], ZERO_POOL_ID); + } + + function test_getRewardsAvailableToRecipientInNoPools() public { + //get index 0 as this recipient is in both default pools + bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(FEE_MANAGER); + + //check the recipient is in neither pool + assertEq(poolIds[0], ZERO_POOL_ID); + assertEq(poolIds[1], ZERO_POOL_ID); + } +} + +contract RewardManagerRecipientClaimDifferentWeightsTest is BaseRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //create a single pool for these tests + createPrimaryPool(); + + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function getPrimaryRecipients() public virtual override returns (Common.AddressAndWeight[] memory) { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + + //init each recipient with uneven weights + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, TEN_PERCENT); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, TEN_PERCENT * 8); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, ONE_PERCENT * 6); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, ONE_PERCENT * 4); + + return recipients; + } + + function test_allRecipientsClaimingReceiveExpectedAmount() public { + //loop all the recipients and claim their expected amount + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //the recipient should have received a share proportional to their weight + uint256 expectedRecipientAmount = (POOL_DEPOSIT_AMOUNT * recipient.weight) / POOL_SCALAR; + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + } +} + +contract RewardManagerRecipientClaimUnevenWeightTest is BaseRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //create a single pool for these tests + createPrimaryPool(); + } + + function getPrimaryRecipients() public virtual override returns (Common.AddressAndWeight[] memory) { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](2); + + uint256 oneThird = POOL_SCALAR / 3; + + //init each recipient with even weights. + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, oneThird); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, 2 * oneThird + 1); + + return recipients; + } + + function test_allRecipientsClaimingReceiveExpectedAmountWithSmallDeposit() public { + //add a smaller amount of funds to the pool + uint256 smallDeposit = 1e8; + + //add a smaller amount of funds to the pool + addFundsToPool(PRIMARY_POOL_ID, getAsset(smallDeposit), FEE_MANAGER); + + //loop all the recipients and claim their expected amount + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //the recipient should have received a share proportional to their weight + uint256 expectedRecipientAmount = (smallDeposit * recipient.weight) / POOL_SCALAR; + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //smaller deposits will consequently have less precision and will not be able to be split as evenly, the remaining 1 will be lost due to 333...|... being paid out instead of 333...4| + assertEq(getAssetBalance(address(rewardManager)), 1); + } + + function test_allRecipientsClaimingReceiveExpectedAmount() public { + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //loop all the recipients and claim their expected amount + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //the recipient should have received a share proportional to their weight + uint256 expectedRecipientAmount = (POOL_DEPOSIT_AMOUNT * recipient.weight) / POOL_SCALAR; + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //their should be 0 wei left over indicating a successful split + assertEq(getAssetBalance(address(rewardManager)), 0); + } +} + +contract RewardManagerNoRecipientSet is BaseRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //add funds to the pool to be split among the recipients once registered + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function test_claimAllRecipientsAfterRecipientsSet() public { + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //try and claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //there should be no rewards claimed as the recipient is not registered + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the recipient received nothing + assertEq(getAssetBalance(recipient.addr), 0); + } + + //Set the recipients after the rewards have been paid into the pool + setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), ADMIN); + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //there should be no rewards claimed as the recipient is registered + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + } +} diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.general.t.sol b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.general.t.sol new file mode 100644 index 00000000000..e656ca1fcf4 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.general.t.sol @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.16; + +import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol"; +import {Common} from "../../../libraries/Common.sol"; +import {RewardManager} from "../../dev/RewardManager.sol"; +import {ERC20Mock} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/mocks/ERC20Mock.sol"; + +/** + * @title BaseRewardManagerTest + * @author Michael Fletcher + * @notice This contract will test the core functionality of the RewardManager contract + */ +contract RewardManagerSetupTest is BaseRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + } + + function test_rejectsZeroLinkAddressOnConstruction() public { + //should revert if the contract is a zero address + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //create a rewardManager with a zero link address + new RewardManager(address(0)); + } + + function test_eventEmittedUponFeeManagerUpdate() public { + //expect the event to be emitted + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit FeeManagerUpdated(FEE_MANAGER); + + //set the verifier proxy + setFeeManager(FEE_MANAGER, ADMIN); + } + + function test_eventEmittedUponFeePaid() public { + //create pool and add funds + createPrimaryPool(); + + //change to the feeManager who is the one who will be paying the fees + changePrank(FEE_MANAGER); + + //approve the amount being paid into the pool + ERC20Mock(getAsset(POOL_DEPOSIT_AMOUNT).assetAddress).approve(address(rewardManager), POOL_DEPOSIT_AMOUNT); + + //event is emitted when funds are added + vm.expectEmit(); + emit FeePaid(PRIMARY_POOL_ID, FEE_MANAGER, POOL_DEPOSIT_AMOUNT); + + //this represents the verifier adding some funds to the pool + rewardManager.onFeePaid(PRIMARY_POOL_ID, FEE_MANAGER, POOL_DEPOSIT_AMOUNT); + } + + function test_setFeeManagerZeroAddress() public { + //should revert if the contract is a zero address + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //set the verifier proxy + setFeeManager(address(0), ADMIN); + } +} diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.payRecipients.t.sol b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.payRecipients.t.sol new file mode 100644 index 00000000000..8506210f2df --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.payRecipients.t.sol @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.16; + +import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol"; +import {Common} from "../../../libraries/Common.sol"; + +/** + * @title BaseRewardManagerTest + * @author Michael Fletcher + * @notice This contract will test the payRecipients functionality of the RewardManager contract + */ +contract RewardManagerPayRecipientsTest is BaseRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //create a single pool for these tests + createPrimaryPool(); + + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function test_payAllRecipients() public { + //pay all the recipients in the pool + payRecipients(PRIMARY_POOL_ID, getPrimaryRecipientAddresses(), ADMIN); + + //each recipient should receive 1/4 of the pool + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check each recipient received the correct amount + for (uint256 i = 0; i < getPrimaryRecipientAddresses().length; i++) { + assertEq(getAssetBalance(getPrimaryRecipientAddresses()[i]), expectedRecipientAmount); + } + } + + function test_paySingleRecipient() public { + //get the first individual recipient + address recipient = getPrimaryRecipientAddresses()[0]; + + //get a single recipient as an array + address[] memory recipients = new address[](1); + recipients[0] = recipient; + + //pay a single recipient + payRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //the recipient should have received 1/4 of the deposit amount + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + assertEq(getAssetBalance(recipient), expectedRecipientAmount); + } + + function test_payRecipientWithInvalidPool() public { + //get the first individual recipient + address recipient = getPrimaryRecipientAddresses()[0]; + + //get a single recipient as an array + address[] memory recipients = new address[](1); + recipients[0] = recipient; + + //pay a single recipient + payRecipients(SECONDARY_POOL_ID, recipients, ADMIN); + + //the recipient should have received nothing + assertEq(getAssetBalance(recipient), 0); + } + + function test_payRecipientsEmptyRecipientList() public { + //get a single recipient + address[] memory recipients = new address[](0); + + //pay a single recipient + payRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //rewardManager should have the full balance + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_payAllRecipientsWithAdditionalUnregisteredRecipient() public { + //load all the recipients and add an additional one who is not in the pool + address[] memory recipients = new address[](getPrimaryRecipientAddresses().length + 1); + for (uint256 i = 0; i < getPrimaryRecipientAddresses().length; i++) { + recipients[i] = getPrimaryRecipientAddresses()[i]; + } + recipients[recipients.length - 1] = DEFAULT_RECIPIENT_5; + + //pay the recipients + payRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //each recipient should receive 1/4 of the pool except the last + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check each recipient received the correct amount + for (uint256 i = 0; i < getPrimaryRecipientAddresses().length; i++) { + assertEq(getAssetBalance(getPrimaryRecipientAddresses()[i]), expectedRecipientAmount); + } + + //the unregistered recipient should receive nothing + assertEq(getAssetBalance(DEFAULT_RECIPIENT_5), 0); + } + + function test_payAllRecipientsWithAdditionalInvalidRecipient() public { + //load all the recipients and add an additional one which is invalid, that should receive nothing + address[] memory recipients = new address[](getPrimaryRecipientAddresses().length + 1); + for (uint256 i = 0; i < getPrimaryRecipientAddresses().length; i++) { + recipients[i] = getPrimaryRecipientAddresses()[i]; + } + recipients[recipients.length - 1] = INVALID_ADDRESS; + + //pay the recipients + payRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //each recipient should receive 1/4 of the pool except the last + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check each recipient received the correct amount + for (uint256 i = 0; i < getPrimaryRecipientAddresses().length; i++) { + assertEq(getAssetBalance(getPrimaryRecipientAddresses()[i]), expectedRecipientAmount); + } + } + + function test_paySubsetOfRecipientsInPool() public { + //load a subset of the recipients into an array + address[] memory recipients = new address[](getPrimaryRecipientAddresses().length - 1); + for (uint256 i = 0; i < recipients.length; i++) { + recipients[i] = getPrimaryRecipientAddresses()[i]; + } + + //pay the subset of recipients + payRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //each recipient should receive 1/4 of the pool except the last + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check each subset of recipients received the correct amount + for (uint256 i = 0; i < recipients.length - 1; i++) { + assertEq(getAssetBalance(recipients[i]), expectedRecipientAmount); + } + + //check the pool has the remaining balance + assertEq( + getAssetBalance(address(rewardManager)), + POOL_DEPOSIT_AMOUNT - expectedRecipientAmount * recipients.length + ); + } + + function test_payAllRecipientsFromNonAdminUser() public { + //should revert if the caller isn't an admin or recipient within the pool + vm.expectRevert(UNAUTHORIZED_ERROR_SELECTOR); + + //pay all the recipients in the pool + payRecipients(PRIMARY_POOL_ID, getPrimaryRecipientAddresses(), FEE_MANAGER); + } + + function test_payAllRecipientsFromRecipientInPool() public { + //pay all the recipients in the pool + payRecipients(PRIMARY_POOL_ID, getPrimaryRecipientAddresses(), DEFAULT_RECIPIENT_1); + + //each recipient should receive 1/4 of the pool + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check each recipient received the correct amount + for (uint256 i = 0; i < getPrimaryRecipientAddresses().length; i++) { + assertEq(getAssetBalance(getPrimaryRecipientAddresses()[i]), expectedRecipientAmount); + } + } + + function test_payRecipientsWithInvalidPoolId() public { + //pay all the recipients in the pool + payRecipients(INVALID_POOL_ID, getPrimaryRecipientAddresses(), ADMIN); + + //pool should still contain the full balance + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_addFundsToPoolAsOwner() public { + //add funds to the pool + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function test_addFundsToPoolAsNonOwnerOrFeeManager() public { + //should revert if the caller isn't an admin or recipient within the pool + vm.expectRevert(UNAUTHORIZED_ERROR_SELECTOR); + + //add funds to the pool + rewardManager.onFeePaid(PRIMARY_POOL_ID, USER, POOL_DEPOSIT_AMOUNT); + } +} diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.setRecipients.t.sol b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.setRecipients.t.sol new file mode 100644 index 00000000000..0c58a8562cf --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.setRecipients.t.sol @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.16; + +import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol"; +import {Common} from "../../../libraries/Common.sol"; +import {RewardManager} from "../../dev/RewardManager.sol"; + +/** + * @title BaseRewardManagerTest + * @author Michael Fletcher + * @notice This contract will test the setRecipient functionality of the RewardManager contract + */ +contract RewardManagerSetRecipientsTest is BaseRewardManagerTest { + function setUp() public override { + //setup contracts + super.setUp(); + } + + function test_setRewardRecipients() public { + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), ADMIN); + } + + function test_setRewardRecipientsIsEmpty() public { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + + //should revert if the recipients array is empty + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_setRewardRecipientWithZeroWeight() public { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](5); + + //init each recipient with even weights + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, ONE_PERCENT * 25); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, ONE_PERCENT * 25); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, ONE_PERCENT * 25); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, ONE_PERCENT * 25); + recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, 0); + + //Zero weight should fail + vm.expectRevert(INVALID_WEIGHT_ERROR_SELECTOR); + + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_setRewardRecipientWithZeroAddress() public { + //array of recipients + Common.AddressAndWeight[] memory recipients = getPrimaryRecipients(); + + //override the first recipient with a zero address + recipients[0].addr = address(0); + + //should revert if the recipients array is empty + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_setRewardRecipientWeights() public { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + + //init each recipient with even weights + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, 25); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, 25); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, 25); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, 25); + + //should revert if the recipients array is empty + vm.expectRevert(INVALID_WEIGHT_ERROR_SELECTOR); + + //set the recipients with a recipient with a weight of 100% + setRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_setSingleRewardRecipient() public { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](1); + + //init each recipient with even weights + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, POOL_SCALAR); + + //set the recipients with a recipient with a weight of 100% + setRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_setRewardRecipientTwice() public { + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), ADMIN); + + //should revert if recipients for this pool have already been set + vm.expectRevert(INVALID_POOL_ID_ERROR_SELECTOR); + + //set the recipients again + setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), ADMIN); + } + + function test_setRewardRecipientFromNonOwnerOrFeeManagerAddress() public { + //should revert if the sender is not the owner or proxy + vm.expectRevert(UNAUTHORIZED_ERROR_SELECTOR); + + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), USER); + } + + function test_setRewardRecipientFromManagerAddress() public { + //update the proxy address + setFeeManager(FEE_MANAGER, ADMIN); + + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), FEE_MANAGER); + } + + function test_eventIsEmittedUponSetRecipients() public { + //expect an emit + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit RewardRecipientsUpdated(PRIMARY_POOL_ID, getPrimaryRecipients()); + + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), ADMIN); + } + + function test_setRecipientContainsDuplicateRecipients() public { + //create a new array to hold the existing recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length * 2); + + //add all the existing recipients + for (uint256 i; i < getPrimaryRecipients().length; i++) { + recipients[i] = getPrimaryRecipients()[i]; + } + //add all the existing recipients again + for (uint256 i; i < getPrimaryRecipients().length; i++) { + recipients[i + getPrimaryRecipients().length] = getPrimaryRecipients()[i]; + } + + //should revert as the list contains a duplicate + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } +} diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.updateRewardRecipients.t.sol b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.updateRewardRecipients.t.sol new file mode 100644 index 00000000000..de12f11bf92 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.updateRewardRecipients.t.sol @@ -0,0 +1,466 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.16; + +import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol"; +import {Common} from "../../../libraries/Common.sol"; +import {RewardManager} from "../../dev/RewardManager.sol"; + +/** + * @title BaseRewardManagerTest + * @author Michael Fletcher + * @notice This contract will test the updateRecipient functionality of the RewardManager contract + */ +contract RewardManagerUpdateRewardRecipientsTest is BaseRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //create a single pool for these tests + createPrimaryPool(); + + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function test_onlyAdminCanUpdateRecipients() public { + //should revert if the caller is not the admin + vm.expectRevert(ONLY_CALLABLE_BY_OWNER_ERROR); + + //updating a recipient should force the funds to be paid out + updateRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), FEE_MANAGER); + } + + function test_updateAllRecipientsWithSameAddressAndWeight() public { + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //updating a recipient should force the funds to be paid out + updateRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), ADMIN); + + //check each recipient received the correct amount + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(getPrimaryRecipients()[i].addr), expectedRecipientAmount); + } + } + + function test_updatePartialRecipientsWithSameAddressAndWeight() public { + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //get a subset of the recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](2); + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, ONE_PERCENT * 25); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, ONE_PERCENT * 25); + + //updating a recipient should force the funds to be paid out + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //check each recipient received the correct amount + for (uint256 i; i < recipients.length; i++) { + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipients[i].addr), expectedRecipientAmount); + } + + //the reward manager should still have half remaining funds + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT / 2); + } + + function test_updateRecipientWithNewZeroAddress() public { + //create a new array to hold the existing recipients plus a new zero address + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length + 1); + + //add all the existing recipients + for (uint256 i; i < getPrimaryRecipients().length; i++) { + recipients[i] = getPrimaryRecipients()[i]; + } + //add a new address to the primary recipients + recipients[recipients.length - 1] = Common.AddressAndWeight(address(0), 0); + + //should revert if the recipient is a zero address + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //update the recipients with invalid address + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientsContainsDuplicateRecipients() public { + //create a new array to hold the existing recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length * 2); + + //add all the existing recipients + for (uint256 i; i < getPrimaryRecipients().length; i++) { + recipients[i] = getPrimaryRecipients()[i]; + } + //add all the existing recipients again + for (uint256 i; i < getPrimaryRecipients().length; i++) { + recipients[i + getPrimaryRecipients().length] = getPrimaryRecipients()[i]; + } + + //should revert as the list contains a duplicate + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //update the recipients with the duplicate addresses + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientsToDifferentSet() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length + 4); + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //copy the recipient and set the weight to 0 which implies the recipient is being replaced + recipients[i] = Common.AddressAndWeight(getPrimaryRecipients()[i].addr, 0); + } + + //add the new recipients individually + recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, ONE_PERCENT * 25); + recipients[5] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, ONE_PERCENT * 25); + recipients[6] = Common.AddressAndWeight(DEFAULT_RECIPIENT_7, ONE_PERCENT * 25); + recipients[7] = Common.AddressAndWeight(DEFAULT_RECIPIENT_8, ONE_PERCENT * 25); + + //should revert as it's not possible to new recipients + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientsToDifferentPartialSet() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length + 2); + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //copy the recipient and set the weight to 0 which implies the recipient is being replaced + recipients[i] = Common.AddressAndWeight(getPrimaryRecipients()[i].addr, 0); + } + + //add the new recipients individually + recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, FIFTY_PERCENT); + recipients[5] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, FIFTY_PERCENT); + + //should revert as it's not possible to add new recipients + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientsToDifferentLargerSet() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length + 5); + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //copy the recipient and set the weight to 0 which implies the recipient is being replaced + recipients[i] = Common.AddressAndWeight(getPrimaryRecipients()[i].addr, 0); + } + + //add the new recipients individually + recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, TEN_PERCENT * 2); + recipients[5] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, TEN_PERCENT * 2); + recipients[6] = Common.AddressAndWeight(DEFAULT_RECIPIENT_7, TEN_PERCENT * 2); + recipients[7] = Common.AddressAndWeight(DEFAULT_RECIPIENT_8, TEN_PERCENT * 2); + recipients[8] = Common.AddressAndWeight(DEFAULT_RECIPIENT_9, TEN_PERCENT * 2); + + //should revert as changing the recipient set is not allowed + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientsUpdateAndRemoveExistingForLargerSet() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](9); + + //update the existing recipients + recipients[0] = Common.AddressAndWeight(getPrimaryRecipients()[0].addr, 0); + recipients[1] = Common.AddressAndWeight(getPrimaryRecipients()[1].addr, 0); + recipients[2] = Common.AddressAndWeight(getPrimaryRecipients()[2].addr, TEN_PERCENT * 3); + recipients[3] = Common.AddressAndWeight(getPrimaryRecipients()[3].addr, TEN_PERCENT * 3); + + //add the new recipients individually + recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, TEN_PERCENT); + recipients[5] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, TEN_PERCENT); + recipients[6] = Common.AddressAndWeight(DEFAULT_RECIPIENT_7, TEN_PERCENT); + recipients[7] = Common.AddressAndWeight(DEFAULT_RECIPIENT_8, TEN_PERCENT); + recipients[8] = Common.AddressAndWeight(DEFAULT_RECIPIENT_9, TEN_PERCENT); + + //should revert as it's not possible to add new recipients + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientsUpdateAndRemoveExistingForSmallerSet() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](5); + + //update the existing recipients + recipients[0] = Common.AddressAndWeight(getPrimaryRecipients()[0].addr, 0); + recipients[1] = Common.AddressAndWeight(getPrimaryRecipients()[1].addr, 0); + recipients[2] = Common.AddressAndWeight(getPrimaryRecipients()[2].addr, TEN_PERCENT * 3); + recipients[3] = Common.AddressAndWeight(getPrimaryRecipients()[3].addr, TEN_PERCENT * 2); + + //add the new recipients individually + recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, TEN_PERCENT * 5); + + //should revert as it's not possible to add new recipients + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientsToDifferentSetWithInvalidWeights() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length + 2); + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //copy the recipient and set the weight to 0 which implies the recipient is being replaced + recipients[i] = Common.AddressAndWeight(getPrimaryRecipients()[i].addr, 0); + } + + //add the new recipients individually + recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, TEN_PERCENT * 5); + recipients[5] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, TEN_PERCENT); + + //should revert as the addresses are not in the configured set + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updatePartialRecipientsToSubset() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, 0); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, 0); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, TEN_PERCENT * 5); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, TEN_PERCENT * 5); + + //should revert as changing the recipients is not allowed + vm.expectRevert(INVALID_WEIGHT_ERROR_SELECTOR); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updatePartialRecipientsWithUnderWeightSet() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, TEN_PERCENT); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, TEN_PERCENT); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, TEN_PERCENT); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, TEN_PERCENT); + + //should revert as the new weights exceed the previous weights being replaced + vm.expectRevert(INVALID_WEIGHT_ERROR_SELECTOR); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updatePartialRecipientsWithExcessiveWeight() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, TEN_PERCENT); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, TEN_PERCENT); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, TEN_PERCENT); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, POOL_SCALAR); + + //should revert as the new weights exceed the previous weights being replaced + vm.expectRevert(INVALID_WEIGHT_ERROR_SELECTOR); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientWeights() public { + //expected recipient amount is 1/4 of the pool deposit for original recipients + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //create a list of containing recipients from the primary configured set with their new weights + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, TEN_PERCENT); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, TEN_PERCENT); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, TEN_PERCENT * 3); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, TEN_PERCENT * 5); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //check each recipient received the correct amount + for (uint256 i; i < recipients.length; i++) { + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipients[i].addr), expectedRecipientAmount); + } + + //the reward manager should have no funds remaining + assertEq(getAssetBalance(address(rewardManager)), 0); + + //add more funds to the pool to check new distribution + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //loop each user and claim the rewards + for (uint256 i; i < recipients.length; i++) { + //claim the rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, recipients[i].addr); + } + + //manually check the balance of each recipient + assertEq( + getAssetBalance(DEFAULT_RECIPIENT_1), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT) / POOL_SCALAR + expectedRecipientAmount + ); + assertEq( + getAssetBalance(DEFAULT_RECIPIENT_2), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT) / POOL_SCALAR + expectedRecipientAmount + ); + assertEq( + getAssetBalance(DEFAULT_RECIPIENT_3), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT * 3) / POOL_SCALAR + expectedRecipientAmount + ); + assertEq( + getAssetBalance(DEFAULT_RECIPIENT_4), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT * 5) / POOL_SCALAR + expectedRecipientAmount + ); + } + + function test_partialUpdateRecipientWeights() public { + //expected recipient amount is 1/4 of the pool deposit for original recipients + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //create a list of containing recipients from the primary configured set with their new weights + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](2); + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, TEN_PERCENT); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, TEN_PERCENT * 4); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //check each recipient received the correct amount + for (uint256 i; i < recipients.length; i++) { + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipients[i].addr), expectedRecipientAmount); + } + + //the reward manager should have half the funds remaining + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT / 2); + + //add more funds to the pool to check new distribution + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //loop each user and claim the rewards + for (uint256 i; i < recipients.length; i++) { + //claim the rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, recipients[i].addr); + } + + //manually check the balance of each recipient + assertEq( + getAssetBalance(DEFAULT_RECIPIENT_1), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT) / POOL_SCALAR + expectedRecipientAmount + ); + assertEq( + getAssetBalance(DEFAULT_RECIPIENT_2), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT * 4) / POOL_SCALAR + expectedRecipientAmount + ); + + //the reward manager should have half the funds remaining + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_eventIsEmittedUponUpdateRecipients() public { + //expect an emit + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit RewardRecipientsUpdated(PRIMARY_POOL_ID, getPrimaryRecipients()); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //updating a recipient should force the funds to be paid out + updateRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), ADMIN); + + //check each recipient received the correct amount + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(getPrimaryRecipients()[i].addr), expectedRecipientAmount); + } + } +} + +contract RewardManagerUpdateRewardRecipientsMultiplePoolsTest is BaseRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //create a single pool for these tests + createPrimaryPool(); + createSecondaryPool(); + + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + addFundsToPool(SECONDARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function getSecondaryRecipients() public override returns (Common.AddressAndWeight[] memory) { + //for testing purposes, the primary and secondary pool to contain the same recipients + return getPrimaryRecipients(); + } + + function test_updatePrimaryRecipientWeights() public { + //expected recipient amount is 1/4 of the pool deposit for original recipients + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, TEN_PERCENT * 4); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, TEN_PERCENT * 4); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, TEN_PERCENT); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, TEN_PERCENT); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //check each recipient received the correct amount + for (uint256 i; i < recipients.length; i++) { + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipients[i].addr), expectedRecipientAmount); + } + + //the reward manager should still have the funds for the secondary pool + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + + //add more funds to the pool to check new distribution + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //claim the rewards for the updated recipients manually + claimRewards(PRIMARY_POOL_ARRAY, recipients[0].addr); + claimRewards(PRIMARY_POOL_ARRAY, recipients[1].addr); + claimRewards(PRIMARY_POOL_ARRAY, recipients[2].addr); + claimRewards(PRIMARY_POOL_ARRAY, recipients[3].addr); + + //check the balance matches the ratio the recipient who were updated should have received + assertEq( + getAssetBalance(recipients[0].addr), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT * 4) / POOL_SCALAR + expectedRecipientAmount + ); + assertEq( + getAssetBalance(recipients[1].addr), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT * 4) / POOL_SCALAR + expectedRecipientAmount + ); + assertEq( + getAssetBalance(recipients[2].addr), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT) / POOL_SCALAR + expectedRecipientAmount + ); + assertEq( + getAssetBalance(recipients[3].addr), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT) / POOL_SCALAR + expectedRecipientAmount + ); + } +} diff --git a/contracts/src/v0.8/llo-feeds/test/BaseVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/BaseVerifierTest.t.sol similarity index 55% rename from contracts/src/v0.8/llo-feeds/test/BaseVerifierTest.t.sol rename to contracts/src/v0.8/llo-feeds/test/verifier/BaseVerifierTest.t.sol index a57e6c23781..38ceb3030ef 100644 --- a/contracts/src/v0.8/llo-feeds/test/BaseVerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/BaseVerifierTest.t.sol @@ -2,13 +2,19 @@ pragma solidity 0.8.16; import {Test} from "forge-std/Test.sol"; -import {VerifierProxy} from "../VerifierProxy.sol"; -import {IERC165} from "../../shared/vendor/IERC165.sol"; -import {IVerifier} from "../interfaces/IVerifier.sol"; -import {ErroredVerifier} from "./mocks/ErroredVerifier.sol"; -import {Verifier} from "../Verifier.sol"; +import {VerifierProxy} from "../../VerifierProxy.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol"; +import {IVerifier} from "../../interfaces/IVerifier.sol"; +import {ErroredVerifier} from "../mocks/ErroredVerifier.sol"; +import {Verifier} from "../../Verifier.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; -import {AccessControllerInterface} from "../../interfaces/AccessControllerInterface.sol"; +import {AccessControllerInterface} from "../../../interfaces/AccessControllerInterface.sol"; +import {FeeManager} from "../../dev/FeeManager.sol"; +import {Common} from "../../../libraries/Common.sol"; +import {ERC20Mock} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/mocks/ERC20Mock.sol"; +import {WERC20Mock} from "../../../shared/mocks/WERC20Mock.sol"; +import {FeeManager} from "../../dev/FeeManager.sol"; +import {RewardManager} from "../../dev/RewardManager.sol"; contract BaseTest is Test { uint256 internal constant MAX_ORACLES = 31; @@ -18,9 +24,19 @@ contract BaseTest is Test { address internal constant MOCK_VERIFIER_ADDRESS_TWO = address(200); address internal constant ACCESS_CONTROLLER_ADDRESS = address(300); - bytes32 internal constant FEED_ID = keccak256("ETH-USD"); - bytes32 internal constant FEED_ID_2 = keccak256("LINK-USD"); - bytes32 internal constant FEED_ID_3 = keccak256("BTC-USD"); + bytes32 internal constant V_MASK = 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; + bytes32 internal constant V1_BITMASK = 0x0001000000000000000000000000000000000000000000000000000000000000; + bytes32 internal constant V2_BITMASK = 0x0002000000000000000000000000000000000000000000000000000000000000; + bytes32 internal constant V3_BITMASK = 0x0003000000000000000000000000000000000000000000000000000000000000; + + //version 0 feeds + bytes32 internal constant FEED_ID = (keccak256("ETH-USD") & V_MASK) | V1_BITMASK; + bytes32 internal constant FEED_ID_2 = (keccak256("LINK-USD") & V_MASK) | V1_BITMASK; + bytes32 internal constant FEED_ID_3 = (keccak256("BTC-USD") & V_MASK) | V1_BITMASK; + + //version 3 feeds + bytes32 internal constant FEED_ID_V3 = (keccak256("ETH-USD") & V_MASK) | V3_BITMASK; + bytes32 internal constant INVALID_FEED = keccak256("INVALID"); uint32 internal constant OBSERVATIONS_TIMESTAMP = 1000; uint64 internal constant BLOCKNUMBER_LOWER_BOUND = 1000; @@ -47,7 +63,7 @@ contract BaseTest is Test { address signerAddress; } - struct Report { + struct V0Report { // The feed ID the report has data for bytes32 feedId; // The time the median value was observed on @@ -64,6 +80,8 @@ contract BaseTest is Test { bytes32 upperBlockhash; // The lower bound of the block range the median value was observed within uint64 blocknumberLowerBound; + // The current block timestamp + uint64 currentBlockTimestamp; } Signer[MAX_ORACLES] internal s_signers; @@ -111,7 +129,7 @@ contract BaseTest is Test { } function _generateSignerSignatures( - Report memory report, + bytes memory report, bytes32[3] memory reportContext, Signer[] memory signers ) internal pure returns (bytes32[] memory rawRs, bytes32[] memory rawSs, bytes32 rawVs) { @@ -119,7 +137,7 @@ contract BaseTest is Test { bytes32[] memory ss = new bytes32[](signers.length); bytes memory vs = new bytes(signers.length); - bytes32 hash = keccak256(abi.encodePacked(keccak256(abi.encode(report)), reportContext)); + bytes32 hash = keccak256(abi.encodePacked(keccak256(report), reportContext)); for (uint256 i = 0; i < signers.length; i++) { (uint8 v, bytes32 r, bytes32 s) = vm.sign(signers[i].mockPrivateKey, hash); @@ -131,20 +149,22 @@ contract BaseTest is Test { } function _generateEncodedBlob( - Report memory report, + V0Report memory report, bytes32[3] memory reportContext, Signer[] memory signers ) internal pure returns (bytes memory) { + bytes memory reportBytes = abi.encode(report); (bytes32[] memory rs, bytes32[] memory ss, bytes32 rawVs) = _generateSignerSignatures( - report, + reportBytes, reportContext, signers ); - return abi.encode(reportContext, abi.encode(report), rs, ss, rawVs); + return abi.encode(reportContext, reportBytes, rs, ss, rawVs); } function _configDigestFromConfigData( bytes32 feedId, + uint256 chainId, address verifierAddr, uint64 configCount, address[] memory signers, @@ -158,7 +178,7 @@ contract BaseTest is Test { keccak256( abi.encode( feedId, - block.chainid, + chainId, verifierAddr, configCount, signers, @@ -175,7 +195,7 @@ contract BaseTest is Test { return bytes32((prefix & prefixMask) | (h & ~prefixMask)); } - function _createReport( + function _createV0Report( bytes32 feedId, uint32 observationsTimestamp, int192 median, @@ -183,10 +203,11 @@ contract BaseTest is Test { int192 ask, uint64 blocknumberUpperBound, bytes32 upperBlockhash, - uint64 blocknumberLowerBound - ) internal pure returns (Report memory) { + uint64 blocknumberLowerBound, + uint32 currentBlockTimestamp + ) internal pure returns (V0Report memory) { return - Report({ + V0Report({ feedId: feedId, observationsTimestamp: observationsTimestamp, median: median, @@ -194,7 +215,8 @@ contract BaseTest is Test { ask: ask, blocknumberUpperBound: blocknumberUpperBound, upperBlockhash: upperBlockhash, - blocknumberLowerBound: blocknumberLowerBound + blocknumberLowerBound: blocknumberLowerBound, + currentBlockTimestamp: currentBlockTimestamp }); } @@ -212,12 +234,40 @@ contract BaseTest is Test { } } -contract BaseTestWithConfiguredVerifier is BaseTest { +contract BaseTestWithConfiguredVerifierAndFeeManager is BaseTest { + FeeManager internal feeManager; + RewardManager internal rewardManager; + ERC20Mock internal link; + WERC20Mock internal native; + + uint256 internal constant DEFAULT_REPORT_LINK_FEE = 1e10; + uint256 internal constant DEFAULT_REPORT_NATIVE_FEE = 1e12; + + struct V2Report { + // The feed ID the report has data for + bytes32 feedId; + // The time the median value was observed on + uint32 observationsTimestamp; + // The timestamp the report is valid from + uint32 validFromTimestamp; + // The median value agreed in an OCR round + int192 benchmarkPrice; + // The link fee + uint192 linkFee; + // The native fee + uint192 nativeFee; + // The expiry of the report + uint32 expiresAt; + // The best bid value agreed in an OCR round + int192 bid; + // The best ask value agreed in an OCR round + int192 ask; + } + function setUp() public virtual override { BaseTest.setUp(); Signer[] memory signers = _getSigners(MAX_ORACLES); - // Verifier 1, Feed 1, Config 1 s_verifierProxy.initializeVerifier(address(s_verifier)); s_verifier.setConfig( FEED_ID, @@ -226,12 +276,116 @@ contract BaseTestWithConfiguredVerifier is BaseTest { FAULT_TOLERANCE, bytes(""), VERIFIER_VERSION, - bytes("") + bytes(""), + new Common.AddressAndWeight[](0) + ); + + s_verifier.setConfig( + FEED_ID_V3, + _getSignerAddresses(signers), + s_offchaintransmitters, + FAULT_TOLERANCE, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + + link = new ERC20Mock("LINK", "LINK", ADMIN, 0); + native = new WERC20Mock(); + + rewardManager = new RewardManager(address(link)); + feeManager = new FeeManager(address(link), address(native), address(s_verifierProxy), address(rewardManager)); + + s_verifierProxy.setFeeManager(feeManager); + rewardManager.setFeeManager(address(feeManager)); + } + + function _encodeReport(V2Report memory report) internal pure returns (bytes memory) { + return + abi.encode( + report.feedId, + report.observationsTimestamp, + report.validFromTimestamp, + report.benchmarkPrice, + report.linkFee, + report.nativeFee, + report.expiresAt, + report.bid, + report.ask + ); + } + + function _generateEncodedBlobWithQuote( + V2Report memory report, + bytes32[3] memory reportContext, + Signer[] memory signers, + bytes memory quote + ) internal pure returns (bytes memory) { + bytes memory reportBytes = _encodeReport(report); + (bytes32[] memory rs, bytes32[] memory ss, bytes32 rawVs) = _generateSignerSignatures( + reportBytes, + reportContext, + signers ); + + return abi.encode(reportContext, reportBytes, rs, ss, rawVs, quote); + } + + function _generateQuote(address billingAddress) internal pure returns (bytes memory) { + return abi.encode(billingAddress); + } + + function _generateV2Report() internal view returns (V2Report memory) { + return + V2Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(block.timestamp), + benchmarkPrice: MEDIAN, + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + expiresAt: uint32(block.timestamp), + bid: BID, + ask: ASK + }); + } + + function _generateReportContext(bytes32 feedId) internal view returns (bytes32[3] memory) { + (, , bytes32 latestConfigDigest) = s_verifier.latestConfigDetails(feedId); + bytes32[3] memory reportContext; + reportContext[0] = latestConfigDigest; + reportContext[1] = bytes32(abi.encode(uint32(5), uint8(1))); + return reportContext; + } + + function _approveLink(address spender, uint256 quantity, address sender) internal { + address originalAddr = msg.sender; + changePrank(sender); + + link.approve(spender, quantity); + changePrank(originalAddr); + } + + function _approveNative(address spender, uint256 quantity, address sender) internal { + address originalAddr = msg.sender; + changePrank(sender); + + native.approve(spender, quantity); + changePrank(originalAddr); + } + + function _verify(bytes memory payload, uint256 wrappedNativeValue, address sender) internal { + address originalAddr = msg.sender; + changePrank(sender); + + s_verifierProxy.verify{value: wrappedNativeValue}(payload); + + changePrank(originalAddr); } } -contract BaseTestWithMultipleConfiguredDigests is BaseTestWithConfiguredVerifier { +contract BaseTestWithMultipleConfiguredDigests is BaseTestWithConfiguredVerifierAndFeeManager { bytes32 internal s_configDigestOne; bytes32 internal s_configDigestTwo; bytes32 internal s_configDigestThree; @@ -244,7 +398,7 @@ contract BaseTestWithMultipleConfiguredDigests is BaseTestWithConfiguredVerifier uint8 internal constant FAULT_TOLERANCE_THREE = 1; function setUp() public virtual override { - BaseTestWithConfiguredVerifier.setUp(); + BaseTestWithConfiguredVerifierAndFeeManager.setUp(); Signer[] memory signers = _getSigners(MAX_ORACLES); (, , s_configDigestOne) = s_verifier.latestConfigDetails(FEED_ID); @@ -258,7 +412,8 @@ contract BaseTestWithMultipleConfiguredDigests is BaseTestWithConfiguredVerifier FAULT_TOLERANCE_TWO, bytes(""), 2, - bytes("") + bytes(""), + new Common.AddressAndWeight[](0) ); (, , s_configDigestTwo) = s_verifier.latestConfigDetails(FEED_ID); @@ -271,7 +426,8 @@ contract BaseTestWithMultipleConfiguredDigests is BaseTestWithConfiguredVerifier FAULT_TOLERANCE_THREE, bytes(""), 3, - bytes("") + bytes(""), + new Common.AddressAndWeight[](0) ); (s_numConfigsSet, , s_configDigestThree) = s_verifier.latestConfigDetails(FEED_ID); @@ -283,7 +439,8 @@ contract BaseTestWithMultipleConfiguredDigests is BaseTestWithConfiguredVerifier FAULT_TOLERANCE, bytes(""), 4, - bytes("") + bytes(""), + new Common.AddressAndWeight[](0) ); (, , s_configDigestFour) = s_verifier.latestConfigDetails(FEED_ID_2); @@ -296,7 +453,8 @@ contract BaseTestWithMultipleConfiguredDigests is BaseTestWithConfiguredVerifier FAULT_TOLERANCE, bytes(""), VERIFIER_VERSION, - bytes("") + bytes(""), + new Common.AddressAndWeight[](0) ); (, , s_configDigestFive) = s_verifier_2.latestConfigDetails(FEED_ID_3); } diff --git a/contracts/src/v0.8/llo-feeds/test/VerifierActivateConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierActivateConfigTest.t.sol similarity index 81% rename from contracts/src/v0.8/llo-feeds/test/VerifierActivateConfigTest.t.sol rename to contracts/src/v0.8/llo-feeds/test/verifier/VerifierActivateConfigTest.t.sol index e7bc4ab23fb..501f23d10d3 100644 --- a/contracts/src/v0.8/llo-feeds/test/VerifierActivateConfigTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierActivateConfigTest.t.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.16; -import {BaseTestWithConfiguredVerifier, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; -import {Verifier} from "../Verifier.sol"; -import {VerifierProxy} from "../VerifierProxy.sol"; +import {BaseTestWithConfiguredVerifierAndFeeManager, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; +import {Verifier} from "../../Verifier.sol"; +import {VerifierProxy} from "../../VerifierProxy.sol"; -contract VerifierActivateConfigTest is BaseTestWithConfiguredVerifier { +contract VerifierActivateConfigTest is BaseTestWithConfiguredVerifierAndFeeManager { function test_revertsIfNotOwner() public { vm.expectRevert("Only callable by owner"); @@ -29,13 +29,13 @@ contract VerifierActivateConfigWithDeactivatedConfigTest is BaseTestWithMultiple event ConfigActivated(bytes32 configDigest); - Report internal s_testReportOne; + V0Report internal s_testReportOne; function setUp() public override { BaseTestWithMultipleConfiguredDigests.setUp(); s_reportContext[0] = s_configDigestTwo; s_reportContext[1] = bytes32(abi.encode(uint32(5), uint8(1))); - s_testReportOne = _createReport( + s_testReportOne = _createV0Report( FEED_ID, uint32(block.timestamp), MEDIAN, @@ -43,7 +43,8 @@ contract VerifierActivateConfigWithDeactivatedConfigTest is BaseTestWithMultiple ASK, uint64(block.number), blockhash(block.number + 3), - uint64(block.number + 3) + uint64(block.number + 3), + uint32(block.timestamp) ); s_verifier.deactivateConfig(FEED_ID, s_configDigestTwo); diff --git a/contracts/src/v0.8/llo-feeds/test/VerifierDeactivateFeedTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierDeactivateFeedTest.t.sol similarity index 88% rename from contracts/src/v0.8/llo-feeds/test/VerifierDeactivateFeedTest.t.sol rename to contracts/src/v0.8/llo-feeds/test/verifier/VerifierDeactivateFeedTest.t.sol index 1f55be2ca72..e44a9a03f81 100644 --- a/contracts/src/v0.8/llo-feeds/test/VerifierDeactivateFeedTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierDeactivateFeedTest.t.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.16; -import {BaseTestWithConfiguredVerifier, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; -import {Verifier} from "../Verifier.sol"; -import {VerifierProxy} from "../VerifierProxy.sol"; +import {BaseTestWithConfiguredVerifierAndFeeManager, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; +import {Verifier} from "../../Verifier.sol"; +import {VerifierProxy} from "../../VerifierProxy.sol"; -contract VerifierActivateFeedTest is BaseTestWithConfiguredVerifier { +contract VerifierActivateFeedTest is BaseTestWithConfiguredVerifierAndFeeManager { function test_revertsIfNotOwnerActivateFeed() public { changePrank(address(s_verifierProxy)); vm.expectRevert("Only callable by owner"); @@ -34,13 +34,13 @@ contract VerifierDeactivateFeedWithVerifyTest is BaseTestWithMultipleConfiguredD event ConfigActivated(bytes32 configDigest); - Report internal s_testReportOne; + V0Report internal s_testReportOne; function setUp() public override { BaseTestWithMultipleConfiguredDigests.setUp(); s_reportContext[0] = s_configDigestOne; s_reportContext[1] = bytes32(abi.encode(uint32(5), uint8(1))); - s_testReportOne = _createReport( + s_testReportOne = _createV0Report( FEED_ID, uint32(block.timestamp), MEDIAN, @@ -48,7 +48,8 @@ contract VerifierDeactivateFeedWithVerifyTest is BaseTestWithMultipleConfiguredD ASK, uint64(block.number), blockhash(block.number + 3), - uint64(block.number + 3) + uint64(block.number + 3), + uint32(block.timestamp) ); s_verifier.deactivateFeed(FEED_ID); diff --git a/contracts/src/v0.8/llo-feeds/test/VerifierProxyConstructorTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyConstructorTest.t.sol similarity index 67% rename from contracts/src/v0.8/llo-feeds/test/VerifierProxyConstructorTest.t.sol rename to contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyConstructorTest.t.sol index 879814d949c..b4d13423ecd 100644 --- a/contracts/src/v0.8/llo-feeds/test/VerifierProxyConstructorTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyConstructorTest.t.sol @@ -2,9 +2,9 @@ pragma solidity 0.8.16; import {BaseTest} from "./BaseVerifierTest.t.sol"; -import {IVerifier} from "../interfaces/IVerifier.sol"; -import {VerifierProxy} from "../VerifierProxy.sol"; -import {AccessControllerInterface} from "../../interfaces/AccessControllerInterface.sol"; +import {IVerifier} from "../../interfaces/IVerifier.sol"; +import {VerifierProxy} from "../../VerifierProxy.sol"; +import {AccessControllerInterface} from "../../../interfaces/AccessControllerInterface.sol"; contract VerifierProxyConstructorTest is BaseTest { function test_correctlySetsTheOwner() public { @@ -15,11 +15,11 @@ contract VerifierProxyConstructorTest is BaseTest { function test_correctlySetsTheCorrectAccessControllerInterface() public { address accessControllerAddr = address(1234); VerifierProxy proxy = new VerifierProxy(AccessControllerInterface(accessControllerAddr)); - assertEq(address(proxy.getAccessController()), accessControllerAddr); + assertEq(address(proxy.s_accessController()), accessControllerAddr); } function test_correctlySetsVersion() public { string memory version = s_verifierProxy.typeAndVersion(); - assertEq(version, "VerifierProxy 1.0.0"); + assertEq(version, "VerifierProxy 1.1.0"); } } diff --git a/contracts/src/v0.8/llo-feeds/test/VerifierProxyInitializeVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyInitializeVerifierTest.t.sol similarity index 78% rename from contracts/src/v0.8/llo-feeds/test/VerifierProxyInitializeVerifierTest.t.sol rename to contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyInitializeVerifierTest.t.sol index 67cf548f268..92b98c6d9d2 100644 --- a/contracts/src/v0.8/llo-feeds/test/VerifierProxyInitializeVerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyInitializeVerifierTest.t.sol @@ -2,16 +2,15 @@ pragma solidity 0.8.16; import {BaseTest} from "./BaseVerifierTest.t.sol"; -import {IVerifier} from "../interfaces/IVerifier.sol"; -import {VerifierProxy} from "..//VerifierProxy.sol"; -import {AccessControllerInterface} from "../../interfaces/AccessControllerInterface.sol"; +import {IVerifier} from "../../interfaces/IVerifier.sol"; +import {VerifierProxy} from "../../VerifierProxy.sol"; +import {AccessControllerInterface} from "../../../interfaces/AccessControllerInterface.sol"; contract VerifierProxyInitializeVerifierTest is BaseTest { bytes32 latestDigest; function setUp() public override { BaseTest.setUp(); - Signer[] memory signers = _getSigners(MAX_ORACLES); } function test_revertsIfNotOwner() public { diff --git a/contracts/src/v0.8/llo-feeds/test/VerifierProxySetAccessControllerTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetAccessControllerTest.t.sol similarity index 82% rename from contracts/src/v0.8/llo-feeds/test/VerifierProxySetAccessControllerTest.t.sol rename to contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetAccessControllerTest.t.sol index ca8c8e22fc2..a93f30a743a 100644 --- a/contracts/src/v0.8/llo-feeds/test/VerifierProxySetAccessControllerTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetAccessControllerTest.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.16; import {BaseTest} from "./BaseVerifierTest.t.sol"; -import {AccessControllerInterface} from "../../interfaces/AccessControllerInterface.sol"; +import {AccessControllerInterface} from "../../../interfaces/AccessControllerInterface.sol"; contract VerifierProxySetAccessControllerTest is BaseTest { event AccessControllerSet(address oldAccessController, address newAccessController); @@ -16,13 +16,13 @@ contract VerifierProxySetAccessControllerTest is BaseTest { function test_successfullySetsNewAccessController() public { s_verifierProxy.setAccessController(AccessControllerInterface(ACCESS_CONTROLLER_ADDRESS)); - AccessControllerInterface ac = s_verifierProxy.getAccessController(); + AccessControllerInterface ac = s_verifierProxy.s_accessController(); assertEq(address(ac), ACCESS_CONTROLLER_ADDRESS); } function test_successfullySetsNewAccessControllerIsEmpty() public { s_verifierProxy.setAccessController(AccessControllerInterface(address(0))); - AccessControllerInterface ac = s_verifierProxy.getAccessController(); + AccessControllerInterface ac = s_verifierProxy.s_accessController(); assertEq(address(ac), address(0)); } diff --git a/contracts/src/v0.8/llo-feeds/test/VerifierProxySetVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetVerifierTest.t.sol similarity index 67% rename from contracts/src/v0.8/llo-feeds/test/VerifierProxySetVerifierTest.t.sol rename to contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetVerifierTest.t.sol index 2e40706f2a3..ee7b2c96b7b 100644 --- a/contracts/src/v0.8/llo-feeds/test/VerifierProxySetVerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetVerifierTest.t.sol @@ -1,16 +1,17 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.16; -import {BaseTestWithConfiguredVerifier} from "./BaseVerifierTest.t.sol"; -import {IVerifier} from "../interfaces/IVerifier.sol"; -import {VerifierProxy} from "../VerifierProxy.sol"; -import {AccessControllerInterface} from "../../interfaces/AccessControllerInterface.sol"; -import {IERC165} from "../../shared/vendor/IERC165.sol"; +import {BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol"; +import {IVerifier} from "../../interfaces/IVerifier.sol"; +import {VerifierProxy} from "../../VerifierProxy.sol"; +import {AccessControllerInterface} from "../../../interfaces/AccessControllerInterface.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol"; +import {Common} from "../../../libraries/Common.sol"; -contract VerifierProxyInitializeVerifierTest is BaseTestWithConfiguredVerifier { +contract VerifierProxyInitializeVerifierTest is BaseTestWithConfiguredVerifierAndFeeManager { function test_revertsIfNotCorrectVerifier() public { vm.expectRevert(abi.encodeWithSelector(VerifierProxy.AccessForbidden.selector)); - s_verifierProxy.setVerifier(bytes32("prev-config"), bytes32("new-config")); + s_verifierProxy.setVerifier(bytes32("prev-config"), bytes32("new-config"), new Common.AddressAndWeight[](0)); } function test_revertsIfDigestAlreadySet() public { @@ -28,13 +29,13 @@ contract VerifierProxyInitializeVerifierTest is BaseTestWithConfiguredVerifier { abi.encodeWithSelector(VerifierProxy.ConfigDigestAlreadySet.selector, takenDigest, address(s_verifier)) ); changePrank(address(maliciousVerifier)); - s_verifierProxy.setVerifier(maliciousDigest, takenDigest); + s_verifierProxy.setVerifier(maliciousDigest, takenDigest, new Common.AddressAndWeight[](0)); } function test_updatesVerifierIfVerifier() public { (, , bytes32 prevDigest) = s_verifier.latestConfigDetails(FEED_ID); changePrank(address(s_verifier)); - s_verifierProxy.setVerifier(prevDigest, bytes32("new-config")); + s_verifierProxy.setVerifier(prevDigest, bytes32("new-config"), new Common.AddressAndWeight[](0)); assertEq(s_verifierProxy.getVerifier(bytes32("new-config")), address(s_verifier)); assertEq(s_verifierProxy.getVerifier(prevDigest), address(s_verifier)); } diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyTest.t.sol new file mode 100644 index 00000000000..ffce4e6fa50 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyTest.t.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.16; + +import {BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol"; +import {IVerifier} from "../../interfaces/IVerifier.sol"; +import {VerifierProxy} from "../../VerifierProxy.sol"; +import {AccessControllerInterface} from "../../../interfaces/AccessControllerInterface.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol"; +import {Common} from "../../../libraries/Common.sol"; +import {FeeManager} from "../../dev/FeeManager.sol"; + +contract VerifierProxyInitializeVerifierTest is BaseTestWithConfiguredVerifierAndFeeManager { + function test_setFeeManagerZeroAddress() public { + vm.expectRevert(abi.encodeWithSelector(VerifierProxy.ZeroAddress.selector)); + s_verifierProxy.setFeeManager(FeeManager(address(0))); + } +} diff --git a/contracts/src/v0.8/llo-feeds/test/VerifierProxyUnsetVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyUnsetVerifierTest.t.sol similarity index 79% rename from contracts/src/v0.8/llo-feeds/test/VerifierProxyUnsetVerifierTest.t.sol rename to contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyUnsetVerifierTest.t.sol index c5b49e41e1b..a64d6ee0f78 100644 --- a/contracts/src/v0.8/llo-feeds/test/VerifierProxyUnsetVerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyUnsetVerifierTest.t.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.16; -import {BaseTest, BaseTestWithConfiguredVerifier} from "./BaseVerifierTest.t.sol"; -import {IVerifier} from "../interfaces/IVerifier.sol"; -import {VerifierProxy} from "../VerifierProxy.sol"; +import {BaseTest, BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol"; +import {IVerifier} from "../../interfaces/IVerifier.sol"; +import {VerifierProxy} from "../../VerifierProxy.sol"; contract VerifierProxyUnsetVerifierTest is BaseTest { function test_revertsIfNotAdmin() public { @@ -19,13 +19,13 @@ contract VerifierProxyUnsetVerifierTest is BaseTest { } } -contract VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest is BaseTestWithConfiguredVerifier { +contract VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest is BaseTestWithConfiguredVerifierAndFeeManager { bytes32 internal s_configDigest; event VerifierUnset(bytes32 configDigest, address verifierAddr); function setUp() public override { - BaseTestWithConfiguredVerifier.setUp(); + BaseTestWithConfiguredVerifierAndFeeManager.setUp(); (, , s_configDigest) = s_verifier.latestConfigDetails(FEED_ID); } diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigFromSourceTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigFromSourceTest.t.sol new file mode 100644 index 00000000000..2ba25294168 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigFromSourceTest.t.sol @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.16; + +import {BaseTest, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; +import {Verifier} from "../../Verifier.sol"; +import {VerifierProxy} from "../../VerifierProxy.sol"; +import {Common} from "../../../libraries/Common.sol"; + +contract VerifierSetConfigFromSourceTest is BaseTest { + function setUp() public virtual override { + BaseTest.setUp(); + } + + function test_revertsIfCalledByNonOwner() public { + vm.expectRevert("Only callable by owner"); + Signer[] memory signers = _getSigners(MAX_ORACLES); + + changePrank(USER); + s_verifier.setConfigFromSource( + FEED_ID, + 12345, + address(12345), + _getSignerAddresses(signers), + s_offchaintransmitters, + FAULT_TOLERANCE, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + } +} + +contract VerifierSetConfigFromSourceMultipleDigestsTest is BaseTestWithMultipleConfiguredDigests { + function test_correctlyUpdatesTheDigestInTheProxy() public { + Signer[] memory newSigners = _getSigners(15); + + s_verifier.setConfigFromSource( + FEED_ID, + 12345, + address(12345), + _getSignerAddresses(newSigners), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + + (, , bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID); + address verifierAddr = s_verifierProxy.getVerifier(configDigest); + assertEq(verifierAddr, address(s_verifier)); + } + + function test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() public { + Signer[] memory newSigners = _getSigners(15); + + s_verifier.setConfigFromSource( + FEED_ID_2, + 12345, + address(12345), + _getSignerAddresses(newSigners), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + + (, , bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID_2); + address verifierAddr = s_verifierProxy.getVerifier(configDigest); + assertEq(verifierAddr, address(s_verifier)); + + s_verifier_2.setConfigFromSource( + FEED_ID_3, + 12345, + address(12345), + _getSignerAddresses(newSigners), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + + (, , bytes32 configDigest2) = s_verifier_2.latestConfigDetails(FEED_ID_3); + address verifierAddr2 = s_verifierProxy.getVerifier(configDigest2); + assertEq(verifierAddr2, address(s_verifier_2)); + } + + function test_correctlySetsConfigWhenDigestsAreRemoved() public { + s_verifier.deactivateConfig(FEED_ID, s_configDigestTwo); + + Signer[] memory newSigners = _getSigners(15); + + s_verifier.setConfigFromSource( + FEED_ID, + 12345, + address(s_verifier), + _getSignerAddresses(newSigners), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + + bytes32 expectedConfigDigest = _configDigestFromConfigData( + FEED_ID, + 12345, + address(s_verifier), + s_numConfigsSet + 1, + _getSignerAddresses(newSigners), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes("") + ); + + (uint32 configCount, uint32 blockNumber, bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID); + + assertEq(configCount, s_numConfigsSet + 1); + assertEq(blockNumber, block.number); + assertEq(configDigest, expectedConfigDigest); + } +} diff --git a/contracts/src/v0.8/llo-feeds/test/VerifierSetConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigTest.t.sol similarity index 88% rename from contracts/src/v0.8/llo-feeds/test/VerifierSetConfigTest.t.sol rename to contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigTest.t.sol index dfffd47f571..faa1f98bc30 100644 --- a/contracts/src/v0.8/llo-feeds/test/VerifierSetConfigTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigTest.t.sol @@ -2,8 +2,9 @@ pragma solidity 0.8.16; import {BaseTest, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; -import {Verifier} from "../Verifier.sol"; -import {VerifierProxy} from "../VerifierProxy.sol"; +import {Verifier} from "../../Verifier.sol"; +import {VerifierProxy} from "../../VerifierProxy.sol"; +import {Common} from "../../../libraries/Common.sol"; contract VerifierSetConfigTest is BaseTest { function setUp() public virtual override { @@ -22,7 +23,8 @@ contract VerifierSetConfigTest is BaseTest { FAULT_TOLERANCE, bytes(""), VERIFIER_VERSION, - bytes("") + bytes(""), + new Common.AddressAndWeight[](0) ); } @@ -36,7 +38,8 @@ contract VerifierSetConfigTest is BaseTest { FAULT_TOLERANCE, bytes(""), VERIFIER_VERSION, - bytes("") + bytes(""), + new Common.AddressAndWeight[](0) ); } @@ -50,7 +53,8 @@ contract VerifierSetConfigTest is BaseTest { 0, bytes(""), VERIFIER_VERSION, - bytes("") + bytes(""), + new Common.AddressAndWeight[](0) ); } @@ -69,7 +73,8 @@ contract VerifierSetConfigTest is BaseTest { FAULT_TOLERANCE, bytes(""), VERIFIER_VERSION, - bytes("") + bytes(""), + new Common.AddressAndWeight[](0) ); } @@ -85,7 +90,8 @@ contract VerifierSetConfigTest is BaseTest { FAULT_TOLERANCE, bytes(""), VERIFIER_VERSION, - bytes("") + bytes(""), + new Common.AddressAndWeight[](0) ); } @@ -101,7 +107,8 @@ contract VerifierSetConfigTest is BaseTest { FAULT_TOLERANCE, bytes(""), VERIFIER_VERSION, - bytes("") + bytes(""), + new Common.AddressAndWeight[](0) ); } @@ -116,11 +123,13 @@ contract VerifierSetConfigTest is BaseTest { FAULT_TOLERANCE, bytes(""), VERIFIER_VERSION, - bytes("") + bytes(""), + new Common.AddressAndWeight[](0) ); bytes32 expectedConfigDigest = _configDigestFromConfigData( FEED_ID, + block.chainid, address(s_verifier), 1, _getSignerAddresses(signers), @@ -154,7 +163,8 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl 4, bytes(""), VERIFIER_VERSION, - bytes("") + bytes(""), + new Common.AddressAndWeight[](0) ); (, , bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID); @@ -172,7 +182,8 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl 4, bytes(""), VERIFIER_VERSION, - bytes("") + bytes(""), + new Common.AddressAndWeight[](0) ); (, , bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID_2); @@ -186,7 +197,8 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl 4, bytes(""), VERIFIER_VERSION, - bytes("") + bytes(""), + new Common.AddressAndWeight[](0) ); (, , bytes32 configDigest2) = s_verifier_2.latestConfigDetails(FEED_ID_3); @@ -206,11 +218,13 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl 4, bytes(""), VERIFIER_VERSION, - bytes("") + bytes(""), + new Common.AddressAndWeight[](0) ); bytes32 expectedConfigDigest = _configDigestFromConfigData( FEED_ID, + block.chainid, address(s_verifier), s_numConfigsSet + 1, _getSignerAddresses(newSigners), diff --git a/contracts/src/v0.8/llo-feeds/test/VerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTest.t.sol similarity index 90% rename from contracts/src/v0.8/llo-feeds/test/VerifierTest.t.sol rename to contracts/src/v0.8/llo-feeds/test/verifier/VerifierTest.t.sol index 514b8ce50a0..424b1124b92 100644 --- a/contracts/src/v0.8/llo-feeds/test/VerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTest.t.sol @@ -2,8 +2,8 @@ pragma solidity 0.8.16; import {BaseTest} from "./BaseVerifierTest.t.sol"; -import {Verifier} from "../Verifier.sol"; -import {VerifierProxy} from "../VerifierProxy.sol"; +import {Verifier} from "../../Verifier.sol"; +import {VerifierProxy} from "../../VerifierProxy.sol"; contract VerifierConstructorTest is BaseTest { function test_revertsIfInitializedWithEmptyVerifierProxy() public { @@ -26,7 +26,7 @@ contract VerifierConstructorTest is BaseTest { assertEq(configDigestTwo, EMPTY_BYTES); string memory typeAndVersion = s_verifier.typeAndVersion(); - assertEq(typeAndVersion, "Verifier 1.0.0"); + assertEq(typeAndVersion, "Verifier 1.1.0"); } } diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTestBillingReport.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTestBillingReport.t.sol new file mode 100644 index 00000000000..086816a7c57 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTestBillingReport.t.sol @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.16; + +import {BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol"; +import {Verifier} from "../../Verifier.sol"; +import {VerifierProxy} from "../../VerifierProxy.sol"; +import {Common} from "../../../libraries/Common.sol"; + +contract VerifierTestWithConfiguredVerifierAndFeeManager is BaseTestWithConfiguredVerifierAndFeeManager { + uint256 internal constant DEFAULT_LINK_MINT_QUANTITY = 100 ether; + uint256 internal constant DEFAULT_NATIVE_MINT_QUANTITY = 100 ether; + + function setUp() public virtual override { + super.setUp(); + + //mint some tokens to the user + link.mint(USER, DEFAULT_LINK_MINT_QUANTITY); + native.mint(USER, DEFAULT_NATIVE_MINT_QUANTITY); + vm.deal(USER, DEFAULT_NATIVE_MINT_QUANTITY); + } +} + +contract VerifierTestBillingReport is VerifierTestWithConfiguredVerifierAndFeeManager { + function test_verifyWithLink() public { + bytes memory signedReport = _generateEncodedBlobWithQuote( + _generateV2Report(), + _generateReportContext(FEED_ID_V3), + _getSigners(FAULT_TOLERANCE + 1), + _generateQuote(address(link)) + ); + + _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + + _verify(signedReport, 0, USER); + + assertEq(link.balanceOf(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE); + } + + function test_verifyWithNative() public { + bytes memory signedReport = _generateEncodedBlobWithQuote( + _generateV2Report(), + _generateReportContext(FEED_ID_V3), + _getSigners(FAULT_TOLERANCE + 1), + _generateQuote(address(native)) + ); + + _approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + + _verify(signedReport, 0, USER); + + assertEq(native.balanceOf(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + } + + function test_verifyWithNativeUnwrapped() public { + bytes memory signedReport = _generateEncodedBlobWithQuote( + _generateV2Report(), + _generateReportContext(FEED_ID_V3), + _getSigners(FAULT_TOLERANCE + 1), + _generateQuote(address(native)) + ); + + _verify(signedReport, DEFAULT_REPORT_NATIVE_FEE, USER); + + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + assertEq(address(feeManager).balance, 0); + } + + function test_verifyWithNativeUnwrappedReturnsChange() public { + bytes memory signedReport = _generateEncodedBlobWithQuote( + _generateV2Report(), + _generateReportContext(FEED_ID_V3), + _getSigners(FAULT_TOLERANCE + 1), + _generateQuote(address(native)) + ); + + _verify(signedReport, DEFAULT_REPORT_NATIVE_FEE * 2, USER); + + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + assertEq(address(feeManager).balance, 0); + } +} diff --git a/contracts/src/v0.8/llo-feeds/test/VerifierUnsetConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierUnsetConfigTest.t.sol similarity index 90% rename from contracts/src/v0.8/llo-feeds/test/VerifierUnsetConfigTest.t.sol rename to contracts/src/v0.8/llo-feeds/test/verifier/VerifierUnsetConfigTest.t.sol index d97e0499186..467c5072d55 100644 --- a/contracts/src/v0.8/llo-feeds/test/VerifierUnsetConfigTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierUnsetConfigTest.t.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.16; -import {BaseTestWithConfiguredVerifier, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; -import {Verifier} from "../Verifier.sol"; -import {VerifierProxy} from "../VerifierProxy.sol"; +import {BaseTestWithConfiguredVerifierAndFeeManager, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; +import {Verifier} from "../../Verifier.sol"; +import {VerifierProxy} from "../../VerifierProxy.sol"; contract VerificationdeactivateConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipleConfiguredDigests { function test_revertsIfCalledByNonOwner() public { diff --git a/contracts/src/v0.8/llo-feeds/test/VerifierVerifyTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierVerifyTest.t.sol similarity index 90% rename from contracts/src/v0.8/llo-feeds/test/VerifierVerifyTest.t.sol rename to contracts/src/v0.8/llo-feeds/test/verifier/VerifierVerifyTest.t.sol index 065a9cd9c5e..38bb86a663d 100644 --- a/contracts/src/v0.8/llo-feeds/test/VerifierVerifyTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierVerifyTest.t.sol @@ -1,24 +1,25 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.16; -import {BaseTestWithConfiguredVerifier} from "./BaseVerifierTest.t.sol"; -import {Verifier} from "../Verifier.sol"; -import {VerifierProxy} from "../VerifierProxy.sol"; -import {AccessControllerInterface} from "../../interfaces/AccessControllerInterface.sol"; +import {BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol"; +import {Verifier} from "../../Verifier.sol"; +import {VerifierProxy} from "../../VerifierProxy.sol"; +import {AccessControllerInterface} from "../../../interfaces/AccessControllerInterface.sol"; +import {Common} from "../../../libraries/Common.sol"; -contract VerifierVerifyTest is BaseTestWithConfiguredVerifier { +contract VerifierVerifyTest is BaseTestWithConfiguredVerifierAndFeeManager { bytes32[3] internal s_reportContext; event ReportVerified(bytes32 indexed feedId, address requester); - Report internal s_testReportOne; + V0Report internal s_testReportOne; function setUp() public virtual override { - BaseTestWithConfiguredVerifier.setUp(); + BaseTestWithConfiguredVerifierAndFeeManager.setUp(); (, , bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID); s_reportContext[0] = configDigest; s_reportContext[1] = bytes32(abi.encode(uint32(5), uint8(1))); - s_testReportOne = _createReport( + s_testReportOne = _createV0Report( FEED_ID, OBSERVATIONS_TIMESTAMP, MEDIAN, @@ -26,11 +27,12 @@ contract VerifierVerifyTest is BaseTestWithConfiguredVerifier { ASK, BLOCKNUMBER_UPPER_BOUND, blockhash(BLOCKNUMBER_UPPER_BOUND), - BLOCKNUMBER_LOWER_BOUND + BLOCKNUMBER_LOWER_BOUND, + uint32(block.timestamp) ); } - function assertReportsEqual(bytes memory response, Report memory testReport) public { + function assertReportsEqual(bytes memory response, V0Report memory testReport) public { ( bytes32 feedId, uint32 timestamp, @@ -136,7 +138,7 @@ contract VerifierVerifySingleConfigDigestTest is VerifierVerifyTest { signers[10].mockPrivateKey = 1234; bytes memory signedReport = _generateEncodedBlob(s_testReportOne, s_reportContext, signers); changePrank(address(s_verifierProxy)); - vm.expectRevert(abi.encodeWithSelector(Verifier.AccessForbidden.selector)); + vm.expectRevert(abi.encodeWithSelector(Verifier.BadVerification.selector)); s_verifier.verify(signedReport, msg.sender); } @@ -160,7 +162,7 @@ contract VerifierVerifySingleConfigDigestTest is VerifierVerifyTest { } function test_revertsIfReportHasUnconfiguredFeedID() public { - Report memory report = _createReport( + V0Report memory report = _createV0Report( FEED_ID_2, OBSERVATIONS_TIMESTAMP, MEDIAN, @@ -168,7 +170,8 @@ contract VerifierVerifySingleConfigDigestTest is VerifierVerifyTest { ASK, BLOCKNUMBER_UPPER_BOUND, blockhash(BLOCKNUMBER_UPPER_BOUND), - BLOCKNUMBER_LOWER_BOUND + BLOCKNUMBER_LOWER_BOUND, + uint32(block.timestamp) ); bytes memory signedReport = _generateEncodedBlob(report, s_reportContext, _getSigners(FAULT_TOLERANCE + 1)); vm.expectRevert(abi.encodeWithSelector(Verifier.DigestInactive.selector, FEED_ID_2, s_reportContext[0])); @@ -188,7 +191,7 @@ contract VerifierVerifySingleConfigDigestTest is VerifierVerifyTest { // Duplicate signer at index 1 signers[0] = signers[1]; bytes memory signedReport = _generateEncodedBlob(s_testReportOne, s_reportContext, signers); - vm.expectRevert(abi.encodeWithSelector(Verifier.NonUniqueSignatures.selector)); + vm.expectRevert(abi.encodeWithSelector(Verifier.BadVerification.selector)); changePrank(address(s_verifierProxy)); s_verifier.verify(signedReport, msg.sender); } @@ -248,7 +251,8 @@ contract VerifierVerifyMultipleConfigDigestTest is VerifierVerifyTest { FAULT_TOLERANCE_TWO, bytes(""), VERIFIER_VERSION, - bytes("") + bytes(""), + new Common.AddressAndWeight[](0) ); (, , s_newConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); } diff --git a/contracts/src/v0.8/mocks/MockLinkToken.sol b/contracts/src/v0.8/mocks/MockLinkToken.sol index f69c2cfefb5..a68f1b1d341 100644 --- a/contracts/src/v0.8/mocks/MockLinkToken.sol +++ b/contracts/src/v0.8/mocks/MockLinkToken.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {ERC677ReceiverInterface} from "../interfaces/ERC677ReceiverInterface.sol"; +import {IERC677Receiver} from "../shared/interfaces/IERC677Receiver.sol"; contract MockLinkToken { uint256 private constant TOTAL_SUPPLY = 1_000_000_000 * 1e18; @@ -48,7 +48,7 @@ contract MockLinkToken { } function contractFallback(address _to, uint256 _value, bytes calldata _data) private { - ERC677ReceiverInterface receiver = ERC677ReceiverInterface(_to); + IERC677Receiver receiver = IERC677Receiver(_to); receiver.onTokenTransfer(msg.sender, _value, _data); } } diff --git a/contracts/src/v0.8/mocks/VRFCoordinatorMock.sol b/contracts/src/v0.8/mocks/VRFCoordinatorMock.sol index 1d2f4a2c73b..7e179d5a445 100644 --- a/contracts/src/v0.8/mocks/VRFCoordinatorMock.sol +++ b/contracts/src/v0.8/mocks/VRFCoordinatorMock.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../interfaces/LinkTokenInterface.sol"; +import "../shared/interfaces/LinkTokenInterface.sol"; import "../vrf/VRFConsumerBase.sol"; contract VRFCoordinatorMock { diff --git a/contracts/src/v0.8/mocks/VRFCoordinatorV2Mock.sol b/contracts/src/v0.8/mocks/VRFCoordinatorV2Mock.sol index eb4f8141956..8dfb0dca7c5 100644 --- a/contracts/src/v0.8/mocks/VRFCoordinatorV2Mock.sol +++ b/contracts/src/v0.8/mocks/VRFCoordinatorV2Mock.sol @@ -2,7 +2,7 @@ // A mock for testing code that relies on VRFCoordinatorV2. pragma solidity ^0.8.4; -import "../interfaces/LinkTokenInterface.sol"; +import "../shared/interfaces/LinkTokenInterface.sol"; import "../interfaces/VRFCoordinatorV2Interface.sol"; import "../vrf/VRFConsumerBaseV2.sol"; diff --git a/contracts/src/v0.8/ConfirmedOwner.sol b/contracts/src/v0.8/shared/access/ConfirmedOwner.sol similarity index 100% rename from contracts/src/v0.8/ConfirmedOwner.sol rename to contracts/src/v0.8/shared/access/ConfirmedOwner.sol diff --git a/contracts/src/v0.8/ConfirmedOwnerWithProposal.sol b/contracts/src/v0.8/shared/access/ConfirmedOwnerWithProposal.sol similarity index 94% rename from contracts/src/v0.8/ConfirmedOwnerWithProposal.sol rename to contracts/src/v0.8/shared/access/ConfirmedOwnerWithProposal.sol index 65071d16df7..c2a01cfca18 100644 --- a/contracts/src/v0.8/ConfirmedOwnerWithProposal.sol +++ b/contracts/src/v0.8/shared/access/ConfirmedOwnerWithProposal.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "./interfaces/OwnableInterface.sol"; +import "../interfaces/IOwnable.sol"; /** * @title The ConfirmedOwner contract * @notice A contract with helpers for basic contract ownership. */ -contract ConfirmedOwnerWithProposal is OwnableInterface { +contract ConfirmedOwnerWithProposal is IOwnable { address private s_owner; address private s_pendingOwner; diff --git a/contracts/src/v0.8/shared/access/OwnerIsCreator.sol b/contracts/src/v0.8/shared/access/OwnerIsCreator.sol new file mode 100644 index 00000000000..829c68794a5 --- /dev/null +++ b/contracts/src/v0.8/shared/access/OwnerIsCreator.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {ConfirmedOwner} from "./ConfirmedOwner.sol"; + +/// @title The OwnerIsCreator contract +/// @notice A contract with helpers for basic contract ownership. +contract OwnerIsCreator is ConfirmedOwner { + constructor() ConfirmedOwner(msg.sender) {} +} diff --git a/contracts/src/v0.8/shared/interfaces/IAccessController.sol b/contracts/src/v0.8/shared/interfaces/IAccessController.sol new file mode 100644 index 00000000000..07cb7a154d4 --- /dev/null +++ b/contracts/src/v0.8/shared/interfaces/IAccessController.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IAccessController { + function hasAccess(address user, bytes calldata data) external view returns (bool); +} diff --git a/contracts/src/v0.8/interfaces/ERC677ReceiverInterface.sol b/contracts/src/v0.8/shared/interfaces/IERC677Receiver.sol similarity index 80% rename from contracts/src/v0.8/interfaces/ERC677ReceiverInterface.sol rename to contracts/src/v0.8/shared/interfaces/IERC677Receiver.sol index f6f0d44ee0c..5cb8cfcc082 100644 --- a/contracts/src/v0.8/interfaces/ERC677ReceiverInterface.sol +++ b/contracts/src/v0.8/shared/interfaces/IERC677Receiver.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; -interface ERC677ReceiverInterface { +interface IERC677Receiver { function onTokenTransfer(address sender, uint256 amount, bytes calldata data) external; } diff --git a/contracts/src/v0.8/shared/interfaces/ITypeAndVersion.sol b/contracts/src/v0.8/shared/interfaces/ITypeAndVersion.sol index b2b61eeb587..135f6d0aebf 100644 --- a/contracts/src/v0.8/shared/interfaces/ITypeAndVersion.sol +++ b/contracts/src/v0.8/shared/interfaces/ITypeAndVersion.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -abstract contract ITypeAndVersion { - function typeAndVersion() external pure virtual returns (string memory); +interface ITypeAndVersion { + function typeAndVersion() external pure returns (string memory); } diff --git a/contracts/src/v0.8/shared/interfaces/IWERC20.sol b/contracts/src/v0.8/shared/interfaces/IWERC20.sol new file mode 100644 index 00000000000..e79712a593d --- /dev/null +++ b/contracts/src/v0.8/shared/interfaces/IWERC20.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IWERC20 { + function deposit() external payable; + + function withdraw(uint) external; +} diff --git a/contracts/src/v0.8/interfaces/LinkTokenInterface.sol b/contracts/src/v0.8/shared/interfaces/LinkTokenInterface.sol similarity index 100% rename from contracts/src/v0.8/interfaces/LinkTokenInterface.sol rename to contracts/src/v0.8/shared/interfaces/LinkTokenInterface.sol diff --git a/contracts/src/v0.8/shared/mocks/WERC20Mock.sol b/contracts/src/v0.8/shared/mocks/WERC20Mock.sol new file mode 100644 index 00000000000..11bdb790c02 --- /dev/null +++ b/contracts/src/v0.8/shared/mocks/WERC20Mock.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {ERC20} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/ERC20.sol"; + +contract WERC20Mock is ERC20 { + constructor() ERC20("WERC20Mock", "WERC") {} + + event Deposit(address indexed dst, uint wad); + event Withdrawal(address indexed src, uint wad); + + receive() external payable { + deposit(); + } + + function deposit() public payable { + _mint(msg.sender, msg.value); + emit Deposit(msg.sender, msg.value); + } + + function withdraw(uint wad) public { + require(balanceOf(msg.sender) >= wad); + _burn(msg.sender, wad); + payable(msg.sender).transfer(wad); + emit Withdrawal(msg.sender, wad); + } + + function mint(address account, uint256 amount) external { + _mint(account, amount); + } + + function burn(address account, uint256 amount) external { + _burn(account, amount); + } +} diff --git a/contracts/src/v0.8/OCR2Abstract.sol b/contracts/src/v0.8/shared/ocr2/OCR2Abstract.sol similarity index 97% rename from contracts/src/v0.8/OCR2Abstract.sol rename to contracts/src/v0.8/shared/ocr2/OCR2Abstract.sol index 1a4f13729a3..5031a528b3d 100644 --- a/contracts/src/v0.8/OCR2Abstract.sol +++ b/contracts/src/v0.8/shared/ocr2/OCR2Abstract.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "./interfaces/TypeAndVersionInterface.sol"; +import {ITypeAndVersion} from "../interfaces/ITypeAndVersion.sol"; -abstract contract OCR2Abstract is TypeAndVersionInterface { +abstract contract OCR2Abstract is ITypeAndVersion { // Maximum number of oracles the offchain reporting protocol is designed for uint256 internal constant maxNumOracles = 31; uint256 private constant prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 diff --git a/contracts/src/v0.8/shared/test/BaseTest.t.sol b/contracts/src/v0.8/shared/test/BaseTest.t.sol new file mode 100644 index 00000000000..4d8ef60eb20 --- /dev/null +++ b/contracts/src/v0.8/shared/test/BaseTest.t.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import "forge-std/Test.sol"; + +contract BaseTest is Test { + bool private s_baseTestInitialized; + address internal constant OWNER = 0x72da681452Ab957d1020c25fFaCA47B43980b7C3; + address internal constant STRANGER = 0x02e7d5DD1F4dDbC9f512FfA01d30aa190Ae3edBb; + + // Fri May 26 2023 13:49:53 GMT+0000 + uint256 internal constant BLOCK_TIME = 1685108993; + + function setUp() public virtual { + // BaseTest.setUp is often called multiple times from tests' setUp due to inheritance. + if (s_baseTestInitialized) return; + s_baseTestInitialized = true; + + vm.label(OWNER, "Owner"); + vm.label(STRANGER, "Stranger"); + + // Set the sender to OWNER permanently + vm.startPrank(OWNER); + deal(OWNER, 1e20); + + // Set the block time to a constant known value + vm.warp(BLOCK_TIME); + } +} diff --git a/contracts/src/v0.8/shared/test/token/ERC677/BurnMintERC677.t.sol b/contracts/src/v0.8/shared/test/token/ERC677/BurnMintERC677.t.sol new file mode 100644 index 00000000000..6b223f51236 --- /dev/null +++ b/contracts/src/v0.8/shared/test/token/ERC677/BurnMintERC677.t.sol @@ -0,0 +1,348 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {IBurnMintERC20} from "../../../token/ERC20/IBurnMintERC20.sol"; +import {IERC677} from "../../../token/ERC677/IERC677.sol"; + +import {BaseTest} from "../../BaseTest.t.sol"; +import {BurnMintERC677} from "../../../token/ERC677/BurnMintERC677.sol"; + +import {IERC20} from "../../../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/IERC20.sol"; +import {Strings} from "../../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Strings.sol"; +import {IERC165} from "../../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/introspection/IERC165.sol"; + +contract BurnMintERC677Setup is BaseTest { + event Transfer(address indexed from, address indexed to, uint256 value); + event MintAccessGranted(address indexed minter); + event BurnAccessGranted(address indexed burner); + event MintAccessRevoked(address indexed minter); + event BurnAccessRevoked(address indexed burner); + + BurnMintERC677 internal s_burnMintERC677; + + address internal s_mockPool = address(6243783892); + uint256 internal s_amount = 1e18; + + function setUp() public virtual override { + BaseTest.setUp(); + s_burnMintERC677 = new BurnMintERC677("Chainlink Token", "LINK", 18, 1e27); + + // Set s_mockPool to be a burner and minter + s_burnMintERC677.grantMintAndBurnRoles(s_mockPool); + deal(address(s_burnMintERC677), OWNER, s_amount); + } +} + +contract BurnMintERC677_constructor is BurnMintERC677Setup { + function testConstructorSuccess() public { + string memory name = "Chainlink token v2"; + string memory symbol = "LINK2"; + uint8 decimals = 19; + uint256 maxSupply = 1e33; + s_burnMintERC677 = new BurnMintERC677(name, symbol, decimals, maxSupply); + + assertEq(name, s_burnMintERC677.name()); + assertEq(symbol, s_burnMintERC677.symbol()); + assertEq(decimals, s_burnMintERC677.decimals()); + assertEq(maxSupply, s_burnMintERC677.maxSupply()); + } +} + +contract BurnMintERC677_approve is BurnMintERC677Setup { + function testApproveSuccess() public { + uint256 balancePre = s_burnMintERC677.balanceOf(STRANGER); + uint256 sendingAmount = s_amount / 2; + + s_burnMintERC677.approve(STRANGER, sendingAmount); + + changePrank(STRANGER); + + s_burnMintERC677.transferFrom(OWNER, STRANGER, sendingAmount); + + assertEq(sendingAmount + balancePre, s_burnMintERC677.balanceOf(STRANGER)); + } + + // Reverts + + function testInvalidAddressReverts() public { + vm.expectRevert(); + + s_burnMintERC677.approve(address(s_burnMintERC677), s_amount); + } +} + +contract BurnMintERC677_transfer is BurnMintERC677Setup { + function testTransferSuccess() public { + uint256 balancePre = s_burnMintERC677.balanceOf(STRANGER); + uint256 sendingAmount = s_amount / 2; + + s_burnMintERC677.transfer(STRANGER, sendingAmount); + + assertEq(sendingAmount + balancePre, s_burnMintERC677.balanceOf(STRANGER)); + } + + // Reverts + + function testInvalidAddressReverts() public { + vm.expectRevert(); + + s_burnMintERC677.transfer(address(s_burnMintERC677), s_amount); + } +} + +contract BurnMintERC677_mint is BurnMintERC677Setup { + function testBasicMintSuccess() public { + uint256 balancePre = s_burnMintERC677.balanceOf(OWNER); + + s_burnMintERC677.grantMintAndBurnRoles(OWNER); + + vm.expectEmit(); + emit Transfer(address(0), OWNER, s_amount); + + s_burnMintERC677.mint(OWNER, s_amount); + + assertEq(balancePre + s_amount, s_burnMintERC677.balanceOf(OWNER)); + } + + // Revert + + function testSenderNotMinterReverts() public { + vm.expectRevert(abi.encodeWithSelector(BurnMintERC677.SenderNotMinter.selector, OWNER)); + s_burnMintERC677.mint(STRANGER, 1e18); + } + + function testMaxSupplyExceededReverts() public { + changePrank(s_mockPool); + + // Mint max supply + s_burnMintERC677.mint(OWNER, s_burnMintERC677.maxSupply()); + + vm.expectRevert( + abi.encodeWithSelector(BurnMintERC677.MaxSupplyExceeded.selector, s_burnMintERC677.maxSupply() + 1) + ); + + // Attempt to mint 1 more than max supply + s_burnMintERC677.mint(OWNER, 1); + } +} + +contract BurnMintERC677_burn is BurnMintERC677Setup { + function testBasicBurnSuccess() public { + s_burnMintERC677.grantBurnRole(OWNER); + deal(address(s_burnMintERC677), OWNER, s_amount); + + vm.expectEmit(); + emit Transfer(OWNER, address(0), s_amount); + + s_burnMintERC677.burn(s_amount); + + assertEq(0, s_burnMintERC677.balanceOf(OWNER)); + } + + // Revert + + function testSenderNotBurnerReverts() public { + vm.expectRevert(abi.encodeWithSelector(BurnMintERC677.SenderNotBurner.selector, OWNER)); + + s_burnMintERC677.burnFrom(STRANGER, s_amount); + } + + function testExceedsBalanceReverts() public { + changePrank(s_mockPool); + + vm.expectRevert("ERC20: burn amount exceeds balance"); + + s_burnMintERC677.burn(s_amount * 2); + } + + function testBurnFromZeroAddressReverts() public { + s_burnMintERC677.grantBurnRole(address(0)); + changePrank(address(0)); + + vm.expectRevert("ERC20: burn from the zero address"); + + s_burnMintERC677.burn(0); + } +} + +contract BurnMintERC677_burnFromAlias is BurnMintERC677Setup { + function setUp() public virtual override { + BurnMintERC677Setup.setUp(); + } + + function testBurnFromSuccess() public { + s_burnMintERC677.approve(s_mockPool, s_amount); + + changePrank(s_mockPool); + + s_burnMintERC677.burn(OWNER, s_amount); + + assertEq(0, s_burnMintERC677.balanceOf(OWNER)); + } + + // Reverts + + function testSenderNotBurnerReverts() public { + vm.expectRevert(abi.encodeWithSelector(BurnMintERC677.SenderNotBurner.selector, OWNER)); + + s_burnMintERC677.burn(OWNER, s_amount); + } + + function testInsufficientAllowanceReverts() public { + changePrank(s_mockPool); + + vm.expectRevert("ERC20: insufficient allowance"); + + s_burnMintERC677.burn(OWNER, s_amount); + } + + function testExceedsBalanceReverts() public { + s_burnMintERC677.approve(s_mockPool, s_amount * 2); + + changePrank(s_mockPool); + + vm.expectRevert("ERC20: burn amount exceeds balance"); + + s_burnMintERC677.burn(OWNER, s_amount * 2); + } +} + +contract BurnMintERC677_burnFrom is BurnMintERC677Setup { + function setUp() public virtual override { + BurnMintERC677Setup.setUp(); + } + + function testBurnFromSuccess() public { + s_burnMintERC677.approve(s_mockPool, s_amount); + + changePrank(s_mockPool); + + s_burnMintERC677.burnFrom(OWNER, s_amount); + + assertEq(0, s_burnMintERC677.balanceOf(OWNER)); + } + + // Reverts + + function testSenderNotBurnerReverts() public { + vm.expectRevert(abi.encodeWithSelector(BurnMintERC677.SenderNotBurner.selector, OWNER)); + + s_burnMintERC677.burnFrom(OWNER, s_amount); + } + + function testInsufficientAllowanceReverts() public { + changePrank(s_mockPool); + + vm.expectRevert("ERC20: insufficient allowance"); + + s_burnMintERC677.burnFrom(OWNER, s_amount); + } + + function testExceedsBalanceReverts() public { + s_burnMintERC677.approve(s_mockPool, s_amount * 2); + + changePrank(s_mockPool); + + vm.expectRevert("ERC20: burn amount exceeds balance"); + + s_burnMintERC677.burnFrom(OWNER, s_amount * 2); + } +} + +contract BurnMintERC677_grantRole is BurnMintERC677Setup { + function testGrantMintAccessSuccess() public { + assertFalse(s_burnMintERC677.isMinter(STRANGER)); + + vm.expectEmit(); + emit MintAccessGranted(STRANGER); + + s_burnMintERC677.grantMintAndBurnRoles(STRANGER); + + assertTrue(s_burnMintERC677.isMinter(STRANGER)); + + vm.expectEmit(); + emit MintAccessRevoked(STRANGER); + + s_burnMintERC677.revokeMintRole(STRANGER); + + assertFalse(s_burnMintERC677.isMinter(STRANGER)); + } + + function testGrantBurnAccessSuccess() public { + assertFalse(s_burnMintERC677.isBurner(STRANGER)); + + vm.expectEmit(); + emit BurnAccessGranted(STRANGER); + + s_burnMintERC677.grantBurnRole(STRANGER); + + assertTrue(s_burnMintERC677.isBurner(STRANGER)); + + vm.expectEmit(); + emit BurnAccessRevoked(STRANGER); + + s_burnMintERC677.revokeBurnRole(STRANGER); + + assertFalse(s_burnMintERC677.isBurner(STRANGER)); + } + + function testGrantManySuccess() public { + uint256 numberOfPools = 10; + address[] memory permissionedAddresses = new address[](numberOfPools + 1); + permissionedAddresses[0] = s_mockPool; + + for (uint160 i = 0; i < numberOfPools; ++i) { + permissionedAddresses[i + 1] = address(i); + s_burnMintERC677.grantMintAndBurnRoles(address(i)); + } + + assertEq(permissionedAddresses, s_burnMintERC677.getBurners()); + assertEq(permissionedAddresses, s_burnMintERC677.getMinters()); + } +} + +contract BurnMintERC677_grantMintAndBurnRoles is BurnMintERC677Setup { + function testGrantMintAndBurnRolesSuccess() public { + assertFalse(s_burnMintERC677.isMinter(STRANGER)); + assertFalse(s_burnMintERC677.isBurner(STRANGER)); + + vm.expectEmit(); + emit MintAccessGranted(STRANGER); + vm.expectEmit(); + emit BurnAccessGranted(STRANGER); + + s_burnMintERC677.grantMintAndBurnRoles(STRANGER); + + assertTrue(s_burnMintERC677.isMinter(STRANGER)); + assertTrue(s_burnMintERC677.isBurner(STRANGER)); + } +} + +contract BurnMintERC677_decreaseApproval is BurnMintERC677Setup { + function testDecreaseApprovalSuccess() public { + s_burnMintERC677.approve(s_mockPool, s_amount); + uint256 allowance = s_burnMintERC677.allowance(OWNER, s_mockPool); + assertEq(allowance, s_amount); + s_burnMintERC677.decreaseApproval(s_mockPool, s_amount); + assertEq(s_burnMintERC677.allowance(OWNER, s_mockPool), allowance - s_amount); + } +} + +contract BurnMintERC677_increaseApproval is BurnMintERC677Setup { + function testIncreaseApprovalSuccess() public { + s_burnMintERC677.approve(s_mockPool, s_amount); + uint256 allowance = s_burnMintERC677.allowance(OWNER, s_mockPool); + assertEq(allowance, s_amount); + s_burnMintERC677.increaseApproval(s_mockPool, s_amount); + assertEq(s_burnMintERC677.allowance(OWNER, s_mockPool), allowance + s_amount); + } +} + +contract BurnMintERC677_supportsInterface is BurnMintERC677Setup { + function testConstructorSuccess() public { + assertTrue(s_burnMintERC677.supportsInterface(type(IERC20).interfaceId)); + assertTrue(s_burnMintERC677.supportsInterface(type(IERC677).interfaceId)); + assertTrue(s_burnMintERC677.supportsInterface(type(IBurnMintERC20).interfaceId)); + assertTrue(s_burnMintERC677.supportsInterface(type(IERC165).interfaceId)); + } +} diff --git a/contracts/src/v0.8/shared/test/token/ERC677/OpStackBurnMintERC677.t.sol b/contracts/src/v0.8/shared/test/token/ERC677/OpStackBurnMintERC677.t.sol new file mode 100644 index 00000000000..f22a92a4258 --- /dev/null +++ b/contracts/src/v0.8/shared/test/token/ERC677/OpStackBurnMintERC677.t.sol @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IBurnMintERC20} from "../../../token/ERC20/IBurnMintERC20.sol"; +import {IOptimismMintableERC20Minimal, IOptimismMintableERC20} from "../../../token/ERC20/IOptimismMintableERC20.sol"; +import {IERC677} from "../../../token/ERC677/IERC677.sol"; + +import {BurnMintERC677} from "../../../token/ERC677/BurnMintERC677.sol"; +import {BaseTest} from "../../BaseTest.t.sol"; +import {OpStackBurnMintERC677} from "../../../token/ERC677/OpStackBurnMintERC677.sol"; + +import {IERC165} from "../../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/introspection/IERC165.sol"; + +contract OpStackBurnMintERC677Setup is BaseTest { + address internal s_l1Token = address(897352983527); + address internal s_l2Bridge = address(1928235235); + + OpStackBurnMintERC677 internal s_opStackBurnMintERC677; + + function setUp() public virtual override { + BaseTest.setUp(); + s_opStackBurnMintERC677 = new OpStackBurnMintERC677("Chainlink Token", "LINK", 18, 1e27, s_l1Token, s_l2Bridge); + } +} + +contract OpStackBurnMintERC677_constructor is OpStackBurnMintERC677Setup { + function testConstructorSuccess() public { + string memory name = "Chainlink token l2"; + string memory symbol = "LINK L2"; + uint8 decimals = 18; + uint256 maxSupply = 1e33; + s_opStackBurnMintERC677 = new OpStackBurnMintERC677(name, symbol, decimals, maxSupply, s_l1Token, s_l2Bridge); + + assertEq(name, s_opStackBurnMintERC677.name()); + assertEq(symbol, s_opStackBurnMintERC677.symbol()); + assertEq(decimals, s_opStackBurnMintERC677.decimals()); + assertEq(maxSupply, s_opStackBurnMintERC677.maxSupply()); + assertEq(s_l1Token, s_opStackBurnMintERC677.remoteToken()); + assertEq(s_l2Bridge, s_opStackBurnMintERC677.bridge()); + } +} + +contract OpStackBurnMintERC677_supportsInterface is OpStackBurnMintERC677Setup { + function testConstructorSuccess() public { + assertTrue(s_opStackBurnMintERC677.supportsInterface(type(IOptimismMintableERC20Minimal).interfaceId)); + assertTrue(s_opStackBurnMintERC677.supportsInterface(type(IERC677).interfaceId)); + assertTrue(s_opStackBurnMintERC677.supportsInterface(type(IBurnMintERC20).interfaceId)); + assertTrue(s_opStackBurnMintERC677.supportsInterface(type(IERC165).interfaceId)); + } +} + +contract OpStackBurnMintERC677_interfaceCompatibility is OpStackBurnMintERC677Setup { + event Transfer(address indexed from, address indexed to, uint256 value); + + IOptimismMintableERC20 internal s_opStackToken; + + function setUp() public virtual override { + OpStackBurnMintERC677Setup.setUp(); + s_opStackToken = IOptimismMintableERC20(address(s_opStackBurnMintERC677)); + } + + function testStaticFunctionsCompatibility() public { + assertEq(s_l1Token, s_opStackToken.remoteToken()); + assertEq(s_l2Bridge, s_opStackToken.bridge()); + } + + function testMintCompatibility() public { + // Ensure roles work + vm.expectRevert(abi.encodeWithSelector(BurnMintERC677.SenderNotMinter.selector, OWNER)); + s_opStackToken.mint(OWNER, 1); + + // Use the actual contract to grant mint + s_opStackBurnMintERC677.grantMintRole(OWNER); + + // Ensure zero address check works + vm.expectRevert("ERC20: mint to the zero address"); + s_opStackToken.mint(address(0x0), 0); + + address mintToAddress = address(0x1); + uint256 mintAmount = 1; + + vm.expectEmit(); + emit Transfer(address(0), mintToAddress, mintAmount); + + s_opStackToken.mint(mintToAddress, mintAmount); + } + + function testBurnCompatibility() public { + // Ensure roles work + vm.expectRevert(abi.encodeWithSelector(BurnMintERC677.SenderNotBurner.selector, OWNER)); + s_opStackToken.burn(address(0x0), 1); + + // Use the actual contract to grant burn + s_opStackBurnMintERC677.grantBurnRole(OWNER); + + // Ensure zero address check works + vm.expectRevert("ERC20: approve from the zero address"); + s_opStackToken.burn(address(0x0), 0); + + address burnFromAddress = address(0x1); + uint256 burnAmount = 1; + + // Ensure `burn(address, amount)` works like burnFrom and requires allowance + vm.expectRevert("ERC20: insufficient allowance"); + s_opStackToken.burn(burnFromAddress, burnAmount); + + changePrank(burnFromAddress); + deal(address(s_opStackToken), burnFromAddress, burnAmount); + s_opStackBurnMintERC677.approve(OWNER, burnAmount); + changePrank(OWNER); + + vm.expectEmit(); + emit Transfer(burnFromAddress, address(0x0), burnAmount); + + s_opStackToken.burn(burnFromAddress, burnAmount); + } +} diff --git a/contracts/src/v0.8/shared/token/ERC20/IBurnMintERC20.sol b/contracts/src/v0.8/shared/token/ERC20/IBurnMintERC20.sol new file mode 100644 index 00000000000..2b2f3fd3787 --- /dev/null +++ b/contracts/src/v0.8/shared/token/ERC20/IBurnMintERC20.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/IERC20.sol"; + +interface IBurnMintERC20 is IERC20 { + /// @notice Mints new tokens for a given address. + /// @param account The address to mint the new tokens to. + /// @param amount The number of tokens to be minted. + /// @dev this function increases the total supply. + function mint(address account, uint256 amount) external; + + /// @notice Burns tokens from the sender. + /// @param amount The number of tokens to be burned. + /// @dev this function decreases the total supply. + function burn(uint256 amount) external; + + /// @notice Burns tokens from a given address.. + /// @param account The address to burn tokens from. + /// @param amount The number of tokens to be burned. + /// @dev this function decreases the total supply. + function burn(address account, uint256 amount) external; + + /// @notice Burns tokens from a given address.. + /// @param account The address to burn tokens from. + /// @param amount The number of tokens to be burned. + /// @dev this function decreases the total supply. + function burnFrom(address account, uint256 amount) external; +} diff --git a/contracts/src/v0.8/shared/token/ERC20/IOptimismMintableERC20.sol b/contracts/src/v0.8/shared/token/ERC20/IOptimismMintableERC20.sol new file mode 100644 index 00000000000..79441cf89f7 --- /dev/null +++ b/contracts/src/v0.8/shared/token/ERC20/IOptimismMintableERC20.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/introspection/IERC165.sol"; + +/// @title IOptimismMintableERC20Minimal +/// @dev This interface is a subset of the Optimism ERC20 interface that is defined +/// below. This is done to now have to overwrite the burn and mint functions again in +/// the implementation, as that leads to more complicated, error prone code. +interface IOptimismMintableERC20Minimal is IERC165 { + /// @notice Returns the address of the token on L1. + function remoteToken() external view returns (address); + + /// @notice Returns the address of the bridge on L2. + function bridge() external returns (address); +} + +/// @title IOptimismMintableERC20 +/// @notice This is the complete interface for the Optimism mintable ERC20 token as defined in +/// https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/contracts/universal/IOptimismMintableERC20.sol +interface IOptimismMintableERC20 is IERC165, IOptimismMintableERC20Minimal { + function mint(address _to, uint256 _amount) external; + + function burn(address _from, uint256 _amount) external; +} diff --git a/contracts/src/v0.8/shared/token/ERC677/BurnMintERC677.sol b/contracts/src/v0.8/shared/token/ERC677/BurnMintERC677.sol new file mode 100644 index 00000000000..0d78581b13c --- /dev/null +++ b/contracts/src/v0.8/shared/token/ERC677/BurnMintERC677.sol @@ -0,0 +1,216 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IBurnMintERC20} from "../ERC20/IBurnMintERC20.sol"; +import {IERC677} from "./IERC677.sol"; + +import {ERC677} from "./ERC677.sol"; +import {OwnerIsCreator} from "../../access/OwnerIsCreator.sol"; + +import {ERC20Burnable} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/ERC20Burnable.sol"; +import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/structs/EnumerableSet.sol"; +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/introspection/IERC165.sol"; +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/IERC20.sol"; + +/// @notice A basic ERC677 compatible token contract with burn and minting roles. +/// @dev The total supply can be limited during deployment. +contract BurnMintERC677 is IBurnMintERC20, ERC677, IERC165, ERC20Burnable, OwnerIsCreator { + using EnumerableSet for EnumerableSet.AddressSet; + + error SenderNotMinter(address sender); + error SenderNotBurner(address sender); + error MaxSupplyExceeded(uint256 supplyAfterMint); + + event MintAccessGranted(address indexed minter); + event BurnAccessGranted(address indexed burner); + event MintAccessRevoked(address indexed minter); + event BurnAccessRevoked(address indexed burner); + + // @dev the allowed minter addresses + EnumerableSet.AddressSet internal s_minters; + // @dev the allowed burner addresses + EnumerableSet.AddressSet internal s_burners; + + /// @dev The number of decimals for the token + uint8 internal immutable i_decimals; + + /// @dev The maximum supply of the token, 0 if unlimited + uint256 internal immutable i_maxSupply; + + constructor(string memory name, string memory symbol, uint8 decimals_, uint256 maxSupply_) ERC677(name, symbol) { + i_decimals = decimals_; + i_maxSupply = maxSupply_; + } + + function supportsInterface(bytes4 interfaceId) public pure virtual override returns (bool) { + return + interfaceId == type(IERC20).interfaceId || + interfaceId == type(IERC677).interfaceId || + interfaceId == type(IBurnMintERC20).interfaceId || + interfaceId == type(IERC165).interfaceId; + } + + // ================================================================ + // | ERC20 | + // ================================================================ + + /// @dev Returns the number of decimals used in its user representation. + function decimals() public view virtual override returns (uint8) { + return i_decimals; + } + + /// @dev Returns the max supply of the token, 0 if unlimited. + function maxSupply() public view virtual returns (uint256) { + return i_maxSupply; + } + + /// @dev Uses OZ ERC20 _transfer to disallow sending to address(0). + /// @dev Disallows sending to address(this) + function _transfer(address from, address to, uint256 amount) internal virtual override validAddress(to) { + super._transfer(from, to, amount); + } + + /// @dev Uses OZ ERC20 _approve to disallow approving for address(0). + /// @dev Disallows approving for address(this) + function _approve(address owner, address spender, uint256 amount) internal virtual override validAddress(spender) { + super._approve(owner, spender, amount); + } + + /// @dev Exists to be backwards compatible with the older naming convention. + function decreaseApproval(address spender, uint256 subtractedValue) external returns (bool success) { + return decreaseAllowance(spender, subtractedValue); + } + + /// @dev Exists to be backwards compatible with the older naming convention. + function increaseApproval(address spender, uint256 addedValue) external { + increaseAllowance(spender, addedValue); + } + + /// @notice Check if recipient is valid (not this contract address). + /// @param recipient the account we transfer/approve to. + /// @dev Reverts with an empty revert to be compatible with the existing link token when + /// the recipient is this contract address. + modifier validAddress(address recipient) virtual { + if (recipient == address(this)) revert(); + _; + } + + // ================================================================ + // | Burning & minting | + // ================================================================ + + /// @inheritdoc ERC20Burnable + /// @dev Uses OZ ERC20 _burn to disallow burning from address(0). + /// @dev Decreases the total supply. + function burn(uint256 amount) public override(IBurnMintERC20, ERC20Burnable) onlyBurner { + super.burn(amount); + } + + /// @inheritdoc IBurnMintERC20 + /// @dev Alias for BurnFrom for compatibility with the older naming convention. + /// @dev Uses burnFrom for all validation & logic. + function burn(address account, uint256 amount) public virtual override { + burnFrom(account, amount); + } + + /// @inheritdoc ERC20Burnable + /// @dev Uses OZ ERC20 _burn to disallow burning from address(0). + /// @dev Decreases the total supply. + function burnFrom(address account, uint256 amount) public override(IBurnMintERC20, ERC20Burnable) onlyBurner { + super.burnFrom(account, amount); + } + + /// @inheritdoc IBurnMintERC20 + /// @dev Uses OZ ERC20 _mint to disallow minting to address(0). + /// @dev Disallows minting to address(this) + /// @dev Increases the total supply. + function mint(address account, uint256 amount) external override onlyMinter validAddress(account) { + if (i_maxSupply != 0 && totalSupply() + amount > i_maxSupply) revert MaxSupplyExceeded(totalSupply() + amount); + + _mint(account, amount); + } + + // ================================================================ + // | Roles | + // ================================================================ + + /// @notice grants both mint and burn roles to `burnAndMinter`. + /// @dev calls public functions so this function does not require + /// access controls. This is handled in the inner functions. + function grantMintAndBurnRoles(address burnAndMinter) external { + grantMintRole(burnAndMinter); + grantBurnRole(burnAndMinter); + } + + /// @notice Grants mint role to the given address. + /// @dev only the owner can call this function. + function grantMintRole(address minter) public onlyOwner { + if (s_minters.add(minter)) { + emit MintAccessGranted(minter); + } + } + + /// @notice Grants burn role to the given address. + /// @dev only the owner can call this function. + function grantBurnRole(address burner) public onlyOwner { + if (s_burners.add(burner)) { + emit BurnAccessGranted(burner); + } + } + + /// @notice Revokes mint role for the given address. + /// @dev only the owner can call this function. + function revokeMintRole(address minter) public onlyOwner { + if (s_minters.remove(minter)) { + emit MintAccessRevoked(minter); + } + } + + /// @notice Revokes burn role from the given address. + /// @dev only the owner can call this function + function revokeBurnRole(address burner) public onlyOwner { + if (s_burners.remove(burner)) { + emit BurnAccessRevoked(burner); + } + } + + /// @notice Returns all permissioned minters + function getMinters() public view returns (address[] memory) { + return s_minters.values(); + } + + /// @notice Returns all permissioned burners + function getBurners() public view returns (address[] memory) { + return s_burners.values(); + } + + // ================================================================ + // | Access | + // ================================================================ + + /// @notice Checks whether a given address is a minter for this token. + /// @return true if the address is allowed to mint. + function isMinter(address minter) public view returns (bool) { + return s_minters.contains(minter); + } + + /// @notice Checks whether a given address is a burner for this token. + /// @return true if the address is allowed to burn. + function isBurner(address burner) public view returns (bool) { + return s_burners.contains(burner); + } + + /// @notice Checks whether the msg.sender is a permissioned minter for this token + /// @dev Reverts with a SenderNotMinter if the check fails + modifier onlyMinter() { + if (!isMinter(msg.sender)) revert SenderNotMinter(msg.sender); + _; + } + + /// @notice Checks whether the msg.sender is a permissioned burner for this token + /// @dev Reverts with a SenderNotBurner if the check fails + modifier onlyBurner() { + if (!isBurner(msg.sender)) revert SenderNotBurner(msg.sender); + _; + } +} diff --git a/contracts/src/v0.8/shared/token/ERC677/ERC677.sol b/contracts/src/v0.8/shared/token/ERC677/ERC677.sol new file mode 100644 index 00000000000..de124d53c55 --- /dev/null +++ b/contracts/src/v0.8/shared/token/ERC677/ERC677.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.0; + +import {IERC677} from "./IERC677.sol"; +import {IERC677Receiver} from "./IERC677Receiver.sol"; + +import {Address} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Address.sol"; +import {ERC20} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/ERC20.sol"; + +contract ERC677 is IERC677, ERC20 { + using Address for address; + + constructor(string memory name, string memory symbol) ERC20(name, symbol) {} + + /// @inheritdoc IERC677 + function transferAndCall(address to, uint amount, bytes memory data) public returns (bool success) { + super.transfer(to, amount); + emit Transfer(msg.sender, to, amount, data); + if (to.isContract()) { + IERC677Receiver(to).onTokenTransfer(msg.sender, amount, data); + } + return true; + } +} diff --git a/contracts/src/v0.8/shared/token/ERC677/IERC677.sol b/contracts/src/v0.8/shared/token/ERC677/IERC677.sol new file mode 100644 index 00000000000..7e303a42efb --- /dev/null +++ b/contracts/src/v0.8/shared/token/ERC677/IERC677.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IERC677 { + event Transfer(address indexed from, address indexed to, uint256 value, bytes data); + + /// @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver + /// @param to The address which you want to transfer to + /// @param amount The amount of tokens to be transferred + /// @param data bytes Additional data with no specified format, sent in call to `to` + /// @return true unless throwing + function transferAndCall(address to, uint256 amount, bytes memory data) external returns (bool); +} diff --git a/contracts/src/v0.8/shared/token/ERC677/IERC677Receiver.sol b/contracts/src/v0.8/shared/token/ERC677/IERC677Receiver.sol new file mode 100644 index 00000000000..2e44d860a82 --- /dev/null +++ b/contracts/src/v0.8/shared/token/ERC677/IERC677Receiver.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IERC677Receiver { + function onTokenTransfer(address sender, uint256 amount, bytes calldata data) external; +} diff --git a/contracts/src/v0.8/shared/token/ERC677/LinkToken.sol b/contracts/src/v0.8/shared/token/ERC677/LinkToken.sol new file mode 100644 index 00000000000..b4640a8e311 --- /dev/null +++ b/contracts/src/v0.8/shared/token/ERC677/LinkToken.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {BurnMintERC677} from "./BurnMintERC677.sol"; + +contract LinkToken is BurnMintERC677 { + constructor() BurnMintERC677("ChainLink Token", "LINK", 18, 1e27) {} +} diff --git a/contracts/src/v0.8/shared/token/ERC677/OpStackBurnMintERC677.sol b/contracts/src/v0.8/shared/token/ERC677/OpStackBurnMintERC677.sol new file mode 100644 index 00000000000..714a4a11baf --- /dev/null +++ b/contracts/src/v0.8/shared/token/ERC677/OpStackBurnMintERC677.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IOptimismMintableERC20Minimal, IOptimismMintableERC20} from "../ERC20/IOptimismMintableERC20.sol"; + +import {BurnMintERC677} from "./BurnMintERC677.sol"; + +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/introspection/IERC165.sol"; + +/// @notice A basic ERC677 compatible token contract with burn and minting roles that supports +/// the native L2 bridging requirements of the Optimism Stack. +/// @dev Note: the L2 bridge contract needs to be given burn and mint privileges manually, +/// since this contract does not automatically grant them. This allows the owner to revoke +/// the bridge's privileges if necessary. +contract OpStackBurnMintERC677 is BurnMintERC677, IOptimismMintableERC20Minimal { + /// @dev The address of the L1 token. + address internal immutable i_l1Token; + /// @dev The address of the L2 bridge. + address internal immutable i_l2Bridge; + + constructor( + string memory name, + string memory symbol, + uint8 decimals_, + uint256 maxSupply_, + address l1Token, + address l2Bridge + ) BurnMintERC677(name, symbol, decimals_, maxSupply_) { + i_l1Token = l1Token; + i_l2Bridge = l2Bridge; + } + + function supportsInterface(bytes4 interfaceId) public pure virtual override(IERC165, BurnMintERC677) returns (bool) { + return + interfaceId == type(IOptimismMintableERC20).interfaceId || + interfaceId == type(IOptimismMintableERC20Minimal).interfaceId || + super.supportsInterface(interfaceId); + } + + /// @notice Returns the address of the L1 token. + function remoteToken() public view override returns (address) { + return i_l1Token; + } + + /// @notice Returns the address of the L2 bridge. + function bridge() public view override returns (address) { + return i_l2Bridge; + } +} diff --git a/contracts/src/v0.8/shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/utils/SafeCast.sol b/contracts/src/v0.8/shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/utils/SafeCast.sol deleted file mode 100644 index e49292d0661..00000000000 --- a/contracts/src/v0.8/shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/utils/SafeCast.sol +++ /dev/null @@ -1,1136 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol) -// This file was procedurally generated from scripts/generate/templates/SafeCast.js. - -pragma solidity ^0.8.0; - -/** - * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow - * checks. - * - * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can - * easily result in undesired exploitation or bugs, since developers usually - * assume that overflows raise errors. `SafeCast` restores this intuition by - * reverting the transaction when such an operation overflows. - * - * Using this library instead of the unchecked operations eliminates an entire - * class of bugs, so it's recommended to use it always. - * - * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing - * all math on `uint256` and `int256` and then downcasting. - */ -library SafeCast { - /** - * @dev Returns the downcasted uint248 from uint256, reverting on - * overflow (when the input is greater than largest uint248). - * - * Counterpart to Solidity's `uint248` operator. - * - * Requirements: - * - * - input must fit into 248 bits - * - * _Available since v4.7._ - */ - function toUint248(uint256 value) internal pure returns (uint248) { - require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits"); - return uint248(value); - } - - /** - * @dev Returns the downcasted uint240 from uint256, reverting on - * overflow (when the input is greater than largest uint240). - * - * Counterpart to Solidity's `uint240` operator. - * - * Requirements: - * - * - input must fit into 240 bits - * - * _Available since v4.7._ - */ - function toUint240(uint256 value) internal pure returns (uint240) { - require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits"); - return uint240(value); - } - - /** - * @dev Returns the downcasted uint232 from uint256, reverting on - * overflow (when the input is greater than largest uint232). - * - * Counterpart to Solidity's `uint232` operator. - * - * Requirements: - * - * - input must fit into 232 bits - * - * _Available since v4.7._ - */ - function toUint232(uint256 value) internal pure returns (uint232) { - require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits"); - return uint232(value); - } - - /** - * @dev Returns the downcasted uint224 from uint256, reverting on - * overflow (when the input is greater than largest uint224). - * - * Counterpart to Solidity's `uint224` operator. - * - * Requirements: - * - * - input must fit into 224 bits - * - * _Available since v4.2._ - */ - function toUint224(uint256 value) internal pure returns (uint224) { - require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); - return uint224(value); - } - - /** - * @dev Returns the downcasted uint216 from uint256, reverting on - * overflow (when the input is greater than largest uint216). - * - * Counterpart to Solidity's `uint216` operator. - * - * Requirements: - * - * - input must fit into 216 bits - * - * _Available since v4.7._ - */ - function toUint216(uint256 value) internal pure returns (uint216) { - require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits"); - return uint216(value); - } - - /** - * @dev Returns the downcasted uint208 from uint256, reverting on - * overflow (when the input is greater than largest uint208). - * - * Counterpart to Solidity's `uint208` operator. - * - * Requirements: - * - * - input must fit into 208 bits - * - * _Available since v4.7._ - */ - function toUint208(uint256 value) internal pure returns (uint208) { - require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); - return uint208(value); - } - - /** - * @dev Returns the downcasted uint200 from uint256, reverting on - * overflow (when the input is greater than largest uint200). - * - * Counterpart to Solidity's `uint200` operator. - * - * Requirements: - * - * - input must fit into 200 bits - * - * _Available since v4.7._ - */ - function toUint200(uint256 value) internal pure returns (uint200) { - require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits"); - return uint200(value); - } - - /** - * @dev Returns the downcasted uint192 from uint256, reverting on - * overflow (when the input is greater than largest uint192). - * - * Counterpart to Solidity's `uint192` operator. - * - * Requirements: - * - * - input must fit into 192 bits - * - * _Available since v4.7._ - */ - function toUint192(uint256 value) internal pure returns (uint192) { - require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits"); - return uint192(value); - } - - /** - * @dev Returns the downcasted uint184 from uint256, reverting on - * overflow (when the input is greater than largest uint184). - * - * Counterpart to Solidity's `uint184` operator. - * - * Requirements: - * - * - input must fit into 184 bits - * - * _Available since v4.7._ - */ - function toUint184(uint256 value) internal pure returns (uint184) { - require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits"); - return uint184(value); - } - - /** - * @dev Returns the downcasted uint176 from uint256, reverting on - * overflow (when the input is greater than largest uint176). - * - * Counterpart to Solidity's `uint176` operator. - * - * Requirements: - * - * - input must fit into 176 bits - * - * _Available since v4.7._ - */ - function toUint176(uint256 value) internal pure returns (uint176) { - require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits"); - return uint176(value); - } - - /** - * @dev Returns the downcasted uint168 from uint256, reverting on - * overflow (when the input is greater than largest uint168). - * - * Counterpart to Solidity's `uint168` operator. - * - * Requirements: - * - * - input must fit into 168 bits - * - * _Available since v4.7._ - */ - function toUint168(uint256 value) internal pure returns (uint168) { - require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits"); - return uint168(value); - } - - /** - * @dev Returns the downcasted uint160 from uint256, reverting on - * overflow (when the input is greater than largest uint160). - * - * Counterpart to Solidity's `uint160` operator. - * - * Requirements: - * - * - input must fit into 160 bits - * - * _Available since v4.7._ - */ - function toUint160(uint256 value) internal pure returns (uint160) { - require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits"); - return uint160(value); - } - - /** - * @dev Returns the downcasted uint152 from uint256, reverting on - * overflow (when the input is greater than largest uint152). - * - * Counterpart to Solidity's `uint152` operator. - * - * Requirements: - * - * - input must fit into 152 bits - * - * _Available since v4.7._ - */ - function toUint152(uint256 value) internal pure returns (uint152) { - require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits"); - return uint152(value); - } - - /** - * @dev Returns the downcasted uint144 from uint256, reverting on - * overflow (when the input is greater than largest uint144). - * - * Counterpart to Solidity's `uint144` operator. - * - * Requirements: - * - * - input must fit into 144 bits - * - * _Available since v4.7._ - */ - function toUint144(uint256 value) internal pure returns (uint144) { - require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits"); - return uint144(value); - } - - /** - * @dev Returns the downcasted uint136 from uint256, reverting on - * overflow (when the input is greater than largest uint136). - * - * Counterpart to Solidity's `uint136` operator. - * - * Requirements: - * - * - input must fit into 136 bits - * - * _Available since v4.7._ - */ - function toUint136(uint256 value) internal pure returns (uint136) { - require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits"); - return uint136(value); - } - - /** - * @dev Returns the downcasted uint128 from uint256, reverting on - * overflow (when the input is greater than largest uint128). - * - * Counterpart to Solidity's `uint128` operator. - * - * Requirements: - * - * - input must fit into 128 bits - * - * _Available since v2.5._ - */ - function toUint128(uint256 value) internal pure returns (uint128) { - require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); - return uint128(value); - } - - /** - * @dev Returns the downcasted uint120 from uint256, reverting on - * overflow (when the input is greater than largest uint120). - * - * Counterpart to Solidity's `uint120` operator. - * - * Requirements: - * - * - input must fit into 120 bits - * - * _Available since v4.7._ - */ - function toUint120(uint256 value) internal pure returns (uint120) { - require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits"); - return uint120(value); - } - - /** - * @dev Returns the downcasted uint112 from uint256, reverting on - * overflow (when the input is greater than largest uint112). - * - * Counterpart to Solidity's `uint112` operator. - * - * Requirements: - * - * - input must fit into 112 bits - * - * _Available since v4.7._ - */ - function toUint112(uint256 value) internal pure returns (uint112) { - require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); - return uint112(value); - } - - /** - * @dev Returns the downcasted uint104 from uint256, reverting on - * overflow (when the input is greater than largest uint104). - * - * Counterpart to Solidity's `uint104` operator. - * - * Requirements: - * - * - input must fit into 104 bits - * - * _Available since v4.7._ - */ - function toUint104(uint256 value) internal pure returns (uint104) { - require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); - return uint104(value); - } - - /** - * @dev Returns the downcasted uint96 from uint256, reverting on - * overflow (when the input is greater than largest uint96). - * - * Counterpart to Solidity's `uint96` operator. - * - * Requirements: - * - * - input must fit into 96 bits - * - * _Available since v4.2._ - */ - function toUint96(uint256 value) internal pure returns (uint96) { - require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); - return uint96(value); - } - - /** - * @dev Returns the downcasted uint88 from uint256, reverting on - * overflow (when the input is greater than largest uint88). - * - * Counterpart to Solidity's `uint88` operator. - * - * Requirements: - * - * - input must fit into 88 bits - * - * _Available since v4.7._ - */ - function toUint88(uint256 value) internal pure returns (uint88) { - require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); - return uint88(value); - } - - /** - * @dev Returns the downcasted uint80 from uint256, reverting on - * overflow (when the input is greater than largest uint80). - * - * Counterpart to Solidity's `uint80` operator. - * - * Requirements: - * - * - input must fit into 80 bits - * - * _Available since v4.7._ - */ - function toUint80(uint256 value) internal pure returns (uint80) { - require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits"); - return uint80(value); - } - - /** - * @dev Returns the downcasted uint72 from uint256, reverting on - * overflow (when the input is greater than largest uint72). - * - * Counterpart to Solidity's `uint72` operator. - * - * Requirements: - * - * - input must fit into 72 bits - * - * _Available since v4.7._ - */ - function toUint72(uint256 value) internal pure returns (uint72) { - require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits"); - return uint72(value); - } - - /** - * @dev Returns the downcasted uint64 from uint256, reverting on - * overflow (when the input is greater than largest uint64). - * - * Counterpart to Solidity's `uint64` operator. - * - * Requirements: - * - * - input must fit into 64 bits - * - * _Available since v2.5._ - */ - function toUint64(uint256 value) internal pure returns (uint64) { - require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); - return uint64(value); - } - - /** - * @dev Returns the downcasted uint56 from uint256, reverting on - * overflow (when the input is greater than largest uint56). - * - * Counterpart to Solidity's `uint56` operator. - * - * Requirements: - * - * - input must fit into 56 bits - * - * _Available since v4.7._ - */ - function toUint56(uint256 value) internal pure returns (uint56) { - require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits"); - return uint56(value); - } - - /** - * @dev Returns the downcasted uint48 from uint256, reverting on - * overflow (when the input is greater than largest uint48). - * - * Counterpart to Solidity's `uint48` operator. - * - * Requirements: - * - * - input must fit into 48 bits - * - * _Available since v4.7._ - */ - function toUint48(uint256 value) internal pure returns (uint48) { - require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits"); - return uint48(value); - } - - /** - * @dev Returns the downcasted uint40 from uint256, reverting on - * overflow (when the input is greater than largest uint40). - * - * Counterpart to Solidity's `uint40` operator. - * - * Requirements: - * - * - input must fit into 40 bits - * - * _Available since v4.7._ - */ - function toUint40(uint256 value) internal pure returns (uint40) { - require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits"); - return uint40(value); - } - - /** - * @dev Returns the downcasted uint32 from uint256, reverting on - * overflow (when the input is greater than largest uint32). - * - * Counterpart to Solidity's `uint32` operator. - * - * Requirements: - * - * - input must fit into 32 bits - * - * _Available since v2.5._ - */ - function toUint32(uint256 value) internal pure returns (uint32) { - require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); - return uint32(value); - } - - /** - * @dev Returns the downcasted uint24 from uint256, reverting on - * overflow (when the input is greater than largest uint24). - * - * Counterpart to Solidity's `uint24` operator. - * - * Requirements: - * - * - input must fit into 24 bits - * - * _Available since v4.7._ - */ - function toUint24(uint256 value) internal pure returns (uint24) { - require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits"); - return uint24(value); - } - - /** - * @dev Returns the downcasted uint16 from uint256, reverting on - * overflow (when the input is greater than largest uint16). - * - * Counterpart to Solidity's `uint16` operator. - * - * Requirements: - * - * - input must fit into 16 bits - * - * _Available since v2.5._ - */ - function toUint16(uint256 value) internal pure returns (uint16) { - require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); - return uint16(value); - } - - /** - * @dev Returns the downcasted uint8 from uint256, reverting on - * overflow (when the input is greater than largest uint8). - * - * Counterpart to Solidity's `uint8` operator. - * - * Requirements: - * - * - input must fit into 8 bits - * - * _Available since v2.5._ - */ - function toUint8(uint256 value) internal pure returns (uint8) { - require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); - return uint8(value); - } - - /** - * @dev Converts a signed int256 into an unsigned uint256. - * - * Requirements: - * - * - input must be greater than or equal to 0. - * - * _Available since v3.0._ - */ - function toUint256(int256 value) internal pure returns (uint256) { - require(value >= 0, "SafeCast: value must be positive"); - return uint256(value); - } - - /** - * @dev Returns the downcasted int248 from int256, reverting on - * overflow (when the input is less than smallest int248 or - * greater than largest int248). - * - * Counterpart to Solidity's `int248` operator. - * - * Requirements: - * - * - input must fit into 248 bits - * - * _Available since v4.7._ - */ - function toInt248(int256 value) internal pure returns (int248 downcasted) { - downcasted = int248(value); - require(downcasted == value, "SafeCast: value doesn't fit in 248 bits"); - } - - /** - * @dev Returns the downcasted int240 from int256, reverting on - * overflow (when the input is less than smallest int240 or - * greater than largest int240). - * - * Counterpart to Solidity's `int240` operator. - * - * Requirements: - * - * - input must fit into 240 bits - * - * _Available since v4.7._ - */ - function toInt240(int256 value) internal pure returns (int240 downcasted) { - downcasted = int240(value); - require(downcasted == value, "SafeCast: value doesn't fit in 240 bits"); - } - - /** - * @dev Returns the downcasted int232 from int256, reverting on - * overflow (when the input is less than smallest int232 or - * greater than largest int232). - * - * Counterpart to Solidity's `int232` operator. - * - * Requirements: - * - * - input must fit into 232 bits - * - * _Available since v4.7._ - */ - function toInt232(int256 value) internal pure returns (int232 downcasted) { - downcasted = int232(value); - require(downcasted == value, "SafeCast: value doesn't fit in 232 bits"); - } - - /** - * @dev Returns the downcasted int224 from int256, reverting on - * overflow (when the input is less than smallest int224 or - * greater than largest int224). - * - * Counterpart to Solidity's `int224` operator. - * - * Requirements: - * - * - input must fit into 224 bits - * - * _Available since v4.7._ - */ - function toInt224(int256 value) internal pure returns (int224 downcasted) { - downcasted = int224(value); - require(downcasted == value, "SafeCast: value doesn't fit in 224 bits"); - } - - /** - * @dev Returns the downcasted int216 from int256, reverting on - * overflow (when the input is less than smallest int216 or - * greater than largest int216). - * - * Counterpart to Solidity's `int216` operator. - * - * Requirements: - * - * - input must fit into 216 bits - * - * _Available since v4.7._ - */ - function toInt216(int256 value) internal pure returns (int216 downcasted) { - downcasted = int216(value); - require(downcasted == value, "SafeCast: value doesn't fit in 216 bits"); - } - - /** - * @dev Returns the downcasted int208 from int256, reverting on - * overflow (when the input is less than smallest int208 or - * greater than largest int208). - * - * Counterpart to Solidity's `int208` operator. - * - * Requirements: - * - * - input must fit into 208 bits - * - * _Available since v4.7._ - */ - function toInt208(int256 value) internal pure returns (int208 downcasted) { - downcasted = int208(value); - require(downcasted == value, "SafeCast: value doesn't fit in 208 bits"); - } - - /** - * @dev Returns the downcasted int200 from int256, reverting on - * overflow (when the input is less than smallest int200 or - * greater than largest int200). - * - * Counterpart to Solidity's `int200` operator. - * - * Requirements: - * - * - input must fit into 200 bits - * - * _Available since v4.7._ - */ - function toInt200(int256 value) internal pure returns (int200 downcasted) { - downcasted = int200(value); - require(downcasted == value, "SafeCast: value doesn't fit in 200 bits"); - } - - /** - * @dev Returns the downcasted int192 from int256, reverting on - * overflow (when the input is less than smallest int192 or - * greater than largest int192). - * - * Counterpart to Solidity's `int192` operator. - * - * Requirements: - * - * - input must fit into 192 bits - * - * _Available since v4.7._ - */ - function toInt192(int256 value) internal pure returns (int192 downcasted) { - downcasted = int192(value); - require(downcasted == value, "SafeCast: value doesn't fit in 192 bits"); - } - - /** - * @dev Returns the downcasted int184 from int256, reverting on - * overflow (when the input is less than smallest int184 or - * greater than largest int184). - * - * Counterpart to Solidity's `int184` operator. - * - * Requirements: - * - * - input must fit into 184 bits - * - * _Available since v4.7._ - */ - function toInt184(int256 value) internal pure returns (int184 downcasted) { - downcasted = int184(value); - require(downcasted == value, "SafeCast: value doesn't fit in 184 bits"); - } - - /** - * @dev Returns the downcasted int176 from int256, reverting on - * overflow (when the input is less than smallest int176 or - * greater than largest int176). - * - * Counterpart to Solidity's `int176` operator. - * - * Requirements: - * - * - input must fit into 176 bits - * - * _Available since v4.7._ - */ - function toInt176(int256 value) internal pure returns (int176 downcasted) { - downcasted = int176(value); - require(downcasted == value, "SafeCast: value doesn't fit in 176 bits"); - } - - /** - * @dev Returns the downcasted int168 from int256, reverting on - * overflow (when the input is less than smallest int168 or - * greater than largest int168). - * - * Counterpart to Solidity's `int168` operator. - * - * Requirements: - * - * - input must fit into 168 bits - * - * _Available since v4.7._ - */ - function toInt168(int256 value) internal pure returns (int168 downcasted) { - downcasted = int168(value); - require(downcasted == value, "SafeCast: value doesn't fit in 168 bits"); - } - - /** - * @dev Returns the downcasted int160 from int256, reverting on - * overflow (when the input is less than smallest int160 or - * greater than largest int160). - * - * Counterpart to Solidity's `int160` operator. - * - * Requirements: - * - * - input must fit into 160 bits - * - * _Available since v4.7._ - */ - function toInt160(int256 value) internal pure returns (int160 downcasted) { - downcasted = int160(value); - require(downcasted == value, "SafeCast: value doesn't fit in 160 bits"); - } - - /** - * @dev Returns the downcasted int152 from int256, reverting on - * overflow (when the input is less than smallest int152 or - * greater than largest int152). - * - * Counterpart to Solidity's `int152` operator. - * - * Requirements: - * - * - input must fit into 152 bits - * - * _Available since v4.7._ - */ - function toInt152(int256 value) internal pure returns (int152 downcasted) { - downcasted = int152(value); - require(downcasted == value, "SafeCast: value doesn't fit in 152 bits"); - } - - /** - * @dev Returns the downcasted int144 from int256, reverting on - * overflow (when the input is less than smallest int144 or - * greater than largest int144). - * - * Counterpart to Solidity's `int144` operator. - * - * Requirements: - * - * - input must fit into 144 bits - * - * _Available since v4.7._ - */ - function toInt144(int256 value) internal pure returns (int144 downcasted) { - downcasted = int144(value); - require(downcasted == value, "SafeCast: value doesn't fit in 144 bits"); - } - - /** - * @dev Returns the downcasted int136 from int256, reverting on - * overflow (when the input is less than smallest int136 or - * greater than largest int136). - * - * Counterpart to Solidity's `int136` operator. - * - * Requirements: - * - * - input must fit into 136 bits - * - * _Available since v4.7._ - */ - function toInt136(int256 value) internal pure returns (int136 downcasted) { - downcasted = int136(value); - require(downcasted == value, "SafeCast: value doesn't fit in 136 bits"); - } - - /** - * @dev Returns the downcasted int128 from int256, reverting on - * overflow (when the input is less than smallest int128 or - * greater than largest int128). - * - * Counterpart to Solidity's `int128` operator. - * - * Requirements: - * - * - input must fit into 128 bits - * - * _Available since v3.1._ - */ - function toInt128(int256 value) internal pure returns (int128 downcasted) { - downcasted = int128(value); - require(downcasted == value, "SafeCast: value doesn't fit in 128 bits"); - } - - /** - * @dev Returns the downcasted int120 from int256, reverting on - * overflow (when the input is less than smallest int120 or - * greater than largest int120). - * - * Counterpart to Solidity's `int120` operator. - * - * Requirements: - * - * - input must fit into 120 bits - * - * _Available since v4.7._ - */ - function toInt120(int256 value) internal pure returns (int120 downcasted) { - downcasted = int120(value); - require(downcasted == value, "SafeCast: value doesn't fit in 120 bits"); - } - - /** - * @dev Returns the downcasted int112 from int256, reverting on - * overflow (when the input is less than smallest int112 or - * greater than largest int112). - * - * Counterpart to Solidity's `int112` operator. - * - * Requirements: - * - * - input must fit into 112 bits - * - * _Available since v4.7._ - */ - function toInt112(int256 value) internal pure returns (int112 downcasted) { - downcasted = int112(value); - require(downcasted == value, "SafeCast: value doesn't fit in 112 bits"); - } - - /** - * @dev Returns the downcasted int104 from int256, reverting on - * overflow (when the input is less than smallest int104 or - * greater than largest int104). - * - * Counterpart to Solidity's `int104` operator. - * - * Requirements: - * - * - input must fit into 104 bits - * - * _Available since v4.7._ - */ - function toInt104(int256 value) internal pure returns (int104 downcasted) { - downcasted = int104(value); - require(downcasted == value, "SafeCast: value doesn't fit in 104 bits"); - } - - /** - * @dev Returns the downcasted int96 from int256, reverting on - * overflow (when the input is less than smallest int96 or - * greater than largest int96). - * - * Counterpart to Solidity's `int96` operator. - * - * Requirements: - * - * - input must fit into 96 bits - * - * _Available since v4.7._ - */ - function toInt96(int256 value) internal pure returns (int96 downcasted) { - downcasted = int96(value); - require(downcasted == value, "SafeCast: value doesn't fit in 96 bits"); - } - - /** - * @dev Returns the downcasted int88 from int256, reverting on - * overflow (when the input is less than smallest int88 or - * greater than largest int88). - * - * Counterpart to Solidity's `int88` operator. - * - * Requirements: - * - * - input must fit into 88 bits - * - * _Available since v4.7._ - */ - function toInt88(int256 value) internal pure returns (int88 downcasted) { - downcasted = int88(value); - require(downcasted == value, "SafeCast: value doesn't fit in 88 bits"); - } - - /** - * @dev Returns the downcasted int80 from int256, reverting on - * overflow (when the input is less than smallest int80 or - * greater than largest int80). - * - * Counterpart to Solidity's `int80` operator. - * - * Requirements: - * - * - input must fit into 80 bits - * - * _Available since v4.7._ - */ - function toInt80(int256 value) internal pure returns (int80 downcasted) { - downcasted = int80(value); - require(downcasted == value, "SafeCast: value doesn't fit in 80 bits"); - } - - /** - * @dev Returns the downcasted int72 from int256, reverting on - * overflow (when the input is less than smallest int72 or - * greater than largest int72). - * - * Counterpart to Solidity's `int72` operator. - * - * Requirements: - * - * - input must fit into 72 bits - * - * _Available since v4.7._ - */ - function toInt72(int256 value) internal pure returns (int72 downcasted) { - downcasted = int72(value); - require(downcasted == value, "SafeCast: value doesn't fit in 72 bits"); - } - - /** - * @dev Returns the downcasted int64 from int256, reverting on - * overflow (when the input is less than smallest int64 or - * greater than largest int64). - * - * Counterpart to Solidity's `int64` operator. - * - * Requirements: - * - * - input must fit into 64 bits - * - * _Available since v3.1._ - */ - function toInt64(int256 value) internal pure returns (int64 downcasted) { - downcasted = int64(value); - require(downcasted == value, "SafeCast: value doesn't fit in 64 bits"); - } - - /** - * @dev Returns the downcasted int56 from int256, reverting on - * overflow (when the input is less than smallest int56 or - * greater than largest int56). - * - * Counterpart to Solidity's `int56` operator. - * - * Requirements: - * - * - input must fit into 56 bits - * - * _Available since v4.7._ - */ - function toInt56(int256 value) internal pure returns (int56 downcasted) { - downcasted = int56(value); - require(downcasted == value, "SafeCast: value doesn't fit in 56 bits"); - } - - /** - * @dev Returns the downcasted int48 from int256, reverting on - * overflow (when the input is less than smallest int48 or - * greater than largest int48). - * - * Counterpart to Solidity's `int48` operator. - * - * Requirements: - * - * - input must fit into 48 bits - * - * _Available since v4.7._ - */ - function toInt48(int256 value) internal pure returns (int48 downcasted) { - downcasted = int48(value); - require(downcasted == value, "SafeCast: value doesn't fit in 48 bits"); - } - - /** - * @dev Returns the downcasted int40 from int256, reverting on - * overflow (when the input is less than smallest int40 or - * greater than largest int40). - * - * Counterpart to Solidity's `int40` operator. - * - * Requirements: - * - * - input must fit into 40 bits - * - * _Available since v4.7._ - */ - function toInt40(int256 value) internal pure returns (int40 downcasted) { - downcasted = int40(value); - require(downcasted == value, "SafeCast: value doesn't fit in 40 bits"); - } - - /** - * @dev Returns the downcasted int32 from int256, reverting on - * overflow (when the input is less than smallest int32 or - * greater than largest int32). - * - * Counterpart to Solidity's `int32` operator. - * - * Requirements: - * - * - input must fit into 32 bits - * - * _Available since v3.1._ - */ - function toInt32(int256 value) internal pure returns (int32 downcasted) { - downcasted = int32(value); - require(downcasted == value, "SafeCast: value doesn't fit in 32 bits"); - } - - /** - * @dev Returns the downcasted int24 from int256, reverting on - * overflow (when the input is less than smallest int24 or - * greater than largest int24). - * - * Counterpart to Solidity's `int24` operator. - * - * Requirements: - * - * - input must fit into 24 bits - * - * _Available since v4.7._ - */ - function toInt24(int256 value) internal pure returns (int24 downcasted) { - downcasted = int24(value); - require(downcasted == value, "SafeCast: value doesn't fit in 24 bits"); - } - - /** - * @dev Returns the downcasted int16 from int256, reverting on - * overflow (when the input is less than smallest int16 or - * greater than largest int16). - * - * Counterpart to Solidity's `int16` operator. - * - * Requirements: - * - * - input must fit into 16 bits - * - * _Available since v3.1._ - */ - function toInt16(int256 value) internal pure returns (int16 downcasted) { - downcasted = int16(value); - require(downcasted == value, "SafeCast: value doesn't fit in 16 bits"); - } - - /** - * @dev Returns the downcasted int8 from int256, reverting on - * overflow (when the input is less than smallest int8 or - * greater than largest int8). - * - * Counterpart to Solidity's `int8` operator. - * - * Requirements: - * - * - input must fit into 8 bits - * - * _Available since v3.1._ - */ - function toInt8(int256 value) internal pure returns (int8 downcasted) { - downcasted = int8(value); - require(downcasted == value, "SafeCast: value doesn't fit in 8 bits"); - } - - /** - * @dev Converts an unsigned uint256 into a signed int256. - * - * Requirements: - * - * - input must be less than or equal to maxInt256. - * - * _Available since v3.0._ - */ - function toInt256(uint256 value) internal pure returns (int256) { - // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive - require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); - return int256(value); - } -} \ No newline at end of file diff --git a/contracts/src/v0.8/tests/Greeter.sol b/contracts/src/v0.8/tests/Greeter.sol index cb10fa1b193..88ccca560de 100644 --- a/contracts/src/v0.8/tests/Greeter.sol +++ b/contracts/src/v0.8/tests/Greeter.sol @@ -1,6 +1,6 @@ pragma solidity ^0.8.0; -import "../ConfirmedOwner.sol"; +import "../shared/access/ConfirmedOwner.sol"; contract Greeter is ConfirmedOwner { string public greeting; diff --git a/contracts/src/v0.8/tests/LogEmitter.sol b/contracts/src/v0.8/tests/LogEmitter.sol index 4d7b9799eb1..d3f950c5ccb 100644 --- a/contracts/src/v0.8/tests/LogEmitter.sol +++ b/contracts/src/v0.8/tests/LogEmitter.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract LogEmitter { diff --git a/contracts/src/v0.8/tests/MercuryUpkeep.sol b/contracts/src/v0.8/tests/MercuryUpkeep.sol index 336d2ba4a73..cf3ca6be519 100644 --- a/contracts/src/v0.8/tests/MercuryUpkeep.sol +++ b/contracts/src/v0.8/tests/MercuryUpkeep.sol @@ -1,8 +1,8 @@ -pragma solidity 0.8.15; +pragma solidity 0.8.16; -import "../interfaces/automation/AutomationCompatibleInterface.sol"; +import "../automation/interfaces/AutomationCompatibleInterface.sol"; import "../dev/automation/2_1/interfaces/FeedLookupCompatibleInterface.sol"; -import {ArbSys} from "../dev/vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; +import {ArbSys} from "../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; //interface IVerifierProxy { // /** @@ -45,7 +45,7 @@ contract MercuryUpkeep is AutomationCompatibleInterface, FeedLookupCompatibleInt previousPerformBlock = 0; initialBlock = 0; counter = 0; - feedParamKey = "feedIDHex"; // feedIDStr is deprecated + feedParamKey = "feedIdHex"; // feedIDStr is deprecated feeds = [ "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000" diff --git a/contracts/src/v0.8/tests/MockArbitrumInbox.sol b/contracts/src/v0.8/tests/MockArbitrumInbox.sol index 0c90d19b324..cd85ed4d6ea 100644 --- a/contracts/src/v0.8/tests/MockArbitrumInbox.sol +++ b/contracts/src/v0.8/tests/MockArbitrumInbox.sol @@ -1,5 +1,5 @@ -import {IInbox} from "../dev/vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IInbox.sol"; -import {IBridge} from "../dev/vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IBridge.sol"; +import {IInbox} from "../vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IInbox.sol"; +import {IBridge} from "../vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IBridge.sol"; contract MockArbitrumInbox is IInbox { event RetryableTicketNoRefundAliasRewriteCreated( diff --git a/contracts/src/v0.8/tests/VerifiableLoadBase.sol b/contracts/src/v0.8/tests/VerifiableLoadBase.sol index 66c0df85d2b..03f581dab1d 100644 --- a/contracts/src/v0.8/tests/VerifiableLoadBase.sol +++ b/contracts/src/v0.8/tests/VerifiableLoadBase.sol @@ -1,25 +1,24 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.6; +pragma solidity ^0.8.16; import "../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; -import "../automation/2_0/KeeperRegistrar2_0.sol"; import "../dev/automation/2_1/interfaces/IKeeperRegistryMaster.sol"; -import {ArbSys} from "../dev/vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; +import {ArbSys} from "../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; +import "../dev/automation/2_1/AutomationRegistrar2_1.sol"; +import {LogTriggerConfig} from "../dev/automation/2_1/AutomationUtils2_1.sol"; abstract contract VerifiableLoadBase is ConfirmedOwner { error IndexOutOfRange(); + event LogEmitted(uint256 indexed upkeepId, uint256 indexed blockNum, address addr); event UpkeepsRegistered(uint256[] upkeepIds); - event UpkeepsCancelled(uint256[] upkeepIds); - event RegistrarSet(address newRegistrar); - event FundsAdded(uint256 upkeepId, uint96 amount); event UpkeepTopUp(uint256 upkeepId, uint96 amount, uint256 blockNum); - event InsufficientFunds(uint256 balance, uint256 blockNum); event Received(address sender, uint256 value); - event PerformingUpkeep(uint256 firstPerformBlock, uint256 lastBlock, uint256 previousBlock, uint256 counter); using EnumerableSet for EnumerableSet.UintSet; ArbSys internal constant ARB_SYS = ArbSys(0x0000000000000000000000000000000000000064); + //bytes32 public constant emittedSig = 0x97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf08; //keccak256(LogEmitted(uint256,uint256,address)) + bytes32 public immutable emittedSig = LogEmitted.selector; mapping(uint256 => uint256) public lastTopUpBlocks; mapping(uint256 => uint256) public intervals; @@ -30,17 +29,13 @@ abstract contract VerifiableLoadBase is ConfirmedOwner { mapping(uint256 => uint256) public checkGasToBurns; mapping(uint256 => uint256) public performDataSizes; mapping(uint256 => uint256) public gasLimits; - mapping(uint256 => bytes) public checkDatas; mapping(bytes32 => bool) public dummyMap; // used to force storage lookup mapping(uint256 => uint256[]) public delays; // how to query for delays for a certain past period: calendar day and/or past 24 hours mapping(uint256 => mapping(uint16 => uint256[])) public bucketedDelays; - mapping(uint256 => mapping(uint16 => uint256[])) public timestampDelays; - mapping(uint256 => uint256[]) public timestamps; - mapping(uint256 => uint16) public timestampBuckets; mapping(uint256 => uint16) public buckets; EnumerableSet.UintSet internal s_upkeepIDs; - KeeperRegistrar2_0 public registrar; + AutomationRegistrar2_1 public registrar; LinkTokenInterface public linkToken; IKeeperRegistryMaster public registry; // check if an upkeep is eligible for adding funds at this interval @@ -55,18 +50,17 @@ abstract contract VerifiableLoadBase is ConfirmedOwner { // the following fields are immutable bc if they are adjusted, the existing upkeeps' delays will be stored in // different sizes of buckets. it's better to redeploy this contract with new values. uint16 public immutable BUCKET_SIZE = 100; - uint16 public immutable TIMESTAMP_INTERVAL = 3600; /** - * @param registrarAddress a registrar address - * @param useArb if this contract will use arbitrum block number + * @param _registrar a automation registrar 2.1 address + * @param _useArb if this contract will use arbitrum block number */ - constructor(address registrarAddress, bool useArb) ConfirmedOwner(msg.sender) { - registrar = KeeperRegistrar2_0(registrarAddress); - (, , , address registryAddress, ) = registrar.getRegistrationConfig(); + constructor(AutomationRegistrar2_1 _registrar, bool _useArb) ConfirmedOwner(msg.sender) { + registrar = _registrar; + (address registryAddress, ) = registrar.getConfig(); registry = IKeeperRegistryMaster(payable(address(registryAddress))); linkToken = registrar.LINK(); - useArbitrumBlockNum = useArb; + useArbitrumBlockNum = _useArb; } receive() external payable { @@ -93,13 +87,11 @@ abstract contract VerifiableLoadBase is ConfirmedOwner { * @notice sets registrar, registry, and link token address. * @param newRegistrar the new registrar address */ - function setConfig(KeeperRegistrar2_0 newRegistrar) external { + function setConfig(AutomationRegistrar2_1 newRegistrar) external { registrar = newRegistrar; - (, , , address registryAddress, ) = registrar.getRegistrationConfig(); + (address registryAddress, ) = registrar.getConfig(); registry = IKeeperRegistryMaster(payable(address(registryAddress))); linkToken = registrar.LINK(); - - emit RegistrarSet(address(registrar)); } /** @@ -126,18 +118,31 @@ abstract contract VerifiableLoadBase is ConfirmedOwner { * @param params a registration params struct * @return an upkeep ID */ - function _registerUpkeep(KeeperRegistrar2_0.RegistrationParams memory params) private returns (uint256) { + function _registerUpkeep(AutomationRegistrar2_1.RegistrationParams memory params) private returns (uint256) { uint256 upkeepId = registrar.registerUpkeep(params); s_upkeepIDs.add(upkeepId); gasLimits[upkeepId] = params.gasLimit; - checkDatas[upkeepId] = params.checkData; return upkeepId; } + function getLogTriggerConfig(uint256 upkeepId) external view returns (bytes memory logTrigger) { + LogTriggerConfig memory cfg = LogTriggerConfig({ + contractAddress: address(this), + filterSelector: 1, // only filter by topic1 + topic0: emittedSig, + topic1: bytes32(abi.encode(upkeepId)), + topic2: 0x000000000000000000000000000000000000000000000000000000000000000, + topic3: 0x000000000000000000000000000000000000000000000000000000000000000 + }); + return abi.encode(cfg); + } + /** * @notice batch registering upkeeps. * @param number the number of upkeeps to be registered * @param gasLimit the gas limit of each upkeep + * @param triggerType the trigger type of this upkeep, 0 for conditional, 1 for log trigger + * @param triggerConfig the trigger config of this upkeep * @param amount the amount of LINK to fund each upkeep * @param checkGasToBurn the amount of check gas to burn * @param performGasToBurn the amount of perform gas to burn @@ -145,17 +150,21 @@ abstract contract VerifiableLoadBase is ConfirmedOwner { function batchRegisterUpkeeps( uint8 number, uint32 gasLimit, + uint8 triggerType, + bytes memory triggerConfig, uint96 amount, uint256 checkGasToBurn, uint256 performGasToBurn ) external { - KeeperRegistrar2_0.RegistrationParams memory params = KeeperRegistrar2_0.RegistrationParams({ + AutomationRegistrar2_1.RegistrationParams memory params = AutomationRegistrar2_1.RegistrationParams({ name: "test", encryptedEmail: bytes(""), upkeepContract: address(this), gasLimit: gasLimit, adminAddress: address(this), // use address of this contract as the admin + triggerType: triggerType, checkData: bytes(""), // update pipeline data later bc upkeep id is not available now + triggerConfig: triggerConfig, offchainConfig: bytes(""), amount: amount }); @@ -165,6 +174,10 @@ abstract contract VerifiableLoadBase is ConfirmedOwner { uint256[] memory upkeepIds = new uint256[](number); for (uint8 i = 0; i < number; i++) { uint256 upkeepId = _registerUpkeep(params); + if (triggerType == 1) { + bytes memory triggerCfg = this.getLogTriggerConfig(upkeepId); + registry.setUpkeepTriggerConfig(upkeepId, triggerCfg); + } upkeepIds[i] = upkeepId; checkGasToBurns[upkeepId] = checkGasToBurn; performGasToBurns[upkeepId] = performGasToBurn; @@ -172,15 +185,33 @@ abstract contract VerifiableLoadBase is ConfirmedOwner { emit UpkeepsRegistered(upkeepIds); } + function topUpFund(uint256 upkeepId, uint256 blockNum) public { + if (blockNum - lastTopUpBlocks[upkeepId] > upkeepTopUpCheckInterval) { + KeeperRegistryBase2_1.UpkeepInfo memory info = registry.getUpkeep(upkeepId); + uint96 minBalance = registry.getMinBalanceForUpkeep(upkeepId); + if (info.balance < minBalanceThresholdMultiplier * minBalance) { + addFunds(upkeepId, addLinkAmount); + lastTopUpBlocks[upkeepId] = blockNum; + emit UpkeepTopUp(upkeepId, addLinkAmount, blockNum); + } + } + } + + function burnPerformGas(uint256 upkeepId, uint256 startGas, uint256 blockNum) public { + uint256 performGasToBurn = performGasToBurns[upkeepId]; + while (startGas - gasleft() + 10000 < performGasToBurn) { + dummyMap[blockhash(blockNum)] = false; + } + } + /** * @notice adds fund for an upkeep. * @param upkeepId the upkeep ID * @param amount the amount of LINK to be funded for the upkeep */ - function addFunds(uint256 upkeepId, uint96 amount) external { + function addFunds(uint256 upkeepId, uint96 amount) public { linkToken.approve(address(registry), amount); registry.addFunds(upkeepId, amount); - emit FundsAdded(upkeepId, amount); } /** @@ -190,7 +221,6 @@ abstract contract VerifiableLoadBase is ConfirmedOwner { */ function updateUpkeepPipelineData(uint256 upkeepId, bytes calldata pipelineData) external { registry.setUpkeepCheckData(upkeepId, pipelineData); - checkDatas[upkeepId] = pipelineData; } function withdrawLinks(uint256 upkeepId) external { @@ -222,7 +252,6 @@ abstract contract VerifiableLoadBase is ConfirmedOwner { for (uint8 i = 0; i < len; i++) { this.cancelUpkeep(upkeepIds[i]); } - emit UpkeepsCancelled(upkeepIds); } function eligible(uint256 upkeepId) public view returns (bool) { @@ -276,13 +305,6 @@ abstract contract VerifiableLoadBase is ConfirmedOwner { delete bucketedDelays[upkeepId][i]; } delete buckets[upkeepId]; - - currentBucket = timestampBuckets[upkeepId]; - for (uint16 i = 0; i <= currentBucket; i++) { - delete timestampDelays[upkeepId][i]; - } - delete timestamps[upkeepId]; - delete timestampBuckets[upkeepId]; } /** @@ -309,16 +331,29 @@ abstract contract VerifiableLoadBase is ConfirmedOwner { } } - function getDelaysLength(uint256 upkeepId) public view returns (uint256) { - return delays[upkeepId].length; + /** + * @notice finds all log trigger upkeeps and emits logs to serve as the initial trigger for upkeeps + */ + function batchSendLogs() external { + uint256[] memory upkeepIds = registry.getActiveUpkeepIDs(0, 0); + uint256 len = upkeepIds.length; + uint256 blockNum = getBlockNumber(); + for (uint256 i = 0; i < len; i++) { + uint256 upkeepId = upkeepIds[i]; + uint8 triggerType = registry.getTriggerType(upkeepId); + if (triggerType == 1) { + emit LogEmitted(upkeepId, blockNum, address(this)); + } + } } - function getDelaysLengthAtBucket(uint256 upkeepId, uint16 bucket) public view returns (uint256) { - return bucketedDelays[upkeepId][bucket].length; + function sendLog(uint256 upkeepId) external { + uint256 blockNum = getBlockNumber(); + emit LogEmitted(upkeepId, blockNum, address(this)); } - function getDelaysLengthAtTimestampBucket(uint256 upkeepId, uint16 timestampBucket) public view returns (uint256) { - return timestampDelays[upkeepId][timestampBucket].length; + function getDelaysLength(uint256 upkeepId) public view returns (uint256) { + return delays[upkeepId].length; } function getBucketedDelaysLength(uint256 upkeepId) public view returns (uint256) { @@ -330,23 +365,10 @@ abstract contract VerifiableLoadBase is ConfirmedOwner { return len; } - function getTimestampBucketedDelaysLength(uint256 upkeepId) public view returns (uint256) { - uint16 timestampBucket = timestampBuckets[upkeepId]; - uint256 len = 0; - for (uint16 i = 0; i <= timestampBucket; i++) { - len += timestampDelays[upkeepId][i].length; - } - return len; - } - function getDelays(uint256 upkeepId) public view returns (uint256[] memory) { return delays[upkeepId]; } - function getTimestampDelays(uint256 upkeepId, uint16 timestampBucket) public view returns (uint256[] memory) { - return timestampDelays[upkeepId][timestampBucket]; - } - function getBucketedDelays(uint256 upkeepId, uint16 bucket) public view returns (uint256[] memory) { return bucketedDelays[upkeepId][bucket]; } @@ -356,62 +378,11 @@ abstract contract VerifiableLoadBase is ConfirmedOwner { return getSumDelayLastNPerforms(delays, n); } - function getSumBucketedDelayLastNPerforms(uint256 upkeepId, uint256 n) public view returns (uint256, uint256) { - uint256 len = this.getBucketedDelaysLength(upkeepId); - if (n == 0 || n >= len) { - n = len; - } - uint256 nn = n; - uint256 sum = 0; - uint16 currentBucket = buckets[upkeepId]; - for (uint16 i = currentBucket; i >= 0; i--) { - uint256[] memory delays = bucketedDelays[upkeepId][i]; - (uint256 s, uint256 m) = getSumDelayLastNPerforms(delays, nn); - sum += s; - nn -= m; - if (nn <= 0) { - break; - } - } - return (sum, n); - } - - function getSumTimestampBucketedDelayLastNPerforms( - uint256 upkeepId, - uint256 n - ) public view returns (uint256, uint256) { - uint256 len = this.getTimestampBucketedDelaysLength(upkeepId); - if (n == 0 || n >= len) { - n = len; - } - uint256 nn = n; - uint256 sum = 0; - uint16 timestampBucket = timestampBuckets[upkeepId]; - for (uint16 i = timestampBucket; i >= 0; i--) { - uint256[] memory delays = timestampDelays[upkeepId][i]; - (uint256 s, uint256 m) = getSumDelayLastNPerforms(delays, nn); - sum += s; - nn -= m; - if (nn <= 0) { - break; - } - } - return (sum, n); - } - function getSumDelayInBucket(uint256 upkeepId, uint16 bucket) public view returns (uint256, uint256) { uint256[] memory delays = bucketedDelays[upkeepId][bucket]; return getSumDelayLastNPerforms(delays, delays.length); } - function getSumDelayInTimestampBucket( - uint256 upkeepId, - uint16 timestampBucket - ) public view returns (uint256, uint256) { - uint256[] memory delays = timestampDelays[upkeepId][timestampBucket]; - return getSumDelayLastNPerforms(delays, delays.length); - } - function getSumDelayLastNPerforms(uint256[] memory delays, uint256 n) internal view returns (uint256, uint256) { uint256 i; uint256 len = delays.length; @@ -424,60 +395,6 @@ abstract contract VerifiableLoadBase is ConfirmedOwner { return (sum, n); } - function getPxDelayForAllUpkeeps(uint256 p) public view returns (uint256[] memory, uint256[] memory) { - uint256 len = s_upkeepIDs.length(); - uint256[] memory upkeepIds = new uint256[](len); - uint256[] memory pxDelays = new uint256[](len); - - for (uint256 idx = 0; idx < len; idx++) { - uint256 upkeepId = s_upkeepIDs.at(idx); - uint256[] memory delays = delays[upkeepId]; - upkeepIds[idx] = upkeepId; - pxDelays[idx] = getPxDelayLastNPerforms(delays, p, delays.length); - } - - return (upkeepIds, pxDelays); - } - - function getPxBucketedDelaysForAllUpkeeps(uint256 p) public view returns (uint256[] memory, uint256[] memory) { - uint256 len = s_upkeepIDs.length(); - uint256[] memory upkeepIds = new uint256[](len); - uint256[] memory pxDelays = new uint256[](len); - - for (uint256 idx = 0; idx < len; idx++) { - uint256 upkeepId = s_upkeepIDs.at(idx); - upkeepIds[idx] = upkeepId; - uint16 currentBucket = buckets[upkeepId]; - uint256 delayLen = this.getBucketedDelaysLength(upkeepId); - uint256[] memory delays = new uint256[](delayLen); - uint256 i = 0; - mapping(uint16 => uint256[]) storage bucketedDelays = bucketedDelays[upkeepId]; - for (uint16 j = 0; j <= currentBucket; j++) { - uint256[] memory d = bucketedDelays[j]; - for (uint256 k = 0; k < d.length; k++) { - delays[i++] = d[k]; - } - } - pxDelays[idx] = getPxDelayLastNPerforms(delays, p, delayLen); - } - - return (upkeepIds, pxDelays); - } - - function getPxDelayInTimestampBucket( - uint256 upkeepId, - uint256 p, - uint16 timestampBucket - ) public view returns (uint256) { - uint256[] memory delays = timestampDelays[upkeepId][timestampBucket]; - return getPxDelayLastNPerforms(delays, p, delays.length); - } - - function getPxDelayInBucket(uint256 upkeepId, uint256 p, uint16 bucket) public view returns (uint256) { - uint256[] memory delays = bucketedDelays[upkeepId][bucket]; - return getPxDelayLastNPerforms(delays, p, delays.length); - } - function getPxDelayLastNPerforms(uint256 upkeepId, uint256 p, uint256 n) public view returns (uint256) { return getPxDelayLastNPerforms(delays[upkeepId], p, n); } diff --git a/contracts/src/v0.8/tests/VerifiableLoadLogTriggerUpkeep.sol b/contracts/src/v0.8/tests/VerifiableLoadLogTriggerUpkeep.sol new file mode 100644 index 00000000000..a1842449110 --- /dev/null +++ b/contracts/src/v0.8/tests/VerifiableLoadLogTriggerUpkeep.sol @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.16; + +import "./VerifiableLoadBase.sol"; +import "../dev/automation/2_1/interfaces/ILogAutomation.sol"; +import "../dev/automation/2_1/interfaces/FeedLookupCompatibleInterface.sol"; + +contract VerifiableLoadLogTriggerUpkeep is VerifiableLoadBase, FeedLookupCompatibleInterface, ILogAutomation { + string[] public feedsHex = [ + "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", + "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000" + ]; + string public feedParamKey = "feedIdHex"; + string public timeParamKey = "blockNumber"; + bool public autoLog; + bool public useMercury; + + /** + * @param _registrar a automation registrar 2.1 address + * @param _useArb if this contract will use arbitrum block number + * @param _autoLog if the upkeep will emit logs to trigger its next log trigger process + * @param _useMercury if the log trigger upkeeps will use mercury lookup + */ + constructor( + AutomationRegistrar2_1 _registrar, + bool _useArb, + bool _autoLog, + bool _useMercury + ) VerifiableLoadBase(_registrar, _useArb) { + autoLog = _autoLog; + useMercury = _useMercury; + } + + function setAutoLog(bool _autoLog) external { + autoLog = _autoLog; + } + + function setUseMercury(bool _useMercury) external { + useMercury = _useMercury; + } + + function setFeedsHex(string[] memory newFeeds) external { + feedsHex = newFeeds; + } + + function checkLog(Log calldata log, bytes memory checkData) external returns (bool, bytes memory) { + uint256 startGas = gasleft(); + uint256 blockNum = getBlockNumber(); + + // filter by event signature + if (log.topics[0] == emittedSig) { + bytes memory t1 = abi.encodePacked(log.topics[1]); // bytes32 to bytes + uint256 upkeepId = abi.decode(t1, (uint256)); + bytes memory t2 = abi.encodePacked(log.topics[2]); + uint256 blockNum = abi.decode(t2, (uint256)); + + uint256 checkGasToBurn = checkGasToBurns[upkeepId]; + while (startGas - gasleft() + 15000 < checkGasToBurn) { + dummyMap[blockhash(blockNum)] = false; + } + + if (useMercury) { + revert FeedLookup(feedParamKey, feedsHex, timeParamKey, blockNum, abi.encode(upkeepId, blockNum)); + } + + // if we don't use mercury, create a perform data which resembles the output of checkCallback + bytes[] memory values = new bytes[](1); + bytes memory extraData = abi.encode(upkeepId, blockNum); + return (true, abi.encode(values, extraData)); + } + revert("could not find matching event sig"); + } + + function performUpkeep(bytes calldata performData) external { + uint256 startGas = gasleft(); + (bytes[] memory values, bytes memory extraData) = abi.decode(performData, (bytes[], bytes)); + (uint256 upkeepId, uint256 logBlockNumber) = abi.decode(extraData, (uint256, uint256)); + + uint256 firstPerformBlock = firstPerformBlocks[upkeepId]; + uint256 previousPerformBlock = previousPerformBlocks[upkeepId]; + uint256 currentBlockNum = getBlockNumber(); + + if (firstPerformBlock == 0) { + firstPerformBlocks[upkeepId] = currentBlockNum; + } else { + uint256 delay = currentBlockNum - logBlockNumber; + uint16 bucket = buckets[upkeepId]; + uint256[] memory bucketDelays = bucketedDelays[upkeepId][bucket]; + if (bucketDelays.length == BUCKET_SIZE) { + bucket++; + buckets[upkeepId] = bucket; + } + bucketedDelays[upkeepId][bucket].push(delay); + delays[upkeepId].push(delay); + } + + uint256 counter = counters[upkeepId] + 1; + counters[upkeepId] = counter; + previousPerformBlocks[upkeepId] = currentBlockNum; + + // for every upkeepTopUpCheckInterval (5), check if the upkeep balance is at least + // minBalanceThresholdMultiplier (20) * min balance. If not, add addLinkAmount (0.2) to the upkeep + // upkeepTopUpCheckInterval, minBalanceThresholdMultiplier, and addLinkAmount are configurable + topUpFund(upkeepId, currentBlockNum); + if (autoLog) { + emit LogEmitted(upkeepId, currentBlockNum, address(this)); + } + burnPerformGas(upkeepId, startGas, currentBlockNum); + } + + function checkCallback( + bytes[] memory values, + bytes memory extraData + ) external pure override returns (bool, bytes memory) { + bytes memory performData = abi.encode(values, extraData); + return (true, performData); + } +} diff --git a/contracts/src/v0.8/tests/VerifiableLoadMercuryUpkeep.sol b/contracts/src/v0.8/tests/VerifiableLoadMercuryUpkeep.sol index 67eb8301891..09e62f988a5 100644 --- a/contracts/src/v0.8/tests/VerifiableLoadMercuryUpkeep.sol +++ b/contracts/src/v0.8/tests/VerifiableLoadMercuryUpkeep.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.6; +pragma solidity 0.8.16; import "./VerifiableLoadBase.sol"; import "../dev/automation/2_1/interfaces/FeedLookupCompatibleInterface.sol"; @@ -10,18 +10,10 @@ contract VerifiableLoadMercuryUpkeep is VerifiableLoadBase, FeedLookupCompatible "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000", "0x555344432d5553442d415242495452554d2d544553544e455400000000000000" ]; - string public constant feedParamKey = "feedIDHex"; + string public constant feedParamKey = "feedIdHex"; string public constant timeParamKey = "blockNumber"; - event MercuryPerformEvent( - address indexed origin, - uint256 indexed upkeepId, - uint256 indexed blockNumber, - bytes v0, - bytes ed - ); - - constructor(address registrarAddress, bool useArb) VerifiableLoadBase(registrarAddress, useArb) {} + constructor(AutomationRegistrar2_1 _registrar, bool _useArb) VerifiableLoadBase(_registrar, _useArb) {} function setFeedsHex(string[] memory newFeeds) external { feedsHex = newFeeds; @@ -67,19 +59,8 @@ contract VerifiableLoadMercuryUpkeep is VerifiableLoadBase, FeedLookupCompatible if (firstPerformBlock == 0) { firstPerformBlocks[upkeepId] = blockNum; - firstPerformBlock = blockNum; - timestamps[upkeepId].push(block.timestamp); } else { - // Calculate and append delay uint256 delay = blockNum - previousPerformBlock - intervals[upkeepId]; - - uint16 timestampBucket = timestampBuckets[upkeepId]; - if (block.timestamp - TIMESTAMP_INTERVAL > timestamps[upkeepId][timestampBucket]) { - timestamps[upkeepId].push(block.timestamp); - timestampBucket++; - timestampBuckets[upkeepId] = timestampBucket; - } - uint16 bucket = buckets[upkeepId]; uint256[] memory bucketDelays = bucketedDelays[upkeepId][bucket]; if (bucketDelays.length == BUCKET_SIZE) { @@ -87,36 +68,14 @@ contract VerifiableLoadMercuryUpkeep is VerifiableLoadBase, FeedLookupCompatible buckets[upkeepId] = bucket; } bucketedDelays[upkeepId][bucket].push(delay); - timestampDelays[upkeepId][timestampBucket].push(delay); delays[upkeepId].push(delay); } uint256 counter = counters[upkeepId] + 1; counters[upkeepId] = counter; - emit PerformingUpkeep(firstPerformBlock, blockNum, previousPerformBlock, counter); previousPerformBlocks[upkeepId] = blockNum; - // for every upkeepTopUpCheckInterval (5), check if the upkeep balance is at least - // minBalanceThresholdMultiplier (20) * min balance. If not, add addLinkAmount (0.2) to the upkeep - // upkeepTopUpCheckInterval, minBalanceThresholdMultiplier, and addLinkAmount are configurable - if (blockNum - lastTopUpBlocks[upkeepId] > upkeepTopUpCheckInterval) { - KeeperRegistryBase2_1.UpkeepInfo memory info = registry.getUpkeep(upkeepId); - uint96 minBalance = registry.getMinBalanceForUpkeep(upkeepId); - if (info.balance < minBalanceThresholdMultiplier * minBalance) { - this.addFunds(upkeepId, addLinkAmount); - lastTopUpBlocks[upkeepId] = blockNum; - emit UpkeepTopUp(upkeepId, addLinkAmount, blockNum); - } - } - - uint256 performGasToBurn = performGasToBurns[upkeepId]; - while (startGas - gasleft() + 10000 < performGasToBurn) { - // 10K margin over gas to burn - dummyMap[blockhash(blockNum)] = false; // arbitrary storage writes - } - - // bytes memory v0 = VERIFIER.verify(values[0]); - // bytes memory v1 = VERIFIER.verify(values[1]); - emit MercuryPerformEvent(tx.origin, upkeepId, blockNum, values[0], extraData); + topUpFund(upkeepId, blockNum); + burnPerformGas(upkeepId, startGas, blockNum); } } diff --git a/contracts/src/v0.8/tests/VerifiableLoadUpkeep.sol b/contracts/src/v0.8/tests/VerifiableLoadUpkeep.sol index 595c49fdd7a..bab75e9613c 100644 --- a/contracts/src/v0.8/tests/VerifiableLoadUpkeep.sol +++ b/contracts/src/v0.8/tests/VerifiableLoadUpkeep.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.6; +pragma solidity 0.8.16; import "./VerifiableLoadBase.sol"; contract VerifiableLoadUpkeep is VerifiableLoadBase { - constructor(address registrarAddress, bool useArb) VerifiableLoadBase(registrarAddress, useArb) {} + constructor(AutomationRegistrar2_1 _registrar, bool _useArb) VerifiableLoadBase(_registrar, _useArb) {} function checkUpkeep(bytes calldata checkData) external returns (bool, bytes memory) { uint256 startGas = gasleft(); @@ -16,9 +16,7 @@ contract VerifiableLoadUpkeep is VerifiableLoadBase { uint256 blockNum = getBlockNumber(); bool needed = eligible(upkeepId); while (startGas - gasleft() + 10000 < checkGasToBurn) { - // 10K margin over gas to burn - // Hard coded check gas to burn - dummyMap[blockhash(blockNum)] = false; // arbitrary storage writes + dummyMap[blockhash(blockNum)] = false; blockNum--; } return (needed, pData); @@ -32,19 +30,8 @@ contract VerifiableLoadUpkeep is VerifiableLoadBase { uint256 blockNum = getBlockNumber(); if (firstPerformBlock == 0) { firstPerformBlocks[upkeepId] = blockNum; - firstPerformBlock = blockNum; - timestamps[upkeepId].push(block.timestamp); } else { - // Calculate and append delay uint256 delay = blockNum - previousPerformBlock - intervals[upkeepId]; - - uint16 timestampBucket = timestampBuckets[upkeepId]; - if (block.timestamp - TIMESTAMP_INTERVAL > timestamps[upkeepId][timestampBucket]) { - timestamps[upkeepId].push(block.timestamp); - timestampBucket++; - timestampBuckets[upkeepId] = timestampBucket; - } - uint16 bucket = buckets[upkeepId]; uint256[] memory bucketDelays = bucketedDelays[upkeepId][bucket]; if (bucketDelays.length == BUCKET_SIZE) { @@ -52,33 +39,14 @@ contract VerifiableLoadUpkeep is VerifiableLoadBase { buckets[upkeepId] = bucket; } bucketedDelays[upkeepId][bucket].push(delay); - timestampDelays[upkeepId][timestampBucket].push(delay); delays[upkeepId].push(delay); } uint256 counter = counters[upkeepId] + 1; counters[upkeepId] = counter; - emit PerformingUpkeep(firstPerformBlock, blockNum, previousPerformBlock, counter); previousPerformBlocks[upkeepId] = blockNum; - // for every upkeepTopUpCheckInterval (5), check if the upkeep balance is at least - // minBalanceThresholdMultiplier (20) * min balance. If not, add addLinkAmount (0.2) to the upkeep - // upkeepTopUpCheckInterval, minBalanceThresholdMultiplier, and addLinkAmount are configurable - if (blockNum - lastTopUpBlocks[upkeepId] > upkeepTopUpCheckInterval) { - KeeperRegistryBase2_1.UpkeepInfo memory info = registry.getUpkeep(upkeepId); - uint96 minBalance = registry.getMinBalanceForUpkeep(upkeepId); - if (info.balance < minBalanceThresholdMultiplier * minBalance) { - this.addFunds(upkeepId, addLinkAmount); - lastTopUpBlocks[upkeepId] = blockNum; - emit UpkeepTopUp(upkeepId, addLinkAmount, blockNum); - } - } - - uint256 performGasToBurn = performGasToBurns[upkeepId]; - while (startGas - gasleft() + 10000 < performGasToBurn) { - // 10K margin over gas to burn - dummyMap[blockhash(blockNum)] = false; // arbitrary storage writes - blockNum--; - } + topUpFund(upkeepId, blockNum); + burnPerformGas(upkeepId, startGas, blockNum); } } diff --git a/contracts/src/v0.8/utils/utils.sol b/contracts/src/v0.8/utils/utils.sol deleted file mode 100644 index 8ad933eabec..00000000000 --- a/contracts/src/v0.8/utils/utils.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -/** - * @notice getRevertMsg extracts a revert reason from a failed contract call - */ -function getRevertMsg(bytes memory payload) pure returns (string memory) { - if (payload.length < 68) return "transaction reverted silently"; - assembly { - payload := add(payload, 0x04) - } - return abi.decode(payload, (string)); -} diff --git a/contracts/src/v0.8/shared/vendor/@ensdomains/buffer/0.1.0/Buffer.sol b/contracts/src/v0.8/vendor/@ensdomains/buffer/0.1.0/Buffer.sol similarity index 100% rename from contracts/src/v0.8/shared/vendor/@ensdomains/buffer/0.1.0/Buffer.sol rename to contracts/src/v0.8/vendor/@ensdomains/buffer/0.1.0/Buffer.sol diff --git a/contracts/src/v0.8/dev/vendor/@eth-optimism/contracts/0.4.7/contracts/optimistic-ethereum/iOVM/bridge/messaging/iOVM_CrossDomainMessenger.sol b/contracts/src/v0.8/vendor/@eth-optimism/contracts/0.4.7/contracts/optimistic-ethereum/iOVM/bridge/messaging/iOVM_CrossDomainMessenger.sol similarity index 100% rename from contracts/src/v0.8/dev/vendor/@eth-optimism/contracts/0.4.7/contracts/optimistic-ethereum/iOVM/bridge/messaging/iOVM_CrossDomainMessenger.sol rename to contracts/src/v0.8/vendor/@eth-optimism/contracts/0.4.7/contracts/optimistic-ethereum/iOVM/bridge/messaging/iOVM_CrossDomainMessenger.sol diff --git a/contracts/src/v0.8/shared/vendor/IERC165.sol b/contracts/src/v0.8/vendor/IERC165.sol similarity index 100% rename from contracts/src/v0.8/shared/vendor/IERC165.sol rename to contracts/src/v0.8/vendor/IERC165.sol diff --git a/contracts/src/v0.8/tests/vendor/MockOVMCrossDomainMessenger.sol b/contracts/src/v0.8/vendor/MockOVMCrossDomainMessenger.sol similarity index 95% rename from contracts/src/v0.8/tests/vendor/MockOVMCrossDomainMessenger.sol rename to contracts/src/v0.8/vendor/MockOVMCrossDomainMessenger.sol index ebb53f4ecc0..1266b484b8b 100644 --- a/contracts/src/v0.8/tests/vendor/MockOVMCrossDomainMessenger.sol +++ b/contracts/src/v0.8/vendor/MockOVMCrossDomainMessenger.sol @@ -2,7 +2,7 @@ pragma solidity >=0.7.6 <0.9.0; -import "../../dev/vendor/openzeppelin-solidity/v4.3.1/contracts/utils/Address.sol"; +import "./openzeppelin-solidity/v4.7.0/contracts/utils/Address.sol"; /** * @title iOVM_CrossDomainMessenger diff --git a/contracts/src/v0.8/tests/vendor/MultiSend.sol b/contracts/src/v0.8/vendor/MultiSend.sol similarity index 100% rename from contracts/src/v0.8/tests/vendor/MultiSend.sol rename to contracts/src/v0.8/vendor/MultiSend.sol diff --git a/contracts/src/v0.8/dev/vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IBridge.sol b/contracts/src/v0.8/vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IBridge.sol similarity index 100% rename from contracts/src/v0.8/dev/vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IBridge.sol rename to contracts/src/v0.8/vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IBridge.sol diff --git a/contracts/src/v0.8/dev/vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IInbox.sol b/contracts/src/v0.8/vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IInbox.sol similarity index 100% rename from contracts/src/v0.8/dev/vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IInbox.sol rename to contracts/src/v0.8/vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IInbox.sol diff --git a/contracts/src/v0.8/dev/vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IMessageProvider.sol b/contracts/src/v0.8/vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IMessageProvider.sol similarity index 100% rename from contracts/src/v0.8/dev/vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IMessageProvider.sol rename to contracts/src/v0.8/vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IMessageProvider.sol diff --git a/contracts/src/v0.8/dev/vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol b/contracts/src/v0.8/vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol similarity index 100% rename from contracts/src/v0.8/dev/vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol rename to contracts/src/v0.8/vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol diff --git a/contracts/src/v0.8/dev/vendor/entrypoint/core/EntryPoint.sol b/contracts/src/v0.8/vendor/entrypoint/core/EntryPoint.sol similarity index 100% rename from contracts/src/v0.8/dev/vendor/entrypoint/core/EntryPoint.sol rename to contracts/src/v0.8/vendor/entrypoint/core/EntryPoint.sol diff --git a/contracts/src/v0.8/dev/vendor/entrypoint/core/Helpers.sol b/contracts/src/v0.8/vendor/entrypoint/core/Helpers.sol similarity index 100% rename from contracts/src/v0.8/dev/vendor/entrypoint/core/Helpers.sol rename to contracts/src/v0.8/vendor/entrypoint/core/Helpers.sol diff --git a/contracts/src/v0.8/dev/vendor/entrypoint/core/SenderCreator.sol b/contracts/src/v0.8/vendor/entrypoint/core/SenderCreator.sol similarity index 100% rename from contracts/src/v0.8/dev/vendor/entrypoint/core/SenderCreator.sol rename to contracts/src/v0.8/vendor/entrypoint/core/SenderCreator.sol diff --git a/contracts/src/v0.8/dev/vendor/entrypoint/core/StakeManager.sol b/contracts/src/v0.8/vendor/entrypoint/core/StakeManager.sol similarity index 100% rename from contracts/src/v0.8/dev/vendor/entrypoint/core/StakeManager.sol rename to contracts/src/v0.8/vendor/entrypoint/core/StakeManager.sol diff --git a/contracts/src/v0.8/dev/vendor/entrypoint/interfaces/IAccount.sol b/contracts/src/v0.8/vendor/entrypoint/interfaces/IAccount.sol similarity index 100% rename from contracts/src/v0.8/dev/vendor/entrypoint/interfaces/IAccount.sol rename to contracts/src/v0.8/vendor/entrypoint/interfaces/IAccount.sol diff --git a/contracts/src/v0.8/dev/vendor/entrypoint/interfaces/IAggregator.sol b/contracts/src/v0.8/vendor/entrypoint/interfaces/IAggregator.sol similarity index 100% rename from contracts/src/v0.8/dev/vendor/entrypoint/interfaces/IAggregator.sol rename to contracts/src/v0.8/vendor/entrypoint/interfaces/IAggregator.sol diff --git a/contracts/src/v0.8/dev/vendor/entrypoint/interfaces/IEntryPoint.sol b/contracts/src/v0.8/vendor/entrypoint/interfaces/IEntryPoint.sol similarity index 100% rename from contracts/src/v0.8/dev/vendor/entrypoint/interfaces/IEntryPoint.sol rename to contracts/src/v0.8/vendor/entrypoint/interfaces/IEntryPoint.sol diff --git a/contracts/src/v0.8/dev/vendor/entrypoint/interfaces/IPaymaster.sol b/contracts/src/v0.8/vendor/entrypoint/interfaces/IPaymaster.sol similarity index 100% rename from contracts/src/v0.8/dev/vendor/entrypoint/interfaces/IPaymaster.sol rename to contracts/src/v0.8/vendor/entrypoint/interfaces/IPaymaster.sol diff --git a/contracts/src/v0.8/dev/vendor/entrypoint/interfaces/IStakeManager.sol b/contracts/src/v0.8/vendor/entrypoint/interfaces/IStakeManager.sol similarity index 100% rename from contracts/src/v0.8/dev/vendor/entrypoint/interfaces/IStakeManager.sol rename to contracts/src/v0.8/vendor/entrypoint/interfaces/IStakeManager.sol diff --git a/contracts/src/v0.8/dev/vendor/entrypoint/interfaces/UserOperation.sol b/contracts/src/v0.8/vendor/entrypoint/interfaces/UserOperation.sol similarity index 100% rename from contracts/src/v0.8/dev/vendor/entrypoint/interfaces/UserOperation.sol rename to contracts/src/v0.8/vendor/entrypoint/interfaces/UserOperation.sol diff --git a/contracts/src/v0.8/dev/vendor/entrypoint/utils/Exec.sol b/contracts/src/v0.8/vendor/entrypoint/utils/Exec.sol similarity index 100% rename from contracts/src/v0.8/dev/vendor/entrypoint/utils/Exec.sol rename to contracts/src/v0.8/vendor/entrypoint/utils/Exec.sol diff --git a/contracts/src/v0.8/shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol b/contracts/src/v0.8/vendor/openzeppelin-contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol similarity index 100% rename from contracts/src/v0.8/shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol rename to contracts/src/v0.8/vendor/openzeppelin-contracts-upgradeable/v4.8.1/proxy/utils/Initializable.sol diff --git a/contracts/src/v0.8/shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/security/PausableUpgradeable.sol b/contracts/src/v0.8/vendor/openzeppelin-contracts-upgradeable/v4.8.1/security/PausableUpgradeable.sol similarity index 100% rename from contracts/src/v0.8/shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/security/PausableUpgradeable.sol rename to contracts/src/v0.8/vendor/openzeppelin-contracts-upgradeable/v4.8.1/security/PausableUpgradeable.sol diff --git a/contracts/src/v0.8/shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/utils/AddressUpgradeable.sol b/contracts/src/v0.8/vendor/openzeppelin-contracts-upgradeable/v4.8.1/utils/AddressUpgradeable.sol similarity index 100% rename from contracts/src/v0.8/shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/utils/AddressUpgradeable.sol rename to contracts/src/v0.8/vendor/openzeppelin-contracts-upgradeable/v4.8.1/utils/AddressUpgradeable.sol diff --git a/contracts/src/v0.8/shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/utils/ContextUpgradeable.sol b/contracts/src/v0.8/vendor/openzeppelin-contracts-upgradeable/v4.8.1/utils/ContextUpgradeable.sol similarity index 100% rename from contracts/src/v0.8/shared/vendor/@openzeppelin/contracts-upgradeable/v4.8.1/utils/ContextUpgradeable.sol rename to contracts/src/v0.8/vendor/openzeppelin-contracts-upgradeable/v4.8.1/utils/ContextUpgradeable.sol diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol new file mode 100644 index 00000000000..91bb8f82e54 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol) + +pragma solidity ^0.8.0; + +import "../utils/introspection/IERC165.sol"; \ No newline at end of file diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC20.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC20.sol new file mode 100644 index 00000000000..7c95dfca935 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC20.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol) + +pragma solidity ^0.8.0; + +import "../token/ERC20/IERC20.sol"; \ No newline at end of file diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/draft-IERC20Permit.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/draft-IERC20Permit.sol new file mode 100644 index 00000000000..84ac72c7f73 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/draft-IERC20Permit.sol @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/** + * @dev Standard ERC20 Errors + * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens. + */ +interface IERC20Errors { + /** + * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + * @param balance Current balance for the interacting account. + * @param needed Minimum amount required to perform a transfer. + */ + error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); + + /** + * @dev Indicates a failure with the token `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + */ + error ERC20InvalidSender(address sender); + + /** + * @dev Indicates a failure with the token `receiver`. Used in transfers. + * @param receiver Address to which tokens are being transferred. + */ + error ERC20InvalidReceiver(address receiver); + + /** + * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. + * @param spender Address that may be allowed to operate on tokens without being their owner. + * @param allowance Amount of tokens a `spender` is allowed to operate with. + * @param needed Minimum amount required to perform a transfer. + */ + error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); + + /** + * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. + * @param approver Address initiating an approval operation. + */ + error ERC20InvalidApprover(address approver); + + /** + * @dev Indicates a failure with the `spender` to be approved. Used in approvals. + * @param spender Address that may be allowed to operate on tokens without being their owner. + */ + error ERC20InvalidSpender(address spender); +} + +/** + * @dev Standard ERC721 Errors + * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens. + */ +interface IERC721Errors { + /** + * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20. + * Used in balance queries. + * @param owner Address of the current owner of a token. + */ + error ERC721InvalidOwner(address owner); + + /** + * @dev Indicates a `tokenId` whose `owner` is the zero address. + * @param tokenId Identifier number of a token. + */ + error ERC721NonexistentToken(uint256 tokenId); + + /** + * @dev Indicates an error related to the ownership over a particular token. Used in transfers. + * @param sender Address whose tokens are being transferred. + * @param tokenId Identifier number of a token. + * @param owner Address of the current owner of a token. + */ + error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); + + /** + * @dev Indicates a failure with the token `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + */ + error ERC721InvalidSender(address sender); + + /** + * @dev Indicates a failure with the token `receiver`. Used in transfers. + * @param receiver Address to which tokens are being transferred. + */ + error ERC721InvalidReceiver(address receiver); + + /** + * @dev Indicates a failure with the `operator`’s approval. Used in transfers. + * @param operator Address that may be allowed to operate on tokens without being their owner. + * @param tokenId Identifier number of a token. + */ + error ERC721InsufficientApproval(address operator, uint256 tokenId); + + /** + * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. + * @param approver Address initiating an approval operation. + */ + error ERC721InvalidApprover(address approver); + + /** + * @dev Indicates a failure with the `operator` to be approved. Used in approvals. + * @param operator Address that may be allowed to operate on tokens without being their owner. + */ + error ERC721InvalidOperator(address operator); +} + +/** + * @dev Standard ERC1155 Errors + * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens. + */ +interface IERC1155Errors { + /** + * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + * @param balance Current balance for the interacting account. + * @param needed Minimum amount required to perform a transfer. + * @param tokenId Identifier number of a token. + */ + error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); + + /** + * @dev Indicates a failure with the token `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + */ + error ERC1155InvalidSender(address sender); + + /** + * @dev Indicates a failure with the token `receiver`. Used in transfers. + * @param receiver Address to which tokens are being transferred. + */ + error ERC1155InvalidReceiver(address receiver); + + /** + * @dev Indicates a failure with the `operator`’s approval. Used in transfers. + * @param operator Address that may be allowed to operate on tokens without being their owner. + * @param owner Address of the current owner of a token. + */ + error ERC1155MissingApprovalForAll(address operator, address owner); + + /** + * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. + * @param approver Address initiating an approval operation. + */ + error ERC1155InvalidApprover(address approver); + + /** + * @dev Indicates a failure with the `operator` to be approved. Used in approvals. + * @param operator Address that may be allowed to operate on tokens without being their owner. + */ + error ERC1155InvalidOperator(address operator); + + /** + * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. + * Used in batch transfers. + * @param idsLength Length of the array of token identifiers + * @param valuesLength Length of the array of token amounts + */ + error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/mocks/ERC20Mock.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/mocks/ERC20Mock.sol new file mode 100644 index 00000000000..4db5eb2e066 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/mocks/ERC20Mock.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "../token/ERC20/ERC20.sol"; + +// mock class using ERC20 +contract ERC20Mock is ERC20 { + constructor( + string memory name, + string memory symbol, + address initialAccount, + uint256 initialBalance + ) payable ERC20(name, symbol) { + _mint(initialAccount, initialBalance); + } + + function mint(address account, uint256 amount) public { + _mint(account, amount); + } + + function burn(address account, uint256 amount) public { + _burn(account, amount); + } + + function transferInternal( + address from, + address to, + uint256 value + ) public { + _transfer(from, to, value); + } + + function approveInternal( + address owner, + address spender, + uint256 value + ) public { + _approve(owner, spender, value); + } +} \ No newline at end of file diff --git a/contracts/src/v0.8/shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/security/Pausable.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/security/Pausable.sol similarity index 100% rename from contracts/src/v0.8/shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/security/Pausable.sol rename to contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/security/Pausable.sol diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/ERC20.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/ERC20.sol new file mode 100644 index 00000000000..0e9b0776df5 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/ERC20.sol @@ -0,0 +1,365 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol) + +pragma solidity ^0.8.0; + +import "./IERC20.sol"; +import "./extensions/IERC20Metadata.sol"; +import "../../utils/Context.sol"; + +/** + * @dev Implementation of the {IERC20} interface. + * + * This implementation is agnostic to the way tokens are created. This means + * that a supply mechanism has to be added in a derived contract using {_mint}. + * For a generic mechanism see {ERC20PresetMinterPauser}. + * + * TIP: For a detailed writeup see our guide + * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How + * to implement supply mechanisms]. + * + * We have followed general OpenZeppelin Contracts guidelines: functions revert + * instead returning `false` on failure. This behavior is nonetheless + * conventional and does not conflict with the expectations of ERC20 + * applications. + * + * Additionally, an {Approval} event is emitted on calls to {transferFrom}. + * This allows applications to reconstruct the allowance for all accounts just + * by listening to said events. Other implementations of the EIP may not emit + * these events, as it isn't required by the specification. + * + * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} + * functions have been added to mitigate the well-known issues around setting + * allowances. See {IERC20-approve}. + */ +contract ERC20 is Context, IERC20, IERC20Metadata { + mapping(address => uint256) private _balances; + + mapping(address => mapping(address => uint256)) private _allowances; + + uint256 private _totalSupply; + + string private _name; + string private _symbol; + + /** + * @dev Sets the values for {name} and {symbol}. + * + * The default value of {decimals} is 18. To select a different value for + * {decimals} you should overload it. + * + * All two of these values are immutable: they can only be set once during + * construction. + */ + constructor(string memory name_, string memory symbol_) { + _name = name_; + _symbol = symbol_; + } + + /** + * @dev Returns the name of the token. + */ + function name() public view virtual override returns (string memory) { + return _name; + } + + /** + * @dev Returns the symbol of the token, usually a shorter version of the + * name. + */ + function symbol() public view virtual override returns (string memory) { + return _symbol; + } + + /** + * @dev Returns the number of decimals used to get its user representation. + * For example, if `decimals` equals `2`, a balance of `505` tokens should + * be displayed to a user as `5.05` (`505 / 10 ** 2`). + * + * Tokens usually opt for a value of 18, imitating the relationship between + * Ether and Wei. This is the value {ERC20} uses, unless this function is + * overridden; + * + * NOTE: This information is only used for _display_ purposes: it in + * no way affects any of the arithmetic of the contract, including + * {IERC20-balanceOf} and {IERC20-transfer}. + */ + function decimals() public view virtual override returns (uint8) { + return 18; + } + + /** + * @dev See {IERC20-totalSupply}. + */ + function totalSupply() public view virtual override returns (uint256) { + return _totalSupply; + } + + /** + * @dev See {IERC20-balanceOf}. + */ + function balanceOf(address account) public view virtual override returns (uint256) { + return _balances[account]; + } + + /** + * @dev See {IERC20-transfer}. + * + * Requirements: + * + * - `to` cannot be the zero address. + * - the caller must have a balance of at least `amount`. + */ + function transfer(address to, uint256 amount) public virtual override returns (bool) { + address owner = _msgSender(); + _transfer(owner, to, amount); + return true; + } + + /** + * @dev See {IERC20-allowance}. + */ + function allowance(address owner, address spender) public view virtual override returns (uint256) { + return _allowances[owner][spender]; + } + + /** + * @dev See {IERC20-approve}. + * + * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on + * `transferFrom`. This is semantically equivalent to an infinite approval. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function approve(address spender, uint256 amount) public virtual override returns (bool) { + address owner = _msgSender(); + _approve(owner, spender, amount); + return true; + } + + /** + * @dev See {IERC20-transferFrom}. + * + * Emits an {Approval} event indicating the updated allowance. This is not + * required by the EIP. See the note at the beginning of {ERC20}. + * + * NOTE: Does not update the allowance if the current allowance + * is the maximum `uint256`. + * + * Requirements: + * + * - `from` and `to` cannot be the zero address. + * - `from` must have a balance of at least `amount`. + * - the caller must have allowance for ``from``'s tokens of at least + * `amount`. + */ + function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { + address spender = _msgSender(); + _spendAllowance(from, spender, amount); + _transfer(from, to, amount); + return true; + } + + /** + * @dev Atomically increases the allowance granted to `spender` by the caller. + * + * This is an alternative to {approve} that can be used as a mitigation for + * problems described in {IERC20-approve}. + * + * Emits an {Approval} event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { + address owner = _msgSender(); + _approve(owner, spender, allowance(owner, spender) + addedValue); + return true; + } + + /** + * @dev Atomically decreases the allowance granted to `spender` by the caller. + * + * This is an alternative to {approve} that can be used as a mitigation for + * problems described in {IERC20-approve}. + * + * Emits an {Approval} event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. + * - `spender` must have allowance for the caller of at least + * `subtractedValue`. + */ + function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { + address owner = _msgSender(); + uint256 currentAllowance = allowance(owner, spender); + require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); + unchecked { + _approve(owner, spender, currentAllowance - subtractedValue); + } + + return true; + } + + /** + * @dev Moves `amount` of tokens from `from` to `to`. + * + * This internal function is equivalent to {transfer}, and can be used to + * e.g. implement automatic token fees, slashing mechanisms, etc. + * + * Emits a {Transfer} event. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `from` must have a balance of at least `amount`. + */ + function _transfer(address from, address to, uint256 amount) internal virtual { + require(from != address(0), "ERC20: transfer from the zero address"); + require(to != address(0), "ERC20: transfer to the zero address"); + + _beforeTokenTransfer(from, to, amount); + + uint256 fromBalance = _balances[from]; + require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); + unchecked { + _balances[from] = fromBalance - amount; + // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by + // decrementing then incrementing. + _balances[to] += amount; + } + + emit Transfer(from, to, amount); + + _afterTokenTransfer(from, to, amount); + } + + /** @dev Creates `amount` tokens and assigns them to `account`, increasing + * the total supply. + * + * Emits a {Transfer} event with `from` set to the zero address. + * + * Requirements: + * + * - `account` cannot be the zero address. + */ + function _mint(address account, uint256 amount) internal virtual { + require(account != address(0), "ERC20: mint to the zero address"); + + _beforeTokenTransfer(address(0), account, amount); + + _totalSupply += amount; + unchecked { + // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. + _balances[account] += amount; + } + emit Transfer(address(0), account, amount); + + _afterTokenTransfer(address(0), account, amount); + } + + /** + * @dev Destroys `amount` tokens from `account`, reducing the + * total supply. + * + * Emits a {Transfer} event with `to` set to the zero address. + * + * Requirements: + * + * - `account` cannot be the zero address. + * - `account` must have at least `amount` tokens. + */ + function _burn(address account, uint256 amount) internal virtual { + require(account != address(0), "ERC20: burn from the zero address"); + + _beforeTokenTransfer(account, address(0), amount); + + uint256 accountBalance = _balances[account]; + require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); + unchecked { + _balances[account] = accountBalance - amount; + // Overflow not possible: amount <= accountBalance <= totalSupply. + _totalSupply -= amount; + } + + emit Transfer(account, address(0), amount); + + _afterTokenTransfer(account, address(0), amount); + } + + /** + * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. + * + * This internal function is equivalent to `approve`, and can be used to + * e.g. set automatic allowances for certain subsystems, etc. + * + * Emits an {Approval} event. + * + * Requirements: + * + * - `owner` cannot be the zero address. + * - `spender` cannot be the zero address. + */ + function _approve(address owner, address spender, uint256 amount) internal virtual { + require(owner != address(0), "ERC20: approve from the zero address"); + require(spender != address(0), "ERC20: approve to the zero address"); + + _allowances[owner][spender] = amount; + emit Approval(owner, spender, amount); + } + + /** + * @dev Updates `owner` s allowance for `spender` based on spent `amount`. + * + * Does not update the allowance amount in case of infinite allowance. + * Revert if not enough allowance is available. + * + * Might emit an {Approval} event. + */ + function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { + uint256 currentAllowance = allowance(owner, spender); + if (currentAllowance != type(uint256).max) { + require(currentAllowance >= amount, "ERC20: insufficient allowance"); + unchecked { + _approve(owner, spender, currentAllowance - amount); + } + } + } + + /** + * @dev Hook that is called before any transfer of tokens. This includes + * minting and burning. + * + * Calling conditions: + * + * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens + * will be transferred to `to`. + * - when `from` is zero, `amount` tokens will be minted for `to`. + * - when `to` is zero, `amount` of ``from``'s tokens will be burned. + * - `from` and `to` are never both zero. + * + * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. + */ + function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} + + /** + * @dev Hook that is called after any transfer of tokens. This includes + * minting and burning. + * + * Calling conditions: + * + * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens + * has been transferred to `to`. + * - when `from` is zero, `amount` tokens have been minted for `to`. + * - when `to` is zero, `amount` of ``from``'s tokens have been burned. + * - `from` and `to` are never both zero. + * + * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. + */ + function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {} +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/IERC20.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/IERC20.sol new file mode 100644 index 00000000000..536ba0b96cd --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/IERC20.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) + +pragma solidity ^0.8.0; + +/** + * @dev Interface of the ERC20 standard as defined in the EIP. + */ +interface IERC20 { + /** + * @dev Emitted when `value` tokens are moved from one account (`from`) to + * another (`to`). + * + * Note that `value` may be zero. + */ + event Transfer(address indexed from, address indexed to, uint256 value); + + /** + * @dev Emitted when the allowance of a `spender` for an `owner` is set by + * a call to {approve}. `value` is the new allowance. + */ + event Approval(address indexed owner, address indexed spender, uint256 value); + + /** + * @dev Returns the amount of tokens in existence. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns the amount of tokens owned by `account`. + */ + function balanceOf(address account) external view returns (uint256); + + /** + * @dev Moves `amount` tokens from the caller's account to `to`. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transfer(address to, uint256 amount) external returns (bool); + + /** + * @dev Returns the remaining number of tokens that `spender` will be + * allowed to spend on behalf of `owner` through {transferFrom}. This is + * zero by default. + * + * This value changes when {approve} or {transferFrom} are called. + */ + function allowance(address owner, address spender) external view returns (uint256); + + /** + * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * IMPORTANT: Beware that changing an allowance with this method brings the risk + * that someone may use both the old and the new allowance by unfortunate + * transaction ordering. One possible solution to mitigate this race + * condition is to first reduce the spender's allowance to 0 and set the + * desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * + * Emits an {Approval} event. + */ + function approve(address spender, uint256 amount) external returns (bool); + + /** + * @dev Moves `amount` tokens from `from` to `to` using the + * allowance mechanism. `amount` is then deducted from the caller's + * allowance. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transferFrom(address from, address to, uint256 amount) external returns (bool); +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/ERC20Burnable.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/ERC20Burnable.sol new file mode 100644 index 00000000000..e7752729b42 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/ERC20Burnable.sol @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol) + +pragma solidity ^0.8.0; + +import "../ERC20.sol"; +import "../../../utils/Context.sol"; + +/** + * @dev Extension of {ERC20} that allows token holders to destroy both their own + * tokens and those that they have an allowance for, in a way that can be + * recognized off-chain (via event analysis). + */ +abstract contract ERC20Burnable is Context, ERC20 { + /** + * @dev Destroys `amount` tokens from the caller. + * + * See {ERC20-_burn}. + */ + function burn(uint256 amount) public virtual { + _burn(_msgSender(), amount); + } + + /** + * @dev Destroys `amount` tokens from `account`, deducting from the caller's + * allowance. + * + * See {ERC20-_burn} and {ERC20-allowance}. + * + * Requirements: + * + * - the caller must have allowance for ``accounts``'s tokens of at least + * `amount`. + */ + function burnFrom(address account, uint256 amount) public virtual { + _spendAllowance(account, _msgSender(), amount); + _burn(account, amount); + } +} \ No newline at end of file diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/IERC20Metadata.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/IERC20Metadata.sol new file mode 100644 index 00000000000..6e29892a1c2 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/IERC20Metadata.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) + +pragma solidity ^0.8.0; + +import "../IERC20.sol"; + +/** + * @dev Interface for the optional metadata functions from the ERC20 standard. + * + * _Available since v4.1._ + */ +interface IERC20Metadata is IERC20 { + /** + * @dev Returns the name of the token. + */ + function name() external view returns (string memory); + + /** + * @dev Returns the symbol of the token. + */ + function symbol() external view returns (string memory); + + /** + * @dev Returns the decimals places of the token. + */ + function decimals() external view returns (uint8); +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/draft-ERC20Permit.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/draft-ERC20Permit.sol new file mode 100644 index 00000000000..3c29ed05668 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/draft-ERC20Permit.sol @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/extensions/draft-ERC20Permit.sol) + +pragma solidity ^0.8.0; + +import "./draft-IERC20Permit.sol"; +import "../ERC20.sol"; +import "../../../utils/cryptography/ECDSA.sol"; +import "../../../utils/cryptography/EIP712.sol"; +import "../../../utils/Counters.sol"; + +/** + * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in + * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. + * + * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by + * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't + * need to send a transaction, and thus is not required to hold Ether at all. + * + * _Available since v3.4._ + */ +abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 { + using Counters for Counters.Counter; + + mapping(address => Counters.Counter) private _nonces; + + // solhint-disable-next-line var-name-mixedcase + bytes32 private constant _PERMIT_TYPEHASH = + keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); + /** + * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`. + * However, to ensure consistency with the upgradeable transpiler, we will continue + * to reserve a slot. + * @custom:oz-renamed-from _PERMIT_TYPEHASH + */ + // solhint-disable-next-line var-name-mixedcase + bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT; + + /** + * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`. + * + * It's a good idea to use the same `name` that is defined as the ERC20 token name. + */ + constructor(string memory name) EIP712(name, "1") {} + + /** + * @dev See {IERC20Permit-permit}. + */ + function permit( + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) public virtual override { + require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); + + bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline)); + + bytes32 hash = _hashTypedDataV4(structHash); + + address signer = ECDSA.recover(hash, v, r, s); + require(signer == owner, "ERC20Permit: invalid signature"); + + _approve(owner, spender, value); + } + + /** + * @dev See {IERC20Permit-nonces}. + */ + function nonces(address owner) public view virtual override returns (uint256) { + return _nonces[owner].current(); + } + + /** + * @dev See {IERC20Permit-DOMAIN_SEPARATOR}. + */ + // solhint-disable-next-line func-name-mixedcase + function DOMAIN_SEPARATOR() external view override returns (bytes32) { + return _domainSeparatorV4(); + } + + /** + * @dev "Consume a nonce": return the current value and increment. + * + * _Available since v4.1._ + */ + function _useNonce(address owner) internal virtual returns (uint256 current) { + Counters.Counter storage nonce = _nonces[owner]; + current = nonce.current(); + nonce.increment(); + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/draft-IERC20Permit.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/draft-IERC20Permit.sol new file mode 100644 index 00000000000..b14bbfe20a0 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/draft-IERC20Permit.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) + +pragma solidity ^0.8.0; + +/** + * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in + * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. + * + * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by + * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't + * need to send a transaction, and thus is not required to hold Ether at all. + */ +interface IERC20Permit { + /** + * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, + * given ``owner``'s signed approval. + * + * IMPORTANT: The same issues {IERC20-approve} has related to transaction + * ordering also apply here. + * + * Emits an {Approval} event. + * + * Requirements: + * + * - `spender` cannot be the zero address. + * - `deadline` must be a timestamp in the future. + * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` + * over the EIP712-formatted function arguments. + * - the signature must use ``owner``'s current nonce (see {nonces}). + * + * For more information on the signature format, see the + * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP + * section]. + */ + function permit( + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) external; + + /** + * @dev Returns the current nonce for `owner`. This value must be + * included whenever a signature is generated for {permit}. + * + * Every successful call to {permit} increases ``owner``'s nonce by one. This + * prevents a signature from being used multiple times. + */ + function nonces(address owner) external view returns (uint256); + + /** + * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. + */ + // solhint-disable-next-line func-name-mixedcase + function DOMAIN_SEPARATOR() external view returns (bytes32); +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol new file mode 100644 index 00000000000..2a6939eda04 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) + +pragma solidity ^0.8.0; + +import "../IERC20.sol"; +import "../extensions/draft-IERC20Permit.sol"; +import "../../../utils/Address.sol"; + +/** + * @title SafeERC20 + * @dev Wrappers around ERC20 operations that throw on failure (when the token + * contract returns false). Tokens that return no value (and instead revert or + * throw on failure) are also supported, non-reverting calls are assumed to be + * successful. + * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, + * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. + */ +library SafeERC20 { + using Address for address; + + function safeTransfer(IERC20 token, address to, uint256 value) internal { + _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); + } + + function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { + _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); + } + + /** + * @dev Deprecated. This function has issues similar to the ones found in + * {IERC20-approve}, and its usage is discouraged. + * + * Whenever possible, use {safeIncreaseAllowance} and + * {safeDecreaseAllowance} instead. + */ + function safeApprove(IERC20 token, address spender, uint256 value) internal { + // safeApprove should only be called when setting an initial allowance, + // or when resetting it to zero. To increase and decrease it, use + // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' + require( + (value == 0) || (token.allowance(address(this), spender) == 0), + "SafeERC20: approve from non-zero to non-zero allowance" + ); + _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); + } + + function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { + uint256 newAllowance = token.allowance(address(this), spender) + value; + _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); + } + + function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { + unchecked { + uint256 oldAllowance = token.allowance(address(this), spender); + require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); + uint256 newAllowance = oldAllowance - value; + _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); + } + } + + function safePermit( + IERC20Permit token, + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) internal { + uint256 nonceBefore = token.nonces(owner); + token.permit(owner, spender, value, deadline, v, r, s); + uint256 nonceAfter = token.nonces(owner); + require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); + } + + /** + * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement + * on the return value: the return value is optional (but if data is returned, it must not be false). + * @param token The token targeted by the call. + * @param data The call data (encoded using abi.encode or one of its variants). + */ + function _callOptionalReturn(IERC20 token, bytes memory data) private { + // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since + // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that + // the target address contains contract code and also asserts for success in the low-level call. + + bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); + if (returndata.length > 0) { + // Return data is optional + require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); + } + } +} diff --git a/contracts/src/v0.8/dev/vendor/openzeppelin-solidity/v4.3.1/contracts/utils/Address.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Address.sol similarity index 68% rename from contracts/src/v0.8/dev/vendor/openzeppelin-solidity/v4.3.1/contracts/utils/Address.sol rename to contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Address.sol index 5b9c5b3ba9c..d966c06d995 100644 --- a/contracts/src/v0.8/dev/vendor/openzeppelin-solidity/v4.3.1/contracts/utils/Address.sol +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Address.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) -pragma solidity ^0.8.0; +pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type @@ -22,17 +23,22 @@ library Address { * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== + * + * [IMPORTANT] + * ==== + * You shouldn't rely on `isContract` to protect against flash loan attacks! + * + * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets + * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract + * constructor. + * ==== */ function isContract(address account) internal view returns (bool) { - // This method relies on extcodesize, which returns 0 for contracts in - // construction, since the code is only stored at the end of the - // constructor execution. + // This method relies on extcodesize/address.code.length, which returns 0 + // for contracts in construction, since the code is only stored at the end + // of the constructor execution. - uint256 size; - assembly { - size := extcodesize(account) - } - return size > 0; + return account.code.length > 0; } /** @@ -77,7 +83,7 @@ library Address { * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { - return functionCall(target, data, "Address: low-level call failed"); + return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** @@ -86,11 +92,7 @@ library Address { * * _Available since v3.1._ */ - function functionCall( - address target, - bytes memory data, - string memory errorMessage - ) internal returns (bytes memory) { + function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } @@ -105,11 +107,7 @@ library Address { * * _Available since v3.1._ */ - function functionCallWithValue( - address target, - bytes memory data, - uint256 value - ) internal returns (bytes memory) { + function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } @@ -126,10 +124,8 @@ library Address { string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); - require(isContract(target), "Address: call to non-contract"); - (bool success, bytes memory returndata) = target.call{value: value}(data); - return verifyCallResult(success, returndata, errorMessage); + return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** @@ -153,10 +149,8 @@ library Address { bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { - require(isContract(target), "Address: static call to non-contract"); - (bool success, bytes memory returndata) = target.staticcall(data); - return verifyCallResult(success, returndata, errorMessage); + return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** @@ -180,15 +174,37 @@ library Address { bytes memory data, string memory errorMessage ) internal returns (bytes memory) { - require(isContract(target), "Address: delegate call to non-contract"); - (bool success, bytes memory returndata) = target.delegatecall(data); - return verifyCallResult(success, returndata, errorMessage); + return verifyCallResultFromTarget(target, success, returndata, errorMessage); + } + + /** + * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling + * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. + * + * _Available since v4.8._ + */ + function verifyCallResultFromTarget( + address target, + bool success, + bytes memory returndata, + string memory errorMessage + ) internal view returns (bytes memory) { + if (success) { + if (returndata.length == 0) { + // only check isContract if the call was successful and the return data is empty + // otherwise we already know that it was a contract + require(isContract(target), "Address: call to non-contract"); + } + return returndata; + } else { + _revert(returndata, errorMessage); + } } /** - * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the - * revert reason using the provided one. + * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the + * revert reason or using the provided one. * * _Available since v4.3._ */ @@ -200,17 +216,21 @@ library Address { if (success) { return returndata; } else { - // Look for revert reason and bubble it up if present - if (returndata.length > 0) { - // The easiest way to bubble the revert reason is using memory via assembly - - assembly { - let returndata_size := mload(returndata) - revert(add(32, returndata), returndata_size) - } - } else { - revert(errorMessage); + _revert(returndata, errorMessage); + } + } + + function _revert(bytes memory returndata, string memory errorMessage) private pure { + // Look for revert reason and bubble it up if present + if (returndata.length > 0) { + // The easiest way to bubble the revert reason is using memory via assembly + /// @solidity memory-safe-assembly + assembly { + let returndata_size := mload(returndata) + revert(add(32, returndata), returndata_size) } + } else { + revert(errorMessage); } } } diff --git a/contracts/src/v0.8/shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/utils/Context.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Context.sol similarity index 100% rename from contracts/src/v0.8/shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/utils/Context.sol rename to contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Context.sol diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Counters.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Counters.sol new file mode 100644 index 00000000000..ea330e9d2d7 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Counters.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) + +pragma solidity ^0.8.0; + +/** + * @title Counters + * @author Matt Condon (@shrugs) + * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number + * of elements in a mapping, issuing ERC721 ids, or counting request ids. + * + * Include with `using Counters for Counters.Counter;` + */ +library Counters { + struct Counter { + // This variable should never be directly accessed by users of the library: interactions must be restricted to + // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add + // this feature: see https://github.com/ethereum/solidity/issues/4637 + uint256 _value; // default: 0 + } + + function current(Counter storage counter) internal view returns (uint256) { + return counter._value; + } + + function increment(Counter storage counter) internal { + unchecked { + counter._value += 1; + } + } + + function decrement(Counter storage counter) internal { + uint256 value = counter._value; + require(value > 0, "Counter: decrement overflow"); + unchecked { + counter._value = value - 1; + } + } + + function reset(Counter storage counter) internal { + counter._value = 0; + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/StorageSlot.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/StorageSlot.sol new file mode 100644 index 00000000000..7e91bc6298c --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/StorageSlot.sol @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) + +pragma solidity ^0.8.0; + +/** + * @dev Library for reading and writing primitive types to specific storage slots. + * + * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. + * This library helps with reading and writing to such slots without the need for inline assembly. + * + * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. + * + * Example usage to set ERC1967 implementation slot: + * ``` + * contract ERC1967 { + * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; + * + * function _getImplementation() internal view returns (address) { + * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; + * } + * + * function _setImplementation(address newImplementation) internal { + * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); + * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; + * } + * } + * ``` + * + * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ + */ +library StorageSlot { + struct AddressSlot { + address value; + } + + struct BooleanSlot { + bool value; + } + + struct Bytes32Slot { + bytes32 value; + } + + struct Uint256Slot { + uint256 value; + } + + /** + * @dev Returns an `AddressSlot` with member `value` located at `slot`. + */ + function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { + /// @solidity memory-safe-assembly + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `BooleanSlot` with member `value` located at `slot`. + */ + function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { + /// @solidity memory-safe-assembly + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. + */ + function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { + /// @solidity memory-safe-assembly + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `Uint256Slot` with member `value` located at `slot`. + */ + function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { + /// @solidity memory-safe-assembly + assembly { + r.slot := slot + } + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Strings.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Strings.sol new file mode 100644 index 00000000000..377ba46ad3b --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Strings.sol @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) + +pragma solidity ^0.8.0; + +import "./math/Math.sol"; + +/** + * @dev String operations. + */ +library Strings { + bytes16 private constant _SYMBOLS = "0123456789abcdef"; + uint8 private constant _ADDRESS_LENGTH = 20; + + /** + * @dev Converts a `uint256` to its ASCII `string` decimal representation. + */ + function toString(uint256 value) internal pure returns (string memory) { + unchecked { + uint256 length = Math.log10(value) + 1; + string memory buffer = new string(length); + uint256 ptr; + /// @solidity memory-safe-assembly + assembly { + ptr := add(buffer, add(32, length)) + } + while (true) { + ptr--; + /// @solidity memory-safe-assembly + assembly { + mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) + } + value /= 10; + if (value == 0) break; + } + return buffer; + } + } + + /** + * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. + */ + function toHexString(uint256 value) internal pure returns (string memory) { + unchecked { + return toHexString(value, Math.log256(value) + 1); + } + } + + /** + * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. + */ + function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { + bytes memory buffer = new bytes(2 * length + 2); + buffer[0] = "0"; + buffer[1] = "x"; + for (uint256 i = 2 * length + 1; i > 1; --i) { + buffer[i] = _SYMBOLS[value & 0xf]; + value >>= 4; + } + require(value == 0, "Strings: hex length insufficient"); + return string(buffer); + } + + /** + * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. + */ + function toHexString(address addr) internal pure returns (string memory) { + return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/cryptography/ECDSA.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/cryptography/ECDSA.sol new file mode 100644 index 00000000000..65d4b81b7fd --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/cryptography/ECDSA.sol @@ -0,0 +1,195 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol) + +pragma solidity ^0.8.0; + +import "../Strings.sol"; + +/** + * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. + * + * These functions can be used to verify that a message was signed by the holder + * of the private keys of a given address. + */ +library ECDSA { + enum RecoverError { + NoError, + InvalidSignature, + InvalidSignatureLength, + InvalidSignatureS, + InvalidSignatureV // Deprecated in v4.8 + } + + function _throwError(RecoverError error) private pure { + if (error == RecoverError.NoError) { + return; // no error: do nothing + } else if (error == RecoverError.InvalidSignature) { + revert("ECDSA: invalid signature"); + } else if (error == RecoverError.InvalidSignatureLength) { + revert("ECDSA: invalid signature length"); + } else if (error == RecoverError.InvalidSignatureS) { + revert("ECDSA: invalid signature 's' value"); + } + } + + /** + * @dev Returns the address that signed a hashed message (`hash`) with + * `signature` or error string. This address can then be used for verification purposes. + * + * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: + * this function rejects them by requiring the `s` value to be in the lower + * half order, and the `v` value to be either 27 or 28. + * + * IMPORTANT: `hash` _must_ be the result of a hash operation for the + * verification to be secure: it is possible to craft signatures that + * recover to arbitrary addresses for non-hashed data. A safe way to ensure + * this is by receiving a hash of the original message (which may otherwise + * be too long), and then calling {toEthSignedMessageHash} on it. + * + * Documentation for signature generation: + * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] + * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] + * + * _Available since v4.3._ + */ + function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { + if (signature.length == 65) { + bytes32 r; + bytes32 s; + uint8 v; + // ecrecover takes the signature parameters, and the only way to get them + // currently is to use assembly. + /// @solidity memory-safe-assembly + assembly { + r := mload(add(signature, 0x20)) + s := mload(add(signature, 0x40)) + v := byte(0, mload(add(signature, 0x60))) + } + return tryRecover(hash, v, r, s); + } else { + return (address(0), RecoverError.InvalidSignatureLength); + } + } + + /** + * @dev Returns the address that signed a hashed message (`hash`) with + * `signature`. This address can then be used for verification purposes. + * + * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: + * this function rejects them by requiring the `s` value to be in the lower + * half order, and the `v` value to be either 27 or 28. + * + * IMPORTANT: `hash` _must_ be the result of a hash operation for the + * verification to be secure: it is possible to craft signatures that + * recover to arbitrary addresses for non-hashed data. A safe way to ensure + * this is by receiving a hash of the original message (which may otherwise + * be too long), and then calling {toEthSignedMessageHash} on it. + */ + function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { + (address recovered, RecoverError error) = tryRecover(hash, signature); + _throwError(error); + return recovered; + } + + /** + * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. + * + * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] + * + * _Available since v4.3._ + */ + function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { + bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); + uint8 v = uint8((uint256(vs) >> 255) + 27); + return tryRecover(hash, v, r, s); + } + + /** + * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. + * + * _Available since v4.2._ + */ + function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { + (address recovered, RecoverError error) = tryRecover(hash, r, vs); + _throwError(error); + return recovered; + } + + /** + * @dev Overload of {ECDSA-tryRecover} that receives the `v`, + * `r` and `s` signature fields separately. + * + * _Available since v4.3._ + */ + function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { + // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature + // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines + // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most + // signatures from current libraries generate a unique signature with an s-value in the lower half order. + // + // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value + // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or + // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept + // these malleable signatures as well. + if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { + return (address(0), RecoverError.InvalidSignatureS); + } + + // If the signature is valid (and not malleable), return the signer address + address signer = ecrecover(hash, v, r, s); + if (signer == address(0)) { + return (address(0), RecoverError.InvalidSignature); + } + + return (signer, RecoverError.NoError); + } + + /** + * @dev Overload of {ECDSA-recover} that receives the `v`, + * `r` and `s` signature fields separately. + */ + function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { + (address recovered, RecoverError error) = tryRecover(hash, v, r, s); + _throwError(error); + return recovered; + } + + /** + * @dev Returns an Ethereum Signed Message, created from a `hash`. This + * produces hash corresponding to the one signed with the + * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] + * JSON-RPC method as part of EIP-191. + * + * See {recover}. + */ + function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { + // 32 is the length in bytes of hash, + // enforced by the type signature above + return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); + } + + /** + * @dev Returns an Ethereum Signed Message, created from `s`. This + * produces hash corresponding to the one signed with the + * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] + * JSON-RPC method as part of EIP-191. + * + * See {recover}. + */ + function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { + return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); + } + + /** + * @dev Returns an Ethereum Signed Typed Data, created from a + * `domainSeparator` and a `structHash`. This produces hash corresponding + * to the one signed with the + * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] + * JSON-RPC method as part of EIP-712. + * + * See {recover}. + */ + function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { + return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/cryptography/EIP712.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/cryptography/EIP712.sol new file mode 100644 index 00000000000..6924570ec04 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/cryptography/EIP712.sol @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/EIP712.sol) + +pragma solidity ^0.8.0; + +import "./ECDSA.sol"; + +/** + * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. + * + * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, + * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding + * they need in their contracts using a combination of `abi.encode` and `keccak256`. + * + * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding + * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA + * ({_hashTypedDataV4}). + * + * The implementation of the domain separator was designed to be as efficient as possible while still properly updating + * the chain id to protect against replay attacks on an eventual fork of the chain. + * + * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method + * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. + * + * _Available since v3.4._ + */ +abstract contract EIP712 { + /* solhint-disable var-name-mixedcase */ + // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to + // invalidate the cached domain separator if the chain id changes. + bytes32 private immutable _CACHED_DOMAIN_SEPARATOR; + uint256 private immutable _CACHED_CHAIN_ID; + address private immutable _CACHED_THIS; + + bytes32 private immutable _HASHED_NAME; + bytes32 private immutable _HASHED_VERSION; + bytes32 private immutable _TYPE_HASH; + + /* solhint-enable var-name-mixedcase */ + + /** + * @dev Initializes the domain separator and parameter caches. + * + * The meaning of `name` and `version` is specified in + * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: + * + * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. + * - `version`: the current major version of the signing domain. + * + * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart + * contract upgrade]. + */ + constructor(string memory name, string memory version) { + bytes32 hashedName = keccak256(bytes(name)); + bytes32 hashedVersion = keccak256(bytes(version)); + bytes32 typeHash = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); + _HASHED_NAME = hashedName; + _HASHED_VERSION = hashedVersion; + _CACHED_CHAIN_ID = block.chainid; + _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion); + _CACHED_THIS = address(this); + _TYPE_HASH = typeHash; + } + + /** + * @dev Returns the domain separator for the current chain. + */ + function _domainSeparatorV4() internal view returns (bytes32) { + if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) { + return _CACHED_DOMAIN_SEPARATOR; + } else { + return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION); + } + } + + function _buildDomainSeparator( + bytes32 typeHash, + bytes32 nameHash, + bytes32 versionHash + ) private view returns (bytes32) { + return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this))); + } + + /** + * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this + * function returns the hash of the fully encoded EIP712 message for this domain. + * + * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: + * + * ```solidity + * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( + * keccak256("Mail(address to,string contents)"), + * mailTo, + * keccak256(bytes(mailContents)) + * ))); + * address signer = ECDSA.recover(digest, signature); + * ``` + */ + function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { + return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash); + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/introspection/IERC165.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/introspection/IERC165.sol new file mode 100644 index 00000000000..5fa65516d27 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/introspection/IERC165.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) + +pragma solidity ^0.8.0; + +/** + * @dev Interface of the ERC165 standard, as defined in the + * https://eips.ethereum.org/EIPS/eip-165[EIP]. + * + * Implementers can declare support of contract interfaces, which can then be + * queried by others ({ERC165Checker}). + * + * For an implementation, see {ERC165}. + */ +interface IERC165 { + /** + * @dev Returns true if this contract implements the interface defined by + * `interfaceId`. See the corresponding + * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] + * to learn more about how these ids are created. + * + * This function call must use less than 30 000 gas. + */ + function supportsInterface(bytes4 interfaceId) external view returns (bool); +} \ No newline at end of file diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/Math.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/Math.sol new file mode 100644 index 00000000000..7a793295ae1 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/Math.sol @@ -0,0 +1,336 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) + +pragma solidity ^0.8.0; + +/** + * @dev Standard math utilities missing in the Solidity language. + */ +library Math { + enum Rounding { + Down, // Toward negative infinity + Up, // Toward infinity + Zero // Toward zero + } + + /** + * @dev Returns the largest of two numbers. + */ + function max(uint256 a, uint256 b) internal pure returns (uint256) { + return a > b ? a : b; + } + + /** + * @dev Returns the smallest of two numbers. + */ + function min(uint256 a, uint256 b) internal pure returns (uint256) { + return a < b ? a : b; + } + + /** + * @dev Returns the average of two numbers. The result is rounded towards + * zero. + */ + function average(uint256 a, uint256 b) internal pure returns (uint256) { + // (a + b) / 2 can overflow. + return (a & b) + (a ^ b) / 2; + } + + /** + * @dev Returns the ceiling of the division of two numbers. + * + * This differs from standard division with `/` in that it rounds up instead + * of rounding down. + */ + function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { + // (a + b - 1) / b can overflow on addition, so we distribute. + return a == 0 ? 0 : (a - 1) / b + 1; + } + + /** + * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 + * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) + * with further edits by Uniswap Labs also under MIT license. + */ + function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { + unchecked { + // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use + // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 + // variables such that product = prod1 * 2^256 + prod0. + uint256 prod0; // Least significant 256 bits of the product + uint256 prod1; // Most significant 256 bits of the product + assembly { + let mm := mulmod(x, y, not(0)) + prod0 := mul(x, y) + prod1 := sub(sub(mm, prod0), lt(mm, prod0)) + } + + // Handle non-overflow cases, 256 by 256 division. + if (prod1 == 0) { + return prod0 / denominator; + } + + // Make sure the result is less than 2^256. Also prevents denominator == 0. + require(denominator > prod1); + + /////////////////////////////////////////////// + // 512 by 256 division. + /////////////////////////////////////////////// + + // Make division exact by subtracting the remainder from [prod1 prod0]. + uint256 remainder; + assembly { + // Compute remainder using mulmod. + remainder := mulmod(x, y, denominator) + + // Subtract 256 bit number from 512 bit number. + prod1 := sub(prod1, gt(remainder, prod0)) + prod0 := sub(prod0, remainder) + } + + // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. + // See https://cs.stackexchange.com/q/138556/92363. + + // Does not overflow because the denominator cannot be zero at this stage in the function. + uint256 twos = denominator & (~denominator + 1); + assembly { + // Divide denominator by twos. + denominator := div(denominator, twos) + + // Divide [prod1 prod0] by twos. + prod0 := div(prod0, twos) + + // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. + twos := add(div(sub(0, twos), twos), 1) + } + + // Shift in bits from prod1 into prod0. + prod0 |= prod1 * twos; + + // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such + // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for + // four bits. That is, denominator * inv = 1 mod 2^4. + uint256 inverse = (3 * denominator) ^ 2; + + // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works + // in modular arithmetic, doubling the correct bits in each step. + inverse *= 2 - denominator * inverse; // inverse mod 2^8 + inverse *= 2 - denominator * inverse; // inverse mod 2^16 + inverse *= 2 - denominator * inverse; // inverse mod 2^32 + inverse *= 2 - denominator * inverse; // inverse mod 2^64 + inverse *= 2 - denominator * inverse; // inverse mod 2^128 + inverse *= 2 - denominator * inverse; // inverse mod 2^256 + + // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. + // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is + // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 + // is no longer required. + result = prod0 * inverse; + return result; + } + } + + /** + * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. + */ + function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { + uint256 result = mulDiv(x, y, denominator); + if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { + result += 1; + } + return result; + } + + /** + * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. + * + * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). + */ + function sqrt(uint256 a) internal pure returns (uint256) { + if (a == 0) { + return 0; + } + + // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. + // + // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have + // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. + // + // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` + // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` + // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` + // + // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. + uint256 result = 1 << (log2(a) >> 1); + + // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, + // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at + // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision + // into the expected uint128 result. + unchecked { + result = (result + a / result) >> 1; + result = (result + a / result) >> 1; + result = (result + a / result) >> 1; + result = (result + a / result) >> 1; + result = (result + a / result) >> 1; + result = (result + a / result) >> 1; + result = (result + a / result) >> 1; + return min(result, a / result); + } + } + + /** + * @notice Calculates sqrt(a), following the selected rounding direction. + */ + function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { + unchecked { + uint256 result = sqrt(a); + return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); + } + } + + /** + * @dev Return the log in base 2, rounded down, of a positive value. + * Returns 0 if given 0. + */ + function log2(uint256 value) internal pure returns (uint256) { + uint256 result = 0; + unchecked { + if (value >> 128 > 0) { + value >>= 128; + result += 128; + } + if (value >> 64 > 0) { + value >>= 64; + result += 64; + } + if (value >> 32 > 0) { + value >>= 32; + result += 32; + } + if (value >> 16 > 0) { + value >>= 16; + result += 16; + } + if (value >> 8 > 0) { + value >>= 8; + result += 8; + } + if (value >> 4 > 0) { + value >>= 4; + result += 4; + } + if (value >> 2 > 0) { + value >>= 2; + result += 2; + } + if (value >> 1 > 0) { + result += 1; + } + } + return result; + } + + /** + * @dev Return the log in base 2, following the selected rounding direction, of a positive value. + * Returns 0 if given 0. + */ + function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { + unchecked { + uint256 result = log2(value); + return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); + } + } + + /** + * @dev Return the log in base 10, rounded down, of a positive value. + * Returns 0 if given 0. + */ + function log10(uint256 value) internal pure returns (uint256) { + uint256 result = 0; + unchecked { + if (value >= 10 ** 64) { + value /= 10 ** 64; + result += 64; + } + if (value >= 10 ** 32) { + value /= 10 ** 32; + result += 32; + } + if (value >= 10 ** 16) { + value /= 10 ** 16; + result += 16; + } + if (value >= 10 ** 8) { + value /= 10 ** 8; + result += 8; + } + if (value >= 10 ** 4) { + value /= 10 ** 4; + result += 4; + } + if (value >= 10 ** 2) { + value /= 10 ** 2; + result += 2; + } + if (value >= 10 ** 1) { + result += 1; + } + } + return result; + } + + /** + * @dev Return the log in base 10, following the selected rounding direction, of a positive value. + * Returns 0 if given 0. + */ + function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { + unchecked { + uint256 result = log10(value); + return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); + } + } + + /** + * @dev Return the log in base 256, rounded down, of a positive value. + * Returns 0 if given 0. + * + * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. + */ + function log256(uint256 value) internal pure returns (uint256) { + uint256 result = 0; + unchecked { + if (value >> 128 > 0) { + value >>= 128; + result += 16; + } + if (value >> 64 > 0) { + value >>= 64; + result += 8; + } + if (value >> 32 > 0) { + value >>= 32; + result += 4; + } + if (value >> 16 > 0) { + value >>= 16; + result += 2; + } + if (value >> 8 > 0) { + result += 1; + } + } + return result; + } + + /** + * @dev Return the log in base 10, following the selected rounding direction, of a positive value. + * Returns 0 if given 0. + */ + function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { + unchecked { + uint256 result = log256(value); + return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); + } + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/SafeCast.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/SafeCast.sol new file mode 100644 index 00000000000..28c11118317 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/SafeCast.sol @@ -0,0 +1,1136 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol) +// This file was procedurally generated from scripts/generate/templates/SafeCast.js. + +pragma solidity ^0.8.0; + +/** + * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow + * checks. + * + * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can + * easily result in undesired exploitation or bugs, since developers usually + * assume that overflows raise errors. `SafeCast` restores this intuition by + * reverting the transaction when such an operation overflows. + * + * Using this library instead of the unchecked operations eliminates an entire + * class of bugs, so it's recommended to use it always. + * + * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing + * all math on `uint256` and `int256` and then downcasting. + */ +library SafeCast { + /** + * @dev Returns the downcasted uint248 from uint256, reverting on + * overflow (when the input is greater than largest uint248). + * + * Counterpart to Solidity's `uint248` operator. + * + * Requirements: + * + * - input must fit into 248 bits + * + * _Available since v4.7._ + */ + function toUint248(uint256 value) internal pure returns (uint248) { + require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits"); + return uint248(value); + } + + /** + * @dev Returns the downcasted uint240 from uint256, reverting on + * overflow (when the input is greater than largest uint240). + * + * Counterpart to Solidity's `uint240` operator. + * + * Requirements: + * + * - input must fit into 240 bits + * + * _Available since v4.7._ + */ + function toUint240(uint256 value) internal pure returns (uint240) { + require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits"); + return uint240(value); + } + + /** + * @dev Returns the downcasted uint232 from uint256, reverting on + * overflow (when the input is greater than largest uint232). + * + * Counterpart to Solidity's `uint232` operator. + * + * Requirements: + * + * - input must fit into 232 bits + * + * _Available since v4.7._ + */ + function toUint232(uint256 value) internal pure returns (uint232) { + require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits"); + return uint232(value); + } + + /** + * @dev Returns the downcasted uint224 from uint256, reverting on + * overflow (when the input is greater than largest uint224). + * + * Counterpart to Solidity's `uint224` operator. + * + * Requirements: + * + * - input must fit into 224 bits + * + * _Available since v4.2._ + */ + function toUint224(uint256 value) internal pure returns (uint224) { + require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); + return uint224(value); + } + + /** + * @dev Returns the downcasted uint216 from uint256, reverting on + * overflow (when the input is greater than largest uint216). + * + * Counterpart to Solidity's `uint216` operator. + * + * Requirements: + * + * - input must fit into 216 bits + * + * _Available since v4.7._ + */ + function toUint216(uint256 value) internal pure returns (uint216) { + require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits"); + return uint216(value); + } + + /** + * @dev Returns the downcasted uint208 from uint256, reverting on + * overflow (when the input is greater than largest uint208). + * + * Counterpart to Solidity's `uint208` operator. + * + * Requirements: + * + * - input must fit into 208 bits + * + * _Available since v4.7._ + */ + function toUint208(uint256 value) internal pure returns (uint208) { + require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); + return uint208(value); + } + + /** + * @dev Returns the downcasted uint200 from uint256, reverting on + * overflow (when the input is greater than largest uint200). + * + * Counterpart to Solidity's `uint200` operator. + * + * Requirements: + * + * - input must fit into 200 bits + * + * _Available since v4.7._ + */ + function toUint200(uint256 value) internal pure returns (uint200) { + require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits"); + return uint200(value); + } + + /** + * @dev Returns the downcasted uint192 from uint256, reverting on + * overflow (when the input is greater than largest uint192). + * + * Counterpart to Solidity's `uint192` operator. + * + * Requirements: + * + * - input must fit into 192 bits + * + * _Available since v4.7._ + */ + function toUint192(uint256 value) internal pure returns (uint192) { + require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits"); + return uint192(value); + } + + /** + * @dev Returns the downcasted uint184 from uint256, reverting on + * overflow (when the input is greater than largest uint184). + * + * Counterpart to Solidity's `uint184` operator. + * + * Requirements: + * + * - input must fit into 184 bits + * + * _Available since v4.7._ + */ + function toUint184(uint256 value) internal pure returns (uint184) { + require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits"); + return uint184(value); + } + + /** + * @dev Returns the downcasted uint176 from uint256, reverting on + * overflow (when the input is greater than largest uint176). + * + * Counterpart to Solidity's `uint176` operator. + * + * Requirements: + * + * - input must fit into 176 bits + * + * _Available since v4.7._ + */ + function toUint176(uint256 value) internal pure returns (uint176) { + require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits"); + return uint176(value); + } + + /** + * @dev Returns the downcasted uint168 from uint256, reverting on + * overflow (when the input is greater than largest uint168). + * + * Counterpart to Solidity's `uint168` operator. + * + * Requirements: + * + * - input must fit into 168 bits + * + * _Available since v4.7._ + */ + function toUint168(uint256 value) internal pure returns (uint168) { + require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits"); + return uint168(value); + } + + /** + * @dev Returns the downcasted uint160 from uint256, reverting on + * overflow (when the input is greater than largest uint160). + * + * Counterpart to Solidity's `uint160` operator. + * + * Requirements: + * + * - input must fit into 160 bits + * + * _Available since v4.7._ + */ + function toUint160(uint256 value) internal pure returns (uint160) { + require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits"); + return uint160(value); + } + + /** + * @dev Returns the downcasted uint152 from uint256, reverting on + * overflow (when the input is greater than largest uint152). + * + * Counterpart to Solidity's `uint152` operator. + * + * Requirements: + * + * - input must fit into 152 bits + * + * _Available since v4.7._ + */ + function toUint152(uint256 value) internal pure returns (uint152) { + require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits"); + return uint152(value); + } + + /** + * @dev Returns the downcasted uint144 from uint256, reverting on + * overflow (when the input is greater than largest uint144). + * + * Counterpart to Solidity's `uint144` operator. + * + * Requirements: + * + * - input must fit into 144 bits + * + * _Available since v4.7._ + */ + function toUint144(uint256 value) internal pure returns (uint144) { + require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits"); + return uint144(value); + } + + /** + * @dev Returns the downcasted uint136 from uint256, reverting on + * overflow (when the input is greater than largest uint136). + * + * Counterpart to Solidity's `uint136` operator. + * + * Requirements: + * + * - input must fit into 136 bits + * + * _Available since v4.7._ + */ + function toUint136(uint256 value) internal pure returns (uint136) { + require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits"); + return uint136(value); + } + + /** + * @dev Returns the downcasted uint128 from uint256, reverting on + * overflow (when the input is greater than largest uint128). + * + * Counterpart to Solidity's `uint128` operator. + * + * Requirements: + * + * - input must fit into 128 bits + * + * _Available since v2.5._ + */ + function toUint128(uint256 value) internal pure returns (uint128) { + require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); + return uint128(value); + } + + /** + * @dev Returns the downcasted uint120 from uint256, reverting on + * overflow (when the input is greater than largest uint120). + * + * Counterpart to Solidity's `uint120` operator. + * + * Requirements: + * + * - input must fit into 120 bits + * + * _Available since v4.7._ + */ + function toUint120(uint256 value) internal pure returns (uint120) { + require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits"); + return uint120(value); + } + + /** + * @dev Returns the downcasted uint112 from uint256, reverting on + * overflow (when the input is greater than largest uint112). + * + * Counterpart to Solidity's `uint112` operator. + * + * Requirements: + * + * - input must fit into 112 bits + * + * _Available since v4.7._ + */ + function toUint112(uint256 value) internal pure returns (uint112) { + require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); + return uint112(value); + } + + /** + * @dev Returns the downcasted uint104 from uint256, reverting on + * overflow (when the input is greater than largest uint104). + * + * Counterpart to Solidity's `uint104` operator. + * + * Requirements: + * + * - input must fit into 104 bits + * + * _Available since v4.7._ + */ + function toUint104(uint256 value) internal pure returns (uint104) { + require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); + return uint104(value); + } + + /** + * @dev Returns the downcasted uint96 from uint256, reverting on + * overflow (when the input is greater than largest uint96). + * + * Counterpart to Solidity's `uint96` operator. + * + * Requirements: + * + * - input must fit into 96 bits + * + * _Available since v4.2._ + */ + function toUint96(uint256 value) internal pure returns (uint96) { + require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); + return uint96(value); + } + + /** + * @dev Returns the downcasted uint88 from uint256, reverting on + * overflow (when the input is greater than largest uint88). + * + * Counterpart to Solidity's `uint88` operator. + * + * Requirements: + * + * - input must fit into 88 bits + * + * _Available since v4.7._ + */ + function toUint88(uint256 value) internal pure returns (uint88) { + require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); + return uint88(value); + } + + /** + * @dev Returns the downcasted uint80 from uint256, reverting on + * overflow (when the input is greater than largest uint80). + * + * Counterpart to Solidity's `uint80` operator. + * + * Requirements: + * + * - input must fit into 80 bits + * + * _Available since v4.7._ + */ + function toUint80(uint256 value) internal pure returns (uint80) { + require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits"); + return uint80(value); + } + + /** + * @dev Returns the downcasted uint72 from uint256, reverting on + * overflow (when the input is greater than largest uint72). + * + * Counterpart to Solidity's `uint72` operator. + * + * Requirements: + * + * - input must fit into 72 bits + * + * _Available since v4.7._ + */ + function toUint72(uint256 value) internal pure returns (uint72) { + require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits"); + return uint72(value); + } + + /** + * @dev Returns the downcasted uint64 from uint256, reverting on + * overflow (when the input is greater than largest uint64). + * + * Counterpart to Solidity's `uint64` operator. + * + * Requirements: + * + * - input must fit into 64 bits + * + * _Available since v2.5._ + */ + function toUint64(uint256 value) internal pure returns (uint64) { + require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); + return uint64(value); + } + + /** + * @dev Returns the downcasted uint56 from uint256, reverting on + * overflow (when the input is greater than largest uint56). + * + * Counterpart to Solidity's `uint56` operator. + * + * Requirements: + * + * - input must fit into 56 bits + * + * _Available since v4.7._ + */ + function toUint56(uint256 value) internal pure returns (uint56) { + require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits"); + return uint56(value); + } + + /** + * @dev Returns the downcasted uint48 from uint256, reverting on + * overflow (when the input is greater than largest uint48). + * + * Counterpart to Solidity's `uint48` operator. + * + * Requirements: + * + * - input must fit into 48 bits + * + * _Available since v4.7._ + */ + function toUint48(uint256 value) internal pure returns (uint48) { + require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits"); + return uint48(value); + } + + /** + * @dev Returns the downcasted uint40 from uint256, reverting on + * overflow (when the input is greater than largest uint40). + * + * Counterpart to Solidity's `uint40` operator. + * + * Requirements: + * + * - input must fit into 40 bits + * + * _Available since v4.7._ + */ + function toUint40(uint256 value) internal pure returns (uint40) { + require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits"); + return uint40(value); + } + + /** + * @dev Returns the downcasted uint32 from uint256, reverting on + * overflow (when the input is greater than largest uint32). + * + * Counterpart to Solidity's `uint32` operator. + * + * Requirements: + * + * - input must fit into 32 bits + * + * _Available since v2.5._ + */ + function toUint32(uint256 value) internal pure returns (uint32) { + require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); + return uint32(value); + } + + /** + * @dev Returns the downcasted uint24 from uint256, reverting on + * overflow (when the input is greater than largest uint24). + * + * Counterpart to Solidity's `uint24` operator. + * + * Requirements: + * + * - input must fit into 24 bits + * + * _Available since v4.7._ + */ + function toUint24(uint256 value) internal pure returns (uint24) { + require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits"); + return uint24(value); + } + + /** + * @dev Returns the downcasted uint16 from uint256, reverting on + * overflow (when the input is greater than largest uint16). + * + * Counterpart to Solidity's `uint16` operator. + * + * Requirements: + * + * - input must fit into 16 bits + * + * _Available since v2.5._ + */ + function toUint16(uint256 value) internal pure returns (uint16) { + require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); + return uint16(value); + } + + /** + * @dev Returns the downcasted uint8 from uint256, reverting on + * overflow (when the input is greater than largest uint8). + * + * Counterpart to Solidity's `uint8` operator. + * + * Requirements: + * + * - input must fit into 8 bits + * + * _Available since v2.5._ + */ + function toUint8(uint256 value) internal pure returns (uint8) { + require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); + return uint8(value); + } + + /** + * @dev Converts a signed int256 into an unsigned uint256. + * + * Requirements: + * + * - input must be greater than or equal to 0. + * + * _Available since v3.0._ + */ + function toUint256(int256 value) internal pure returns (uint256) { + require(value >= 0, "SafeCast: value must be positive"); + return uint256(value); + } + + /** + * @dev Returns the downcasted int248 from int256, reverting on + * overflow (when the input is less than smallest int248 or + * greater than largest int248). + * + * Counterpart to Solidity's `int248` operator. + * + * Requirements: + * + * - input must fit into 248 bits + * + * _Available since v4.7._ + */ + function toInt248(int256 value) internal pure returns (int248 downcasted) { + downcasted = int248(value); + require(downcasted == value, "SafeCast: value doesn't fit in 248 bits"); + } + + /** + * @dev Returns the downcasted int240 from int256, reverting on + * overflow (when the input is less than smallest int240 or + * greater than largest int240). + * + * Counterpart to Solidity's `int240` operator. + * + * Requirements: + * + * - input must fit into 240 bits + * + * _Available since v4.7._ + */ + function toInt240(int256 value) internal pure returns (int240 downcasted) { + downcasted = int240(value); + require(downcasted == value, "SafeCast: value doesn't fit in 240 bits"); + } + + /** + * @dev Returns the downcasted int232 from int256, reverting on + * overflow (when the input is less than smallest int232 or + * greater than largest int232). + * + * Counterpart to Solidity's `int232` operator. + * + * Requirements: + * + * - input must fit into 232 bits + * + * _Available since v4.7._ + */ + function toInt232(int256 value) internal pure returns (int232 downcasted) { + downcasted = int232(value); + require(downcasted == value, "SafeCast: value doesn't fit in 232 bits"); + } + + /** + * @dev Returns the downcasted int224 from int256, reverting on + * overflow (when the input is less than smallest int224 or + * greater than largest int224). + * + * Counterpart to Solidity's `int224` operator. + * + * Requirements: + * + * - input must fit into 224 bits + * + * _Available since v4.7._ + */ + function toInt224(int256 value) internal pure returns (int224 downcasted) { + downcasted = int224(value); + require(downcasted == value, "SafeCast: value doesn't fit in 224 bits"); + } + + /** + * @dev Returns the downcasted int216 from int256, reverting on + * overflow (when the input is less than smallest int216 or + * greater than largest int216). + * + * Counterpart to Solidity's `int216` operator. + * + * Requirements: + * + * - input must fit into 216 bits + * + * _Available since v4.7._ + */ + function toInt216(int256 value) internal pure returns (int216 downcasted) { + downcasted = int216(value); + require(downcasted == value, "SafeCast: value doesn't fit in 216 bits"); + } + + /** + * @dev Returns the downcasted int208 from int256, reverting on + * overflow (when the input is less than smallest int208 or + * greater than largest int208). + * + * Counterpart to Solidity's `int208` operator. + * + * Requirements: + * + * - input must fit into 208 bits + * + * _Available since v4.7._ + */ + function toInt208(int256 value) internal pure returns (int208 downcasted) { + downcasted = int208(value); + require(downcasted == value, "SafeCast: value doesn't fit in 208 bits"); + } + + /** + * @dev Returns the downcasted int200 from int256, reverting on + * overflow (when the input is less than smallest int200 or + * greater than largest int200). + * + * Counterpart to Solidity's `int200` operator. + * + * Requirements: + * + * - input must fit into 200 bits + * + * _Available since v4.7._ + */ + function toInt200(int256 value) internal pure returns (int200 downcasted) { + downcasted = int200(value); + require(downcasted == value, "SafeCast: value doesn't fit in 200 bits"); + } + + /** + * @dev Returns the downcasted int192 from int256, reverting on + * overflow (when the input is less than smallest int192 or + * greater than largest int192). + * + * Counterpart to Solidity's `int192` operator. + * + * Requirements: + * + * - input must fit into 192 bits + * + * _Available since v4.7._ + */ + function toInt192(int256 value) internal pure returns (int192 downcasted) { + downcasted = int192(value); + require(downcasted == value, "SafeCast: value doesn't fit in 192 bits"); + } + + /** + * @dev Returns the downcasted int184 from int256, reverting on + * overflow (when the input is less than smallest int184 or + * greater than largest int184). + * + * Counterpart to Solidity's `int184` operator. + * + * Requirements: + * + * - input must fit into 184 bits + * + * _Available since v4.7._ + */ + function toInt184(int256 value) internal pure returns (int184 downcasted) { + downcasted = int184(value); + require(downcasted == value, "SafeCast: value doesn't fit in 184 bits"); + } + + /** + * @dev Returns the downcasted int176 from int256, reverting on + * overflow (when the input is less than smallest int176 or + * greater than largest int176). + * + * Counterpart to Solidity's `int176` operator. + * + * Requirements: + * + * - input must fit into 176 bits + * + * _Available since v4.7._ + */ + function toInt176(int256 value) internal pure returns (int176 downcasted) { + downcasted = int176(value); + require(downcasted == value, "SafeCast: value doesn't fit in 176 bits"); + } + + /** + * @dev Returns the downcasted int168 from int256, reverting on + * overflow (when the input is less than smallest int168 or + * greater than largest int168). + * + * Counterpart to Solidity's `int168` operator. + * + * Requirements: + * + * - input must fit into 168 bits + * + * _Available since v4.7._ + */ + function toInt168(int256 value) internal pure returns (int168 downcasted) { + downcasted = int168(value); + require(downcasted == value, "SafeCast: value doesn't fit in 168 bits"); + } + + /** + * @dev Returns the downcasted int160 from int256, reverting on + * overflow (when the input is less than smallest int160 or + * greater than largest int160). + * + * Counterpart to Solidity's `int160` operator. + * + * Requirements: + * + * - input must fit into 160 bits + * + * _Available since v4.7._ + */ + function toInt160(int256 value) internal pure returns (int160 downcasted) { + downcasted = int160(value); + require(downcasted == value, "SafeCast: value doesn't fit in 160 bits"); + } + + /** + * @dev Returns the downcasted int152 from int256, reverting on + * overflow (when the input is less than smallest int152 or + * greater than largest int152). + * + * Counterpart to Solidity's `int152` operator. + * + * Requirements: + * + * - input must fit into 152 bits + * + * _Available since v4.7._ + */ + function toInt152(int256 value) internal pure returns (int152 downcasted) { + downcasted = int152(value); + require(downcasted == value, "SafeCast: value doesn't fit in 152 bits"); + } + + /** + * @dev Returns the downcasted int144 from int256, reverting on + * overflow (when the input is less than smallest int144 or + * greater than largest int144). + * + * Counterpart to Solidity's `int144` operator. + * + * Requirements: + * + * - input must fit into 144 bits + * + * _Available since v4.7._ + */ + function toInt144(int256 value) internal pure returns (int144 downcasted) { + downcasted = int144(value); + require(downcasted == value, "SafeCast: value doesn't fit in 144 bits"); + } + + /** + * @dev Returns the downcasted int136 from int256, reverting on + * overflow (when the input is less than smallest int136 or + * greater than largest int136). + * + * Counterpart to Solidity's `int136` operator. + * + * Requirements: + * + * - input must fit into 136 bits + * + * _Available since v4.7._ + */ + function toInt136(int256 value) internal pure returns (int136 downcasted) { + downcasted = int136(value); + require(downcasted == value, "SafeCast: value doesn't fit in 136 bits"); + } + + /** + * @dev Returns the downcasted int128 from int256, reverting on + * overflow (when the input is less than smallest int128 or + * greater than largest int128). + * + * Counterpart to Solidity's `int128` operator. + * + * Requirements: + * + * - input must fit into 128 bits + * + * _Available since v3.1._ + */ + function toInt128(int256 value) internal pure returns (int128 downcasted) { + downcasted = int128(value); + require(downcasted == value, "SafeCast: value doesn't fit in 128 bits"); + } + + /** + * @dev Returns the downcasted int120 from int256, reverting on + * overflow (when the input is less than smallest int120 or + * greater than largest int120). + * + * Counterpart to Solidity's `int120` operator. + * + * Requirements: + * + * - input must fit into 120 bits + * + * _Available since v4.7._ + */ + function toInt120(int256 value) internal pure returns (int120 downcasted) { + downcasted = int120(value); + require(downcasted == value, "SafeCast: value doesn't fit in 120 bits"); + } + + /** + * @dev Returns the downcasted int112 from int256, reverting on + * overflow (when the input is less than smallest int112 or + * greater than largest int112). + * + * Counterpart to Solidity's `int112` operator. + * + * Requirements: + * + * - input must fit into 112 bits + * + * _Available since v4.7._ + */ + function toInt112(int256 value) internal pure returns (int112 downcasted) { + downcasted = int112(value); + require(downcasted == value, "SafeCast: value doesn't fit in 112 bits"); + } + + /** + * @dev Returns the downcasted int104 from int256, reverting on + * overflow (when the input is less than smallest int104 or + * greater than largest int104). + * + * Counterpart to Solidity's `int104` operator. + * + * Requirements: + * + * - input must fit into 104 bits + * + * _Available since v4.7._ + */ + function toInt104(int256 value) internal pure returns (int104 downcasted) { + downcasted = int104(value); + require(downcasted == value, "SafeCast: value doesn't fit in 104 bits"); + } + + /** + * @dev Returns the downcasted int96 from int256, reverting on + * overflow (when the input is less than smallest int96 or + * greater than largest int96). + * + * Counterpart to Solidity's `int96` operator. + * + * Requirements: + * + * - input must fit into 96 bits + * + * _Available since v4.7._ + */ + function toInt96(int256 value) internal pure returns (int96 downcasted) { + downcasted = int96(value); + require(downcasted == value, "SafeCast: value doesn't fit in 96 bits"); + } + + /** + * @dev Returns the downcasted int88 from int256, reverting on + * overflow (when the input is less than smallest int88 or + * greater than largest int88). + * + * Counterpart to Solidity's `int88` operator. + * + * Requirements: + * + * - input must fit into 88 bits + * + * _Available since v4.7._ + */ + function toInt88(int256 value) internal pure returns (int88 downcasted) { + downcasted = int88(value); + require(downcasted == value, "SafeCast: value doesn't fit in 88 bits"); + } + + /** + * @dev Returns the downcasted int80 from int256, reverting on + * overflow (when the input is less than smallest int80 or + * greater than largest int80). + * + * Counterpart to Solidity's `int80` operator. + * + * Requirements: + * + * - input must fit into 80 bits + * + * _Available since v4.7._ + */ + function toInt80(int256 value) internal pure returns (int80 downcasted) { + downcasted = int80(value); + require(downcasted == value, "SafeCast: value doesn't fit in 80 bits"); + } + + /** + * @dev Returns the downcasted int72 from int256, reverting on + * overflow (when the input is less than smallest int72 or + * greater than largest int72). + * + * Counterpart to Solidity's `int72` operator. + * + * Requirements: + * + * - input must fit into 72 bits + * + * _Available since v4.7._ + */ + function toInt72(int256 value) internal pure returns (int72 downcasted) { + downcasted = int72(value); + require(downcasted == value, "SafeCast: value doesn't fit in 72 bits"); + } + + /** + * @dev Returns the downcasted int64 from int256, reverting on + * overflow (when the input is less than smallest int64 or + * greater than largest int64). + * + * Counterpart to Solidity's `int64` operator. + * + * Requirements: + * + * - input must fit into 64 bits + * + * _Available since v3.1._ + */ + function toInt64(int256 value) internal pure returns (int64 downcasted) { + downcasted = int64(value); + require(downcasted == value, "SafeCast: value doesn't fit in 64 bits"); + } + + /** + * @dev Returns the downcasted int56 from int256, reverting on + * overflow (when the input is less than smallest int56 or + * greater than largest int56). + * + * Counterpart to Solidity's `int56` operator. + * + * Requirements: + * + * - input must fit into 56 bits + * + * _Available since v4.7._ + */ + function toInt56(int256 value) internal pure returns (int56 downcasted) { + downcasted = int56(value); + require(downcasted == value, "SafeCast: value doesn't fit in 56 bits"); + } + + /** + * @dev Returns the downcasted int48 from int256, reverting on + * overflow (when the input is less than smallest int48 or + * greater than largest int48). + * + * Counterpart to Solidity's `int48` operator. + * + * Requirements: + * + * - input must fit into 48 bits + * + * _Available since v4.7._ + */ + function toInt48(int256 value) internal pure returns (int48 downcasted) { + downcasted = int48(value); + require(downcasted == value, "SafeCast: value doesn't fit in 48 bits"); + } + + /** + * @dev Returns the downcasted int40 from int256, reverting on + * overflow (when the input is less than smallest int40 or + * greater than largest int40). + * + * Counterpart to Solidity's `int40` operator. + * + * Requirements: + * + * - input must fit into 40 bits + * + * _Available since v4.7._ + */ + function toInt40(int256 value) internal pure returns (int40 downcasted) { + downcasted = int40(value); + require(downcasted == value, "SafeCast: value doesn't fit in 40 bits"); + } + + /** + * @dev Returns the downcasted int32 from int256, reverting on + * overflow (when the input is less than smallest int32 or + * greater than largest int32). + * + * Counterpart to Solidity's `int32` operator. + * + * Requirements: + * + * - input must fit into 32 bits + * + * _Available since v3.1._ + */ + function toInt32(int256 value) internal pure returns (int32 downcasted) { + downcasted = int32(value); + require(downcasted == value, "SafeCast: value doesn't fit in 32 bits"); + } + + /** + * @dev Returns the downcasted int24 from int256, reverting on + * overflow (when the input is less than smallest int24 or + * greater than largest int24). + * + * Counterpart to Solidity's `int24` operator. + * + * Requirements: + * + * - input must fit into 24 bits + * + * _Available since v4.7._ + */ + function toInt24(int256 value) internal pure returns (int24 downcasted) { + downcasted = int24(value); + require(downcasted == value, "SafeCast: value doesn't fit in 24 bits"); + } + + /** + * @dev Returns the downcasted int16 from int256, reverting on + * overflow (when the input is less than smallest int16 or + * greater than largest int16). + * + * Counterpart to Solidity's `int16` operator. + * + * Requirements: + * + * - input must fit into 16 bits + * + * _Available since v3.1._ + */ + function toInt16(int256 value) internal pure returns (int16 downcasted) { + downcasted = int16(value); + require(downcasted == value, "SafeCast: value doesn't fit in 16 bits"); + } + + /** + * @dev Returns the downcasted int8 from int256, reverting on + * overflow (when the input is less than smallest int8 or + * greater than largest int8). + * + * Counterpart to Solidity's `int8` operator. + * + * Requirements: + * + * - input must fit into 8 bits + * + * _Available since v3.1._ + */ + function toInt8(int256 value) internal pure returns (int8 downcasted) { + downcasted = int8(value); + require(downcasted == value, "SafeCast: value doesn't fit in 8 bits"); + } + + /** + * @dev Converts an unsigned uint256 into a signed int256. + * + * Requirements: + * + * - input must be less than or equal to maxInt256. + * + * _Available since v3.0._ + */ + function toInt256(uint256 value) internal pure returns (int256) { + // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive + require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); + return int256(value); + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/SignedMath.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/SignedMath.sol new file mode 100644 index 00000000000..93524bb79c0 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/SignedMath.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) + +pragma solidity ^0.8.0; + +/** + * @dev Standard signed math utilities missing in the Solidity language. + */ +library SignedMath { + /** + * @dev Returns the largest of two signed numbers. + */ + function max(int256 a, int256 b) internal pure returns (int256) { + return a > b ? a : b; + } + + /** + * @dev Returns the smallest of two signed numbers. + */ + function min(int256 a, int256 b) internal pure returns (int256) { + return a < b ? a : b; + } + + /** + * @dev Returns the average of two signed numbers without overflow. + * The result is rounded towards zero. + */ + function average(int256 a, int256 b) internal pure returns (int256) { + // Formula from the book "Hacker's Delight" + int256 x = (a & b) + ((a ^ b) >> 1); + return x + (int256(uint256(x) >> 255) & (a ^ b)); + } + + /** + * @dev Returns the absolute unsigned value of a signed value. + */ + function abs(int256 n) internal pure returns (uint256) { + unchecked { + // must be unchecked in order to support `n = type(int256).min` + return uint256(n >= 0 ? n : -n); + } + } +} diff --git a/contracts/src/v0.8/shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/utils/structs/EnumerableSet.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/structs/EnumerableSet.sol similarity index 100% rename from contracts/src/v0.8/shared/vendor/openzeppelin-solidity/v.4.8.0/contracts/utils/structs/EnumerableSet.sol rename to contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/structs/EnumerableSet.sol diff --git a/contracts/src/v0.8/shared/vendor/solidity-cborutils/v2.0.0/CBOR.sol b/contracts/src/v0.8/vendor/solidity-cborutils/v2.0.0/CBOR.sol similarity index 100% rename from contracts/src/v0.8/shared/vendor/solidity-cborutils/v2.0.0/CBOR.sol rename to contracts/src/v0.8/vendor/solidity-cborutils/v2.0.0/CBOR.sol diff --git a/contracts/src/v0.8/AuthorizedReceiver.sol b/contracts/src/v0.8/vrf/AuthorizedReceiver.sol similarity index 100% rename from contracts/src/v0.8/AuthorizedReceiver.sol rename to contracts/src/v0.8/vrf/AuthorizedReceiver.sol diff --git a/contracts/src/v0.8/vrf/VRFConsumerBase.sol b/contracts/src/v0.8/vrf/VRFConsumerBase.sol index ed4e09ea93f..983a5b23cb7 100644 --- a/contracts/src/v0.8/vrf/VRFConsumerBase.sol +++ b/contracts/src/v0.8/vrf/VRFConsumerBase.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../interfaces/LinkTokenInterface.sol"; +import "../shared/interfaces/LinkTokenInterface.sol"; import "./VRFRequestIDBase.sol"; diff --git a/contracts/src/v0.8/vrf/VRFCoordinatorV2.sol b/contracts/src/v0.8/vrf/VRFCoordinatorV2.sol index 79365175bbe..52b7ab295e2 100644 --- a/contracts/src/v0.8/vrf/VRFCoordinatorV2.sol +++ b/contracts/src/v0.8/vrf/VRFCoordinatorV2.sol @@ -1,24 +1,18 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.4; -import "../interfaces/LinkTokenInterface.sol"; +import "../shared/interfaces/LinkTokenInterface.sol"; import "../interfaces/BlockhashStoreInterface.sol"; import "../interfaces/AggregatorV3Interface.sol"; import "../interfaces/VRFCoordinatorV2Interface.sol"; import "../interfaces/TypeAndVersionInterface.sol"; -import "../interfaces/ERC677ReceiverInterface.sol"; +import "../shared/interfaces/IERC677Receiver.sol"; import "./VRF.sol"; -import "../ConfirmedOwner.sol"; +import "../shared/access/ConfirmedOwner.sol"; import "./VRFConsumerBaseV2.sol"; import "../ChainSpecificUtil.sol"; -contract VRFCoordinatorV2 is - VRF, - ConfirmedOwner, - TypeAndVersionInterface, - VRFCoordinatorV2Interface, - ERC677ReceiverInterface -{ +contract VRFCoordinatorV2 is VRF, ConfirmedOwner, TypeAndVersionInterface, VRFCoordinatorV2Interface, IERC677Receiver { LinkTokenInterface public immutable LINK; AggregatorV3Interface public immutable LINK_ETH_FEED; BlockhashStoreInterface public immutable BLOCKHASH_STORE; diff --git a/contracts/src/v0.8/vrf/VRFOwner.sol b/contracts/src/v0.8/vrf/VRFOwner.sol index f0db4f1ef38..2c4adf36e8c 100644 --- a/contracts/src/v0.8/vrf/VRFOwner.sol +++ b/contracts/src/v0.8/vrf/VRFOwner.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; -import {ConfirmedOwner} from "../ConfirmedOwner.sol"; -import {AuthorizedReceiver} from "../AuthorizedReceiver.sol"; +import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol"; +import {AuthorizedReceiver} from "./AuthorizedReceiver.sol"; import "./VRFTypes.sol"; // Taken from VRFCoordinatorV2.sol diff --git a/contracts/src/v0.8/vrf/VRFV2Wrapper.sol b/contracts/src/v0.8/vrf/VRFV2Wrapper.sol index 585c0bdda67..101e1bdfe20 100644 --- a/contracts/src/v0.8/vrf/VRFV2Wrapper.sol +++ b/contracts/src/v0.8/vrf/VRFV2Wrapper.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; -import "../ConfirmedOwner.sol"; +import "../shared/access/ConfirmedOwner.sol"; import "../interfaces/TypeAndVersionInterface.sol"; import "./VRFConsumerBaseV2.sol"; -import "../interfaces/LinkTokenInterface.sol"; +import "../shared/interfaces/LinkTokenInterface.sol"; import "../interfaces/AggregatorV3Interface.sol"; import "../interfaces/VRFCoordinatorV2Interface.sol"; import "../interfaces/VRFV2WrapperInterface.sol"; diff --git a/contracts/src/v0.8/vrf/VRFV2WrapperConsumerBase.sol b/contracts/src/v0.8/vrf/VRFV2WrapperConsumerBase.sol index 7e67d438e84..4c7918e8b7a 100644 --- a/contracts/src/v0.8/vrf/VRFV2WrapperConsumerBase.sol +++ b/contracts/src/v0.8/vrf/VRFV2WrapperConsumerBase.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../interfaces/LinkTokenInterface.sol"; +import "../shared/interfaces/LinkTokenInterface.sol"; import "../interfaces/VRFV2WrapperInterface.sol"; /** ******************************************************************************* diff --git a/contracts/src/v0.8/interfaces/IAuthorizedReceiver.sol b/contracts/src/v0.8/vrf/interfaces/IAuthorizedReceiver.sol similarity index 100% rename from contracts/src/v0.8/interfaces/IAuthorizedReceiver.sol rename to contracts/src/v0.8/vrf/interfaces/IAuthorizedReceiver.sol diff --git a/contracts/src/v0.8/vrf/testhelpers/VRFConsumer.sol b/contracts/src/v0.8/vrf/testhelpers/VRFConsumer.sol index f8347ef6e2a..2f063e67267 100644 --- a/contracts/src/v0.8/vrf/testhelpers/VRFConsumer.sol +++ b/contracts/src/v0.8/vrf/testhelpers/VRFConsumer.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../interfaces/LinkTokenInterface.sol"; +import "../../shared/interfaces/LinkTokenInterface.sol"; import "../VRFConsumerBase.sol"; contract VRFConsumer is VRFConsumerBase { diff --git a/contracts/src/v0.8/vrf/testhelpers/VRFConsumerV2.sol b/contracts/src/v0.8/vrf/testhelpers/VRFConsumerV2.sol index 3b00d382524..466451c7b6a 100644 --- a/contracts/src/v0.8/vrf/testhelpers/VRFConsumerV2.sol +++ b/contracts/src/v0.8/vrf/testhelpers/VRFConsumerV2.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../interfaces/LinkTokenInterface.sol"; +import "../../shared/interfaces/LinkTokenInterface.sol"; import "../../interfaces/VRFCoordinatorV2Interface.sol"; import "../VRFConsumerBaseV2.sol"; diff --git a/contracts/src/v0.8/vrf/testhelpers/VRFConsumerV2UpgradeableExample.sol b/contracts/src/v0.8/vrf/testhelpers/VRFConsumerV2UpgradeableExample.sol index e9f53e5f7b2..b99abedf3c7 100644 --- a/contracts/src/v0.8/vrf/testhelpers/VRFConsumerV2UpgradeableExample.sol +++ b/contracts/src/v0.8/vrf/testhelpers/VRFConsumerV2UpgradeableExample.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../interfaces/LinkTokenInterface.sol"; +import "../../shared/interfaces/LinkTokenInterface.sol"; import "../../interfaces/VRFCoordinatorV2Interface.sol"; import "../../dev/VRFConsumerBaseV2Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable-4.7.3/proxy/utils/Initializable.sol"; diff --git a/contracts/src/v0.8/vrf/testhelpers/VRFExternalSubOwnerExample.sol b/contracts/src/v0.8/vrf/testhelpers/VRFExternalSubOwnerExample.sol index 049a976f119..f6b171cb508 100644 --- a/contracts/src/v0.8/vrf/testhelpers/VRFExternalSubOwnerExample.sol +++ b/contracts/src/v0.8/vrf/testhelpers/VRFExternalSubOwnerExample.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../interfaces/LinkTokenInterface.sol"; +import "../../shared/interfaces/LinkTokenInterface.sol"; import "../../interfaces/VRFCoordinatorV2Interface.sol"; import "../VRFConsumerBaseV2.sol"; diff --git a/contracts/src/v0.8/vrf/testhelpers/VRFLoadTestExternalSubOwner.sol b/contracts/src/v0.8/vrf/testhelpers/VRFLoadTestExternalSubOwner.sol index 643a212e250..b4bf37990d7 100644 --- a/contracts/src/v0.8/vrf/testhelpers/VRFLoadTestExternalSubOwner.sol +++ b/contracts/src/v0.8/vrf/testhelpers/VRFLoadTestExternalSubOwner.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../interfaces/LinkTokenInterface.sol"; +import "../../shared/interfaces/LinkTokenInterface.sol"; import "../../interfaces/VRFCoordinatorV2Interface.sol"; import "../VRFConsumerBaseV2.sol"; -import "../../ConfirmedOwner.sol"; +import "../../shared/access/ConfirmedOwner.sol"; /** * @title The VRFLoadTestExternalSubOwner contract. diff --git a/contracts/src/v0.8/vrf/testhelpers/VRFLoadTestOwnerlessConsumer.sol b/contracts/src/v0.8/vrf/testhelpers/VRFLoadTestOwnerlessConsumer.sol index 5d7691c6817..93c75298d9e 100644 --- a/contracts/src/v0.8/vrf/testhelpers/VRFLoadTestOwnerlessConsumer.sol +++ b/contracts/src/v0.8/vrf/testhelpers/VRFLoadTestOwnerlessConsumer.sol @@ -2,13 +2,13 @@ pragma solidity ^0.8.0; import "../VRFConsumerBase.sol"; -import "../../interfaces/ERC677ReceiverInterface.sol"; +import "../../shared/interfaces/IERC677Receiver.sol"; /** * @title The VRFLoadTestOwnerlessConsumer contract. * @notice Allows making many VRF V1 randomness requests in a single transaction for load testing. */ -contract VRFLoadTestOwnerlessConsumer is VRFConsumerBase, ERC677ReceiverInterface { +contract VRFLoadTestOwnerlessConsumer is VRFConsumerBase, IERC677Receiver { // The price of each VRF request in Juels. 1 LINK = 1e18 Juels. uint256 public immutable PRICE; diff --git a/contracts/src/v0.8/vrf/testhelpers/VRFMaliciousConsumerV2.sol b/contracts/src/v0.8/vrf/testhelpers/VRFMaliciousConsumerV2.sol index 5ed79ae2e86..f11fcc0b7d0 100644 --- a/contracts/src/v0.8/vrf/testhelpers/VRFMaliciousConsumerV2.sol +++ b/contracts/src/v0.8/vrf/testhelpers/VRFMaliciousConsumerV2.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../interfaces/LinkTokenInterface.sol"; +import "../../shared/interfaces/LinkTokenInterface.sol"; import "../../interfaces/VRFCoordinatorV2Interface.sol"; import "../VRFConsumerBaseV2.sol"; diff --git a/contracts/src/v0.8/vrf/testhelpers/VRFOwnerlessConsumerExample.sol b/contracts/src/v0.8/vrf/testhelpers/VRFOwnerlessConsumerExample.sol index 5d2d4ae282a..0eeb5ebc8f1 100644 --- a/contracts/src/v0.8/vrf/testhelpers/VRFOwnerlessConsumerExample.sol +++ b/contracts/src/v0.8/vrf/testhelpers/VRFOwnerlessConsumerExample.sol @@ -4,9 +4,9 @@ pragma solidity ^0.8.4; import "../VRFConsumerBase.sol"; -import "../../interfaces/ERC677ReceiverInterface.sol"; +import "../../shared/interfaces/IERC677Receiver.sol"; -contract VRFOwnerlessConsumerExample is VRFConsumerBase, ERC677ReceiverInterface { +contract VRFOwnerlessConsumerExample is VRFConsumerBase, IERC677Receiver { uint256 public s_randomnessOutput; bytes32 public s_requestId; diff --git a/contracts/src/v0.8/vrf/testhelpers/VRFSingleConsumerExample.sol b/contracts/src/v0.8/vrf/testhelpers/VRFSingleConsumerExample.sol index 12b29599fd1..d4dd7b9087a 100644 --- a/contracts/src/v0.8/vrf/testhelpers/VRFSingleConsumerExample.sol +++ b/contracts/src/v0.8/vrf/testhelpers/VRFSingleConsumerExample.sol @@ -2,7 +2,7 @@ // Example of a single consumer contract which owns the subscription. pragma solidity ^0.8.0; -import "../../interfaces/LinkTokenInterface.sol"; +import "../../shared/interfaces/LinkTokenInterface.sol"; import "../../interfaces/VRFCoordinatorV2Interface.sol"; import "../VRFConsumerBaseV2.sol"; diff --git a/contracts/src/v0.8/vrf/testhelpers/VRFV2LoadTestWithMetrics.sol b/contracts/src/v0.8/vrf/testhelpers/VRFV2LoadTestWithMetrics.sol index ed6c8026388..3fd3f4e4038 100644 --- a/contracts/src/v0.8/vrf/testhelpers/VRFV2LoadTestWithMetrics.sol +++ b/contracts/src/v0.8/vrf/testhelpers/VRFV2LoadTestWithMetrics.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import "../../interfaces/VRFCoordinatorV2Interface.sol"; import "../VRFConsumerBaseV2.sol"; -import "../../ConfirmedOwner.sol"; +import "../../shared/access/ConfirmedOwner.sol"; import "../../ChainSpecificUtil.sol"; /** diff --git a/contracts/src/v0.8/vrf/testhelpers/VRFV2OwnerTestConsumer.sol b/contracts/src/v0.8/vrf/testhelpers/VRFV2OwnerTestConsumer.sol new file mode 100644 index 00000000000..361c32706f4 --- /dev/null +++ b/contracts/src/v0.8/vrf/testhelpers/VRFV2OwnerTestConsumer.sol @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "../../interfaces/VRFCoordinatorV2Interface.sol"; +import "../VRFConsumerBaseV2.sol"; +import "../../shared/access/ConfirmedOwner.sol"; +import "../../ChainSpecificUtil.sol"; +import "../../shared/interfaces/LinkTokenInterface.sol"; + +contract VRFV2OwnerTestConsumer is VRFConsumerBaseV2, ConfirmedOwner { + VRFCoordinatorV2Interface public COORDINATOR; + uint64 public subId; + uint256 public s_responseCount; + uint256 public s_requestCount; + uint256 public s_averageFulfillmentInMillions = 0; // in millions for better precision + uint256 public s_slowestFulfillment = 0; + uint256 public s_fastestFulfillment = 999; + uint256 public s_lastRequestId; + mapping(uint256 => uint256) requestHeights; // requestIds to block number when rand request was made + + struct RequestStatus { + bool fulfilled; + uint256[] randomWords; + uint requestTimestamp; + uint fulfilmentTimestamp; + uint256 requestBlockNumber; + uint256 fulfilmentBlockNumber; + } + + mapping(uint256 => RequestStatus) /* requestId */ /* requestStatus */ public s_requests; + + constructor(address _vrfCoordinator) VRFConsumerBaseV2(_vrfCoordinator) ConfirmedOwner(msg.sender) { + COORDINATOR = VRFCoordinatorV2Interface(_vrfCoordinator); + // create a subscription, address(this) will be the owner + subId = COORDINATOR.createSubscription(); + // add address(this) as a consumer on the subscription + COORDINATOR.addConsumer(subId, address(this)); + } + + function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal override { + uint256 fulfilmentBlockNumber = ChainSpecificUtil.getBlockNumber(); + uint256 requestDelay = fulfilmentBlockNumber - requestHeights[_requestId]; + uint256 requestDelayInMillions = requestDelay * 1_000_000; + + if (requestDelay > s_slowestFulfillment) { + s_slowestFulfillment = requestDelay; + } + s_fastestFulfillment = requestDelay < s_fastestFulfillment ? requestDelay : s_fastestFulfillment; + s_averageFulfillmentInMillions = s_responseCount > 0 + ? (s_averageFulfillmentInMillions * s_responseCount + requestDelayInMillions) / (s_responseCount + 1) + : requestDelayInMillions; + + s_requests[_requestId].fulfilled = true; + s_requests[_requestId].randomWords = _randomWords; + s_requests[_requestId].fulfilmentTimestamp = block.timestamp; + s_requests[_requestId].fulfilmentBlockNumber = fulfilmentBlockNumber; + + s_responseCount++; + } + + function requestRandomWords( + uint16 _requestConfirmations, + bytes32 _keyHash, + uint32 _callbackGasLimit, + uint32 _numWords, + uint16 _requestCount + ) external onlyOwner { + for (uint16 i = 0; i < _requestCount; i++) { + uint256 requestId = COORDINATOR.requestRandomWords( + _keyHash, + subId, + _requestConfirmations, + _callbackGasLimit, + _numWords + ); + s_lastRequestId = requestId; + uint256 requestBlockNumber = ChainSpecificUtil.getBlockNumber(); + s_requests[requestId] = RequestStatus({ + randomWords: new uint256[](0), + fulfilled: false, + requestTimestamp: block.timestamp, + fulfilmentTimestamp: 0, + requestBlockNumber: requestBlockNumber, + fulfilmentBlockNumber: 0 + }); + s_requestCount++; + requestHeights[requestId] = requestBlockNumber; + } + + COORDINATOR.removeConsumer(subId, address(this)); + COORDINATOR.cancelSubscription(subId, msg.sender); + } + + function reset() external { + s_averageFulfillmentInMillions = 0; // in millions for better precision + s_slowestFulfillment = 0; + s_fastestFulfillment = 999; + s_requestCount = 0; + s_responseCount = 0; + } + + function getRequestStatus( + uint256 _requestId + ) + external + view + returns ( + bool fulfilled, + uint256[] memory randomWords, + uint requestTimestamp, + uint fulfilmentTimestamp, + uint256 requestBlockNumber, + uint256 fulfilmentBlockNumber + ) + { + RequestStatus memory request = s_requests[_requestId]; + return ( + request.fulfilled, + request.randomWords, + request.requestTimestamp, + request.fulfilmentTimestamp, + request.requestBlockNumber, + request.fulfilmentBlockNumber + ); + } +} diff --git a/contracts/src/v0.8/vrf/testhelpers/VRFV2RevertingExample.sol b/contracts/src/v0.8/vrf/testhelpers/VRFV2RevertingExample.sol index 738e42219f4..72be535a000 100644 --- a/contracts/src/v0.8/vrf/testhelpers/VRFV2RevertingExample.sol +++ b/contracts/src/v0.8/vrf/testhelpers/VRFV2RevertingExample.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../interfaces/LinkTokenInterface.sol"; +import "../../shared/interfaces/LinkTokenInterface.sol"; import "../../interfaces/VRFCoordinatorV2Interface.sol"; import "../VRFConsumerBaseV2.sol"; diff --git a/contracts/src/v0.8/vrf/testhelpers/VRFV2WrapperConsumerExample.sol b/contracts/src/v0.8/vrf/testhelpers/VRFV2WrapperConsumerExample.sol index a4fb040a6d0..7ab54ee9fa3 100644 --- a/contracts/src/v0.8/vrf/testhelpers/VRFV2WrapperConsumerExample.sol +++ b/contracts/src/v0.8/vrf/testhelpers/VRFV2WrapperConsumerExample.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.6; import "../VRFV2WrapperConsumerBase.sol"; -import "../../ConfirmedOwner.sol"; +import "../../shared/access/ConfirmedOwner.sol"; contract VRFV2WrapperConsumerExample is VRFV2WrapperConsumerBase, ConfirmedOwner { event WrappedRequestFulfilled(uint256 requestId, uint256[] randomWords, uint256 payment); diff --git a/contracts/src/v0.8/vrf/testhelpers/VRFV2WrapperOutOfGasConsumerExample.sol b/contracts/src/v0.8/vrf/testhelpers/VRFV2WrapperOutOfGasConsumerExample.sol index f89229dfe7c..e6747820fdb 100644 --- a/contracts/src/v0.8/vrf/testhelpers/VRFV2WrapperOutOfGasConsumerExample.sol +++ b/contracts/src/v0.8/vrf/testhelpers/VRFV2WrapperOutOfGasConsumerExample.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.6; import "../VRFV2WrapperConsumerBase.sol"; -import "../../ConfirmedOwner.sol"; +import "../../shared/access/ConfirmedOwner.sol"; contract VRFV2WrapperOutOfGasConsumerExample is VRFV2WrapperConsumerBase, ConfirmedOwner { constructor( diff --git a/contracts/src/v0.8/vrf/testhelpers/VRFV2WrapperRevertingConsumerExample.sol b/contracts/src/v0.8/vrf/testhelpers/VRFV2WrapperRevertingConsumerExample.sol index 89f3c752225..c3699a1d74b 100644 --- a/contracts/src/v0.8/vrf/testhelpers/VRFV2WrapperRevertingConsumerExample.sol +++ b/contracts/src/v0.8/vrf/testhelpers/VRFV2WrapperRevertingConsumerExample.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.6; import "../VRFV2WrapperConsumerBase.sol"; -import "../../ConfirmedOwner.sol"; +import "../../shared/access/ConfirmedOwner.sol"; contract VRFV2WrapperRevertingConsumerExample is VRFV2WrapperConsumerBase, ConfirmedOwner { constructor( diff --git a/contracts/src/v0.8/vrf/testhelpers/VRFV2WrapperUnderFundingConsumer.sol b/contracts/src/v0.8/vrf/testhelpers/VRFV2WrapperUnderFundingConsumer.sol index 09ec603a1f2..ae0f9eac83c 100644 --- a/contracts/src/v0.8/vrf/testhelpers/VRFV2WrapperUnderFundingConsumer.sol +++ b/contracts/src/v0.8/vrf/testhelpers/VRFV2WrapperUnderFundingConsumer.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../ConfirmedOwner.sol"; -import "../../interfaces/LinkTokenInterface.sol"; +import "../../shared/access/ConfirmedOwner.sol"; +import "../../shared/interfaces/LinkTokenInterface.sol"; import "../../interfaces/VRFV2WrapperInterface.sol"; contract VRFV2WrapperUnderFundingConsumer is ConfirmedOwner { diff --git a/contracts/test/test-helpers/helpers.ts b/contracts/test/test-helpers/helpers.ts index 94fe91ce4f4..e65cd57e8d9 100644 --- a/contracts/test/test-helpers/helpers.ts +++ b/contracts/test/test-helpers/helpers.ts @@ -336,3 +336,7 @@ export async function reset() { params: [], }) } + +export function randomAddress() { + return ethers.Wallet.createRandom().address +} diff --git a/contracts/test/v0.7/KeeperRegistry1_1.test.ts b/contracts/test/v0.7/KeeperRegistry1_1.test.ts index 845832e76f7..4e3a8c91b35 100644 --- a/contracts/test/v0.7/KeeperRegistry1_1.test.ts +++ b/contracts/test/v0.7/KeeperRegistry1_1.test.ts @@ -2,7 +2,7 @@ import { ethers } from 'hardhat' import { assert, expect } from 'chai' import { evmRevert } from '../test-helpers/matchers' import { getUsers, Personas } from '../test-helpers/setup' -import { BigNumber, Signer, BigNumberish } from 'ethers' +import { BigNumber, BigNumberish, Signer } from 'ethers' import { LinkToken__factory as LinkTokenFactory } from '../../typechain/factories/LinkToken__factory' import { KeeperRegistry1_1__factory as KeeperRegistryFactory } from '../../typechain/factories/KeeperRegistry1_1__factory' import { MockV3Aggregator__factory as MockV3AggregatorFactory } from '../../typechain/factories/MockV3Aggregator__factory' @@ -37,7 +37,9 @@ let personas: Personas before(async () => { personas = (await getUsers()).personas - linkTokenFactory = await ethers.getContractFactory('LinkToken') + linkTokenFactory = await ethers.getContractFactory( + 'src/v0.4/LinkToken.sol:LinkToken', + ) // need full path because there are two contracts with name MockV3Aggregator mockV3AggregatorFactory = (await ethers.getContractFactory( 'src/v0.7/tests/MockV3Aggregator.sol:MockV3Aggregator', diff --git a/contracts/test/v0.7/UpkeepRegistrationRequests.test.ts b/contracts/test/v0.7/UpkeepRegistrationRequests.test.ts index 906c86c6b44..5ec9306c668 100644 --- a/contracts/test/v0.7/UpkeepRegistrationRequests.test.ts +++ b/contracts/test/v0.7/UpkeepRegistrationRequests.test.ts @@ -25,7 +25,9 @@ let personas: Personas before(async () => { personas = (await getUsers()).personas - linkTokenFactory = await ethers.getContractFactory('LinkToken') + linkTokenFactory = await ethers.getContractFactory( + 'src/v0.4/LinkToken.sol:LinkToken', + ) mockV3AggregatorFactory = (await ethers.getContractFactory( 'src/v0.7/tests/MockV3Aggregator.sol:MockV3Aggregator', )) as unknown as MockV3AggregatorFactory diff --git a/contracts/test/v0.8/Cron.test.ts b/contracts/test/v0.8/Cron.test.ts index 0b7bbd2f5db..2cdc7c247f9 100644 --- a/contracts/test/v0.8/Cron.test.ts +++ b/contracts/test/v0.8/Cron.test.ts @@ -3,7 +3,7 @@ import { ethers } from 'hardhat' import { assert, expect } from 'chai' import { CronInternalTestHelper } from '../../typechain/CronInternalTestHelper' import { CronExternalTestHelper } from '../../typechain/CronExternalTestHelper' -import { validCrons, invalidCrons } from '../test-helpers/fixtures' +import { invalidCrons, validCrons } from '../test-helpers/fixtures' import { reset, setTimestamp } from '../test-helpers/helpers' let cron: CronInternalTestHelper | CronExternalTestHelper @@ -21,7 +21,7 @@ describe('Cron', () => { ) cronInternal = await cronInternalTestHelperFactory.deploy() const cronExternalFactory = await ethers.getContractFactory( - 'src/v0.8/libraries/external/Cron.sol:Cron', + 'src/v0.8/automation/libraries/external/Cron.sol:Cron', admin, ) const cronExternalLib = await cronExternalFactory.deploy() diff --git a/contracts/test/v0.8/KeeperRegistrar.test.ts b/contracts/test/v0.8/KeeperRegistrar.test.ts index f4af3bdff31..9cef1d0204f 100644 --- a/contracts/test/v0.8/KeeperRegistrar.test.ts +++ b/contracts/test/v0.8/KeeperRegistrar.test.ts @@ -28,7 +28,9 @@ let personas: Personas before(async () => { personas = (await getUsers()).personas - linkTokenFactory = await ethers.getContractFactory('LinkToken') + linkTokenFactory = await ethers.getContractFactory( + 'src/v0.4/LinkToken.sol:LinkToken', + ) mockV3AggregatorFactory = (await ethers.getContractFactory( 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', )) as unknown as MockV3AggregatorFactory diff --git a/contracts/test/v0.8/VRFSubscriptionBalanceMonitor.test.ts b/contracts/test/v0.8/VRFSubscriptionBalanceMonitor.test.ts index ef022209821..c13d144776c 100644 --- a/contracts/test/v0.8/VRFSubscriptionBalanceMonitor.test.ts +++ b/contracts/test/v0.8/VRFSubscriptionBalanceMonitor.test.ts @@ -2,8 +2,8 @@ import { ethers } from 'hardhat' import { assert, expect } from 'chai' import type { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' import { - VRFSubscriptionBalanceMonitorExposed, LinkToken, + VRFSubscriptionBalanceMonitorExposed, } from '../../typechain' import * as h from '../test-helpers/helpers' import { BigNumber, Contract } from 'ethers' @@ -65,7 +65,10 @@ describe('VRFSubscriptionBalanceMonitor', () => { 'VRFSubscriptionBalanceMonitorExposed', owner, ) - const ltFactory = await ethers.getContractFactory('LinkToken', owner) + const ltFactory = await ethers.getContractFactory( + 'src/v0.4/LinkToken.sol:LinkToken', + owner, + ) const coordinatorFactory = await ethers.getContractFactory( 'src/v0.8/vrf/VRFCoordinatorV2.sol:VRFCoordinatorV2', diff --git a/contracts/test/v0.8/automation/AutomationForwarder.test.ts b/contracts/test/v0.8/automation/AutomationForwarder.test.ts index 6fb91f5f77c..634bfb61ea9 100644 --- a/contracts/test/v0.8/automation/AutomationForwarder.test.ts +++ b/contracts/test/v0.8/automation/AutomationForwarder.test.ts @@ -1,7 +1,8 @@ import { expect } from 'chai' import { ethers } from 'hardhat' import { getUsers, Roles } from '../../test-helpers/setup' -import { AutomationForwarder } from '../../../typechain/AutomationForwarder' +import { IAutomationForwarder } from '../../../typechain/IAutomationForwarder' +import { IAutomationForwarder__factory as IAutomationForwarderFactory } from '../../../typechain/factories/IAutomationForwarder__factory' import { loadFixture } from '@nomicfoundation/hardhat-network-helpers' import { deployMockContract, @@ -15,12 +16,11 @@ import { * the contract factory, which deploys forwarder instances :) */ -const NOT_AUTHORIZED_ERR = 'NotAuthorized()' const CUSTOM_REVERT = 'this is a custom revert message' let roles: Roles let defaultAddress: string -let forwarder: AutomationForwarder +let forwarder: IAutomationForwarder let target: MockContract const targetABI = [ @@ -45,11 +45,24 @@ const setup = async () => { await target.mock.handler.returns() await target.mock.handlerUint.returns(100) await target.mock.iRevert.revertsWithReason(CUSTOM_REVERT) + const logicFactory = await ethers.getContractFactory( + 'AutomationForwarderLogic', + ) + const logicContract = await logicFactory + .connect(roles.defaultAccount) + .deploy() const factory = await ethers.getContractFactory('AutomationForwarder') - forwarder = await factory + const forwarderContract = await factory .connect(roles.defaultAccount) - .deploy(100, target.address, await roles.defaultAccount.getAddress()) - await forwarder.deployed() + .deploy( + target.address, + await roles.defaultAccount.getAddress(), + logicContract.address, + ) + forwarder = IAutomationForwarderFactory.connect( + forwarderContract.address, + roles.defaultAccount, + ) } describe('AutomationForwarder', () => { @@ -61,7 +74,6 @@ describe('AutomationForwarder', () => { it('sets the initial values', async () => { expect(await forwarder.getRegistry()).to.equal(defaultAddress) expect(await forwarder.getTarget()).to.equal(target.address) - expect(await forwarder.getUpkeepID()).to.equal(100) }) }) @@ -78,7 +90,7 @@ describe('AutomationForwarder', () => { it('is only callable by the registry', async () => { await expect( forwarder.connect(roles.stranger).forward(gas, HANDLER), - ).to.be.revertedWith(NOT_AUTHORIZED_ERR) + ).to.be.revertedWith('') await forwarder.connect(roles.defaultAccount).forward(gas, HANDLER) }) @@ -121,7 +133,7 @@ describe('AutomationForwarder', () => { it('is only callable by the existing registry', async () => { await expect( forwarder.connect(roles.stranger).updateRegistry(newRegistry), - ).to.be.revertedWith(NOT_AUTHORIZED_ERR) + ).to.be.revertedWith('') await forwarder.connect(roles.defaultAccount).updateRegistry(newRegistry) }) diff --git a/contracts/test/v0.8/automation/AutomationGasAnalysis.test.ts b/contracts/test/v0.8/automation/AutomationGasAnalysis.test.ts new file mode 100644 index 00000000000..c2e08f4cd81 --- /dev/null +++ b/contracts/test/v0.8/automation/AutomationGasAnalysis.test.ts @@ -0,0 +1,258 @@ +import { ethers } from 'hardhat' +import { BigNumber } from 'ethers' +import { expect, assert } from 'chai' +import { getUsers } from '../../test-helpers/setup' +import { randomAddress, toWei } from '../../test-helpers/helpers' +import { deployRegistry21 } from './helpers' + +// don't run these tests in CI +const describeMaybe = process.env.CI ? describe.skip : describe + +// registry settings +const f = 1 +const linkEth = BigNumber.from(300000000) +const gasWei = BigNumber.from(100) +const minUpkeepSpend = BigNumber.from('1000000000000000000') +const paymentPremiumPPB = BigNumber.from(250000000) +const flatFeeMicroLink = BigNumber.from(0) +const blockCountPerTurn = 20 +const checkGasLimit = BigNumber.from(20000000) +const fallbackGasPrice = BigNumber.from(200) +const fallbackLinkPrice = BigNumber.from(200000000) +const maxCheckDataSize = BigNumber.from(10000) +const maxPerformDataSize = BigNumber.from(10000) +const maxRevertDataSize = BigNumber.from(1000) +const maxPerformGas = BigNumber.from(5000000) +const stalenessSeconds = BigNumber.from(43820) +const gasCeilingMultiplier = BigNumber.from(1) +const signers = [ + randomAddress(), + randomAddress(), + randomAddress(), + randomAddress(), +] +const transmitters = [ + randomAddress(), + randomAddress(), + randomAddress(), + randomAddress(), +] +const transcoder = ethers.constants.AddressZero + +// registrar settings +const triggerType = 0 // conditional +const autoApproveType = 2 // auto-approve enabled +const autoApproveMaxAllowed = 100 // auto-approve enabled + +// upkeep settings +const name = 'test upkeep' +const encryptedEmail = '0xabcd1234' +const gasLimit = 100_000 +const checkData = '0xdeadbeef' +const amount = toWei('5') +const source = 5 +const triggerConfig = '0x' +const offchainConfig = '0x' + +describeMaybe('Automation Gas Analysis', () => { + it('Compares gas usage amongst registries / registrars', async () => { + assert( + Boolean(process.env.REPORT_GAS), + 'this test must be run with REPORT_GAS=true', + ) + + const personas = (await getUsers()).personas + const owner = personas.Default + const ownerAddress = await owner.getAddress() + + // factories + const getFact = ethers.getContractFactory + const linkTokenFactory = await getFact('LinkToken') + const mockV3AggregatorFactory = await getFact( + 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', + ) + const upkeepMockFactory = await getFact('UpkeepMock') + const registry12Factory = await getFact('KeeperRegistry1_2') + const registrar12Factory = await getFact('KeeperRegistrar') + const registry20Factory = await getFact('KeeperRegistry2_0') + const registryLogic20Factory = await getFact('KeeperRegistryLogic2_0') + const registrar20Factory = await getFact('KeeperRegistrar2_0') + const registrar21Factory = await getFact('AutomationRegistrar2_1') + const forwarderLogicFactory = await getFact('AutomationForwarderLogic') + + // deploy dependancy contracts + const linkToken = await linkTokenFactory.connect(owner).deploy() + const gasPriceFeed = await mockV3AggregatorFactory + .connect(owner) + .deploy(0, gasWei) + const linkEthFeed = await mockV3AggregatorFactory + .connect(owner) + .deploy(9, linkEth) + const upkeep = await upkeepMockFactory.connect(owner).deploy() + + // deploy v1.2 + const registrar12 = await registrar12Factory.connect(owner).deploy( + linkToken.address, + autoApproveType, + autoApproveMaxAllowed, + ethers.constants.AddressZero, // set later + minUpkeepSpend, + ) + const registry12 = await registry12Factory + .connect(owner) + .deploy(linkToken.address, linkEthFeed.address, gasPriceFeed.address, { + paymentPremiumPPB, + flatFeeMicroLink, + blockCountPerTurn, + checkGasLimit, + stalenessSeconds, + gasCeilingMultiplier, + minUpkeepSpend, + maxPerformGas, + fallbackGasPrice, + fallbackLinkPrice, + transcoder, + registrar: registrar12.address, + }) + await registrar12.setRegistrationConfig( + autoApproveType, + autoApproveMaxAllowed, + registry12.address, + minUpkeepSpend, + ) + + // deploy v2.0 + const registryLogic20 = await registryLogic20Factory + .connect(owner) + .deploy(0, linkToken.address, linkEthFeed.address, gasPriceFeed.address) + const registry20 = await registry20Factory + .connect(owner) + .deploy(registryLogic20.address) + const registrar20 = await registrar20Factory + .connect(owner) + .deploy( + linkToken.address, + autoApproveType, + autoApproveMaxAllowed, + registry20.address, + minUpkeepSpend, + ) + const config20 = { + paymentPremiumPPB, + flatFeeMicroLink, + checkGasLimit, + stalenessSeconds, + gasCeilingMultiplier, + minUpkeepSpend, + maxCheckDataSize, + maxPerformDataSize, + maxPerformGas, + fallbackGasPrice, + fallbackLinkPrice, + transcoder, + registrar: registrar20.address, + } + const onchainConfig20 = ethers.utils.defaultAbiCoder.encode( + [ + 'tuple(uint32 paymentPremiumPPB,uint32 flatFeeMicroLink,uint32 checkGasLimit,uint24 stalenessSeconds\ + ,uint16 gasCeilingMultiplier,uint96 minUpkeepSpend,uint32 maxPerformGas,uint32 maxCheckDataSize,\ + uint32 maxPerformDataSize,uint256 fallbackGasPrice,uint256 fallbackLinkPrice,address transcoder,\ + address registrar)', + ], + [config20], + ) + await registry20 + .connect(owner) + .setConfig(signers, transmitters, f, onchainConfig20, 1, '0x') + + // deploy v2.1 + const forwarderLogic = await forwarderLogicFactory.connect(owner).deploy() + const registry21 = await deployRegistry21( + owner, + 0, + linkToken.address, + linkEthFeed.address, + gasPriceFeed.address, + forwarderLogic.address, + ) + const registrar21 = await registrar21Factory + .connect(owner) + .deploy(linkToken.address, registry21.address, minUpkeepSpend, [ + { + triggerType, + autoApproveType, + autoApproveMaxAllowed, + }, + ]) + const onchainConfig21 = { + paymentPremiumPPB, + flatFeeMicroLink, + checkGasLimit, + stalenessSeconds, + gasCeilingMultiplier, + minUpkeepSpend, + maxCheckDataSize, + maxPerformDataSize, + maxRevertDataSize, + maxPerformGas, + fallbackGasPrice, + fallbackLinkPrice, + transcoder, + registrars: [registrar21.address], + upkeepPrivilegeManager: randomAddress(), + } + await registry21 + .connect(owner) + .setConfigTypeSafe(signers, transmitters, f, onchainConfig21, 1, '0x') + + // approve LINK + await linkToken.connect(owner).approve(registrar20.address, amount) + await linkToken.connect(owner).approve(registrar21.address, amount) + + const abiEncodedBytes = registrar12.interface.encodeFunctionData( + 'register', + [ + name, + encryptedEmail, + upkeep.address, + gasLimit, + ownerAddress, + checkData, + amount, + source, + ownerAddress, + ], + ) + + let tx = await linkToken + .connect(owner) + .transferAndCall(registrar12.address, amount, abiEncodedBytes) + await expect(tx).to.emit(registry12, 'UpkeepRegistered') + + tx = await registrar20.connect(owner).registerUpkeep({ + name, + encryptedEmail, + upkeepContract: upkeep.address, + gasLimit, + adminAddress: ownerAddress, + checkData, + amount, + offchainConfig, + }) + await expect(tx).to.emit(registry20, 'UpkeepRegistered') + + tx = await registrar21.connect(owner).registerUpkeep({ + name, + encryptedEmail, + upkeepContract: upkeep.address, + gasLimit, + adminAddress: ownerAddress, + triggerType, + checkData, + amount, + triggerConfig, + offchainConfig, + }) + await expect(tx).to.emit(registry21, 'UpkeepRegistered') + }) +}) diff --git a/contracts/test/v0.8/automation/AutomationRegistrar2_1.test.ts b/contracts/test/v0.8/automation/AutomationRegistrar2_1.test.ts index 5912373e9a7..323050def56 100644 --- a/contracts/test/v0.8/automation/AutomationRegistrar2_1.test.ts +++ b/contracts/test/v0.8/automation/AutomationRegistrar2_1.test.ts @@ -29,7 +29,9 @@ let personas: Personas before(async () => { personas = (await getUsers()).personas - linkTokenFactory = await ethers.getContractFactory('LinkToken') + linkTokenFactory = await ethers.getContractFactory( + 'src/v0.4/LinkToken.sol:LinkToken', + ) mockV3AggregatorFactory = (await ethers.getContractFactory( 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', )) as unknown as MockV3AggregatorFactory @@ -163,9 +165,7 @@ describe('AutomationRegistrar2_1', () => { } await registry .connect(owner) - [ - 'setConfig(address[],address[],uint8,(uint32,uint32,uint32,uint24,uint16,uint96,uint32,uint32,uint32,uint32,uint256,uint256,address,address[],address),uint64,bytes)' - ](keepers, keepers, 1, onchainConfig, 1, '0x') + .setConfigTypeSafe(keepers, keepers, 1, onchainConfig, 1, '0x') }) describe('#typeAndVersion', () => { diff --git a/contracts/test/v0.8/automation/CronUpkeep.test.ts b/contracts/test/v0.8/automation/CronUpkeep.test.ts index 2291fd21d91..755b4494c81 100644 --- a/contracts/test/v0.8/automation/CronUpkeep.test.ts +++ b/contracts/test/v0.8/automation/CronUpkeep.test.ts @@ -81,7 +81,7 @@ describe('CronUpkeep', () => { ) cronDelegate = await cronDelegateFactory.deploy() const cronExternalFactory = await ethers.getContractFactory( - 'src/v0.8/libraries/external/Cron.sol:Cron', + 'src/v0.8/automation/libraries/external/Cron.sol:Cron', admin, ) const cronExternalLib = await cronExternalFactory.deploy() @@ -521,7 +521,7 @@ describe.skip('Cron Gas Usage', () => { ) const cronDelegate = await cronDelegateFactory.deploy() const cronExternalFactory = await ethers.getContractFactory( - 'src/v0.8/libraries/external/Cron.sol:Cron', + 'src/v0.8/automation/libraries/external/Cron.sol:Cron', admin, ) const cronExternalLib = await cronExternalFactory.deploy() diff --git a/contracts/test/v0.8/automation/CronUpkeepFactory.test.ts b/contracts/test/v0.8/automation/CronUpkeepFactory.test.ts index aaa1753de10..e9a7de837b7 100644 --- a/contracts/test/v0.8/automation/CronUpkeepFactory.test.ts +++ b/contracts/test/v0.8/automation/CronUpkeepFactory.test.ts @@ -3,8 +3,8 @@ import { Contract } from 'ethers' import { assert, expect } from 'chai' import { CronUpkeepFactory } from '../../../typechain/CronUpkeepFactory' import type { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' -import { reset } from '../../test-helpers/helpers' import * as h from '../../test-helpers/helpers' +import { reset } from '../../test-helpers/helpers' const OWNABLE_ERR = 'Only callable by owner' @@ -22,7 +22,7 @@ describe('CronUpkeepFactory', () => { owner = accounts[1] stranger = accounts[2] const cronExternalFactory = await ethers.getContractFactory( - 'src/v0.8/libraries/external/Cron.sol:Cron', + 'src/v0.8/automation/libraries/external/Cron.sol:Cron', admin, ) cronExternalLib = await cronExternalFactory.deploy() diff --git a/contracts/test/v0.8/automation/ERC20BalanceMonitor.test.ts b/contracts/test/v0.8/automation/ERC20BalanceMonitor.test.ts index 95e72cb0ca4..afab7af5107 100644 --- a/contracts/test/v0.8/automation/ERC20BalanceMonitor.test.ts +++ b/contracts/test/v0.8/automation/ERC20BalanceMonitor.test.ts @@ -66,7 +66,10 @@ describe('ERC20BalanceMonitor', () => { 'ERC20BalanceMonitorExposed', owner, ) - const ltFactory = await ethers.getContractFactory('LinkToken', owner) + const ltFactory = await ethers.getContractFactory( + 'src/v0.4/LinkToken.sol:LinkToken', + owner, + ) const reFactory = await ethers.getContractFactory('ReceiveEmitter', owner) const rfeFactory = await ethers.getContractFactory( 'ReceiveFallbackEmitter', diff --git a/contracts/test/v0.8/automation/KeeperRegistrar2_0.test.ts b/contracts/test/v0.8/automation/KeeperRegistrar2_0.test.ts index 6fdc0668f93..14a5c7eba2d 100644 --- a/contracts/test/v0.8/automation/KeeperRegistrar2_0.test.ts +++ b/contracts/test/v0.8/automation/KeeperRegistrar2_0.test.ts @@ -31,7 +31,9 @@ let personas: Personas before(async () => { personas = (await getUsers()).personas - linkTokenFactory = await ethers.getContractFactory('LinkToken') + linkTokenFactory = await ethers.getContractFactory( + 'src/v0.4/LinkToken.sol:LinkToken', + ) mockV3AggregatorFactory = (await ethers.getContractFactory( 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', )) as unknown as MockV3AggregatorFactory diff --git a/contracts/test/v0.8/automation/KeeperRegistry1_2.test.ts b/contracts/test/v0.8/automation/KeeperRegistry1_2.test.ts index cc8ee3a8d08..ba026fa18d9 100644 --- a/contracts/test/v0.8/automation/KeeperRegistry1_2.test.ts +++ b/contracts/test/v0.8/automation/KeeperRegistry1_2.test.ts @@ -67,7 +67,9 @@ let personas: Personas before(async () => { personas = (await getUsers()).personas - linkTokenFactory = await ethers.getContractFactory('LinkToken') + linkTokenFactory = await ethers.getContractFactory( + 'src/v0.4/LinkToken.sol:LinkToken', + ) // need full path because there are two contracts with name MockV3Aggregator mockV3AggregatorFactory = (await ethers.getContractFactory( 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', diff --git a/contracts/test/v0.8/automation/KeeperRegistry1_3.test.ts b/contracts/test/v0.8/automation/KeeperRegistry1_3.test.ts index c58fb4d7655..eee4344b461 100644 --- a/contracts/test/v0.8/automation/KeeperRegistry1_3.test.ts +++ b/contracts/test/v0.8/automation/KeeperRegistry1_3.test.ts @@ -76,7 +76,9 @@ let personas: Personas before(async () => { personas = (await getUsers()).personas - linkTokenFactory = await ethers.getContractFactory('LinkToken') + linkTokenFactory = await ethers.getContractFactory( + 'src/v0.4/LinkToken.sol:LinkToken', + ) // need full path because there are two contracts with name MockV3Aggregator mockV3AggregatorFactory = (await ethers.getContractFactory( 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', diff --git a/contracts/test/v0.8/automation/KeeperRegistry2_0.test.ts b/contracts/test/v0.8/automation/KeeperRegistry2_0.test.ts index 7a9779b1e88..9886e84854b 100644 --- a/contracts/test/v0.8/automation/KeeperRegistry2_0.test.ts +++ b/contracts/test/v0.8/automation/KeeperRegistry2_0.test.ts @@ -252,7 +252,9 @@ const parseCancelledUpkeepReportLogs = (receipt: any) => { before(async () => { personas = (await getUsers()).personas - linkTokenFactory = await ethers.getContractFactory('LinkToken') + linkTokenFactory = await ethers.getContractFactory( + 'src/v0.4/LinkToken.sol:LinkToken', + ) // need full path because there are two contracts with name MockV3Aggregator mockV3AggregatorFactory = (await ethers.getContractFactory( 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', diff --git a/contracts/test/v0.8/automation/KeeperRegistry2_1.test.ts b/contracts/test/v0.8/automation/KeeperRegistry2_1.test.ts index d7f9a60ebd1..8ddc2f450e6 100644 --- a/contracts/test/v0.8/automation/KeeperRegistry2_1.test.ts +++ b/contracts/test/v0.8/automation/KeeperRegistry2_1.test.ts @@ -4,15 +4,15 @@ import { assert, expect } from 'chai' import { BigNumber, BigNumberish, - Signer, - Wallet, - ContractTransaction, BytesLike, ContractReceipt, + ContractTransaction, + Signer, + Wallet, } from 'ethers' import { evmRevert } from '../../test-helpers/matchers' import { getUsers, Personas } from '../../test-helpers/setup' -import { toWei } from '../../test-helpers/helpers' +import { randomAddress, toWei } from '../../test-helpers/helpers' import { LinkToken__factory as LinkTokenFactory } from '../../../typechain/factories/LinkToken__factory' import { MercuryUpkeep__factory as MercuryUpkeepFactory } from '../../../typechain/factories/MercuryUpkeep__factory' import { MockV3Aggregator__factory as MockV3AggregatorFactory } from '../../../typechain/factories/MockV3Aggregator__factory' @@ -21,6 +21,7 @@ import { UpkeepAutoFunder__factory as UpkeepAutoFunderFactory } from '../../../t import { MockArbGasInfo__factory as MockArbGasInfoFactory } from '../../../typechain/factories/MockArbGasInfo__factory' import { MockOVMGasPriceOracle__factory as MockOVMGasPriceOracleFactory } from '../../../typechain/factories/MockOVMGasPriceOracle__factory' import { ILogAutomation__factory as ILogAutomationactory } from '../../../typechain/factories/ILogAutomation__factory' +import { IAutomationForwarder__factory as IAutomationForwarderFactory } from '../../../typechain/factories/IAutomationForwarder__factory' import { MockArbSys__factory as MockArbSysFactory } from '../../../typechain/factories/MockArbSys__factory' import { AutomationUtils2_1 as AutomationUtils } from '../../../typechain/AutomationUtils2_1' import { MercuryUpkeep } from '../../../typechain/MercuryUpkeep' @@ -32,12 +33,12 @@ import { MockOVMGasPriceOracle } from '../../../typechain/MockOVMGasPriceOracle' import { UpkeepTranscoder } from '../../../typechain/UpkeepTranscoder' import { UpkeepAutoFunder } from '../../../typechain' import { + CancelledUpkeepReportEvent, IKeeperRegistryMaster as IKeeperRegistry, - UpkeepPerformedEvent, + InsufficientFundsUpkeepReportEvent, ReorgedUpkeepReportEvent, StaleUpkeepReportEvent, - InsufficientFundsUpkeepReportEvent, - CancelledUpkeepReportEvent, + UpkeepPerformedEvent, } from '../../../typechain/IKeeperRegistryMaster' import { deployMockContract, @@ -82,16 +83,9 @@ type LogTrigger = Parameters[0] type ConditionalTrigger = Parameters[0] type Log = Parameters[0] -// function signatures for the two setConfig methods -const setConfigRaw = 'setConfig(address[],address[],uint8,bytes,uint64,bytes)' -const setConfigExplicit = - 'setConfig(address[],address[],uint8,(uint32,uint32,uint32,uint24,uint16,uint96,uint32,uint32,uint32,uint32,uint256,uint256,address,address[],address),uint64,bytes)' - // ----------------------------------------------------------------------------------------------- // These values should match the constants declared in registry -let transmitGasOverhead: BigNumber -let checkGasOverhead: BigNumber let registryConditionalOverhead: BigNumber let registryLogOverhead: BigNumber let registryPerSignerGasOverhead: BigNumber @@ -117,6 +111,9 @@ const emptyBytes = '0x' const emptyBytes32 = '0x0000000000000000000000000000000000000000000000000000000000000000' +const transmitGasOverhead = 1_000_000 +const checkGasOverhead = 400_000 + const stalenessSeconds = BigNumber.from(43820) const gasCeilingMultiplier = BigNumber.from(2) const checkGasLimit = BigNumber.from(10000000) @@ -166,10 +163,6 @@ let mockOVMGasPriceOracle: MockOVMGasPriceOracle let mercuryUpkeep: MercuryUpkeep let automationUtils: AutomationUtils -function randomAddress() { - return ethers.Wallet.createRandom().address -} - function now() { return Math.floor(Date.now() / 1000) } @@ -309,7 +302,7 @@ const parseUpkeepPerformedLogs = (receipt: ContractReceipt) => { if ( log.name == registry.interface.events[ - 'UpkeepPerformed(uint256,bool,uint96,uint256,uint256,bytes32)' + 'UpkeepPerformed(uint256,bool,uint96,uint256,uint256,bytes)' ].name ) { parsedLogs.push(log as unknown as UpkeepPerformedEvent) @@ -328,7 +321,7 @@ const parseReorgedUpkeepReportLogs = (receipt: ContractReceipt) => { const log = registry.interface.parseLog(rawLog) if ( log.name == - registry.interface.events['ReorgedUpkeepReport(uint256,bytes32)'].name + registry.interface.events['ReorgedUpkeepReport(uint256,bytes)'].name ) { parsedLogs.push(log as unknown as ReorgedUpkeepReportEvent) } @@ -346,7 +339,7 @@ const parseStaleUpkeepReportLogs = (receipt: ContractReceipt) => { const log = registry.interface.parseLog(rawLog) if ( log.name == - registry.interface.events['StaleUpkeepReport(uint256,bytes32)'].name + registry.interface.events['StaleUpkeepReport(uint256,bytes)'].name ) { parsedLogs.push(log as unknown as StaleUpkeepReportEvent) } @@ -365,7 +358,7 @@ const parseInsufficientFundsUpkeepReportLogs = (receipt: ContractReceipt) => { if ( log.name == registry.interface.events[ - 'InsufficientFundsUpkeepReport(uint256,bytes32)' + 'InsufficientFundsUpkeepReport(uint256,bytes)' ].name ) { parsedLogs.push(log as unknown as InsufficientFundsUpkeepReportEvent) @@ -384,7 +377,7 @@ const parseCancelledUpkeepReportLogs = (receipt: ContractReceipt) => { const log = registry.interface.parseLog(rawLog) if ( log.name == - registry.interface.events['CancelledUpkeepReport(uint256,bytes32)'].name + registry.interface.events['CancelledUpkeepReport(uint256,bytes)'].name ) { parsedLogs.push(log as unknown as CancelledUpkeepReportEvent) } @@ -425,9 +418,7 @@ describe('KeeperRegistry2_1', () => { let signers: Wallet[] let signerAddresses: string[] let config: any - let baseConfig: Parameters< - IKeeperRegistry['setConfig(address[],address[],uint8,bytes,uint64,bytes)'] - > + let baseConfig: Parameters let upkeepManager: string before(async () => { @@ -436,7 +427,9 @@ describe('KeeperRegistry2_1', () => { const utilsFactory = await ethers.getContractFactory('AutomationUtils2_1') automationUtils = await utilsFactory.deploy() - linkTokenFactory = await ethers.getContractFactory('LinkToken') + linkTokenFactory = await ethers.getContractFactory( + 'src/v0.4/LinkToken.sol:LinkToken', + ) // need full path because there are two contracts with name MockV3Aggregator mockV3AggregatorFactory = (await ethers.getContractFactory( 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', @@ -614,7 +607,7 @@ describe('KeeperRegistry2_1', () => { .add(registryPerPerformByteGasOverhead.mul(maxPerformDataSize)) for (const test of tests) { - await registry.connect(owner)[setConfigRaw]( + await registry.connect(owner).setConfig( signerAddresses, keeperAddresses, f, @@ -932,8 +925,6 @@ describe('KeeperRegistry2_1', () => { gasPriceFeed.address, ) - transmitGasOverhead = await registry.getTransmitGasOverhead() - checkGasOverhead = await registry.getCheckGasOverhead() registryConditionalOverhead = await registry.getConditionalGasOverhead() registryLogOverhead = await registry.getLogGasOverhead() registryPerSignerGasOverhead = await registry.getPerSignerGasOverhead() @@ -942,7 +933,7 @@ describe('KeeperRegistry2_1', () => { cancellationDelay = (await registry.getCancellationDelay()).toNumber() for (const reg of [registry, arbRegistry, opRegistry, mgRegistry]) { - await reg.connect(owner)[setConfigRaw](...baseConfig) + await reg.connect(owner).setConfig(...baseConfig) await reg.connect(owner).setPayees(payees) await linkToken.connect(admin).approve(reg.address, toWei('1000')) await linkToken.connect(owner).approve(reg.address, toWei('1000')) @@ -1203,18 +1194,29 @@ describe('KeeperRegistry2_1', () => { } }) - it('handles duplicate logTriggerIDs', async () => { + it('handles duplicate log triggers', async () => { + const txHash = ethers.utils.randomBytes(32) + const logIndex = 0 + const expectedDedupKey = ethers.utils.solidityKeccak256( + ['uint256', 'bytes32', 'uint32'], + [logUpkeepId, txHash, logIndex], + ) + assert.isFalse(await registry.hasDedupKey(expectedDedupKey)) const tx = await getTransmitTx( registry, keeper1, [logUpkeepId, logUpkeepId], - { txHash: ethers.utils.randomBytes(32), logIndex: 0 }, // will result in the same logTriggerID + { txHash, logIndex }, // will result in the same dedup key ) const receipt = await tx.wait() const staleUpkeepReport = parseStaleUpkeepReportLogs(receipt) const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) assert.equal(staleUpkeepReport.length, 1) assert.equal(upkeepPerformedLogs.length, 1) + assert.isTrue(await registry.hasDedupKey(expectedDedupKey)) + await expect(tx) + .to.emit(registry, 'DedupKeyAdded') + .withArgs(expectedDedupKey) }) it('returns early when check block number is less than last perform (block)', async () => { @@ -1715,7 +1717,7 @@ describe('KeeperRegistry2_1', () => { itMaybe( 'has a large enough gas overhead to cover upkeep that use all its gas [ @skip-coverage ]', async () => { - await registry.connect(owner)[setConfigExplicit]( + await registry.connect(owner).setConfigTypeSafe( signerAddresses, keeperAddresses, 10, // maximise f to maximise overhead @@ -1760,7 +1762,7 @@ describe('KeeperRegistry2_1', () => { const newF = fArray[i] await registry .connect(owner) - [setConfigExplicit]( + .setConfigTypeSafe( signerAddresses, keeperAddresses, newF, @@ -1799,24 +1801,18 @@ describe('KeeperRegistry2_1', () => { const id = upkeepPerformedLog.args.id const success = upkeepPerformedLog.args.success - const triggerID = upkeepPerformedLog.args.upkeepTriggerID + const trigger = upkeepPerformedLog.args.trigger const gasUsed = upkeepPerformedLog.args.gasUsed const gasOverhead = upkeepPerformedLog.args.gasOverhead const totalPayment = upkeepPerformedLog.args.totalPayment assert.equal(id.toString(), upkeepId.toString()) assert.equal(success, true) assert.equal( - triggerID, - ethers.utils.keccak256( - ethers.utils.concat([ - ethers.utils.defaultAbiCoder.encode(['uint256'], [upkeepId]), - encodeBlockTrigger({ - blockNum: checkBlock.number, - blockHash: checkBlock.hash, - }), - ]), - ), - 'incorrect calculation of triggerID', + trigger, + encodeBlockTrigger({ + blockNum: checkBlock.number, + blockHash: checkBlock.hash, + }), ) assert.isTrue(gasUsed.gt(BigNumber.from('0'))) assert.isTrue(gasOverhead.gt(BigNumber.from('0'))) @@ -1907,7 +1903,7 @@ describe('KeeperRegistry2_1', () => { await mock.setPerformGasToBurn(performGas) await registry .connect(owner) - [setConfigExplicit]( + .setConfigTypeSafe( signerAddresses, keeperAddresses, newF, @@ -2015,7 +2011,7 @@ describe('KeeperRegistry2_1', () => { const performData = '0x' await mock.setCanPerform(true) await mock.setPerformGasToBurn(performGas) - await registry[setConfigExplicit]( + await registry.setConfigTypeSafe( signerAddresses, keeperAddresses, newF, @@ -2869,6 +2865,18 @@ describe('KeeperRegistry2_1', () => { ) }) + describe('after the registration is paused, then cancelled', () => { + it('allows the admin to withdraw', async () => { + const balance = await registry.getBalance(upkeepId) + const payee = await payee1.getAddress() + await registry.connect(admin).pauseUpkeep(upkeepId) + await registry.connect(owner).cancelUpkeep(upkeepId) + await expect(() => + registry.connect(admin).withdrawFunds(upkeepId, payee), + ).to.changeTokenBalance(linkToken, payee1, balance) + }) + }) + describe('after the registration is cancelled', () => { beforeEach(async () => { await registry.connect(owner).cancelUpkeep(upkeepId) @@ -3193,7 +3201,7 @@ describe('KeeperRegistry2_1', () => { data: ethers.utils.randomBytes(1000), } - await ltUpkeep.mock.checkLog.withArgs(log).returns(true, '0x1234') + await ltUpkeep.mock.checkLog.withArgs(log, '0x').returns(true, '0x1234') const checkData = encodeLog(log) @@ -3535,7 +3543,7 @@ describe('KeeperRegistry2_1', () => { await evmRevert( registry .connect(payee1) - [setConfigExplicit]( + .setConfigTypeSafe( signerAddresses, keeperAddresses, f, @@ -3547,6 +3555,46 @@ describe('KeeperRegistry2_1', () => { ) }) + it('reverts if signers or transmitters are the zero address', async () => { + await evmRevert( + registry + .connect(owner) + .setConfigTypeSafe( + [randomAddress(), randomAddress(), randomAddress(), zeroAddress], + [ + randomAddress(), + randomAddress(), + randomAddress(), + randomAddress(), + ], + f, + newConfig, + offchainVersion, + offchainBytes, + ), + 'InvalidSigner()', + ) + + await evmRevert( + registry + .connect(owner) + .setConfigTypeSafe( + [ + randomAddress(), + randomAddress(), + randomAddress(), + randomAddress(), + ], + [randomAddress(), randomAddress(), randomAddress(), zeroAddress], + f, + newConfig, + offchainVersion, + offchainBytes, + ), + 'InvalidTransmitter()', + ) + }) + it('updates the onchainConfig and configDigest', async () => { const old = await registry.getState() const oldConfig = old.config @@ -3558,7 +3606,7 @@ describe('KeeperRegistry2_1', () => { await registry .connect(owner) - [setConfigExplicit]( + .setConfigTypeSafe( signerAddresses, keeperAddresses, f, @@ -3621,7 +3669,7 @@ describe('KeeperRegistry2_1', () => { await registry .connect(owner) - [setConfigExplicit]( + .setConfigTypeSafe( signerAddresses, keeperAddresses, f, @@ -3637,7 +3685,7 @@ describe('KeeperRegistry2_1', () => { it('emits an event', async () => { const tx = await registry .connect(owner) - [setConfigExplicit]( + .setConfigTypeSafe( signerAddresses, keeperAddresses, f, @@ -3665,7 +3713,7 @@ describe('KeeperRegistry2_1', () => { await evmRevert( registry .connect(payee1) - [setConfigExplicit]( + .setConfigTypeSafe( newKeepers, newKeepers, f, @@ -3684,7 +3732,7 @@ describe('KeeperRegistry2_1', () => { await evmRevert( registry .connect(owner) - [setConfigExplicit]( + .setConfigTypeSafe( newKeepers, newKeepers, f, @@ -3700,7 +3748,7 @@ describe('KeeperRegistry2_1', () => { await evmRevert( registry .connect(owner) - [setConfigExplicit]( + .setConfigTypeSafe( newKeepers, newKeepers, 0, @@ -3717,7 +3765,7 @@ describe('KeeperRegistry2_1', () => { await evmRevert( registry .connect(owner) - [setConfigExplicit]( + .setConfigTypeSafe( signers, newKeepers, f, @@ -3734,7 +3782,7 @@ describe('KeeperRegistry2_1', () => { await evmRevert( registry .connect(owner) - [setConfigExplicit]( + .setConfigTypeSafe( newKeepers, newKeepers, f, @@ -3756,7 +3804,7 @@ describe('KeeperRegistry2_1', () => { await evmRevert( registry .connect(owner) - [setConfigExplicit]( + .setConfigTypeSafe( newSigners, newKeepers, f, @@ -3778,7 +3826,7 @@ describe('KeeperRegistry2_1', () => { await evmRevert( registry .connect(owner) - [setConfigExplicit]( + .setConfigTypeSafe( newKeepers, newTransmitters, f, @@ -3806,7 +3854,7 @@ describe('KeeperRegistry2_1', () => { const newSigners = newKeepers tx = await registry .connect(owner) - [setConfigExplicit]( + .setConfigTypeSafe( newSigners, newKeepers, f, @@ -4490,7 +4538,7 @@ describe('KeeperRegistry2_1', () => { await registry.connect(admin).addFunds(upkeepId, toWei('100')) // Very high min spend, whole balance as cancellation fees const minUpkeepSpend = toWei('1000') - await registry.connect(owner)[setConfigExplicit]( + await registry.connect(owner).setConfigTypeSafe( signerAddresses, keeperAddresses, f, @@ -4735,10 +4783,10 @@ describe('KeeperRegistry2_1', () => { expect((await registry.getState()).state.numUpkeeps).to.equal( numUpkeeps, ) - const forwarderFactory = await ethers.getContractFactory( - 'AutomationForwarder', + const forwarder = await IAutomationForwarderFactory.connect( + forwarderAddress, + owner, ) - const forwarder = await forwarderFactory.attach(forwarderAddress) expect(await forwarder.getRegistry()).to.equal(registry.address) // Set an upkeep admin transfer in progress too await registry @@ -4894,7 +4942,7 @@ describe('KeeperRegistry2_1', () => { }) it('reverts if the payee is the zero address', async () => { - await blankRegistry.connect(owner)[setConfigRaw](...baseConfig) // used to test initial config + await blankRegistry.connect(owner).setConfig(...baseConfig) // used to test initial config await evmRevert( blankRegistry // used to test initial config @@ -4908,7 +4956,7 @@ describe('KeeperRegistry2_1', () => { 'sets the payees when exisitng payees are zero address', async () => { //Initial payees should be zero address - await blankRegistry.connect(owner)[setConfigRaw](...baseConfig) // used to test initial config + await blankRegistry.connect(owner).setConfig(...baseConfig) // used to test initial config for (let i = 0; i < keeperAddresses.length; i++) { const payee = ( @@ -4940,7 +4988,7 @@ describe('KeeperRegistry2_1', () => { // configure registry with 5 keepers // optimism registry await blankRegistry // used to test initial configurations .connect(owner) - [setConfigExplicit]( + .setConfigTypeSafe( signers, keepers, f, @@ -4955,7 +5003,7 @@ describe('KeeperRegistry2_1', () => { // add another keeper // optimism registry await blankRegistry // used to test initial configurations .connect(owner) - [setConfigExplicit]( + .setConfigTypeSafe( [...signers, randomAddress()], [...keepers, newTransmitter], f, @@ -5134,7 +5182,7 @@ describe('KeeperRegistry2_1', () => { it('deducts a cancellation fee from the upkeep and gives to owner', async () => { const minUpkeepSpend = toWei('10') - await registry.connect(owner)[setConfigExplicit]( + await registry.connect(owner).setConfigTypeSafe( signerAddresses, keeperAddresses, f, @@ -5187,7 +5235,7 @@ describe('KeeperRegistry2_1', () => { it('deducts up to balance as cancellation fee', async () => { // Very high min spend, should deduct whole balance as cancellation fees const minUpkeepSpend = toWei('1000') - await registry.connect(owner)[setConfigExplicit]( + await registry.connect(owner).setConfigTypeSafe( signerAddresses, keeperAddresses, f, @@ -5235,7 +5283,7 @@ describe('KeeperRegistry2_1', () => { it('does not deduct cancellation fee if more than minUpkeepSpend is spent', async () => { // Very low min spend, already spent in one perform upkeep const minUpkeepSpend = BigNumber.from(420) - await registry.connect(owner)[setConfigExplicit]( + await registry.connect(owner).setConfigTypeSafe( signerAddresses, keeperAddresses, f, @@ -5634,7 +5682,7 @@ describe('KeeperRegistry2_1', () => { maxAllowedSpareChange = maxAllowedSpareChange.add(BigNumber.from('31')) await verifyConsistentAccounting(maxAllowedSpareChange) - await registry.connect(owner)[setConfigExplicit]( + await registry.connect(owner).setConfigTypeSafe( signerAddresses.slice(2, 15), // only use 2-14th index keepers keeperAddresses.slice(2, 15), f, @@ -5666,7 +5714,7 @@ describe('KeeperRegistry2_1', () => { ) await verifyConsistentAccounting(maxAllowedSpareChange) - await registry.connect(owner)[setConfigExplicit]( + await registry.connect(owner).setConfigTypeSafe( signerAddresses.slice(0, 4), // only use 0-3rd index keepers keeperAddresses.slice(0, 4), f, diff --git a/contracts/test/v0.8/automation/LinkAvailableBalanceMonitor.test.ts b/contracts/test/v0.8/automation/LinkAvailableBalanceMonitor.test.ts index d77401a009a..4efd98039f5 100644 --- a/contracts/test/v0.8/automation/LinkAvailableBalanceMonitor.test.ts +++ b/contracts/test/v0.8/automation/LinkAvailableBalanceMonitor.test.ts @@ -3,16 +3,17 @@ import chai, { assert, expect } from 'chai' import type { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' import { loadFixture } from '@nomicfoundation/hardhat-network-helpers' import * as h from '../../test-helpers/helpers' +import { mineBlock } from '../../test-helpers/helpers' import { IAggregatorProxy__factory as IAggregatorProxyFactory } from '../../../typechain/factories/IAggregatorProxy__factory' import { ILinkAvailable__factory as ILinkAvailableFactory } from '../../../typechain/factories/ILinkAvailable__factory' import { LinkAvailableBalanceMonitor, LinkToken } from '../../../typechain' import { BigNumber } from 'ethers' -import { mineBlock } from '../../test-helpers/helpers' import deepEqualInAnyOrder from 'deep-equal-in-any-order' import { deployMockContract, MockContract, } from '@ethereum-waffle/mock-contract' + chai.use(deepEqualInAnyOrder) //////////////////////////////// GAS USAGE LIMITS - CHANGE WITH CAUTION ////////////////////////// @@ -136,7 +137,10 @@ const setup = async () => { 'LinkAvailableBalanceMonitor', owner, ) - const ltFactory = await ethers.getContractFactory('LinkToken', owner) + const ltFactory = await ethers.getContractFactory( + 'src/v0.4/LinkToken.sol:LinkToken', + owner, + ) lt = await ltFactory.deploy() labm = await labmFactory.deploy(lt.address, twoLINK) diff --git a/contracts/test/v0.8/automation/UpkeepTranscoder3_0.test.ts b/contracts/test/v0.8/automation/UpkeepTranscoder3_0.test.ts index 93ae2a44ea9..8bad7f63873 100644 --- a/contracts/test/v0.8/automation/UpkeepTranscoder3_0.test.ts +++ b/contracts/test/v0.8/automation/UpkeepTranscoder3_0.test.ts @@ -127,7 +127,9 @@ before(async () => { ) personas = (await getUsers()).personas - linkTokenFactory = await ethers.getContractFactory('LinkToken') + linkTokenFactory = await ethers.getContractFactory( + 'src/v0.4/LinkToken.sol:LinkToken', + ) // need full path because there are two contracts with name MockV3Aggregator mockV3AggregatorFactory = (await ethers.getContractFactory( 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', diff --git a/contracts/test/v0.8/automation/UpkeepTranscoder4_0.test.ts b/contracts/test/v0.8/automation/UpkeepTranscoder4_0.test.ts index f7759f935ba..7c7715fd599 100644 --- a/contracts/test/v0.8/automation/UpkeepTranscoder4_0.test.ts +++ b/contracts/test/v0.8/automation/UpkeepTranscoder4_0.test.ts @@ -13,15 +13,14 @@ import { KeeperRegistryLogic1_3__factory as KeeperRegistryLogicFactory } from '. import { toWei } from '../../test-helpers/helpers' import { loadFixture } from '@nomicfoundation/hardhat-network-helpers' import { - LinkToken, - MockV3Aggregator, + IKeeperRegistryMaster, KeeperRegistry1_2, KeeperRegistry1_3, KeeperRegistry2_0, - IKeeperRegistryMaster, + LinkToken, + MockV3Aggregator, UpkeepMock, } from '../../../typechain' -import {} from '../../../typechain' import { deployRegistry21 } from './helpers' let transcoder: UpkeepTranscoder @@ -96,7 +95,7 @@ async function getUpkeepID(tx: any): Promise { return receipt.events[0].args.id } -const encodeConfig = (config: any) => { +const encodeConfig20 = (config: any) => { return ethers.utils.defaultAbiCoder.encode( [ 'tuple(uint32 paymentPremiumPPB,uint32 flatFeeMicroLink,uint32 checkGasLimit,uint24 stalenessSeconds\ @@ -119,38 +118,6 @@ const encodeUpkeepV12 = (ids: number[], upkeeps: any[], checkDatas: any[]) => { ) } -const encodeUpkeepV13 = (ids: number[], upkeeps: any[], checkDatas: any[]) => { - return ethers.utils.defaultAbiCoder.encode( - [ - 'uint256[]', - 'tuple(uint96,address,uint96,address,uint32,uint32,address,bool)[]', - 'bytes[]', - ], - [ids, upkeeps, checkDatas], - ) -} - -const encodeUpkeepV21 = ( - ids: number[], - upkeeps: any[], - admins: string[], - checkDatas: string[], - triggerConfigs: string[], - offchainConfigs: string[], -) => { - return ethers.utils.defaultAbiCoder.encode( - [ - 'uint256[]', - 'tuple(bool,uint32,uint32,address,uint96,uint96,uint32,address)[]', - 'address[]', - 'bytes[]', - 'bytes[]', - 'bytes[]', - ], - [ids, upkeeps, admins, checkDatas, triggerConfigs, offchainConfigs], - ) -} - async function deployRegistry1_2(): Promise<[BigNumber, KeeperRegistry1_2]> { const keeperRegistryFactory = await ethers.getContractFactory( 'KeeperRegistry1_2', @@ -266,7 +233,7 @@ async function deployRegistry2_0(): Promise<[BigNumber, KeeperRegistry2_0]> { signerAddresses, keeperAddresses, f, - encodeConfig(config), + encodeConfig20(config), offchainVersion, offchainBytes, ) @@ -315,9 +282,7 @@ async function deployRegistry2_1() { await registry .connect(owner) - [ - 'setConfig(address[],address[],uint8,(uint32,uint32,uint32,uint24,uint16,uint96,uint32,uint32,uint32,uint32,uint256,uint256,address,address[],address),uint64,bytes)' - ]( + .setConfigTypeSafe( signerAddresses, keeperAddresses, f, @@ -344,7 +309,9 @@ const setup = async () => { ) transcoder = await upkeepTranscoderFactory.connect(owner).deploy() - linkTokenFactory = await ethers.getContractFactory('LinkToken') + linkTokenFactory = await ethers.getContractFactory( + 'src/v0.4/LinkToken.sol:LinkToken', + ) linkToken = await linkTokenFactory.connect(owner).deploy() // need full path because there are two contracts with name MockV3Aggregator const mockV3AggregatorFactory = (await ethers.getContractFactory( @@ -500,47 +467,29 @@ describe('UpkeepTranscoder4_0', () => { ) }) - context('when from and to versions are correct', () => { - it('transcodes v1.2 upkeeps to v2.1 properly, regardless of toVersion value', async () => { - const data = await transcoder.transcodeUpkeeps( + context('when from version is correct', () => { + // note this is a bugfix - the "to" version should be accounted for in + // future versions of the transcoder + it('transcodes to v2.1, regardless of toVersion value', async () => { + const data1 = await transcoder.transcodeUpkeeps( UpkeepFormat.V12, UpkeepFormat.V12, encodeUpkeepV12(idx, upkeepsV12, ['0xabcd', '0xffff']), ) - assert.equal( - encodeUpkeepV21( - idx, - upkeepsV21, - admins, - ['0xabcd', '0xffff'], - ['0x', '0x'], - ['0x', '0x'], - ), - data, - ) - }) - - it('transcodes v1.3 upkeeps to v2.1 properly, regardless of toVersion value', async () => { - const data = await transcoder.transcodeUpkeeps( - UpkeepFormat.V13, + const data2 = await transcoder.transcodeUpkeeps( + UpkeepFormat.V12, UpkeepFormat.V13, - encodeUpkeepV13(idx, upkeepsV13, ['0xabcd', '0xffff']), + encodeUpkeepV12(idx, upkeepsV12, ['0xabcd', '0xffff']), ) - assert.equal( - encodeUpkeepV21( - idx, - upkeepsV21, - admins, - ['0xabcd', '0xffff'], - ['0x', '0x'], - ['0x', '0x'], - ), - data, + const data3 = await transcoder.transcodeUpkeeps( + UpkeepFormat.V12, + 100, + encodeUpkeepV12(idx, upkeepsV12, ['0xabcd', '0xffff']), ) + assert.equal(data1, data2) + assert.equal(data1, data3) }) - // DEV cannot test raw transcoding 2.0 => 2.1 because transcodeUpkeeps is not pure - it('migrates upkeeps from 1.2 registry to 2.1', async () => { await linkToken .connect(owner) @@ -656,9 +605,6 @@ describe('UpkeepTranscoder4_0', () => { expect((await registry20.getUpkeep(id20)).checkData).to.equal( randomBytes, ) - expect((await registry20.getUpkeep(id20)).offchainConfig).to.equal( - randomBytes, - ) expect((await registry20.getState()).state.numUpkeeps).to.equal(1) await registry20 @@ -681,9 +627,6 @@ describe('UpkeepTranscoder4_0', () => { expect((await registry21.getUpkeep(id20)).checkData).to.equal( randomBytes, ) - expect((await registry21.getUpkeep(id20)).offchainConfig).to.equal( - randomBytes, - ) expect(await registry21.getUpkeepTriggerConfig(id20)).to.equal('0x') }) }) diff --git a/contracts/test/v0.8/automation/helpers.ts b/contracts/test/v0.8/automation/helpers.ts index 7abca064978..e2aa762577a 100644 --- a/contracts/test/v0.8/automation/helpers.ts +++ b/contracts/test/v0.8/automation/helpers.ts @@ -6,7 +6,10 @@ import { IKeeperRegistryMaster__factory as IKeeperRegistryMasterFactory } from ' export const deployRegistry21 = async ( from: Signer, - ...params: Parameters + mode: Parameters[0], + link: Parameters[1], + linkNative: Parameters[2], + fastgas: Parameters[3], ): Promise => { const logicBFactory = await ethers.getContractFactory( 'KeeperRegistryLogicB2_1', @@ -15,7 +18,13 @@ export const deployRegistry21 = async ( 'KeeperRegistryLogicA2_1', ) const registryFactory = await ethers.getContractFactory('KeeperRegistry2_1') - const logicB = await logicBFactory.connect(from).deploy(...params) + const forwarderLogicFactory = await ethers.getContractFactory( + 'AutomationForwarderLogic', + ) + const forwarderLogic = await forwarderLogicFactory.connect(from).deploy() + const logicB = await logicBFactory + .connect(from) + .deploy(mode, link, linkNative, fastgas, forwarderLogic.address) const logicA = await logicAFactory.connect(from).deploy(logicB.address) const master = await registryFactory.connect(from).deploy(logicA.address) return IKeeperRegistryMasterFactory.connect(master.address, from) diff --git a/contracts/test/v0.8/dev/ArbitrumCrossDomainGovernor.test.ts b/contracts/test/v0.8/dev/ArbitrumCrossDomainGovernor.test.ts index 115e2ef3aad..c7a8098800c 100644 --- a/contracts/test/v0.8/dev/ArbitrumCrossDomainGovernor.test.ts +++ b/contracts/test/v0.8/dev/ArbitrumCrossDomainGovernor.test.ts @@ -39,7 +39,7 @@ before(async () => { owner, ) multisendFactory = await ethers.getContractFactory( - 'src/v0.8/tests/vendor/MultiSend.sol:MultiSend', + 'src/v0.8/vendor/MultiSend.sol:MultiSend', owner, ) }) diff --git a/contracts/test/v0.8/dev/OptimismCrossDomainForwarder.test.ts b/contracts/test/v0.8/dev/OptimismCrossDomainForwarder.test.ts index 062b0969676..2668f4ea672 100644 --- a/contracts/test/v0.8/dev/OptimismCrossDomainForwarder.test.ts +++ b/contracts/test/v0.8/dev/OptimismCrossDomainForwarder.test.ts @@ -34,7 +34,7 @@ before(async () => { owner, ) crossDomainMessengerFactory = await ethers.getContractFactory( - 'src/v0.8/tests/vendor/MockOVMCrossDomainMessenger.sol:MockOVMCrossDomainMessenger', + 'src/v0.8/vendor/MockOVMCrossDomainMessenger.sol:MockOVMCrossDomainMessenger', ) }) diff --git a/contracts/test/v0.8/dev/OptimismCrossDomainGovernor.test.ts b/contracts/test/v0.8/dev/OptimismCrossDomainGovernor.test.ts index 7f2807d33f4..53c3f4ef254 100644 --- a/contracts/test/v0.8/dev/OptimismCrossDomainGovernor.test.ts +++ b/contracts/test/v0.8/dev/OptimismCrossDomainGovernor.test.ts @@ -36,11 +36,11 @@ before(async () => { owner, ) multisendFactory = await ethers.getContractFactory( - 'src/v0.8/tests/vendor/MultiSend.sol:MultiSend', + 'src/v0.8/vendor/MultiSend.sol:MultiSend', owner, ) crossDomainMessengerFactory = await ethers.getContractFactory( - 'src/v0.8/tests/vendor/MockOVMCrossDomainMessenger.sol:MockOVMCrossDomainMessenger', + 'src/v0.8/vendor/MockOVMCrossDomainMessenger.sol:MockOVMCrossDomainMessenger', ) }) diff --git a/contracts/test/v0.8/dev/VRFV2Wrapper.test.ts b/contracts/test/v0.8/dev/VRFV2Wrapper.test.ts index a8ff77175f7..fc888fc9738 100644 --- a/contracts/test/v0.8/dev/VRFV2Wrapper.test.ts +++ b/contracts/test/v0.8/dev/VRFV2Wrapper.test.ts @@ -1,7 +1,7 @@ -import { expect, assert } from 'chai' +import { assert, expect } from 'chai' import { BigNumber, BigNumberish, Signer } from 'ethers' import { ethers } from 'hardhat' -import { toBytes32String, reset } from '../../test-helpers/helpers' +import { reset, toBytes32String } from '../../test-helpers/helpers' import { bigNumEquals } from '../../test-helpers/matchers' import { describe } from 'mocha' import { @@ -11,8 +11,8 @@ import { VRFCoordinatorV2Mock, VRFV2Wrapper, VRFV2WrapperConsumerExample, - VRFV2WrapperRevertingConsumerExample, VRFV2WrapperOutOfGasConsumerExample, + VRFV2WrapperRevertingConsumerExample, } from '../../../typechain' describe('VRFV2Wrapper', () => { @@ -100,7 +100,10 @@ describe('VRFV2Wrapper', () => { )) as unknown as MockV3Aggregator__factory linkEthFeed = await linkEthFeedFactory.deploy(18, weiPerUnitLink) // 1 LINK = 0.003 ETH - const linkFactory = await ethers.getContractFactory('LinkToken', owner) + const linkFactory = await ethers.getContractFactory( + 'src/v0.4/LinkToken.sol:LinkToken', + owner, + ) link = await linkFactory.deploy() wrongLink = await linkFactory.deploy() diff --git a/contracts/test/v0.8/foundry/transmission/EIP_712_1014_4337.t.sol b/contracts/test/v0.8/foundry/transmission/EIP_712_1014_4337.t.sol index 27e19ddcb82..3040fda97de 100644 --- a/contracts/test/v0.8/foundry/transmission/EIP_712_1014_4337.t.sol +++ b/contracts/test/v0.8/foundry/transmission/EIP_712_1014_4337.t.sol @@ -6,12 +6,12 @@ import "../../../../src/v0.8/dev/transmission/testhelpers/SmartContractAccountHe import "../../../../src/v0.8/dev/transmission/4337/SCA.sol"; import "../../../../src/v0.8/dev/transmission/testhelpers/Greeter.sol"; import "../../../../src/v0.8/dev/transmission/4337/Paymaster.sol"; -import "../../../../src/v0.8/dev/vendor/entrypoint/interfaces/UserOperation.sol"; -import "../../../../src/v0.8/dev/vendor/entrypoint/core/EntryPoint.sol"; -import "../../../../src/v0.8/dev/vendor/entrypoint/interfaces/IEntryPoint.sol"; +import "../../../../src/v0.8/vendor/entrypoint/interfaces/UserOperation.sol"; +import "../../../../src/v0.8/vendor/entrypoint/core/EntryPoint.sol"; +import "../../../../src/v0.8/vendor/entrypoint/interfaces/IEntryPoint.sol"; import "../../../../src/v0.8/dev/transmission/4337/SCALibrary.sol"; import "../../../../src/v0.8/mocks/MockLinkToken.sol"; -import "../../../../src/v0.8/interfaces/LinkTokenInterface.sol"; +import "../../../../src/v0.8/shared/interfaces/LinkTokenInterface.sol"; import "../../../../src/v0.8/mocks/VRFCoordinatorMock.sol"; import "../../../../src/v0.8/tests/MockV3Aggregator.sol"; import "../../../../src/v0.8/vrf/testhelpers/VRFConsumer.sol"; diff --git a/contracts/test/v0.8/foundry/vrf/TrustedBlockhashStore.t.sol b/contracts/test/v0.8/foundry/vrf/TrustedBlockhashStore.t.sol new file mode 100644 index 00000000000..d2f52552e43 --- /dev/null +++ b/contracts/test/v0.8/foundry/vrf/TrustedBlockhashStore.t.sol @@ -0,0 +1,72 @@ +pragma solidity 0.8.6; + +import "../BaseTest.t.sol"; +import {TrustedBlockhashStore} from "../../../../src/v0.8/dev/vrf/TrustedBlockhashStore.sol"; +import {console} from "forge-std/console.sol"; + +contract TrustedBlockhashStoreTest is BaseTest { + address internal constant LINK_WHALE = 0xD883a6A1C22fC4AbFE938a5aDF9B2Cc31b1BF18B; + address internal constant LINK_WHALE_2 = 0xe9b2C5A6D9bA93dD354783a9De0a265da7551a20; + TrustedBlockhashStore bhs; + uint256 unreachableBlockNumber = 5; + bytes32 unreachableBlockhash; + + function setUp() public override { + BaseTest.setUp(); + + // Get the blockhash for a block that later becomes unreachable in the EVM. + vm.roll(10); + unreachableBlockhash = blockhash(unreachableBlockNumber); + + // Fund our users. + vm.roll(1000); + vm.deal(LINK_WHALE, 10_000 ether); + changePrank(LINK_WHALE); + + address[] memory whitelist = new address[](1); + whitelist[0] = LINK_WHALE; + bhs = new TrustedBlockhashStore(whitelist); + } + + function testGenericBHSFunctions() public { + // Should store. + uint256 blockNumber = 999; + bhs.store(blockNumber); + assertEq(bhs.getBlockhash(blockNumber), blockhash(blockNumber)); + + // Should store earliest. + uint256 earliestBlockNumber = block.number - 256; + bhs.storeEarliest(); + assertEq(bhs.getBlockhash(earliestBlockNumber), blockhash(earliestBlockNumber)); + } + + function testTrustedBHSFunctions() public { + uint256 recentBlockNumber = 999; + + // Assume that the EVM cannot access the blockhash for block 5. + uint256 unreachableBlock = 5; + assertEq(blockhash(unreachableBlock), 0); + + // Store blockhash from whitelisted address; + uint256[] memory blockNums = new uint256[](1); + blockNums[0] = unreachableBlock; + bytes32[] memory blockhashes = new bytes32[](1); + blockhashes[0] = unreachableBlockhash; + + // Should not be able to store with invalid recent blockhash + vm.expectRevert(TrustedBlockhashStore.InvalidRecentBlockhash.selector); + bhs.storeTrusted(blockNums, blockhashes, recentBlockNumber, blockhash(998)); + + // Should not be able to store or change whitelist for non-whitelisted address. + changePrank(LINK_WHALE_2); + vm.expectRevert(TrustedBlockhashStore.NotInWhitelist.selector); + bhs.storeTrusted(blockNums, blockhashes, recentBlockNumber, blockhash(recentBlockNumber)); + vm.expectRevert("Only callable by owner"); + bhs.setWhitelist(new address[](0)); + + // Should store unreachable blocks via whitelisted address. + changePrank(LINK_WHALE); + bhs.storeTrusted(blockNums, blockhashes, recentBlockNumber, blockhash(recentBlockNumber)); + assertEq(bhs.getBlockhash(unreachableBlock), unreachableBlockhash); + } +} diff --git a/contracts/test/v0.8/foundry/vrf/VRFCoordinatorV2Plus_Migration.t.sol b/contracts/test/v0.8/foundry/vrf/VRFCoordinatorV2Plus_Migration.t.sol index e35425dfd48..34271a129eb 100644 --- a/contracts/test/v0.8/foundry/vrf/VRFCoordinatorV2Plus_Migration.t.sol +++ b/contracts/test/v0.8/foundry/vrf/VRFCoordinatorV2Plus_Migration.t.sol @@ -45,8 +45,7 @@ contract VRFCoordinatorV2Plus_Migration is BaseTest { subId = v1Coordinator.createSubscription(); linkToken = new MockLinkToken(); linkEthFeed = new MockV3Aggregator(18, 500000000000000000); // .5 ETH (good for testing) - v1Coordinator.setLINK(address(linkToken)); - v1Coordinator.setLinkEthFeed(address(linkEthFeed)); + v1Coordinator.setLINKAndLINKETHFeed(address(linkToken), address(linkEthFeed)); linkTokenAddr = address(linkToken); v2Coordinator = new VRFCoordinatorV2Plus_V2Example(address(linkToken), address(v1Coordinator)); v1CoordinatorAddr = address(v1Coordinator); @@ -119,9 +118,8 @@ contract VRFCoordinatorV2Plus_Migration is BaseTest { v1Coordinator.addConsumer(subId, address(testConsumer)); // subscription exists in V1 coordinator before migration - (uint96 balance, uint96 ethBalance, address owner, address[] memory consumers) = v1Coordinator.getSubscription( - subId - ); + (uint96 balance, uint96 ethBalance, uint64 reqCount, address owner, address[] memory consumers) = v1Coordinator + .getSubscription(subId); assertEq(balance, DEFAULT_LINK_FUNDING); assertEq(ethBalance, DEFAULT_NATIVE_FUNDING); assertEq(owner, address(OWNER)); diff --git a/contracts/test/v0.8/foundry/vrf/VRFV2Plus.t.sol b/contracts/test/v0.8/foundry/vrf/VRFV2Plus.t.sol index 3be839d6ca3..4e22008549c 100644 --- a/contracts/test/v0.8/foundry/vrf/VRFV2Plus.t.sol +++ b/contracts/test/v0.8/foundry/vrf/VRFV2Plus.t.sol @@ -10,6 +10,8 @@ import {BlockhashStore} from "../../../../src/v0.8/dev/BlockhashStore.sol"; import {VRFV2PlusConsumerExample} from "../../../../src/v0.8/dev/vrf/testhelpers/VRFV2PlusConsumerExample.sol"; import {VRFV2PlusClient} from "../../../../src/v0.8/dev/vrf/libraries/VRFV2PlusClient.sol"; import {console} from "forge-std/console.sol"; +import {VmSafe} from "forge-std/Vm.sol"; +import "@openzeppelin/contracts/utils/math/Math.sol"; // for Math.ceilDiv /* * USAGE INSTRUCTIONS: @@ -80,8 +82,7 @@ contract VRFV2Plus is BaseTest { s_testConsumer = VRFV2PlusConsumerExample(consumerCreate2Address); // Configure the coordinator. - s_testCoordinator.setLINK(address(s_linkToken)); - s_testCoordinator.setLinkEthFeed(address(s_linkEthFeed)); + s_testCoordinator.setLINKAndLINKETHFeed(address(s_linkToken), address(s_linkEthFeed)); } function setConfig(VRFCoordinatorV2Plus.FeeConfig memory feeConfig) internal { @@ -141,6 +142,68 @@ contract VRFV2Plus is BaseTest { s_testCoordinator.fundSubscriptionWithEth{value: 10 ether}(subId); } + function testGetActiveSubscriptionIds() public { + uint numSubs = 40; + for (uint i = 0; i < numSubs; i++) { + s_testCoordinator.createSubscription(); + } + // get all subscriptions, assert length is correct + uint256[] memory allSubs = s_testCoordinator.getActiveSubscriptionIds(0, 0); + assertEq(allSubs.length, s_testCoordinator.getActiveSubscriptionIdsLength()); + + // paginate through subscriptions, batching by 10. + // we should eventually get all the subscriptions this way. + uint256[][] memory subIds = paginateSubscriptions(s_testCoordinator, 10); + // check that all subscriptions were returned + uint actualNumSubs = 0; + for (uint batchIdx = 0; batchIdx < subIds.length; batchIdx++) { + for (uint subIdx = 0; subIdx < subIds[batchIdx].length; subIdx++) { + s_testCoordinator.getSubscription(subIds[batchIdx][subIdx]); + actualNumSubs++; + } + } + assertEq(actualNumSubs, s_testCoordinator.getActiveSubscriptionIdsLength()); + + // cancel a bunch of subscriptions, assert that they are not returned + uint256[] memory subsToCancel = new uint256[](3); + for (uint i = 0; i < 3; i++) { + subsToCancel[i] = subIds[0][i]; + } + for (uint i = 0; i < subsToCancel.length; i++) { + s_testCoordinator.cancelSubscription(subsToCancel[i], LINK_WHALE); + } + uint256[][] memory newSubIds = paginateSubscriptions(s_testCoordinator, 10); + // check that all subscriptions were returned + // and assert that none of the canceled subscriptions are returned + actualNumSubs = 0; + for (uint batchIdx = 0; batchIdx < newSubIds.length; batchIdx++) { + for (uint subIdx = 0; subIdx < newSubIds[batchIdx].length; subIdx++) { + for (uint i = 0; i < subsToCancel.length; i++) { + assertFalse(newSubIds[batchIdx][subIdx] == subsToCancel[i]); + } + s_testCoordinator.getSubscription(newSubIds[batchIdx][subIdx]); + actualNumSubs++; + } + } + assertEq(actualNumSubs, s_testCoordinator.getActiveSubscriptionIdsLength()); + } + + function paginateSubscriptions( + ExposedVRFCoordinatorV2Plus coordinator, + uint256 batchSize + ) internal view returns (uint256[][] memory) { + uint arrIndex = 0; + uint startIndex = 0; + uint256 numSubs = coordinator.getActiveSubscriptionIdsLength(); + uint256[][] memory subIds = new uint256[][](Math.ceilDiv(numSubs, batchSize)); + while (startIndex < numSubs) { + subIds[arrIndex] = coordinator.getActiveSubscriptionIds(startIndex, batchSize); + startIndex += batchSize; + arrIndex++; + } + return subIds; + } + event RandomWordsRequested( bytes32 indexed keyHash, uint256 requestId, @@ -152,6 +215,14 @@ contract VRFV2Plus is BaseTest { bytes extraArgs, address indexed sender ); + event RandomWordsFulfilled( + uint256 indexed requestId, + uint256 outputSeed, + uint256 indexed subID, + uint96 payment, + bytes extraArgs, + bool success + ); function testRequestAndFulfillRandomWordsNative() public { uint32 requestBlock = 10; @@ -240,8 +311,18 @@ contract VRFV2Plus is BaseTest { sender: address(s_testConsumer), extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: true})) }); - (, uint96 ethBalanceBefore, , ) = s_testCoordinator.getSubscription(subId); + (, uint96 ethBalanceBefore, , , ) = s_testCoordinator.getSubscription(subId); + + uint256 outputSeed = s_testCoordinator.getRandomnessFromProofExternal(proof, rc).randomness; + vm.recordLogs(); s_testCoordinator.fulfillRandomWords{gas: 1_500_000}(proof, rc); + VmSafe.Log[] memory entries = vm.getRecordedLogs(); + assertEq(entries[0].topics[1], bytes32(uint256(requestId))); + assertEq(entries[0].topics[2], bytes32(uint256(subId))); + (uint256 loggedOutputSeed, , bool loggedSuccess) = abi.decode(entries[0].data, (uint256, uint256, bool)); + assertEq(loggedOutputSeed, outputSeed); + assertEq(loggedSuccess, true); + (fulfilled, , ) = s_testConsumer.s_requests(requestId); assertEq(fulfilled, true); @@ -256,7 +337,7 @@ contract VRFV2Plus is BaseTest { // billed_fee = baseFeeWei + flatFeeWei + l1CostWei // billed_fee = baseFeeWei + 0 + 0 // billed_fee = 150_000 - (, uint96 ethBalanceAfter, , ) = s_testCoordinator.getSubscription(subId); + (, uint96 ethBalanceAfter, , , ) = s_testCoordinator.getSubscription(subId); assertApproxEqAbs(ethBalanceAfter, ethBalanceBefore - 120_000, 10_000); } @@ -272,7 +353,7 @@ contract VRFV2Plus is BaseTest { registerProvingKey(); // Request random words. - vm.expectEmit(true, true, true, true); + vm.expectEmit(true, true, false, true); (uint256 requestId, uint256 preSeed) = s_testCoordinator.computeRequestIdExternal( vrfKeyHash, address(s_testConsumer), @@ -346,8 +427,19 @@ contract VRFV2Plus is BaseTest { sender: address(s_testConsumer), extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: false})) }); - (uint96 linkBalanceBefore, , , ) = s_testCoordinator.getSubscription(subId); + (uint96 linkBalanceBefore, , , , ) = s_testCoordinator.getSubscription(subId); + + uint256 outputSeed = s_testCoordinator.getRandomnessFromProofExternal(proof, rc).randomness; + vm.recordLogs(); s_testCoordinator.fulfillRandomWords{gas: 1_500_000}(proof, rc); + + VmSafe.Log[] memory entries = vm.getRecordedLogs(); + assertEq(entries[0].topics[1], bytes32(uint256(requestId))); + assertEq(entries[0].topics[2], bytes32(uint256(subId))); + (uint256 loggedOutputSeed, , bool loggedSuccess) = abi.decode(entries[0].data, (uint256, uint256, bool)); + assertEq(loggedOutputSeed, outputSeed); + assertEq(loggedSuccess, true); + (fulfilled, , ) = s_testConsumer.s_requests(requestId); assertEq(fulfilled, true); @@ -363,7 +455,7 @@ contract VRFV2Plus is BaseTest { // billed_fee = baseFeeWei + 0 // billed_fee = 280_000 // note: delta is doubled from the native test to account for more variance due to the link/eth ratio - (uint96 linkBalanceAfter, , , ) = s_testCoordinator.getSubscription(subId); + (uint96 linkBalanceAfter, , , , ) = s_testCoordinator.getSubscription(subId); assertApproxEqAbs(linkBalanceAfter, linkBalanceBefore - 280_000, 20_000); } } diff --git a/contracts/test/v0.8/foundry/vrf/VRFV2Wrapper.t.sol b/contracts/test/v0.8/foundry/vrf/VRFV2Wrapper.t.sol index 18e2eb3b987..4b506bb8c50 100644 --- a/contracts/test/v0.8/foundry/vrf/VRFV2Wrapper.t.sol +++ b/contracts/test/v0.8/foundry/vrf/VRFV2Wrapper.t.sol @@ -44,8 +44,7 @@ contract VRFV2PlusWrapperTest is BaseTest { s_consumer = new VRFV2PlusWrapperConsumerExample(address(s_linkToken), address(s_wrapper)); // Configure the coordinator. - s_testCoordinator.setLINK(address(s_linkToken)); - s_testCoordinator.setLinkEthFeed(address(s_linkEthFeed)); + s_testCoordinator.setLINKAndLINKETHFeed(address(s_linkToken), address(s_linkEthFeed)); setConfigCoordinator(basicFeeConfig); setConfigWrapper(); diff --git a/contracts/test/v0.8/functions/v0/FunctionsBillingRegistry.test.ts b/contracts/test/v0.8/functions/v0/FunctionsBillingRegistry.test.ts index a174297c6ed..b9110aea615 100644 --- a/contracts/test/v0.8/functions/v0/FunctionsBillingRegistry.test.ts +++ b/contracts/test/v0.8/functions/v0/FunctionsBillingRegistry.test.ts @@ -69,12 +69,12 @@ before(async () => { ) linkTokenFactory = await ethers.getContractFactory( - 'src/v0.4/LinkToken.sol:LinkToken', + 'src/v0.8/mocks/MockLinkToken.sol:MockLinkToken', roles.consumer, ) mockAggregatorV3Factory = await ethers.getContractFactory( - 'src/v0.7/tests/MockV3Aggregator.sol:MockV3Aggregator', + 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', roles.consumer, ) }) diff --git a/contracts/test/v0.8/functions/v0/FunctionsBillingRegistryUpgradeable.test.ts b/contracts/test/v0.8/functions/v0/FunctionsBillingRegistryUpgradeable.test.ts index 643602d86b0..04a7db0b2c0 100644 --- a/contracts/test/v0.8/functions/v0/FunctionsBillingRegistryUpgradeable.test.ts +++ b/contracts/test/v0.8/functions/v0/FunctionsBillingRegistryUpgradeable.test.ts @@ -68,12 +68,12 @@ before(async () => { ) linkTokenFactory = await ethers.getContractFactory( - 'src/v0.4/LinkToken.sol:LinkToken', + 'src/v0.8/mocks/MockLinkToken.sol:MockLinkToken', roles.consumer, ) mockAggregatorV3Factory = await ethers.getContractFactory( - 'src/v0.7/tests/MockV3Aggregator.sol:MockV3Aggregator', + 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', roles.consumer, ) }) diff --git a/contracts/test/v0.8/functions/v0/FunctionsClient.test.ts b/contracts/test/v0.8/functions/v0/FunctionsClient.test.ts index 28eb9daae72..4a474aadef2 100644 --- a/contracts/test/v0.8/functions/v0/FunctionsClient.test.ts +++ b/contracts/test/v0.8/functions/v0/FunctionsClient.test.ts @@ -48,12 +48,12 @@ before(async () => { ) linkTokenFactory = await ethers.getContractFactory( - 'src/v0.4/LinkToken.sol:LinkToken', + 'src/v0.8/mocks/MockLinkToken.sol:MockLinkToken', roles.consumer, ) mockAggregatorV3Factory = await ethers.getContractFactory( - 'src/v0.7/tests/MockV3Aggregator.sol:MockV3Aggregator', + 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', roles.consumer, ) }) diff --git a/contracts/test/v0.8/functions/v0/FunctionsOracle.test.ts b/contracts/test/v0.8/functions/v0/FunctionsOracle.test.ts index dfb392d9428..ae44e1b037e 100644 --- a/contracts/test/v0.8/functions/v0/FunctionsOracle.test.ts +++ b/contracts/test/v0.8/functions/v0/FunctionsOracle.test.ts @@ -43,12 +43,12 @@ before(async () => { ) linkTokenFactory = await ethers.getContractFactory( - 'src/v0.4/LinkToken.sol:LinkToken', + 'src/v0.8/mocks/MockLinkToken.sol:MockLinkToken', roles.consumer, ) mockAggregatorV3Factory = await ethers.getContractFactory( - 'src/v0.7/tests/MockV3Aggregator.sol:MockV3Aggregator', + 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', roles.consumer, ) }) diff --git a/contracts/test/v0.8/functions/v0/FunctionsOracleUpgradeable.test.ts b/contracts/test/v0.8/functions/v0/FunctionsOracleUpgradeable.test.ts index 64bacbc5562..f127692373a 100644 --- a/contracts/test/v0.8/functions/v0/FunctionsOracleUpgradeable.test.ts +++ b/contracts/test/v0.8/functions/v0/FunctionsOracleUpgradeable.test.ts @@ -59,12 +59,12 @@ before(async () => { ) linkTokenFactory = await ethers.getContractFactory( - 'src/v0.4/LinkToken.sol:LinkToken', + 'src/v0.8/mocks/MockLinkToken.sol:MockLinkToken', roles.consumer, ) mockAggregatorV3Factory = await ethers.getContractFactory( - 'src/v0.7/tests/MockV3Aggregator.sol:MockV3Aggregator', + 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', roles.consumer, ) }) diff --git a/contracts/test/v0.8/functions/v0/Gas.test.ts b/contracts/test/v0.8/functions/v0/Gas.test.ts new file mode 100644 index 00000000000..c84e017972f --- /dev/null +++ b/contracts/test/v0.8/functions/v0/Gas.test.ts @@ -0,0 +1,158 @@ +import { ethers } from 'hardhat' +import { expect } from 'chai' +import { Contract, ContractFactory } from 'ethers' +import { Roles, getUsers } from '../../../test-helpers/setup' +import { stringToBytes } from '../../../test-helpers/helpers' + +let concreteFunctionsClientFactory: ContractFactory +let functionsOracleFactory: ContractFactory +let functionsBillingRegistryFactory: ContractFactory +let linkTokenFactory: ContractFactory +let mockAggregatorV3Factory: ContractFactory +let roles: Roles + +function getEventArg(events: any, eventName: string, argIndex: number) { + if (Array.isArray(events)) { + const event = events.find((e: any) => e.event == eventName) + if (event && Array.isArray(event.args) && event.args.length > 0) { + return event.args[argIndex] + } + } + return undefined +} + +const baselineGasUsed = 641560 +let currentGasUsed = 0 + +before(async () => { + roles = (await getUsers()).roles + + concreteFunctionsClientFactory = await ethers.getContractFactory( + 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsClientTestHelper.sol:FunctionsClientTestHelper', + roles.defaultAccount, + ) + functionsOracleFactory = await ethers.getContractFactory( + 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsOracleHelper.sol:FunctionsOracleHelper', + roles.defaultAccount, + ) + + functionsBillingRegistryFactory = await ethers.getContractFactory( + 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsBillingRegistryWithInit.sol:FunctionsBillingRegistryWithInit', + roles.defaultAccount, + ) + + linkTokenFactory = await ethers.getContractFactory( + 'src/v0.8/mocks/MockLinkToken.sol:MockLinkToken', + roles.consumer, + ) + + mockAggregatorV3Factory = await ethers.getContractFactory( + 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', + roles.consumer, + ) +}) + +after(() => { + const score = currentGasUsed - baselineGasUsed + console.log( + `\n ⛳ Baseline gas used : ${baselineGasUsed} gas`, + ) + console.log(`\n Current gas used : ${currentGasUsed} gas`) + console.log(`\n 🚩 Delta : ${score} gas`) +}) + +let subscriptionId: number + +let client: Contract +let oracle: Contract +let registry: Contract +let linkToken: Contract +let mockLinkEth: Contract + +beforeEach(async () => { + // Deploy + linkToken = await linkTokenFactory.connect(roles.defaultAccount).deploy() + mockLinkEth = await mockAggregatorV3Factory.deploy( + 0, + ethers.BigNumber.from(5021530000000000), + ) + oracle = await functionsOracleFactory.connect(roles.defaultAccount).deploy() + registry = await functionsBillingRegistryFactory + .connect(roles.defaultAccount) + .deploy(linkToken.address, mockLinkEth.address, oracle.address) + + // Setup contracts + await oracle.setRegistry(registry.address) + await oracle.deactivateAuthorizedReceiver() + client = await concreteFunctionsClientFactory + .connect(roles.defaultAccount) + .deploy(oracle.address) + await registry.setAuthorizedSenders([oracle.address]) + + await registry.setConfig( + 1_000_000, + 86_400, + 21_000 + 5_000 + 2_100 + 20_000 + 2 * 2_100 - 15_000 + 7_315, + ethers.BigNumber.from('5000000000000000'), + 100_000, + 300, + ) +}) + +describe('Gas', () => { + it('uses the expected amount of gas', async () => { + // Setup accounts + const createSubTx = await registry + .connect(roles.defaultAccount) + .createSubscription() + const createSubscriptionTxReceipt = await createSubTx.wait() + subscriptionId = + createSubscriptionTxReceipt.events[0].args['subscriptionId'].toNumber() + const createSubscriptionGasUsed = createSubscriptionTxReceipt.gasUsed + + const addConsumerTx = await registry + .connect(roles.defaultAccount) + .addConsumer(subscriptionId, client.address) + const { gasUsed: addConsumerTxGasUsed } = await addConsumerTx.wait() + + const transferAndCallTx = await linkToken + .connect(roles.defaultAccount) + .transferAndCall( + registry.address, + ethers.BigNumber.from('115957983815660167'), + ethers.utils.defaultAbiCoder.encode(['uint64'], [subscriptionId]), + ) + const { gasUsed: transferAndCallTxGasUsed } = await transferAndCallTx.wait() + + const requestTx = await client.sendSimpleRequestWithJavaScript( + 'function run(){return response}', + subscriptionId, + ) + + const { events, gasUsed: requestTxGasUsed } = await requestTx.wait() + const requestId = getEventArg(events, 'RequestSent', 0) + await expect(requestTx).to.emit(client, 'RequestSent').withArgs(requestId) + + const response = stringToBytes('response') + const error = stringToBytes('') + const abi = ethers.utils.defaultAbiCoder + + const report = abi.encode( + ['bytes32[]', 'bytes[]', 'bytes[]'], + [[ethers.utils.hexZeroPad(requestId, 32)], [response], [error]], + ) + + const fulfillmentTx = await oracle.callReport(report, { + gasLimit: 300_000, + }) + + const { gasUsed: fulfillmentTxGasUsed } = await fulfillmentTx.wait() + + currentGasUsed = createSubscriptionGasUsed + .add(addConsumerTxGasUsed) + .add(transferAndCallTxGasUsed) + .add(requestTxGasUsed) + .add(fulfillmentTxGasUsed) + .toNumber() + }) +}) diff --git a/contracts/test/v0.8/functions/v1/Functions.test.ts b/contracts/test/v0.8/functions/v1/Functions.test.ts index 981b3227073..b0128b90204 100644 --- a/contracts/test/v0.8/functions/v1/Functions.test.ts +++ b/contracts/test/v0.8/functions/v1/Functions.test.ts @@ -41,6 +41,7 @@ describe('FunctionsTestHelper', () => { 'addSecretsReference', 'addTwoArgs', 'addEmptyArgs', + 'addSignature', ]), ).to.equal(true) }) @@ -169,4 +170,29 @@ describe('FunctionsTestHelper', () => { await expect(ctr.addEmptyArgs()).to.be.revertedWith('EmptyArgs()') }) }) + + describe('#addSignature', () => { + it('emits CBOR encoded request with js source and signature', async () => { + const signatureHex = 'aabbccddeeff' + const js = 'function run(args, responses) {}' + await ctr.initializeRequestForInlineJavaScript(js) + await ctr.addSignature('0x' + signatureHex) + const tx = await ctr.closeEvent() + const [payload] = await parseRequestDataEvent(tx) + const decoded = await decodeDietCBOR(payload) + assert.deepEqual( + { + ...decoded, + language: decoded.language.toNumber(), + codeLocation: decoded.codeLocation.toNumber(), + }, + { + language: 0, + codeLocation: 0, + source: js, + requestSignature: Buffer.from(signatureHex, 'hex'), + }, + ) + }) + }) }) diff --git a/contracts/test/v0.8/functions/v1/FunctionsClient.test.ts b/contracts/test/v0.8/functions/v1/FunctionsClient.test.ts index c7ee07fd92a..ccb059a5a3f 100644 --- a/contracts/test/v0.8/functions/v1/FunctionsClient.test.ts +++ b/contracts/test/v0.8/functions/v1/FunctionsClient.test.ts @@ -10,6 +10,7 @@ import { createSubscription, getEventArg, parseOracleRequestEventArgs, + encodeReport, } from './utils' const setup = getSetupFactory() @@ -30,6 +31,10 @@ describe('Functions Client', () => { contracts.accessControl, contracts.linkToken, ) + const flags = + '0x0101010101010101010101010101010101010101010101010101010101010101' + const callbackGas = 100_000 + await contracts.router.setFlags(subscriptionId, flags) const defaultAccountAddress = await roles.defaultAccount.getAddress() await expect( contracts.client @@ -38,6 +43,7 @@ describe('Functions Client', () => { 'return `hello world`', subscriptionId, ids.donId, + callbackGas, ), ) .to.emit(contracts.client, 'RequestSent') @@ -51,9 +57,47 @@ describe('Functions Client', () => { roles.subOwnerAddress, anyValue, anyValue, + flags, + callbackGas, + anyValue, ) }) + it('respects gas flag setting', async () => { + const subscriptionId = await createSubscription( + roles.subOwner, + [contracts.client.address], + contracts.router, + contracts.accessControl, + contracts.linkToken, + ) + const flags = + '0x0101010101010101010101010101010101010101010101010101010101010101' + await contracts.router.setFlags(subscriptionId, flags) + await expect( + contracts.client + .connect(roles.defaultAccount) + .sendSimpleRequestWithJavaScript( + 'return `hello world`', + subscriptionId, + ids.donId, + 400_000, + ), + ) + .to.emit(contracts.client, 'RequestSent') + .to.emit(contracts.coordinator, 'OracleRequest') + await expect( + contracts.client + .connect(roles.defaultAccount) + .sendSimpleRequestWithJavaScript( + 'return `hello world`', + subscriptionId, + ids.donId, + 600_000, // limit set by gas flag == 1 is 500_000 + ), + ).to.be.revertedWith('GasLimitTooBig(500000)') + }) + it('encodes user request to CBOR', async () => { const subscriptionId = await createSubscription( roles.subOwner, @@ -67,6 +111,7 @@ describe('Functions Client', () => { js, subscriptionId, ids.donId, + 20_000, ) const args = await parseOracleRequestEventArgs(tx) assert.equal(args.length, 5) @@ -99,6 +144,7 @@ describe('Functions Client', () => { 'function run(){return response}', subscriptionId, ids.donId, + 20_000, ) const { events } = await tx.wait() const requestId = getEventArg(events, 'RequestSent', 0) @@ -108,19 +154,74 @@ describe('Functions Client', () => { const response = stringToBytes('response') const error = stringToBytes('') - const abi = ethers.utils.defaultAbiCoder - - const report = abi.encode( - ['bytes32[]', 'bytes[]', 'bytes[]'], - [[ethers.utils.hexZeroPad(requestId, 32)], [response], [error]], + const oracleRequestEvent = await contracts.coordinator.queryFilter( + contracts.coordinator.filters.OracleRequest(), + ) + const onchainMetadata = oracleRequestEvent[0].args?.['commitment'] + const report = await encodeReport( + ethers.utils.hexZeroPad(requestId, 32), + response, + error, + onchainMetadata, + stringToBytes(''), ) - await expect(contracts.coordinator.callReport(report)) .to.emit(contracts.coordinator, 'OracleResponse') .withArgs(requestId, await roles.defaultAccount.getAddress()) - .to.emit(contracts.coordinator, 'BillingEnd') .to.emit(contracts.client, 'FulfillRequestInvoked') .withArgs(requestId, response, error) }) }) }) + +describe('Faulty Functions Client', () => { + it('can complete requests with an empty callback', async () => { + const clientWithEmptyCallbackTestHelperFactory = + await ethers.getContractFactory( + 'src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsClientWithEmptyCallback.sol:FunctionsClientWithEmptyCallback', + roles.consumer, + ) + + const clientWithEmptyCallback = + await clientWithEmptyCallbackTestHelperFactory + .connect(roles.consumer) + .deploy(contracts.router.address) + + const subscriptionId = await createSubscription( + roles.subOwner, + [clientWithEmptyCallback.address], + contracts.router, + contracts.accessControl, + contracts.linkToken, + ) + const tx = await clientWithEmptyCallback.sendSimpleRequestWithJavaScript( + 'function run(){return response}', + subscriptionId, + ids.donId, + 20_000, + ) + const { events } = await tx.wait() + const requestId = getEventArg(events, 'RequestSent', 0) + await expect(tx) + .to.emit(clientWithEmptyCallback, 'RequestSent') + .withArgs(requestId) + + const response = stringToBytes('response') + const error = stringToBytes('') + const oracleRequestEvent = await contracts.coordinator.queryFilter( + contracts.coordinator.filters.OracleRequest(), + ) + const onchainMetadata = oracleRequestEvent[0].args?.['commitment'] + const report = await encodeReport( + ethers.utils.hexZeroPad(requestId, 32), + response, + error, + onchainMetadata, + stringToBytes(''), + ) + await expect(contracts.coordinator.callReport(report)) + .to.emit(contracts.coordinator, 'OracleResponse') + .withArgs(requestId, await roles.defaultAccount.getAddress()) + .to.emit(contracts.router, 'RequestProcessed') + }) +}) diff --git a/contracts/test/v0.8/functions/v1/FunctionsCoordinator.test.ts b/contracts/test/v0.8/functions/v1/FunctionsCoordinator.test.ts new file mode 100644 index 00000000000..5aece579b66 --- /dev/null +++ b/contracts/test/v0.8/functions/v1/FunctionsCoordinator.test.ts @@ -0,0 +1,68 @@ +import { expect } from 'chai' +import { + getSetupFactory, + FunctionsContracts, + coordinatorConfig, + FunctionsRoles, +} from './utils' + +const setup = getSetupFactory() +let contracts: FunctionsContracts +let roles: FunctionsRoles + +beforeEach(async () => { + ;({ contracts, roles } = setup()) +}) + +describe('Functions Coordinator', () => { + describe('Config', () => { + it('non-owner is unable to update config', async () => { + await expect( + contracts.coordinator + .connect(roles.stranger) + .updateConfig(coordinatorConfig), + ).to.be.revertedWith('Only callable by owner') + }) + + it('Owner can update config', async () => { + const beforeConfig = await contracts.coordinator.getConfig() + await expect( + contracts.coordinator.updateConfig({ + ...coordinatorConfig, + donFee: 10, + }), + ).to.emit(contracts.coordinator, 'ConfigUpdated') + const afterConfig = await contracts.coordinator.getConfig() + expect(beforeConfig).to.not.equal(afterConfig) + }) + + it('returns the config set', async () => { + const config = await contracts.coordinator + .connect(roles.stranger) + .getConfig() + await Promise.all( + Object.keys(coordinatorConfig).map((key) => + expect(config[key]).to.equal( + coordinatorConfig[key as keyof typeof coordinatorConfig], + ), + ), + ) + }) + + it('#fulfillmentGasPriceOverEstimationBP overestimates gas cost', async () => { + const estimateWithNoOverestimaton = + await contracts.coordinator.estimateCost(1, 0x0, 100_000, 20) + + await contracts.coordinator.updateConfig({ + ...coordinatorConfig, + fulfillmentGasPriceOverEstimationBP: 10_000, + }) + + // Halve the gas price, which should be the same estimate because of fulfillmentGasPriceOverEstimationBP doubling the gas price + const estimateWithOverestimaton = + await contracts.coordinator.estimateCost(1, 0x0, 100_000, 10) + + expect(estimateWithNoOverestimaton).to.equal(estimateWithOverestimaton) + }) + }) +}) diff --git a/contracts/test/v0.8/functions/v1/FunctionsRouter.test.ts b/contracts/test/v0.8/functions/v1/FunctionsRouter.test.ts index a36c794d48f..aecad5466bb 100644 --- a/contracts/test/v0.8/functions/v1/FunctionsRouter.test.ts +++ b/contracts/test/v0.8/functions/v1/FunctionsRouter.test.ts @@ -1,36 +1,66 @@ -import { ethers } from 'hardhat' import { expect } from 'chai' +import { ethers } from 'hardhat' +import { stringToBytes } from '../../../test-helpers/helpers' import { getSetupFactory, FunctionsContracts, - FunctionsRoles, functionsRouterConfig, - stringToHex, - anyValue, - createSubscription, + FunctionsRoles, } from './utils' const setup = getSetupFactory() let contracts: FunctionsContracts let roles: FunctionsRoles -const donLabel = ethers.utils.formatBytes32String('1') - beforeEach(async () => { ;({ contracts, roles } = setup()) }) describe('Functions Router - Request lifecycle', () => { - describe('Getters', () => { + describe('Config', () => { it('#typeAndVersion', async () => { expect(await contracts.router.typeAndVersion()).to.be.equal( - 'Functions Router v1', + 'Functions Router v1.0.0', ) }) - it('#adminFee', async () => { - expect(await contracts.router.getAdminFee()).to.be.equal( - functionsRouterConfig.adminFee, + it('non-owner is unable to update config', async () => { + await expect( + contracts.router + .connect(roles.stranger) + .updateConfig(functionsRouterConfig), + ).to.be.revertedWith('Only callable by owner') + }) + + it('owner can update config', async () => { + const beforeConfig = await contracts.router.getConfig() + await expect( + contracts.router.updateConfig({ + ...functionsRouterConfig, + adminFee: 10, + }), + ).to.emit(contracts.router, 'ConfigUpdated') + const afterConfig = await contracts.router.getConfig() + expect(beforeConfig).to.not.equal(afterConfig) + }) + + it('returns the config set', async () => { + const config = await contracts.router.connect(roles.stranger).getConfig() + await Promise.all( + Object.keys(functionsRouterConfig).map((key) => + expect(config[key]).to.deep.equal( + functionsRouterConfig[key as keyof typeof functionsRouterConfig], + ), + ), ) }) }) + describe('Allow List path', () => { + it('non-owner is unable to set Allow List ID', async () => { + await expect( + contracts.router + .connect(roles.stranger) + .setAllowListId(ethers.utils.hexZeroPad(stringToBytes(''), 32)), + ).to.be.revertedWith('Only callable by owner') + }) + }) }) diff --git a/contracts/test/v0.8/functions/v1/FunctionsSubscriptions.test.ts b/contracts/test/v0.8/functions/v1/FunctionsSubscriptions.test.ts index f93748002dd..e2f0372be15 100644 --- a/contracts/test/v0.8/functions/v1/FunctionsSubscriptions.test.ts +++ b/contracts/test/v0.8/functions/v1/FunctionsSubscriptions.test.ts @@ -8,7 +8,12 @@ import { FunctionsRoles, createSubscription, acceptTermsOfService, + ids, + getEventArg, + accessControlMockPrivateKey, + encodeReport, } from './utils' +import { stringToBytes } from '../../../test-helpers/helpers' const setup = getSetupFactory() let contracts: FunctionsContracts @@ -71,11 +76,11 @@ describe('Functions Router - Subscriptions', () => { contracts.router .connect(roles.subOwner) .addConsumer(subId, randomAddressString()), - ).to.be.revertedWith(`TooManyConsumers()`) + ).to.be.revertedWith(`TooManyConsumers`) }) }) - describe('#requestSubscriptionOwnerTransfer', async function () { + describe('#proposeSubscriptionOwnerTransfer', async function () { let subId: number beforeEach(async () => { subId = await createSubscription( @@ -89,23 +94,23 @@ describe('Functions Router - Subscriptions', () => { await expect( contracts.router .connect(roles.stranger) - .requestSubscriptionOwnerTransfer(subId, roles.strangerAddress), - ).to.be.revertedWith(`MustBeSubOwner("${roles.subOwnerAddress}")`) + .proposeSubscriptionOwnerTransfer(subId, roles.strangerAddress), + ).to.be.revertedWith(`MustBeSubscriptionOwner()`) }) it('owner can request transfer', async function () { await expect( contracts.router .connect(roles.subOwner) - .requestSubscriptionOwnerTransfer(subId, roles.strangerAddress), + .proposeSubscriptionOwnerTransfer(subId, roles.strangerAddress), ) .to.emit(contracts.router, 'SubscriptionOwnerTransferRequested') .withArgs(subId, roles.subOwnerAddress, roles.strangerAddress) - // Same request is a noop + // Same request reverts await expect( contracts.router .connect(roles.subOwner) - .requestSubscriptionOwnerTransfer(subId, roles.strangerAddress), - ).to.not.emit(contracts.router, 'SubscriptionOwnerTransferRequested') + .proposeSubscriptionOwnerTransfer(subId, roles.strangerAddress), + ).to.be.revertedWith('InvalidCalldata') }) }) @@ -125,19 +130,19 @@ describe('Functions Router - Subscriptions', () => { contracts.router .connect(roles.subOwner) .acceptSubscriptionOwnerTransfer(1203123123), - ).to.be.revertedWith(`MustBeRequestedOwner`) + ).to.be.revertedWith(`MustBeProposedOwner`) }) it('must be requested owner to accept', async function () { await expect( contracts.router .connect(roles.subOwner) - .requestSubscriptionOwnerTransfer(subId, roles.strangerAddress), + .proposeSubscriptionOwnerTransfer(subId, roles.strangerAddress), ) await expect( contracts.router .connect(roles.subOwner) .acceptSubscriptionOwnerTransfer(subId), - ).to.be.revertedWith(`MustBeRequestedOwner("${roles.strangerAddress}")`) + ).to.be.revertedWith(`MustBeProposedOwner`) }) it('requested owner can accept', async function () { await acceptTermsOfService( @@ -148,7 +153,7 @@ describe('Functions Router - Subscriptions', () => { await expect( contracts.router .connect(roles.subOwner) - .requestSubscriptionOwnerTransfer(subId, roles.strangerAddress), + .proposeSubscriptionOwnerTransfer(subId, roles.strangerAddress), ) .to.emit(contracts.router, 'SubscriptionOwnerTransferRequested') .withArgs(subId, roles.subOwnerAddress, roles.strangerAddress) @@ -184,7 +189,7 @@ describe('Functions Router - Subscriptions', () => { contracts.router .connect(roles.stranger) .addConsumer(subId, roles.strangerAddress), - ).to.be.revertedWith(`MustBeSubOwner("${roles.subOwnerAddress}")`) + ).to.be.revertedWith(`MustBeSubscriptionOwner()`) }) it('add is idempotent', async function () { await contracts.router @@ -209,7 +214,7 @@ describe('Functions Router - Subscriptions', () => { contracts.router .connect(roles.subOwner) .addConsumer(subId, roles.strangerAddress), - ).to.be.revertedWith(`TooManyConsumers()`) + ).to.be.revertedWith(`TooManyConsumers`) // Same is true if we first create with the maximum const consumers: string[] = [] for (let i = 0; i < 100; i++) { @@ -225,7 +230,7 @@ describe('Functions Router - Subscriptions', () => { contracts.router .connect(roles.subOwner) .addConsumer(subId, roles.strangerAddress), - ).to.be.revertedWith(`TooManyConsumers()`) + ).to.be.revertedWith(`TooManyConsumers`) }) it('owner can update', async function () { await expect( @@ -260,7 +265,7 @@ describe('Functions Router - Subscriptions', () => { contracts.router .connect(roles.stranger) .removeConsumer(subId, roles.strangerAddress), - ).to.be.revertedWith(`MustBeSubOwner("${roles.subOwnerAddress}")`) + ).to.be.revertedWith(`MustBeSubscriptionOwner()`) }) it('owner can update', async function () { const subBefore = await contracts.router.getSubscription(subId) @@ -330,6 +335,7 @@ describe('Functions Router - Subscriptions', () => { `return 'hello world'`, subId, donLabel, + 20_000, ) expect( await contracts.router @@ -361,7 +367,7 @@ describe('Functions Router - Subscriptions', () => { contracts.router .connect(roles.stranger) .cancelSubscription(subId, roles.subOwnerAddress), - ).to.be.revertedWith(`MustBeSubOwner("${roles.subOwnerAddress}")`) + ).to.be.revertedWith(`MustBeSubscriptionOwner()`) }) it('can cancel', async function () { await contracts.linkToken @@ -430,13 +436,14 @@ describe('Functions Router - Subscriptions', () => { `return 'hello world'`, subId, donLabel, + 20_000, ) // Should revert with outstanding requests await expect( contracts.router .connect(roles.subOwner) .cancelSubscription(subId, roles.strangerAddress), - ).to.be.revertedWith('PendingRequestExists()') + ).to.be.revertedWith('CannotRemoveWithPendingRequests()') // However the owner is able to cancel // funds go to the sub owner. await expect( @@ -550,4 +557,301 @@ describe('Functions Router - Subscriptions', () => { ).to.be.revertedWith(`InsufficientBalance`) }) }) + + describe('#ownerWithdraw', async function () { + it('cannot withdraw more than balance', async function () { + await expect( + contracts.router.oracleWithdraw( + randomAddressString(), + BigNumber.from('100'), + ), + ).to.be.revertedWith(`InsufficientBalance`) + }) + }) + + describe('#flagsSet', async function () { + it('get flags that were previously set', async function () { + const flags = ethers.utils.formatBytes32String('arbitrary_byte_values') + await acceptTermsOfService( + contracts.accessControl, + roles.subOwner, + roles.subOwnerAddress, + ) + await expect( + contracts.router.connect(roles.subOwner).createSubscription(), + ) + .to.emit(contracts.router, 'SubscriptionCreated') + .withArgs(1, roles.subOwnerAddress) + await contracts.router.setFlags(1, flags) + expect(await contracts.router.getFlags(1)).to.equal(flags) + }) + }) + + describe('#reentrancy', async function () { + // Use a fixed gas price for these tests + const gasPrice = 3000000000 // 3 gwei + + it('allows callbacks to start another request if they have sufficient funds', async function () { + const subscriptionId = await createSubscription( + roles.subOwner, + [contracts.client.address], + contracts.router, + contracts.accessControl, + contracts.linkToken, + ) + + // Set test helper flag + await contracts.client.setDoValidReentrantOperation( + true, + subscriptionId, + ids.donId, + ) + + // Set flag so they have enough callback gas + const flags = new Uint8Array(32) + flags[0] = 1 + await contracts.router + .connect(roles.defaultAccount) + .setFlags(subscriptionId, flags) + + // Send request + const tx = await contracts.client.sendSimpleRequestWithJavaScript( + 'function run(){return response}', + subscriptionId, + ids.donId, + 400_000, + { gasPrice }, + ) + const { events } = await tx.wait() + const requestId = getEventArg(events, 'RequestSent', 0) + await expect(tx) + .to.emit(contracts.client, 'RequestSent') + .withArgs(requestId) + + const response = stringToBytes('response') + const error = stringToBytes('') + const oracleRequestEvent = await contracts.coordinator.queryFilter( + contracts.coordinator.filters.OracleRequest(), + ) + const onchainMetadata = oracleRequestEvent[0].args?.['commitment'] + const offchainMetadata = stringToBytes('') + const report = await encodeReport( + ethers.utils.hexZeroPad(requestId, 32), + response, + error, + onchainMetadata, + offchainMetadata, + ) + + await expect(contracts.coordinator.callReport(report, { gasPrice })) + .to.emit(contracts.coordinator, 'OracleResponse') + .withArgs(requestId, await roles.defaultAccount.getAddress()) + .to.emit(contracts.router, 'RequestProcessed') + .withArgs( + requestId, + subscriptionId, + () => true, + () => true, + 0, // Result code for callback failing + () => true, + () => true, + () => true, + ) + .to.emit(contracts.client, 'FulfillRequestInvoked') + .withArgs(requestId, response, error) + .to.emit(contracts.client, 'SendRequestInvoked') + }) + + it('prevents callbacks from starting another request if have insufficient funds', async function () { + await acceptTermsOfService( + contracts.accessControl, + roles.subOwner, + roles.subOwnerAddress, + ) + const createSubTx = await contracts.router + .connect(roles.subOwner) + .createSubscription() + const createSubReceipt = await createSubTx.wait() + const subscriptionId = + createSubReceipt.events[0].args['subscriptionId'].toNumber() + await contracts.router + .connect(roles.subOwner) + .addConsumer(subscriptionId, contracts.client.address) + await contracts.linkToken + .connect(roles.subOwner) + .transferAndCall( + contracts.router.address, + BigNumber.from('300000000000000000'), + ethers.utils.defaultAbiCoder.encode(['uint64'], [subscriptionId]), + ) + + // Set test helper flag + await contracts.client.setDoValidReentrantOperation( + true, + subscriptionId, + ids.donId, + ) + + // Set flag so they have enough callback gas + const flags = new Uint8Array(32) + flags[0] = 1 + await contracts.router + .connect(roles.defaultAccount) + .setFlags(subscriptionId, flags) + + // Send request + const tx = await contracts.client.sendSimpleRequestWithJavaScript( + 'function run(){return response}', + subscriptionId, + ids.donId, + 400_000, + { gasPrice }, + ) + const { events } = await tx.wait() + const requestId = getEventArg(events, 'RequestSent', 0) + await expect(tx) + .to.emit(contracts.client, 'RequestSent') + .withArgs(requestId) + + const response = stringToBytes('response') + const error = stringToBytes('') + const oracleRequestEvent = await contracts.coordinator.queryFilter( + contracts.coordinator.filters.OracleRequest(), + ) + const onchainMetadata = oracleRequestEvent[0].args?.['commitment'] + const offchainMetadata = stringToBytes('') + const report = await encodeReport( + ethers.utils.hexZeroPad(requestId, 32), + response, + error, + onchainMetadata, + offchainMetadata, + ) + + await expect(contracts.coordinator.callReport(report, { gasPrice })) + .to.emit(contracts.coordinator, 'OracleResponse') + .withArgs(requestId, await roles.defaultAccount.getAddress()) + .to.emit(contracts.client, 'FulfillRequestInvoked') + .withArgs(requestId, response, error) + .to.emit(contracts.router, 'RequestProcessed') + .withArgs( + requestId, + subscriptionId, + () => true, + () => true, + 1, // Result code for callback failing + () => true, + () => true, + () => true, + ) + }) + + it('callbacks are unable to improperly use subscription methods', async function () { + await acceptTermsOfService( + contracts.accessControl, + roles.subOwner, + roles.subOwnerAddress, + ) + const createSubTx = await contracts.router + .connect(roles.subOwner) + .createSubscription() + const createSubReceipt = await createSubTx.wait() + const subscriptionId = + createSubReceipt.events[0].args['subscriptionId'].toNumber() + await contracts.router + .connect(roles.subOwner) + .addConsumer(subscriptionId, contracts.client.address) + await contracts.linkToken + .connect(roles.subOwner) + .transferAndCall( + contracts.router.address, + BigNumber.from('1000000000000000000'), + ethers.utils.defaultAbiCoder.encode(['uint64'], [subscriptionId]), + ) + + // Set flag so they have enough callback gas + const flags = new Uint8Array(32) + flags[0] = 1 + await contracts.router + .connect(roles.defaultAccount) + .setFlags(subscriptionId, flags) + + // Accept ToS for client contract + const acceptorAddress = roles.subOwnerAddress + const recipientAddress = contracts.client.address + const message = await contracts.accessControl.getMessage( + acceptorAddress, + recipientAddress, + ) + const wallet = new ethers.Wallet(accessControlMockPrivateKey) + const flatSignature = await wallet.signMessage( + ethers.utils.arrayify(message), + ) + const { r, s, v } = ethers.utils.splitSignature(flatSignature) + await contracts.client + .connect(roles.subOwner) + .acceptTermsOfService(acceptorAddress, recipientAddress, r, s, v) + + // Transfer Subscription ownership to client contract so that it can call subscription methods + await contracts.router + .connect(roles.subOwner) + .proposeSubscriptionOwnerTransfer( + subscriptionId, + contracts.client.address, + ) + await contracts.client.acceptSubscriptionOwnerTransfer(subscriptionId) + + // Set test helper flag + await contracts.client.setDoInvalidReentrantOperation( + true, + subscriptionId, + ) + + // Send request + const tx = await contracts.client.sendSimpleRequestWithJavaScript( + 'function run(){return response}', + subscriptionId, + ids.donId, + 400_000, + { gasPrice }, + ) + const { events } = await tx.wait() + const requestId = getEventArg(events, 'RequestSent', 0) + await expect(tx) + .to.emit(contracts.client, 'RequestSent') + .withArgs(requestId) + + const response = stringToBytes('response') + const error = stringToBytes('') + const oracleRequestEvent = await contracts.coordinator.queryFilter( + contracts.coordinator.filters.OracleRequest(), + ) + const onchainMetadata = oracleRequestEvent[0].args?.['commitment'] + const offchainMetadata = stringToBytes('') + const report = await encodeReport( + ethers.utils.hexZeroPad(requestId, 32), + response, + error, + onchainMetadata, + offchainMetadata, + ) + + await expect(contracts.coordinator.callReport(report, { gasPrice })) + .to.emit(contracts.coordinator, 'OracleResponse') + .withArgs(requestId, await roles.defaultAccount.getAddress()) + .to.emit(contracts.client, 'FulfillRequestInvoked') + .withArgs(requestId, response, error) + .to.emit(contracts.router, 'RequestProcessed') + .withArgs( + requestId, + subscriptionId, + () => true, + () => true, + 1, // Result code for callback failing + () => true, + () => true, + () => true, + ) + }) + }) }) diff --git a/contracts/test/v0.8/functions/v1/GasGolf.test.ts b/contracts/test/v0.8/functions/v1/GasGolf.test.ts index f0c1bb96f7d..32cc660beda 100644 --- a/contracts/test/v0.8/functions/v1/GasGolf.test.ts +++ b/contracts/test/v0.8/functions/v1/GasGolf.test.ts @@ -1,13 +1,13 @@ import { ethers } from 'hardhat' import { BigNumber } from 'ethers' -import { expect } from 'chai' import { - getSetupFactory, + accessControlMockPrivateKey, + encodeReport, FunctionsContracts, FunctionsRoles, - ids, getEventArg, - accessControlMockPrivateKey, + getSetupFactory, + ids, } from './utils' import { stringToBytes } from '../../../test-helpers/helpers' @@ -15,7 +15,7 @@ const setup = getSetupFactory() let contracts: FunctionsContracts let roles: FunctionsRoles -const baselineGasUsed = 933_007 // TODO: Baseline will be updated at the start of 7/27 +const baselineGasUsed = 721271 let currentGasUsed = 0 beforeEach(async () => { @@ -32,15 +32,24 @@ after(() => { describe('Gas Golf', () => { it('taking a swing', async () => { // User signs Terms of Service - const messageHash = await contracts.accessControl.getMessageHash( + const message = await contracts.accessControl.getMessage( roles.consumerAddress, roles.consumerAddress, ) const wallet = new ethers.Wallet(accessControlMockPrivateKey) - const proof = await wallet.signMessage(ethers.utils.arrayify(messageHash)) + const flatSignature = await wallet.signMessage( + ethers.utils.arrayify(message), + ) + const { r, s, v } = ethers.utils.splitSignature(flatSignature) const acceptTermsOfServiceTx = await contracts.accessControl .connect(roles.consumer) - .acceptTermsOfService(roles.consumerAddress, roles.consumerAddress, proof) + .acceptTermsOfService( + roles.consumerAddress, + roles.consumerAddress, + r, + s, + v, + ) const { gasUsed: acceptTermsOfServiceGasUsed } = await acceptTermsOfServiceTx.wait() @@ -74,16 +83,24 @@ describe('Gas Golf', () => { 'function myFancyFunction(){return "woah, thats fancy"}', subscriptionId, ids.donId, + 20_000, ) const { gasUsed: requestTxGasUsed, events } = await requestTx.wait() const requestId = getEventArg(events, 'RequestSent', 0) - + const oracleRequestEvent = await contracts.coordinator.queryFilter( + contracts.coordinator.filters.OracleRequest(), + ) // DON's transmitter submits a response const response = stringToBytes('woah, thats fancy') const error = stringToBytes('') - const report = ethers.utils.defaultAbiCoder.encode( - ['bytes32[]', 'bytes[]', 'bytes[]'], - [[ethers.utils.hexZeroPad(requestId, 32)], [response], [error]], + const onchainMetadata = oracleRequestEvent[0].args?.['commitment'] + const offchainMetadata = stringToBytes('') + const report = await encodeReport( + ethers.utils.hexZeroPad(requestId, 32), + response, + error, + onchainMetadata, + offchainMetadata, ) const fulfillmentTx = await contracts.coordinator.callReport(report) const { gasUsed: fulfillmentTxGasUsed } = await fulfillmentTx.wait() diff --git a/contracts/test/v0.8/functions/v1/RouterBase.test.ts b/contracts/test/v0.8/functions/v1/RouterBase.test.ts index 4a4553ebd75..3a3b58b8f6b 100644 --- a/contracts/test/v0.8/functions/v1/RouterBase.test.ts +++ b/contracts/test/v0.8/functions/v1/RouterBase.test.ts @@ -23,200 +23,30 @@ beforeEach(async () => { }) describe('FunctionsRouter - Base', () => { - describe('Config', () => { - it('non-owner is unable to set config', async () => { - await expect( - contracts.router - .connect(roles.stranger) - .proposeContractsUpdate([ids.donId], [contracts.coordinator.address]), - ).to.be.revertedWith('Only callable by owner') - }) - - it('non-owner is unable to apply config', async () => { - await expect( - contracts.router.proposeConfigUpdate( - ids.routerId, - ethers.utils.defaultAbiCoder.encode( - ['uint96', 'bytes4'], - [1, 0x0ca76175], - ), - ), - ).to.emit(contracts.router, 'ConfigProposed') - await expect( - contracts.router.connect(roles.stranger).updateConfig(ids.routerId), - ).to.be.revertedWith('Only callable by owner') - }) - - it('incorrect config cannot be applied', async () => { - await contracts.router.proposeConfigUpdate( - ids.routerId, - ethers.utils.defaultAbiCoder.encode( - ['int256', 'bytes4'], - [-100000, 0x0ca76175], - ), - ) - await expect(contracts.router.updateConfig(ids.routerId)).to.be.reverted - }) - - it('Owner can update config of the Router', async () => { - const [ - beforeSystemVersionMajor, - beforeSystemVersionMinor, - beforeSystemVersionPatch, - ] = await contracts.router.version() - const beforeConfigHash = await contracts.router.getConfigHash() - - await expect( - contracts.router.proposeConfigUpdate( - ids.routerId, - ethers.utils.defaultAbiCoder.encode( - ['uint96', 'bytes4'], - [1, 0x0ca76175], - ), - ), - ).to.emit(contracts.router, 'ConfigProposed') - await expect(contracts.router.updateConfig(ids.routerId)).to.emit( - contracts.router, - 'ConfigUpdated', - ) - const [ - afterSystemVersionMajor, - afterSystemVersionMinor, - afterSystemVersionPatch, - ] = await contracts.router.version() - const afterConfigHash = await contracts.router.getConfigHash() - expect(afterSystemVersionMajor).to.equal(beforeSystemVersionMajor) - expect(afterSystemVersionMinor).to.equal(beforeSystemVersionMinor) - expect(afterSystemVersionPatch).to.equal(beforeSystemVersionPatch + 1) - expect(beforeConfigHash).to.not.equal(afterConfigHash) - }) - - it('Config of a contract on a route can be updated', async () => { - const [ - beforeSystemVersionMajor, - beforeSystemVersionMinor, - beforeSystemVersionPatch, - ] = await contracts.router.version() - const beforeConfigHash = await contracts.coordinator.getConfigHash() - - await expect( - contracts.router.proposeConfigUpdate( - ids.donId, - ethers.utils.defaultAbiCoder.encode( - [ - 'uint32', - 'uint32', - 'uint32', - 'uint32', - 'int256', - 'uint32', - 'uint96', - 'uint16', - ], - [ - ...Object.values({ - ...coordinatorConfig, - maxSupportedRequestDataVersion: 2, - }), - ], - ), - ), - ).to.emit(contracts.router, 'ConfigProposed') - await expect(contracts.router.updateConfig(ids.donId)).to.emit( - contracts.router, - 'ConfigUpdated', - ) - const [ - afterSystemVersionMajor, - afterSystemVersionMinor, - afterSystemVersionPatch, - ] = await contracts.router.version() - const afterConfigHash = await contracts.router.getConfigHash() - expect(afterSystemVersionMajor).to.equal(beforeSystemVersionMajor) - expect(afterSystemVersionMinor).to.equal(beforeSystemVersionMinor) - expect(afterSystemVersionPatch).to.equal(beforeSystemVersionPatch + 1) - expect(beforeConfigHash).to.not.equal(afterConfigHash) - }) - - it('returns the config set on the Router', async () => { - expect( - await contracts.router.connect(roles.stranger).getAdminFee(), - ).to.equal(0) - }) - }) - describe('Updates', () => { - it('One or more contracts on a route can be updated', async () => { - const subscriptionId = await createSubscription( - roles.subOwner, - [contracts.client.address], - contracts.router, - contracts.accessControl, - contracts.linkToken, - ) + it('One or more contracts on a route can be updated by the owner', async () => { const coordinator2 = await factories.functionsCoordinatorFactory .connect(roles.defaultAccount) .deploy( contracts.router.address, - ethers.utils.defaultAbiCoder.encode( - [ - 'uint32', - 'uint32', - 'uint32', - 'uint32', - 'int256', - 'uint32', - 'uint96', - 'uint16', - ], - [...Object.values(coordinatorConfig)], - ), + coordinatorConfig, contracts.mockLinkEth.address, ) const coordinator3 = await factories.functionsCoordinatorFactory .connect(roles.defaultAccount) .deploy( contracts.router.address, - ethers.utils.defaultAbiCoder.encode( - [ - 'uint32', - 'uint32', - 'uint32', - 'uint32', - 'int256', - 'uint32', - 'uint96', - 'uint16', - ], - [...Object.values(coordinatorConfig)], - ), + coordinatorConfig, contracts.mockLinkEth.address, ) const coordinator4 = await factories.functionsCoordinatorFactory .connect(roles.defaultAccount) .deploy( contracts.router.address, - ethers.utils.defaultAbiCoder.encode( - [ - 'uint32', - 'uint32', - 'uint32', - 'uint32', - 'int256', - 'uint32', - 'uint96', - 'uint16', - ], - [...Object.values(coordinatorConfig)], - ), + coordinatorConfig, contracts.mockLinkEth.address, ) - const [ - beforeSystemVersionMajor, - beforeSystemVersionMinor, - beforeSystemVersionPatch, - ] = await contracts.router.version() await expect( contracts.router['getContractById(bytes32)'](ids.donId2), ).to.be.revertedWith('RouteNotFound') @@ -233,6 +63,14 @@ describe('FunctionsRouter - Base', () => { ), ).to.emit(contracts.router, `ContractProposed`) + const subscriptionId = await createSubscription( + roles.subOwner, + [contracts.client.address], + contracts.router, + contracts.accessControl, + contracts.linkToken, + ) + const requestProposedTx = await contracts.client.sendRequestProposed( `return 'hello world'`, subscriptionId, @@ -242,10 +80,16 @@ describe('FunctionsRouter - Base', () => { const { events } = await requestProposedTx.wait() const requestId = getEventArg(events, 'RequestSent', 0) - const report = encodeReport( + const oracleRequestEvent = await coordinator2.queryFilter( + contracts.coordinator.filters.OracleRequest(), + ) + const onchainMetadata = oracleRequestEvent[0].args?.['commitment'] + const report = await encodeReport( ethers.utils.hexZeroPad(requestId, 32), stringToHex('hello world'), stringToHex(''), + onchainMetadata, + stringToHex(''), ) await expect( @@ -267,15 +111,6 @@ describe('FunctionsRouter - Base', () => { expect( await contracts.router['getContractById(bytes32)'](ids.donId4), ).to.equal(coordinator4.address) - - const [ - afterSystemVersionMajor, - afterSystemVersionMinor, - afterSystemVersionPatch, - ] = await contracts.router.version() - expect(afterSystemVersionMajor).to.equal(beforeSystemVersionMajor) - expect(afterSystemVersionMinor).to.equal(beforeSystemVersionMinor + 1) - expect(afterSystemVersionPatch).to.equal(beforeSystemVersionPatch) }) it('non-owner is unable to propose contract updates', async () => { @@ -293,70 +128,9 @@ describe('FunctionsRouter - Base', () => { }) }) - describe('Timelock', () => { - it('prevents applying timelock updates', async () => { - await contracts.router.proposeTimelockBlocks(5) - await contracts.router.updateTimelockBlocks() - await contracts.router.proposeTimelockBlocks(6) - await expect(contracts.router.updateTimelockBlocks()).to.be.revertedWith( - 'TimelockInEffect', - ) - }) - - it('prevents applying config updates', async () => { - await contracts.router.proposeTimelockBlocks(5) - await contracts.router.updateTimelockBlocks() - - await contracts.router.proposeConfigUpdate( - ids.routerId, - ethers.utils.defaultAbiCoder.encode( - ['uint96', 'bytes4'], - [20, 0x0ca76175], - ), - ) - await expect( - contracts.router.updateConfig(ids.routerId), - ).to.be.revertedWith('TimelockInEffect') - }) - - it('prevents applying contract updates', async () => { - await contracts.router.proposeTimelockBlocks(5) - await contracts.router.updateTimelockBlocks() - - const coordinator2 = await factories.functionsCoordinatorFactory - .connect(roles.defaultAccount) - .deploy( - contracts.router.address, - ethers.utils.defaultAbiCoder.encode( - [ - 'uint32', - 'uint32', - 'uint32', - 'uint32', - 'int256', - 'uint32', - 'uint96', - 'uint16', - ], - [...Object.values(coordinatorConfig)], - ), - contracts.mockLinkEth.address, - ) - - await contracts.router.proposeContractsUpdate( - [ids.donId2], - [coordinator2.address], - ) - - await expect(contracts.router.updateContracts()).to.be.revertedWith( - 'TimelockInEffect', - ) - }) - }) - describe('Emergency Pause', () => { it('has paused state visible', async () => { - const paused = await contracts.router.isPaused() + const paused = await contracts.router.paused() expect(paused).to.equal(false) }) it('can pause the system', async () => { @@ -368,13 +142,14 @@ describe('FunctionsRouter - Base', () => { contracts.linkToken, ) - await contracts.router.togglePaused() + await contracts.router.pause() await expect( contracts.client.sendSimpleRequestWithJavaScript( `return 'hello world'`, subscriptionId, ids.donId, + 20_000, ), ).to.be.revertedWith('Pausable: paused') }) diff --git a/contracts/test/v0.8/functions/v1/TermsOfServiceAllowList.test.ts b/contracts/test/v0.8/functions/v1/TermsOfServiceAllowList.test.ts index e7adeab490a..1e1ad18a7d6 100644 --- a/contracts/test/v0.8/functions/v1/TermsOfServiceAllowList.test.ts +++ b/contracts/test/v0.8/functions/v1/TermsOfServiceAllowList.test.ts @@ -6,6 +6,7 @@ import { FunctionsRoles, acceptTermsOfService, accessControlMockPrivateKey, + accessControlConfig, } from './utils' const setup = getSetupFactory() @@ -17,24 +18,61 @@ beforeEach(async () => { }) describe('ToS Access Control', () => { + describe('Config', () => { + it('non-owner is unable to update config', async () => { + await expect( + contracts.accessControl + .connect(roles.stranger) + .updateConfig(accessControlConfig), + ).to.be.revertedWith('Only callable by owner') + }) + + it('Owner can update config', async () => { + const beforeConfig = await contracts.accessControl.getConfig() + await expect( + contracts.accessControl.updateConfig({ + ...accessControlConfig, + enabled: false, + }), + ).to.emit(contracts.accessControl, 'ConfigUpdated') + const afterConfig = await contracts.accessControl.getConfig() + expect(beforeConfig).to.not.equal(afterConfig) + }) + it('returns the config set', async () => { + const config = await contracts.accessControl + .connect(roles.stranger) + .getConfig() + await Promise.all( + Object.keys(accessControlConfig).map((key) => { + expect(config[key]).to.equal( + accessControlConfig[key as keyof typeof accessControlConfig], + ) + }), + ) + }) + }) + describe('Accepting', () => { - it('can only be done with a valid proof', async () => { - const messageHash = await contracts.accessControl.getMessageHash( + it('can only be done with a valid signature', async () => { + const message = await contracts.accessControl.getMessage( roles.strangerAddress, roles.strangerAddress, ) - const proof = await roles.stranger.signMessage( - ethers.utils.arrayify(messageHash), + const flatSignature = await roles.stranger.signMessage( + ethers.utils.arrayify(message), ) + const { r, s, v } = ethers.utils.splitSignature(flatSignature) await expect( contracts.accessControl .connect(roles.stranger) .acceptTermsOfService( roles.strangerAddress, roles.strangerAddress, - proof, + r, + s, + v, ), - ).to.be.revertedWith('InvalidProof') + ).to.be.revertedWith('InvalidSignature') }) it('can be done by Externally Owned Accounts if recipient themself', async () => { await acceptTermsOfService( @@ -43,7 +81,7 @@ describe('ToS Access Control', () => { roles.subOwnerAddress, ) expect( - await contracts.accessControl.isAllowedSender(roles.subOwnerAddress), + await contracts.accessControl.hasAccess(roles.subOwnerAddress, '0x'), ).to.equal(true) }) it('cannot be done by Externally Owned Accounts if recipient another EoA', async () => { @@ -53,39 +91,45 @@ describe('ToS Access Control', () => { roles.subOwner, roles.strangerAddress, ), - ).to.be.revertedWith('InvalidProof') + ).to.be.revertedWith('InvalidUsage') }) it('can be done by Contract Accounts if recipient themself', async () => { const acceptorAddress = roles.consumerAddress const recipientAddress = contracts.client.address - const messageHash = await contracts.accessControl.getMessageHash( + const message = await contracts.accessControl.getMessage( acceptorAddress, recipientAddress, ) const wallet = new ethers.Wallet(accessControlMockPrivateKey) - const proof = await wallet.signMessage(ethers.utils.arrayify(messageHash)) + const flatSignature = await wallet.signMessage( + ethers.utils.arrayify(message), + ) + const { r, s, v } = ethers.utils.splitSignature(flatSignature) await contracts.client .connect(roles.consumer) - .acceptTermsOfService(acceptorAddress, recipientAddress, proof) + .acceptTermsOfService(acceptorAddress, recipientAddress, r, s, v) expect( - await contracts.accessControl.isAllowedSender(recipientAddress), + await contracts.accessControl.hasAccess(recipientAddress, '0x'), ).to.equal(true) }) it('cannot be done by Contract Accounts that if they are not the recipient', async () => { const acceptorAddress = roles.consumerAddress const recipientAddress = contracts.coordinator.address - const messageHash = await contracts.accessControl.getMessageHash( + const message = await contracts.accessControl.getMessage( acceptorAddress, recipientAddress, ) const wallet = new ethers.Wallet(accessControlMockPrivateKey) - const proof = await wallet.signMessage(ethers.utils.arrayify(messageHash)) + const flatSignature = await wallet.signMessage( + ethers.utils.arrayify(message), + ) + const { r, s, v } = ethers.utils.splitSignature(flatSignature) await expect( contracts.client .connect(roles.consumer) - .acceptTermsOfService(acceptorAddress, recipientAddress, proof), - ).to.be.revertedWith('InvalidProof') + .acceptTermsOfService(acceptorAddress, recipientAddress, r, s, v), + ).to.be.revertedWith('InvalidUsage') }) }) @@ -95,7 +139,7 @@ describe('ToS Access Control', () => { contracts.accessControl .connect(roles.stranger) .blockSender(roles.subOwnerAddress), - ).to.be.revertedWith('OnlyCallableByRouterOwner') + ).to.be.revertedWith('Only callable by owner') }) it('removes the ability to re-accept the terms of service', async () => { await contracts.accessControl.blockSender(roles.subOwnerAddress) diff --git a/contracts/test/v0.8/functions/v1/utils.ts b/contracts/test/v0.8/functions/v1/utils.ts index b38f97d6bfd..a7a89871f32 100644 --- a/contracts/test/v0.8/functions/v1/utils.ts +++ b/contracts/test/v0.8/functions/v1/utils.ts @@ -1,6 +1,7 @@ import { ethers } from 'hardhat' import { BigNumber, ContractFactory, Signer, Contract, providers } from 'ethers' import { Roles, getUsers } from '../../../test-helpers/setup' +import { EventFragment } from 'ethers/lib/utils' export type FunctionsRoles = Roles & { subOwner: Signer @@ -43,25 +44,46 @@ export const stringToHex = (s: string) => { return ethers.utils.hexlify(ethers.utils.toUtf8Bytes(s)) } -export const encodeReport = ( +export const encodeReport = async ( requestId: string, result: string, err: string, + onchainMetadata: any, + offchainMetadata: string, ) => { + const functionsResponse = await ethers.getContractFactory( + 'src/v0.8/functions/dev/1_0_0/FunctionsCoordinator.sol:FunctionsCoordinator', + ) + const onchainMetadataBytes = functionsResponse.interface._abiCoder.encode( + [ + getEventInputs( + Object.values(functionsResponse.interface.events), + 'OracleRequest', + 9, + ), + ], + [[...onchainMetadata]], + ) const abi = ethers.utils.defaultAbiCoder return abi.encode( - ['bytes32[]', 'bytes[]', 'bytes[]'], - [[requestId], [result], [err]], + ['bytes32[]', 'bytes[]', 'bytes[]', 'bytes[]', 'bytes[]'], + [[requestId], [result], [err], [onchainMetadataBytes], [offchainMetadata]], ) } export type FunctionsRouterConfig = { + maxConsumersPerSubscription: number adminFee: number handleOracleFulfillmentSelector: string + maxCallbackGasLimits: number[] + gasForCallExactCheck: number } export const functionsRouterConfig: FunctionsRouterConfig = { + maxConsumersPerSubscription: 100, adminFee: 0, handleOracleFulfillmentSelector: '0x0ca76175', + maxCallbackGasLimits: [300_000, 500_000, 1_000_000], + gasForCallExactCheck: 5000, } export type CoordinatorConfig = { maxCallbackGasLimit: number @@ -70,8 +92,9 @@ export type CoordinatorConfig = { gasOverheadAfterCallback: number requestTimeoutSeconds: number donFee: number - fallbackNativePerUnitLink: BigNumber maxSupportedRequestDataVersion: number + fulfillmentGasPriceOverEstimationBP: number + fallbackNativePerUnitLink: BigNumber } const fallbackNativePerUnitLink = 5000000000000000 export const coordinatorConfig: CoordinatorConfig = { @@ -81,20 +104,22 @@ export const coordinatorConfig: CoordinatorConfig = { gasOverheadAfterCallback: 44_615, requestTimeoutSeconds: 300, donFee: 0, - fallbackNativePerUnitLink: BigNumber.from(fallbackNativePerUnitLink), maxSupportedRequestDataVersion: 1, + fulfillmentGasPriceOverEstimationBP: 0, + fallbackNativePerUnitLink: BigNumber.from(fallbackNativePerUnitLink), } -export const accessControlMockPublicKey = - '0x32237412cC0321f56422d206e505dB4B3871AF5c' +export const accessControlMockPublicKey = ethers.utils.getAddress( + '0x32237412cC0321f56422d206e505dB4B3871AF5c', +) export const accessControlMockPrivateKey = '2e8c8eaff4159e59711b42424c1555af1b78409e12c6f9c69a6a986d75442b20' export type AccessControlConfig = { enabled: boolean - proofSignerPublicKey: string // address + signerPublicKey: string // address } export const accessControlConfig: AccessControlConfig = { enabled: true, - proofSignerPublicKey: accessControlMockPublicKey, + signerPublicKey: accessControlMockPublicKey, } export async function setupRolesAndFactories(): Promise<{ @@ -119,11 +144,11 @@ export async function setupRolesAndFactories(): Promise<{ roles.consumer, ) const linkTokenFactory = await ethers.getContractFactory( - 'src/v0.4/LinkToken.sol:LinkToken', + 'src/v0.8/mocks/MockLinkToken.sol:MockLinkToken', roles.defaultAccount, ) const mockAggregatorV3Factory = await ethers.getContractFactory( - 'src/v0.7/tests/MockV3Aggregator.sol:MockV3Aggregator', + 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', roles.defaultAccount, ) return { @@ -153,15 +178,16 @@ export async function acceptTermsOfService( recipientAddress: string, ) { const acceptorAddress = await acceptor.getAddress() - const messageHash = await accessControl.getMessageHash( + const message = await accessControl.getMessage( acceptorAddress, recipientAddress, ) const wallet = new ethers.Wallet(accessControlMockPrivateKey) - const proof = await wallet.signMessage(ethers.utils.arrayify(messageHash)) + const flatSignature = await wallet.signMessage(ethers.utils.arrayify(message)) + const { r, s, v } = ethers.utils.splitSignature(flatSignature) return accessControl .connect(acceptor) - .acceptTermsOfService(acceptorAddress, recipientAddress, proof) + .acceptTermsOfService(acceptorAddress, recipientAddress, r, s, v) } export async function createSubscription( @@ -184,7 +210,7 @@ export async function createSubscription( .connect(owner) .transferAndCall( router.address, - BigNumber.from('54666805176129187'), + BigNumber.from('1000000000000000000'), ethers.utils.defaultAbiCoder.encode(['uint64'], [subId]), ) } @@ -213,47 +239,24 @@ export function getSetupFactory(): () => { const linkToken = await factories.linkTokenFactory .connect(roles.defaultAccount) .deploy() + const mockLinkEth = await factories.mockAggregatorV3Factory.deploy( 0, linkEthRate, ) - const routerConfigBytes = ethers.utils.defaultAbiCoder.encode( - ['uint96', 'bytes4'], - [...Object.values(functionsRouterConfig)], - ) - const startingTimelockBlocks = 0 - const maxTimelockBlocks = 20 + const router = await factories.functionsRouterFactory .connect(roles.defaultAccount) - .deploy( - startingTimelockBlocks, - maxTimelockBlocks, - linkToken.address, - routerConfigBytes, - ) - const coordinatorConfigBytes = ethers.utils.defaultAbiCoder.encode( - [ - 'uint32', - 'uint32', - 'uint32', - 'uint32', - 'int256', - 'uint32', - 'uint96', - 'uint16', - ], - [...Object.values(coordinatorConfig)], - ) + .deploy(linkToken.address, functionsRouterConfig) + const coordinator = await factories.functionsCoordinatorFactory .connect(roles.defaultAccount) - .deploy(router.address, coordinatorConfigBytes, mockLinkEth.address) - const accessControlConfigBytes = ethers.utils.defaultAbiCoder.encode( - ['bool', 'address'], - [...Object.values(accessControlConfig)], - ) + .deploy(router.address, coordinatorConfig, mockLinkEth.address) + const accessControl = await factories.accessControlFactory .connect(roles.defaultAccount) - .deploy(router.address, accessControlConfigBytes) + .deploy(accessControlConfig) + const client = await factories.clientTestHelperFactory .connect(roles.consumer) .deploy(router.address) @@ -300,6 +303,20 @@ export function getEventArg(events: any, eventName: string, argIndex: number) { return undefined } +export function getEventInputs( + events: EventFragment[], + eventName: string, + argIndex: number, +) { + if (Array.isArray(events)) { + const event = events.find((e) => e.name.includes(eventName)) + if (event && Array.isArray(event.inputs) && event.inputs.length > 0) { + return event.inputs[argIndex] + } + } + throw 'Not found' +} + export async function parseOracleRequestEventArgs( tx: providers.TransactionResponse, ) { diff --git a/core/assets/wei.go b/core/assets/wei.go index f88fb60e618..7d1240d384c 100644 --- a/core/assets/wei.go +++ b/core/assets/wei.go @@ -76,6 +76,11 @@ func NewWeiI[T constraints.Signed](i T) *Wei { return NewWei(big.NewInt(int64(i))) } +// Returns input big.Int in Wei string format. +func FormatWei(i *big.Int) string { + return NewWei(i).String() +} + func (w *Wei) Text(suffix string) string { switch suffix { default: // empty or unknown diff --git a/core/chains/chain_kv.go b/core/chains/chain_kv.go new file mode 100644 index 00000000000..6292ef10197 --- /dev/null +++ b/core/chains/chain_kv.go @@ -0,0 +1,62 @@ +package chains + +import ( + "errors" + "fmt" + + "golang.org/x/exp/maps" +) + +type ChainsKV[T ChainService] struct { + // note: this is read only after construction so no need for mutex + chains map[string]T +} + +var ErrNoSuchChainID = errors.New("chain id does not exist") + +func NewChainsKV[T ChainService](cs map[string]T) *ChainsKV[T] { + + return &ChainsKV[T]{ + chains: cs, + } +} +func (c *ChainsKV[T]) Len() int { + return len(c.chains) +} + +// Get return [ErrNoSuchChainID] if [id] is not found +func (c *ChainsKV[T]) Get(id string) (T, error) { + var dflt T + chn, exist := c.chains[id] + if !exist { + return dflt, fmt.Errorf("%w: %s", ErrNoSuchChainID, id) + } + return chn, nil +} + +func (c *ChainsKV[T]) List(ids ...string) ([]T, error) { + if len(ids) == 0 { + return c.Slice(), nil + } + + var ( + result []T + err error + ) + + for _, id := range ids { + chn, exists := c.chains[id] + if !exists { + err2 := fmt.Errorf("%w: %s", ErrNoSuchChainID, id) + err = errors.Join(err, err2) + continue + } + result = append(result, chn) + } + + return result, err +} + +func (c *ChainsKV[T]) Slice() []T { + return maps.Values(c.chains) +} diff --git a/core/chains/chain_kv_test.go b/core/chains/chain_kv_test.go new file mode 100644 index 00000000000..c042eea20f1 --- /dev/null +++ b/core/chains/chain_kv_test.go @@ -0,0 +1,93 @@ +package chains_test + +import ( + "context" + "math/big" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink/v2/core/chains" +) + +func Test_ChainKV(t *testing.T) { + var ( + testChainID = "id" + testChain = &testChainService{name: "test chain"} + ) + // test empty case + empty := make(map[string]*testChainService) + kv := chains.NewChainsKV[*testChainService](empty) + c, err := kv.Get(testChainID) + assert.Nil(t, c) + assert.ErrorIs(t, err, chains.ErrNoSuchChainID) + + assert.Equal(t, kv.Len(), 0) + assert.Len(t, kv.Slice(), 0) + + cs, err := kv.List() + assert.NoError(t, err) + assert.Len(t, cs, 0) + + // test with one chain + onechain := map[string]*testChainService{testChainID: testChain} + kv = chains.NewChainsKV[*testChainService](onechain) + c, err = kv.Get(testChainID) + assert.Equal(t, c, testChain) + assert.NoError(t, err) + + assert.Equal(t, kv.Len(), 1) + assert.Len(t, kv.Slice(), 1) + + cs, err = kv.List() + assert.NoError(t, err) + assert.Len(t, cs, 1) + + //List explicit chain + cs, err = kv.List(testChainID) + assert.NoError(t, err) + assert.Len(t, cs, 1) + assert.Equal(t, testChain, cs[0]) + + //List no such id + cs, err = kv.List("no such id") + assert.Error(t, err) + assert.Len(t, cs, 0) +} + +type testChainService struct { + name string +} + +// Start the service. Must quit immediately if the context is cancelled. +// The given context applies to Start function only and must not be retained. +func (s *testChainService) Start(_ context.Context) error { + return nil +} + +// Close stops the Service. +// Invariants: Usually after this call the Service cannot be started +// again, you need to build a new Service to do so. +func (s *testChainService) Close() error { + return nil +} + +// Name returns the fully qualified name of the service +func (s *testChainService) Name() string { + return s.name +} + +// Ready should return nil if ready, or an error message otherwise. +func (s *testChainService) Ready() error { + return nil +} + +// HealthReport returns a full health report of the callee including it's dependencies. +// key is the dep name, value is nil if healthy, or error message otherwise. +func (s *testChainService) HealthReport() map[string]error { + return map[string]error{} +} + +func (s *testChainService) SendTx(ctx context.Context, from string, to string, amount *big.Int, balanceCheck bool) error { + return nil +} diff --git a/core/chains/chain_set.go b/core/chains/chain_set.go index 34211fd0d08..ed5ee918366 100644 --- a/core/chains/chain_set.go +++ b/core/chains/chain_set.go @@ -22,14 +22,16 @@ var ( ErrNotFound = errors.New("not found") ) -// Chains is a generic interface for chain configuration. -type Chains interface { +// ChainStatuser is a generic interface for chain configuration. +type ChainStatuser interface { + // must return [ErrNotFound] if the id is not found ChainStatus(ctx context.Context, id string) (types.ChainStatus, error) ChainStatuses(ctx context.Context, offset, limit int) ([]types.ChainStatus, int, error) } -// Nodes is an interface for node configuration and state. -type Nodes interface { +// NodesStatuser is an interface for node configuration and state. +// TODO BCF2440, BCF-2511 may need Node(ctx,name) to get a node status by name +type NodesStatuser interface { NodeStatuses(ctx context.Context, offset, limit int, chainIDs ...string) (nodes []types.NodeStatus, count int, err error) } @@ -78,7 +80,7 @@ func (c *chainSet[N, S]) Chain(ctx context.Context, id string) (s S, err error) } ch, ok := c.chains[id] if !ok { - err = ErrNotFound + err = fmt.Errorf("chain %s: %w", id, ErrNotFound) return } return ch, nil @@ -92,7 +94,7 @@ func (c *chainSet[N, S]) ChainStatus(ctx context.Context, id string) (cfg types. } l := len(cs) if l == 0 { - err = ErrNotFound + err = fmt.Errorf("chain %s: %w", id, ErrNotFound) return } if l > 1 { diff --git a/core/chains/cosmos/chain.go b/core/chains/cosmos/chain.go index d182d57f8f8..82d9a87f4d1 100644 --- a/core/chains/cosmos/chain.go +++ b/core/chains/cosmos/chain.go @@ -62,7 +62,7 @@ func newChain(id string, cfg coscfg.Config, db *sqlx.DB, ks keystore.Cosmos, log gpe := cosmosclient.NewMustGasPriceEstimator([]cosmosclient.GasPricesEstimator{ cosmosclient.NewClosureGasPriceEstimator(func() (map[string]sdk.DecCoin, error) { return map[string]sdk.DecCoin{ - "uatom": sdk.NewDecCoinFromDec("uatom", cfg.FallbackGasPrice()), + cfg.FeeToken(): sdk.NewDecCoinFromDec(cfg.FeeToken(), cfg.FallbackGasPrice()), }, nil }), }, lggr) diff --git a/core/chains/cosmos/chain_set.go b/core/chains/cosmos/chain_set.go index 765d2fa358f..008c62c3ffd 100644 --- a/core/chains/cosmos/chain_set.go +++ b/core/chains/cosmos/chain_set.go @@ -1,7 +1,10 @@ package cosmos import ( - "github.com/pkg/errors" + "context" + "errors" + "fmt" + "go.uber.org/multierr" "github.com/smartcontractkit/sqlx" @@ -10,12 +13,14 @@ import ( "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/db" "github.com/smartcontractkit/chainlink-relay/pkg/logger" + "github.com/smartcontractkit/chainlink-relay/pkg/loop" + pkgcosmos "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos" "github.com/smartcontractkit/chainlink/v2/core/chains" "github.com/smartcontractkit/chainlink/v2/core/chains/cosmos/types" - coreconfig "github.com/smartcontractkit/chainlink/v2/core/config" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/services/pg" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) var ( @@ -25,9 +30,12 @@ var ( ErrChainIDInvalid = errors.New("chain id does not match any local chains") ) +// Chain is a wrap for easy use in other places in the core node +type Chain = adapters.Chain + // ChainSetOpts holds options for configuring a ChainSet. type ChainSetOpts struct { - Config coreconfig.AppConfig + QueryConfig pg.QConfig Logger logger.Logger DB *sqlx.DB KeyStore keystore.Cosmos @@ -37,9 +45,9 @@ type ChainSetOpts struct { func (o *ChainSetOpts) Validate() (err error) { required := func(s string) error { - return errors.Errorf("%s is required", s) + return fmt.Errorf("%s is required", s) } - if o.Config == nil { + if o.QueryConfig == nil { err = multierr.Append(err, required("Config")) } if o.Logger == nil { @@ -66,33 +74,106 @@ func (o *ChainSetOpts) ConfigsAndLogger() (chains.Configs[string, db.Node], logg func (o *ChainSetOpts) NewTOMLChain(cfg *CosmosConfig) (adapters.Chain, error) { if !cfg.IsEnabled() { - return nil, errors.Errorf("cannot create new chain with ID %s, the chain is disabled", *cfg.ChainID) + return nil, fmt.Errorf("cannot create new chain with ID %s, the chain is disabled", *cfg.ChainID) } - c, err := newChain(*cfg.ChainID, cfg, o.DB, o.KeyStore, o.Config.Database(), o.EventBroadcaster, o.Configs, o.Logger) + c, err := newChain(*cfg.ChainID, cfg, o.DB, o.KeyStore, o.QueryConfig, o.EventBroadcaster, o.Configs, o.Logger) if err != nil { return nil, err } return c, nil } -type ChainSet = adapters.ChainSet +// LegacyChainContainer is container interface for Cosmos chains +type LegacyChainContainer interface { + Get(id string) (adapters.Chain, error) + Len() int + List(ids ...string) ([]adapters.Chain, error) + Slice() []adapters.Chain +} + +type LegacyChains = chains.ChainsKV[adapters.Chain] + +var _ LegacyChainContainer = &LegacyChains{} + +func NewLegacyChains(m map[string]adapters.Chain) *LegacyChains { + return chains.NewChainsKV[adapters.Chain](m) +} + +type LoopRelayerChainer interface { + loop.Relayer + Chain() adapters.Chain +} + +type LoopRelayerSingleChain struct { + loop.Relayer + singleChain *SingleChainSet +} + +func NewLoopRelayerSingleChain(r *pkgcosmos.Relayer, s *SingleChainSet) *LoopRelayerSingleChain { + ra := relay.NewRelayerAdapter(r, s) + return &LoopRelayerSingleChain{ + Relayer: ra, + singleChain: s, + } +} +func (r *LoopRelayerSingleChain) Chain() adapters.Chain { + return r.singleChain.chain +} + +var _ LoopRelayerChainer = &LoopRelayerSingleChain{} -func NewChainSet(opts ChainSetOpts, cfgs CosmosConfigs) (ChainSet, error) { - solChains := map[string]adapters.Chain{} +func newChainSet(opts ChainSetOpts, cfgs CosmosConfigs) (adapters.ChainSet, map[string]adapters.Chain, error) { + cosmosChains := map[string]adapters.Chain{} var err error for _, chain := range cfgs { if !chain.IsEnabled() { continue } var err2 error - solChains[*chain.ChainID], err2 = opts.NewTOMLChain(chain) + cosmosChains[*chain.ChainID], err2 = opts.NewTOMLChain(chain) if err2 != nil { err = multierr.Combine(err, err2) continue } } if err != nil { - return nil, errors.Wrap(err, "failed to load some Cosmos chains") + return nil, nil, fmt.Errorf("failed to load some Cosmos chains: %w", err) + } + + cs, err := chains.NewChainSet[db.Node, adapters.Chain](cosmosChains, &opts) + if err != nil { + return nil, nil, err + } + + return cs, cosmosChains, nil +} + +// SingleChainSet is a chainset with 1 chain. TODO remove when relayer interface is updated +type SingleChainSet struct { + adapters.ChainSet + ID string + chain adapters.Chain +} + +func (s *SingleChainSet) Chain(ctx context.Context, id string) (adapters.Chain, error) { + return s.chain, nil +} + +func NewSingleChainSet(opts ChainSetOpts, cfg *CosmosConfig) (*SingleChainSet, error) { + cs, m, err := newChainSet(opts, CosmosConfigs{cfg}) + if err != nil { + return nil, err + } + if len(m) != 1 { + return nil, fmt.Errorf("invalid Single chain: more than one chain %d", len(m)) + } + var chain adapters.Chain + for _, ch := range m { + chain = ch } - return chains.NewChainSet[db.Node, adapters.Chain](solChains, &opts) + return &SingleChainSet{ + ChainSet: cs, + ID: *cfg.ChainID, + chain: chain, + }, nil } diff --git a/core/chains/cosmos/config.go b/core/chains/cosmos/config.go index 780e83f1279..62a76be44d1 100644 --- a/core/chains/cosmos/config.go +++ b/core/chains/cosmos/config.go @@ -115,7 +115,7 @@ func (cs CosmosConfigs) Node(name string) (n db.Node, err error) { } } } - err = chains.ErrNotFound + err = fmt.Errorf("node %s: %w", name, chains.ErrNotFound) return } @@ -131,7 +131,7 @@ func (cs CosmosConfigs) nodes(chainID string) (ns CosmosNodes) { func (cs CosmosConfigs) Nodes(chainID string) (ns []db.Node, err error) { nodes := cs.nodes(chainID) if nodes == nil { - err = chains.ErrNotFound + err = fmt.Errorf("no nodes: chain %s: %w", chainID, chains.ErrNotFound) return } for _, n := range nodes { @@ -152,7 +152,7 @@ func (cs CosmosConfigs) NodeStatus(name string) (n relaytypes.NodeStatus, err er } } } - err = chains.ErrNotFound + err = fmt.Errorf("node %s: %w", name, chains.ErrNotFound) return } @@ -255,6 +255,9 @@ func (c *CosmosConfig) SetFrom(f *CosmosConfig) { } func setFromChain(c, f *coscfg.Chain) { + if f.Bech32Prefix != nil { + c.Bech32Prefix = f.Bech32Prefix + } if f.BlockRate != nil { c.BlockRate = f.BlockRate } @@ -267,8 +270,8 @@ func setFromChain(c, f *coscfg.Chain) { if f.FallbackGasPrice != nil { c.FallbackGasPrice = f.FallbackGasPrice } - if f.FCDURL != nil { - c.FCDURL = f.FCDURL + if f.FeeToken != nil { + c.FeeToken = f.FeeToken } if f.GasLimitMultiplier != nil { c.GasLimitMultiplier = f.GasLimitMultiplier @@ -279,11 +282,11 @@ func setFromChain(c, f *coscfg.Chain) { if f.OCR2CachePollPeriod != nil { c.OCR2CachePollPeriod = f.OCR2CachePollPeriod } - if f.BlockRate != nil { - c.BlockRate = f.BlockRate + if f.OCR2CacheTTL != nil { + c.OCR2CacheTTL = f.OCR2CacheTTL } - if f.BlockRate != nil { - c.BlockRate = f.BlockRate + if f.TxMsgTimeout != nil { + c.TxMsgTimeout = f.TxMsgTimeout } } @@ -311,6 +314,10 @@ func (c *CosmosConfig) TOMLString() (string, error) { var _ coscfg.Config = &CosmosConfig{} +func (c *CosmosConfig) Bech32Prefix() string { + return *c.Chain.Bech32Prefix +} + func (c *CosmosConfig) BlockRate() time.Duration { return c.Chain.BlockRate.Duration() } @@ -327,8 +334,8 @@ func (c *CosmosConfig) FallbackGasPrice() sdk.Dec { return sdkDecFromDecimal(c.Chain.FallbackGasPrice) } -func (c *CosmosConfig) FCDURL() url.URL { - return (url.URL)(*c.Chain.FCDURL) +func (c *CosmosConfig) FeeToken() string { + return *c.Chain.FeeToken } func (c *CosmosConfig) GasLimitMultiplier() float64 { diff --git a/core/chains/cosmos/cosmostxm/main_test.go b/core/chains/cosmos/cosmostxm/main_test.go index 24f2533e6df..bc340afa430 100644 --- a/core/chains/cosmos/cosmostxm/main_test.go +++ b/core/chains/cosmos/cosmostxm/main_test.go @@ -9,8 +9,8 @@ import ( func TestMain(m *testing.M) { params.InitCosmosSdk( - /* bech32Prefix= */ "cosmos", - /* token= */ "atom", + /* bech32Prefix= */ "wasm", + /* token= */ "cosm", ) code := m.Run() os.Exit(code) diff --git a/core/chains/cosmos/cosmostxm/txm.go b/core/chains/cosmos/cosmostxm/txm.go index 02be242ad18..7b0e2ad2887 100644 --- a/core/chains/cosmos/cosmostxm/txm.go +++ b/core/chains/cosmos/cosmostxm/txm.go @@ -498,12 +498,12 @@ func (txm *Txm) GetMsgs(ids ...int64) (adapters.Msgs, error) { return txm.orm.GetMsgs(ids...) } -// GasPrice returns the gas price from the estimator in uatom. +// GasPrice returns the gas price from the estimator in the configured fee token. func (txm *Txm) GasPrice() (sdk.DecCoin, error) { prices := txm.gpe.GasPrices() - gasPrice, ok := prices["uatom"] + gasPrice, ok := prices[txm.cfg.FeeToken()] if !ok { - return sdk.DecCoin{}, errors.New("unexpected empty uatom price") + return sdk.DecCoin{}, errors.New("unexpected empty gas price") } return gasPrice, nil } diff --git a/core/chains/cosmos/cosmostxm/txm_internal_test.go b/core/chains/cosmos/cosmostxm/txm_internal_test.go index e4bc1eda9ca..6a9944a1a53 100644 --- a/core/chains/cosmos/cosmostxm/txm_internal_test.go +++ b/core/chains/cosmos/cosmostxm/txm_internal_test.go @@ -23,6 +23,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/cosmostest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -61,21 +62,29 @@ func TestTxm(t *testing.T) { require.NoError(t, err) sender2, err := cosmostypes.AccAddressFromBech32(k2.PublicKeyStr()) require.NoError(t, err) - contract, err := cosmostypes.AccAddressFromBech32("cosmos1z94322r480rhye2atp8z7v0wm37pk36ghzkdnd") + k3, err := ks.Cosmos().Create() require.NoError(t, err) - contract2, err := cosmostypes.AccAddressFromBech32("cosmos1pe6e59rzm5upts599wl8hrvh95afy859yrcva8") + contract, err := cosmostypes.AccAddressFromBech32(k3.PublicKeyStr()) + require.NoError(t, err) + k4, err := ks.Cosmos().Create() + require.NoError(t, err) + contract2, err := cosmostypes.AccAddressFromBech32(k4.PublicKeyStr()) require.NoError(t, err) logCfg := pgtest.NewQConfig(true) chainID := cosmostest.RandomChainID() two := int64(2) + feeToken := "ucosm" cfg := &cosmos.CosmosConfig{Chain: coscfg.Chain{ MaxMsgsPerBatch: &two, + FeeToken: &feeToken, }} cfg.SetDefaults() gpe := cosmosclient.NewMustGasPriceEstimator([]cosmosclient.GasPricesEstimator{ cosmosclient.NewFixedGasPriceEstimator(map[string]cosmostypes.DecCoin{ - "uatom": cosmostypes.NewDecCoinFromDec("uatom", cosmostypes.MustNewDecFromStr("0.01")), - }), + cfg.FeeToken(): cosmostypes.NewDecCoinFromDec(cfg.FeeToken(), cosmostypes.MustNewDecFromStr("0.01")), + }, + lggr.(logger.SugaredLogger), + ), }, lggr) t.Run("single msg", func(t *testing.T) { diff --git a/core/chains/cosmos/cosmostxm/txm_test.go b/core/chains/cosmos/cosmostxm/txm_test.go index 3ae1f89b3f1..7bfd76e1d8c 100644 --- a/core/chains/cosmos/cosmostxm/txm_test.go +++ b/core/chains/cosmos/cosmostxm/txm_test.go @@ -1,18 +1,19 @@ -//go:build integration && wasmd +//go:build integration package cosmostxm_test import ( + "fmt" "testing" "time" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" txtypes "github.com/cosmos/cosmos-sdk/types/tx" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/google/uuid" "github.com/onsi/gomega" - "github.com/shopspring/decimal" "github.com/stretchr/testify/require" cosmosclient "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/client" @@ -22,6 +23,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/cosmos/cosmostxm" "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/cosmostest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" @@ -33,33 +35,35 @@ import ( ) func TestTxm_Integration(t *testing.T) { - // TODO(BCI-978): cleanup once SetupLocalCosmosNode is updated - chainID := cosmotest.RandomChainID() - fallbackGasPrice := sdk.NewDecCoinFromDec("uatom", sdk.MustNewDecFromStr("0.01")) - chain := cosmos.CosmosConfig{ChainID: &chainID, Enabled: ptr(true), Chain: coscfg.Chain{ - FallbackGasPrice: ptr(decimal.RequireFromString("0.01")), - GasLimitMultiplier: ptr(decimal.RequireFromString("1.5")), - }} + chainID := cosmostest.RandomChainID() + cosmosChain := coscfg.Chain{} + cosmosChain.SetDefaults() + fallbackGasPrice := sdk.NewDecCoinFromDec(*cosmosChain.FeeToken, sdk.MustNewDecFromStr("0.01")) + chainConfig := cosmos.CosmosConfig{ChainID: &chainID, Enabled: ptr(true), Chain: cosmosChain} cfg, db := heavyweight.FullTestDBNoFixturesV2(t, "cosmos_txm", func(c *chainlink.Config, s *chainlink.Secrets) { - c.Cosmos = cosmos.CosmosConfigs{&chain} + c.Cosmos = cosmos.CosmosConfigs{&chainConfig} }) lggr := logger.TestLogger(t) logCfg := pgtest.NewQConfig(true) gpe := cosmosclient.NewMustGasPriceEstimator([]cosmosclient.GasPricesEstimator{ cosmosclient.NewFixedGasPriceEstimator(map[string]sdk.DecCoin{ - "uatom": fallbackGasPrice, - }), + *cosmosChain.FeeToken: fallbackGasPrice, + }, + lggr.(logger.SugaredLogger), + ), }, lggr) orm := cosmostxm.NewORM(chainID, db, lggr, logCfg) - eb := pg.NewEventBroadcaster(cfg.DatabaseURL(), 0, 0, lggr, uuid.New()) + eb := pg.NewEventBroadcaster(cfg.Database().URL(), 0, 0, lggr, uuid.New()) require.NoError(t, eb.Start(testutils.Context(t))) t.Cleanup(func() { require.NoError(t, eb.Close()) }) ks := keystore.New(db, utils.FastScryptParams, lggr, pgtest.NewQConfig(true)) - accounts, testdir, tendermintURL := cosmosclient.SetupLocalCosmosNode(t, "42") - tc, err := cosmosclient.NewClient("42", tendermintURL, cosmos.DefaultRequestTimeout, lggr) + zeConfig := sdk.GetConfig() + fmt.Println(zeConfig) + accounts, testdir, tendermintURL := cosmosclient.SetupLocalCosmosNode(t, chainID, *cosmosChain.FeeToken) + tc, err := cosmosclient.NewClient(chainID, tendermintURL, cosmos.DefaultRequestTimeout, lggr) require.NoError(t, err) - // First create a transmitter key and fund it with 1k uatom + // First create a transmitter key and fund it with 1k native tokens require.NoError(t, ks.Unlock("blah")) transmitterKey, err := ks.Cosmos().Create() require.NoError(t, err) @@ -67,13 +71,16 @@ func TestTxm_Integration(t *testing.T) { require.NoError(t, err) an, sn, err := tc.Account(accounts[0].Address) require.NoError(t, err) - _, err = tc.SignAndBroadcast([]sdk.Msg{banktypes.NewMsgSend(accounts[0].Address, transmitterID, sdk.NewCoins(sdk.NewInt64Coin("uatom", 100000)))}, - an, sn, gpe.GasPrices()["uatom"], accounts[0].PrivateKey, txtypes.BroadcastMode_BROADCAST_MODE_BLOCK) + resp, err := tc.SignAndBroadcast([]sdk.Msg{banktypes.NewMsgSend(accounts[0].Address, transmitterID, sdk.NewCoins(sdk.NewInt64Coin(*cosmosChain.FeeToken, 100000)))}, + an, sn, gpe.GasPrices()[*cosmosChain.FeeToken], accounts[0].PrivateKey, txtypes.BroadcastMode_BROADCAST_MODE_SYNC) + tx, success := cosmosclient.AwaitTxCommitted(t, tc, resp.TxResponse.TxHash) + require.True(t, success) + require.Equal(t, types.CodeTypeOK, tx.TxResponse.Code) require.NoError(t, err) // TODO: find a way to pull this test artifact from // the chainlink-cosmos repo instead of copying it to cores testdata - contractID := cosmosclient.DeployTestContract(t, tendermintURL, accounts[0], cosmosclient.Account{ + contractID := cosmosclient.DeployTestContract(t, tendermintURL, chainID, *cosmosChain.FeeToken, accounts[0], cosmosclient.Account{ Name: "transmitter", PrivateKey: cosmostxm.NewKeyWrapper(transmitterKey), Address: transmitterID, @@ -81,7 +88,7 @@ func TestTxm_Integration(t *testing.T) { tcFn := func() (cosmosclient.ReaderWriter, error) { return tc, nil } // Start txm - txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, &chain, ks.Cosmos(), lggr, pgtest.NewQConfig(true), eb) + txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, &chainConfig, ks.Cosmos(), lggr, pgtest.NewQConfig(true), eb) require.NoError(t, txm.Start(testutils.Context(t))) // Change the contract state @@ -100,7 +107,7 @@ func TestTxm_Integration(t *testing.T) { require.NoError(t, err) t.Log("contract value", string(d)) return string(d) == `{"count":5}` - }, 10*time.Second, time.Second).Should(gomega.BeTrue()) + }, 20*time.Second, time.Second).Should(gomega.BeTrue()) // Ensure messages are completed gomega.NewWithT(t).Eventually(func() bool { msgs, err := orm.GetMsgsState(Confirmed, 5) @@ -130,7 +137,7 @@ func TestTxm_Integration(t *testing.T) { require.NoError(t, err) t.Log("errored", len(errored), "succeeded", len(succeeded)) return 2 == len(succeeded) && 2 == len(errored) - }, 10*time.Second, time.Second).Should(gomega.BeTrue()) + }, 20*time.Second, time.Second).Should(gomega.BeTrue()) // Observe the messages have been marked as completed require.NoError(t, txm.Close()) diff --git a/core/chains/evm/chain.go b/core/chains/evm/chain.go index f48a4b40e26..619b3e2db77 100644 --- a/core/chains/evm/chain.go +++ b/core/chains/evm/chain.go @@ -2,16 +2,22 @@ package evm import ( "context" + "errors" "fmt" "math/big" "net/url" + "sync" "time" - "github.com/pkg/errors" "go.uber.org/multierr" "golang.org/x/exp/maps" + "github.com/smartcontractkit/sqlx" + + "github.com/smartcontractkit/chainlink-relay/pkg/types" + "github.com/smartcontractkit/chainlink/v2/core/chains" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" 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/config/toml" @@ -22,16 +28,19 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/monitor" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/config" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/utils" ) //go:generate mockery --quiet --name Chain --output ./mocks/ --case=underscore type Chain interface { - services.ServiceCtx + types.ChainService + ID() *big.Int Client() evmclient.Client Config() evmconfig.ChainScopedConfig @@ -43,11 +52,76 @@ type Chain interface { BalanceMonitor() monitor.BalanceMonitor LogPoller() logpoller.LogPoller GasEstimator() gas.EvmFeeEstimator +} + +var ( + _ Chain = &chain{} + nilBigInt *big.Int + emptyString string +) + +// LegacyChains implements [LegacyChainContainer] +type LegacyChains struct { + *chains.ChainsKV[Chain] + dflt Chain + + cfgs evmtypes.Configs +} + +// LegacyChainContainer is container for EVM chains. +// +//go:generate mockery --quiet --name LegacyChainContainer --output ./mocks/ --case=underscore +type LegacyChainContainer interface { + SetDefault(Chain) + Default() (Chain, error) + Get(id string) (Chain, error) + Len() int + List(ids ...string) ([]Chain, error) + Slice() []Chain + + ChainNodeConfigs() evmtypes.Configs +} + +var _ LegacyChainContainer = &LegacyChains{} + +func NewLegacyChains(cfg AppConfig, m map[string]Chain) (*LegacyChains, error) { + if cfg == nil { + return nil, fmt.Errorf("must provide non-nil app config") + } + return &LegacyChains{ + ChainsKV: chains.NewChainsKV[Chain](m), + cfgs: chains.NewConfigs[utils.Big, evmtypes.Node](cfg.EVMConfigs()), + }, nil +} + +func (c *LegacyChains) ChainNodeConfigs() evmtypes.Configs { + return c.cfgs +} - SendTx(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error +// TODO BCR-2510 this may not be needed if EVM is not enabled by default +func (c *LegacyChains) SetDefault(dflt Chain) { + c.dflt = dflt } -var _ Chain = &chain{} +func (c *LegacyChains) Default() (Chain, error) { + if c.dflt == nil { + return nil, fmt.Errorf("no default chain specified") + } + return c.dflt, nil +} + +// backward compatibility. +// eth keys are represented as multiple types in the code base; +// *big.Int, string, and int64. this lead to special 'default' handling +// of nil big.Int and empty string. +// +// TODO BCF-2507 unify the type system +func (c *LegacyChains) Get(id string) (Chain, error) { + if id == nilBigInt.String() || id == emptyString { + return c.Default() + } + return c.ChainsKV.Get(id) +} type chain struct { utils.StartStopOnce @@ -73,18 +147,63 @@ func (e errChainDisabled) Error() string { return fmt.Sprintf("cannot create new chain with ID %s, the chain is disabled", e.ChainID.String()) } -func newTOMLChain(ctx context.Context, chain *toml.EVMConfig, opts ChainSetOpts) (*chain, error) { +// TODO BCF-2509 what is this and does it need the entire app config? +type AppConfig interface { + config.AppConfig + toml.HasEVMConfigs +} + +type ChainRelayExtenderConfig struct { + Logger logger.Logger + DB *sqlx.DB + KeyStore keystore.Eth + RelayerConfig +} + +// options for the relayer factory. +// TODO BCF-2508 clean up configuration of chain and relayer after BCF-2440 +// the factory wants to own the logger and db +// the factory creates extenders, which need the same and more opts +type RelayerConfig struct { + AppConfig AppConfig + + EventBroadcaster pg.EventBroadcaster + MailMon *utils.MailboxMonitor + GasEstimator gas.EvmFeeEstimator + + init sync.Once + operationalConfigs evmtypes.Configs + + // TODO BCF-2513 remove test code from the API + // Gen-functions are useful for dependency injection by tests + GenEthClient func(*big.Int) client.Client + GenLogBroadcaster func(*big.Int) log.Broadcaster + GenLogPoller func(*big.Int) logpoller.LogPoller + GenHeadTracker func(*big.Int, httypes.HeadBroadcaster) httypes.HeadTracker + GenTxManager func(*big.Int) txmgr.TxManager + GenGasEstimator func(*big.Int) gas.EvmFeeEstimator +} + +func (r *RelayerConfig) EVMConfigs() evmtypes.Configs { + if r.operationalConfigs == nil { + r.init.Do(func() { + r.operationalConfigs = chains.NewConfigs[utils.Big, evmtypes.Node](r.AppConfig.EVMConfigs()) + }) + } + return r.operationalConfigs +} +func NewTOMLChain(ctx context.Context, chain *toml.EVMConfig, opts ChainRelayExtenderConfig) (Chain, error) { chainID := chain.ChainID l := opts.Logger.With("evmChainID", chainID.String()) if !chain.IsEnabled() { return nil, errChainDisabled{ChainID: chainID} } - cfg := evmconfig.NewTOMLChainScopedConfig(opts.Config, chain, l) - // note: per-chain validation is not ncessary at this point since everything is checked earlier on boot. + cfg := evmconfig.NewTOMLChainScopedConfig(opts.AppConfig, chain, l) + // note: per-chain validation is not necessary at this point since everything is checked earlier on boot. return newChain(ctx, cfg, chain.Nodes, opts) } -func newChain(ctx context.Context, cfg evmconfig.ChainScopedConfig, nodes []*toml.Node, opts ChainSetOpts) (*chain, error) { +func newChain(ctx context.Context, cfg evmconfig.ChainScopedConfig, nodes []*toml.Node, opts ChainRelayExtenderConfig) (*chain, error) { chainID, chainType := cfg.EVM().ChainID(), cfg.EVM().ChainType() l := opts.Logger.Named(chainID.String()).With("evmChainID", chainID.String()) var client evmclient.Client @@ -94,7 +213,7 @@ func newChain(ctx context.Context, cfg evmconfig.ChainScopedConfig, nodes []*tom var err2 error client, err2 = newEthClientFromChain(cfg.EVM().NodePool(), cfg.EVM().NodeNoNewHeadsThreshold(), l, chainID, chainType, nodes) if err2 != nil { - return nil, errors.Wrapf(err2, "failed to instantiate eth client for chain with ID %s", cfg.EVM().ChainID().String()) + return nil, fmt.Errorf("failed to instantiate eth client for chain with ID %s: %w", cfg.EVM().ChainID().String(), err2) } } else { client = opts.GenEthClient(chainID) @@ -126,7 +245,7 @@ func newChain(ctx context.Context, cfg evmconfig.ChainScopedConfig, nodes []*tom // note: gas estimator is started as a part of the txm txm, gasEstimator, err := newEvmTxm(db, cfg.EVM(), cfg.EVMRPCEnabled(), cfg.Database(), cfg.Database().Listener(), client, l, logPoller, opts) if err != nil { - return nil, errors.Wrapf(err, "failed to instantiate EvmTxm for chain with ID %s", chainID.String()) + return nil, fmt.Errorf("failed to instantiate EvmTxm for chain with ID %s: %w", chainID.String(), err) } headBroadcaster.Subscribe(txm) @@ -182,7 +301,7 @@ func (c *chain) Start(ctx context.Context) error { // Must ensure that EthClient is dialed first because subsequent // services may make eth calls on startup if err := c.client.Dial(ctx); err != nil { - return errors.Wrap(err, "failed to dial ethclient") + return fmt.Errorf("failed to dial ethclient: %w", err) } // Services should be able to handle a non-functional eth client and // not block start in this case, instead retrying in a background loop @@ -302,3 +421,15 @@ func newPrimary(cfg evmconfig.NodePool, noNewHeadsThreshold time.Duration, lggr return evmclient.NewNode(cfg, noNewHeadsThreshold, lggr, (url.URL)(*n.WSURL), (*url.URL)(n.HTTPURL), *n.Name, id, chainID, *n.Order), nil } + +func (opts *ChainRelayExtenderConfig) Check() error { + if opts.Logger == nil { + return errors.New("logger must be non-nil") + } + if opts.AppConfig == nil { + return errors.New("config must be non-nil") + } + + opts.operationalConfigs = chains.NewConfigs[utils.Big, evmtypes.Node](opts.AppConfig.EVMConfigs()) + return nil +} diff --git a/core/chains/evm/chain_set.go b/core/chains/evm/chain_set.go deleted file mode 100644 index edfc3e1aeb9..00000000000 --- a/core/chains/evm/chain_set.go +++ /dev/null @@ -1,325 +0,0 @@ -package evm - -import ( - "context" - "fmt" - "math/big" - "sync" - - "github.com/pkg/errors" - "go.uber.org/multierr" - "golang.org/x/exp/maps" - - "github.com/smartcontractkit/sqlx" - - relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types" - - "github.com/smartcontractkit/chainlink/v2/core/chains" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" - httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - "github.com/smartcontractkit/chainlink/v2/core/config" - "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" - "github.com/smartcontractkit/chainlink/v2/core/utils" -) - -// ErrNoChains indicates that no EVM chains have been started -var ErrNoChains = errors.New("no EVM chains loaded") - -var _ ChainSet = &chainSet{} - -//go:generate mockery --quiet --name ChainSet --output ./mocks/ --case=underscore -type ChainSet interface { - services.ServiceCtx - chains.Chains - chains.Nodes - - Get(id *big.Int) (Chain, error) - - Default() (Chain, error) - Chains() []Chain - ChainCount() int - - Configs() types.Configs - - SendTx(ctx context.Context, chainID, from, to string, amount *big.Int, balanceCheck bool) error -} - -type chainSet struct { - defaultID *big.Int - chains map[string]*chain - startedChains []Chain - chainsMu sync.RWMutex - logger logger.Logger - opts ChainSetOpts -} - -func (cll *chainSet) Start(ctx context.Context) error { - if !cll.opts.Config.EVMEnabled() { - cll.logger.Warn("EVM is disabled, no EVM-based chains will be started") - return nil - } - if !cll.opts.Config.EVMRPCEnabled() { - cll.logger.Warn("EVM RPC connections are disabled. Chainlink will not connect to any EVM RPC node.") - } - var ms services.MultiStart - for _, c := range cll.Chains() { - if err := ms.Start(ctx, c); err != nil { - return errors.Wrapf(err, "failed to start chain %q", c.ID().String()) - } - cll.startedChains = append(cll.startedChains, c) - } - evmChainIDs := make([]*big.Int, len(cll.startedChains)) - for i, c := range cll.startedChains { - evmChainIDs[i] = c.ID() - } - defChainID := "unspecified" - if cll.defaultID != nil { - defChainID = fmt.Sprintf("%q", cll.defaultID.String()) - } - cll.logger.Infow(fmt.Sprintf("EVM: Started %d/%d chains, default chain ID is %s", len(cll.startedChains), len(cll.Chains()), defChainID), "startedEvmChainIDs", evmChainIDs) - return nil -} - -func (cll *chainSet) Close() (err error) { - cll.logger.Debug("EVM: stopping") - for _, c := range cll.startedChains { - err = multierr.Combine(err, c.Close()) - } - return -} - -func (cll *chainSet) Name() string { - return cll.logger.Name() -} - -func (cll *chainSet) HealthReport() map[string]error { - report := map[string]error{} - for _, c := range cll.Chains() { - maps.Copy(report, c.HealthReport()) - } - return report -} - -func (cll *chainSet) Ready() (err error) { - for _, c := range cll.Chains() { - err = multierr.Combine(err, c.Ready()) - } - return -} - -func (cll *chainSet) Get(id *big.Int) (Chain, error) { - if id == nil { - if cll.defaultID == nil { - cll.logger.Debug("Chain ID not specified, and default is nil") - return nil, errors.New("chain ID not specified, and default is nil") - } - cll.logger.Debugf("Chain ID not specified, using default: %s", cll.defaultID.String()) - return cll.Default() - } - return cll.get(id.String()) -} - -func (cll *chainSet) get(id string) (Chain, error) { - cll.chainsMu.RLock() - defer cll.chainsMu.RUnlock() - c, exists := cll.chains[id] - if exists { - return c, nil - } - return nil, errors.Wrap(chains.ErrNotFound, fmt.Sprintf("failed to get chain with id %s", id)) -} - -func (cll *chainSet) ChainStatus(ctx context.Context, id string) (cfg relaytypes.ChainStatus, err error) { - var cs []relaytypes.ChainStatus - cs, _, err = cll.opts.Configs.Chains(0, -1, id) - if err != nil { - return - } - l := len(cs) - if l == 0 { - err = chains.ErrNotFound - return - } - if l > 1 { - err = fmt.Errorf("multiple chains found: %d", len(cs)) - return - } - cfg = cs[0] - return -} - -func (cll *chainSet) ChainStatuses(ctx context.Context, offset, limit int) ([]relaytypes.ChainStatus, int, error) { - return cll.opts.Configs.Chains(offset, limit) -} - -func (cll *chainSet) Default() (Chain, error) { - cll.chainsMu.RLock() - length := len(cll.chains) - cll.chainsMu.RUnlock() - if length == 0 { - return nil, errors.Wrap(ErrNoChains, "cannot get default EVM chain; no EVM chains are available") - } - if cll.defaultID == nil { - // This is an invariant violation; if any chains are available then a - // default should _always_ have been set in the constructor - return nil, errors.New("no default chain ID specified") - } - - return cll.Get(cll.defaultID) -} - -func (cll *chainSet) Chains() (c []Chain) { - cll.chainsMu.RLock() - defer cll.chainsMu.RUnlock() - for _, chain := range cll.chains { - c = append(c, chain) - } - return c -} - -func (cll *chainSet) ChainCount() int { - cll.chainsMu.RLock() - defer cll.chainsMu.RUnlock() - return len(cll.chains) -} - -func (cll *chainSet) Configs() types.Configs { - return cll.opts.Configs -} - -func (cll *chainSet) NodeStatuses(ctx context.Context, offset, limit int, chainIDs ...string) (nodes []relaytypes.NodeStatus, count int, err error) { - nodes, count, err = cll.opts.Configs.NodeStatusesPaged(offset, limit, chainIDs...) - if err != nil { - err = errors.Wrap(err, "GetNodesForChain failed to load nodes from DB") - return - } - for i := range nodes { - cll.addStateToNode(&nodes[i]) - } - return -} - -func (cll *chainSet) addStateToNode(n *relaytypes.NodeStatus) { - cll.chainsMu.RLock() - chain, exists := cll.chains[n.ChainID] - cll.chainsMu.RUnlock() - if !exists { - // The EVM chain is disabled - n.State = "Disabled" - return - } - states := chain.Client().NodeStates() - if states == nil { - n.State = "Unknown" - return - } - state, exists := states[n.Name] - if exists { - n.State = state - return - } - // The node is in the DB and the chain is enabled but it's not running - n.State = "NotLoaded" -} - -func (cll *chainSet) SendTx(ctx context.Context, chainID, from, to string, amount *big.Int, balanceCheck bool) error { - chain, err := cll.get(chainID) - if err != nil { - return err - } - - return chain.SendTx(ctx, from, to, amount, balanceCheck) -} - -type GeneralConfig interface { - config.AppConfig - toml.HasEVMConfigs -} - -type ChainSetOpts struct { - Config GeneralConfig - Logger logger.Logger - DB *sqlx.DB - KeyStore keystore.Eth - EventBroadcaster pg.EventBroadcaster - Configs types.Configs - MailMon *utils.MailboxMonitor - GasEstimator gas.EvmFeeEstimator - - // Gen-functions are useful for dependency injection by tests - GenEthClient func(*big.Int) client.Client - GenLogBroadcaster func(*big.Int) log.Broadcaster - GenLogPoller func(*big.Int) logpoller.LogPoller - GenHeadTracker func(*big.Int, httypes.HeadBroadcaster) httypes.HeadTracker - GenTxManager func(*big.Int) txmgr.TxManager - GenGasEstimator func(*big.Int) gas.EvmFeeEstimator -} - -// NewTOMLChainSet returns a new ChainSet from TOML configuration. -func NewTOMLChainSet(ctx context.Context, opts ChainSetOpts) (ChainSet, error) { - if err := opts.check(); err != nil { - return nil, err - } - chains := opts.Config.EVMConfigs() - var enabled []*toml.EVMConfig - for i := range chains { - if chains[i].IsEnabled() { - enabled = append(enabled, chains[i]) - } - } - opts.Logger = opts.Logger.Named("EVM") - defaultChainID := opts.Config.DefaultChainID() - if defaultChainID == nil && len(enabled) >= 1 { - defaultChainID = enabled[0].ChainID.ToInt() - if len(enabled) > 1 { - opts.Logger.Debugf("Multiple chains present, default chain: %s", defaultChainID.String()) - } - } - var err error - cll := newChainSet(opts) - cll.defaultID = defaultChainID - for i := range enabled { - cid := enabled[i].ChainID.String() - cll.logger.Infow(fmt.Sprintf("Loading chain %s", cid), "evmChainID", cid) - chain, err2 := newTOMLChain(ctx, enabled[i], opts) - if err2 != nil { - err = multierr.Combine(err, err2) - continue - } - if _, exists := cll.chains[cid]; exists { - return nil, errors.Errorf("duplicate chain with ID %s", cid) - } - cll.chains[cid] = chain - } - return cll, err -} - -func newChainSet(opts ChainSetOpts) *chainSet { - return &chainSet{ - chains: make(map[string]*chain), - startedChains: make([]Chain, 0), - logger: opts.Logger.Named("ChainSet"), - opts: opts, - } -} - -func (opts *ChainSetOpts) check() error { - if opts.Logger == nil { - return errors.New("logger must be non-nil") - } - if opts.Config == nil { - return errors.New("config must be non-nil") - } - - opts.Configs = chains.NewConfigs[utils.Big, types.Node](opts.Config.EVMConfigs()) - return nil -} diff --git a/core/chains/evm/chain_set_test.go b/core/chains/evm/chain_set_test.go deleted file mode 100644 index 2c7de3c62b3..00000000000 --- a/core/chains/evm/chain_set_test.go +++ /dev/null @@ -1,61 +0,0 @@ -package evm_test - -import ( - "math/big" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink/v2/core/chains/evm" - evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" - evmclimocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - configtest "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest/v2" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" - "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/utils" -) - -func TestChainSet(t *testing.T) { - t.Parallel() - - newId := testutils.NewRandomEVMChainID() - cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - one := uint32(1) - c.EVM[0].MinIncomingConfirmations = &one - t := true - c.EVM = append(c.EVM, &toml.EVMConfig{ChainID: utils.NewBig(newId), Enabled: &t, Chain: toml.Defaults(nil)}) - }) - db := pgtest.NewSqlxDB(t) - kst := cltest.NewKeyStore(t, db, cfg.Database()) - require.NoError(t, kst.Unlock(cltest.Password)) - - opts := evmtest.NewChainSetOpts(t, evmtest.TestChainOpts{DB: db, KeyStore: kst.Eth(), GeneralConfig: cfg}) - opts.GenEthClient = func(*big.Int) evmclient.Client { - return cltest.NewEthMocksWithStartupAssertions(t) - } - chainSet, err := evm.NewTOMLChainSet(testutils.Context(t), opts) - require.NoError(t, err) - - require.NoError(t, chainSet.Start(testutils.Context(t))) - require.NoError(t, chainSet.Chains()[0].Ready()) - - chains := chainSet.Chains() - require.Equal(t, 2, len(chains)) - require.NotEqual(t, chains[0].ID().String(), chains[1].ID().String()) - - assert.NoError(t, chains[0].Ready()) - assert.NoError(t, chains[1].Ready()) - - chainSet.Close() - - chains[0].Client().(*evmclimocks.Client).AssertCalled(t, "Close") - chains[1].Client().(*evmclimocks.Client).AssertCalled(t, "Close") - - assert.Error(t, chains[0].Ready()) - assert.Error(t, chains[1].Ready()) -} diff --git a/core/chains/evm/chain_test.go b/core/chains/evm/chain_test.go new file mode 100644 index 00000000000..e80bfc02934 --- /dev/null +++ b/core/chains/evm/chain_test.go @@ -0,0 +1,54 @@ +package evm_test + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/mocks" + configtest "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest/v2" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +func TestLegacyChains(t *testing.T) { + evmCfg := configtest.NewGeneralConfig(t, nil) + + c := mocks.NewChain(t) + c.On("ID").Return(big.NewInt(7)) + m := map[string]evm.Chain{c.ID().String(): c} + + l, err := evm.NewLegacyChains(evmCfg, m) + assert.NoError(t, err) + assert.NotNil(t, l.ChainNodeConfigs()) + got, err := l.Get(c.ID().String()) + assert.NoError(t, err) + assert.Equal(t, c, got) + + l, err = evm.NewLegacyChains(nil, m) + assert.Error(t, err) + assert.Nil(t, l) +} + +func TestRelayConfigInit(t *testing.T) { + appCfg := configtest.NewGeneralConfig(t, nil) + rCfg := evm.RelayerConfig{ + AppConfig: appCfg, + } + + evmCfg := rCfg.EVMConfigs() + assert.NotNil(t, evmCfg) + + // test lazy init is done only once + // note this kind of swapping should never happen in prod + appCfg2 := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { + c.EVM[0].ChainID = utils.NewBig(big.NewInt(27)) + }) + rCfg.AppConfig = appCfg2 + + newEvmCfg := rCfg.EVMConfigs() + assert.NotNil(t, newEvmCfg) + assert.Equal(t, evmCfg, newEvmCfg) +} diff --git a/core/chains/evm/client/client.go b/core/chains/evm/client/client.go index d727c1a6ad1..339542f4ce1 100644 --- a/core/chains/evm/client/client.go +++ b/core/chains/evm/client/client.go @@ -8,7 +8,6 @@ import ( clienttypes "github.com/smartcontractkit/chainlink/v2/common/chains/client" htrktypes "github.com/smartcontractkit/chainlink/v2/common/headtracker/types" - commontypes "github.com/smartcontractkit/chainlink/v2/common/types" "github.com/smartcontractkit/chainlink/v2/core/assets" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/config" @@ -30,16 +29,23 @@ const BALANCE_OF_ADDRESS_FUNCTION_SELECTOR = "0x70a08231" // Client is the interface used to interact with an ethereum node. type Client interface { - commontypes.Client[*big.Int, evmtypes.Nonce, common.Address, types.Block, common.Hash, types.Transaction, common.Hash, types.Receipt, types.Log, ethereum.FilterQuery] - Dial(ctx context.Context) error Close() + // ChainID locally stored for quick access + ConfiguredChainID() *big.Int + // ChainID RPC call + ChainID() (*big.Int, error) // NodeStates returns a map of node Name->node state // It might be nil or empty, e.g. for mock clients etc NodeStates() map[string]string + TokenBalance(ctx context.Context, address common.Address, contractAddress common.Address) (*big.Int, error) + BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error) + LINKBalance(ctx context.Context, address common.Address, linkAddress common.Address) (*assets.Link, error) + // Wrapped RPC methods + CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error BatchCallContext(ctx context.Context, b []rpc.BatchElem) error // BatchCallContextAll calls BatchCallContext for every single node including // sendonlys. @@ -58,22 +64,29 @@ type Client interface { SendTransactionReturnCode(ctx context.Context, tx *types.Transaction, fromAddress common.Address) (clienttypes.SendTxReturnCode, error) // Wrapped Geth client methods + // blockNumber can be specified as `nil` to imply latest block + // if blocks, transactions, or receipts are not found - a nil result and an error are returned + // these methods may not be compatible with non Ethereum chains as return types may follow different formats + // suggested options: use HeadByNumber/HeadByHash (above) or CallContext and parse with custom types + SendTransaction(ctx context.Context, tx *types.Transaction) error CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) - + SequenceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (evmtypes.Nonce, error) + TransactionByHash(ctx context.Context, txHash common.Hash) (*types.Transaction, error) + TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) + BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) + BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) - EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error) SuggestGasPrice(ctx context.Context) (*big.Int, error) SuggestGasTipCap(ctx context.Context) (*big.Int, error) + LatestBlockHeight(ctx context.Context) (*big.Int, error) HeaderByNumber(ctx context.Context, n *big.Int) (*types.Header, error) HeaderByHash(ctx context.Context, h common.Hash) (*types.Header, error) - LINKBalance(ctx context.Context, address common.Address, linkAddress common.Address) (*assets.Link, error) - CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) IsL2() bool @@ -92,7 +105,6 @@ type client struct { var _ Client = (*client)(nil) var _ htrktypes.Client[*evmtypes.Head, ethereum.Subscription, *big.Int, common.Hash] = (*client)(nil) -var _ commontypes.Client[*big.Int, evmtypes.Nonce, common.Address, types.Block, common.Hash, types.Transaction, common.Hash, types.Receipt, types.Log, ethereum.FilterQuery] = (*client)(nil) // NewClientWithNodes instantiates a client from a list of nodes // Currently only supports one primary @@ -209,11 +221,6 @@ func (client *client) SendTransaction(ctx context.Context, tx *types.Transaction return client.pool.SendTransaction(ctx, tx) } -func (client *client) SimulateTransaction(ctx context.Context, tx *types.Transaction) error { - // todo: implement if used - return errors.New("SimulateTransaction not implemented") -} - func (client *client) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) { return client.pool.PendingNonceAt(ctx, account) } @@ -297,10 +304,6 @@ func ToBlockNumArg(number *big.Int) string { return hexutil.EncodeBig(number) } -func (client *client) FilterEvents(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) { - return client.FilterLogs(ctx, q) -} - func (client *client) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) { return client.pool.FilterLogs(ctx, q) } diff --git a/core/chains/evm/client/mocks/client.go b/core/chains/evm/client/mocks/client.go index 1f3ceb6870d..aec16a9e524 100644 --- a/core/chains/evm/client/mocks/client.go +++ b/core/chains/evm/client/mocks/client.go @@ -29,17 +29,17 @@ type Client struct { mock.Mock } -// BalanceAt provides a mock function with given fields: ctx, accountAddress, blockNumber -func (_m *Client) BalanceAt(ctx context.Context, accountAddress common.Address, blockNumber *big.Int) (*big.Int, error) { - ret := _m.Called(ctx, accountAddress, blockNumber) +// BalanceAt provides a mock function with given fields: ctx, account, blockNumber +func (_m *Client) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error) { + ret := _m.Called(ctx, account, blockNumber) var r0 *big.Int var r1 error if rf, ok := ret.Get(0).(func(context.Context, common.Address, *big.Int) (*big.Int, error)); ok { - return rf(ctx, accountAddress, blockNumber) + return rf(ctx, account, blockNumber) } if rf, ok := ret.Get(0).(func(context.Context, common.Address, *big.Int) *big.Int); ok { - r0 = rf(ctx, accountAddress, blockNumber) + r0 = rf(ctx, account, blockNumber) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*big.Int) @@ -47,7 +47,7 @@ func (_m *Client) BalanceAt(ctx context.Context, accountAddress common.Address, } if rf, ok := ret.Get(1).(func(context.Context, common.Address, *big.Int) error); ok { - r1 = rf(ctx, accountAddress, blockNumber) + r1 = rf(ctx, account, blockNumber) } else { r1 = ret.Error(1) } @@ -289,32 +289,6 @@ func (_m *Client) EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint6 return r0, r1 } -// FilterEvents provides a mock function with given fields: ctx, query -func (_m *Client) FilterEvents(ctx context.Context, query ethereum.FilterQuery) ([]types.Log, error) { - ret := _m.Called(ctx, query) - - var r0 []types.Log - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, ethereum.FilterQuery) ([]types.Log, error)); ok { - return rf(ctx, query) - } - if rf, ok := ret.Get(0).(func(context.Context, ethereum.FilterQuery) []types.Log); ok { - r0 = rf(ctx, query) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]types.Log) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, ethereum.FilterQuery) error); ok { - r1 = rf(ctx, query) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - // FilterLogs provides a mock function with given fields: ctx, q func (_m *Client) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) { ret := _m.Called(ctx, q) @@ -485,17 +459,17 @@ func (_m *Client) LINKBalance(ctx context.Context, address common.Address, linkA return r0, r1 } -// LatestBlockHeight provides a mock function with given fields: _a0 -func (_m *Client) LatestBlockHeight(_a0 context.Context) (*big.Int, error) { - ret := _m.Called(_a0) +// LatestBlockHeight provides a mock function with given fields: ctx +func (_m *Client) LatestBlockHeight(ctx context.Context) (*big.Int, error) { + ret := _m.Called(ctx) var r0 *big.Int var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*big.Int, error)); ok { - return rf(_a0) + return rf(ctx) } if rf, ok := ret.Get(0).(func(context.Context) *big.Int); ok { - r0 = rf(_a0) + r0 = rf(ctx) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*big.Int) @@ -503,7 +477,7 @@ func (_m *Client) LatestBlockHeight(_a0 context.Context) (*big.Int, error) { } if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(_a0) + r1 = rf(ctx) } else { r1 = ret.Error(1) } @@ -615,23 +589,23 @@ func (_m *Client) SendTransactionReturnCode(ctx context.Context, tx *types.Trans return r0, r1 } -// SequenceAt provides a mock function with given fields: ctx, accountAddress, blockNumber -func (_m *Client) SequenceAt(ctx context.Context, accountAddress common.Address, blockNumber *big.Int) (evmtypes.Nonce, error) { - ret := _m.Called(ctx, accountAddress, blockNumber) +// SequenceAt provides a mock function with given fields: ctx, account, blockNumber +func (_m *Client) SequenceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (evmtypes.Nonce, error) { + ret := _m.Called(ctx, account, blockNumber) var r0 evmtypes.Nonce var r1 error if rf, ok := ret.Get(0).(func(context.Context, common.Address, *big.Int) (evmtypes.Nonce, error)); ok { - return rf(ctx, accountAddress, blockNumber) + return rf(ctx, account, blockNumber) } if rf, ok := ret.Get(0).(func(context.Context, common.Address, *big.Int) evmtypes.Nonce); ok { - r0 = rf(ctx, accountAddress, blockNumber) + r0 = rf(ctx, account, blockNumber) } else { r0 = ret.Get(0).(evmtypes.Nonce) } if rf, ok := ret.Get(1).(func(context.Context, common.Address, *big.Int) error); ok { - r1 = rf(ctx, accountAddress, blockNumber) + r1 = rf(ctx, account, blockNumber) } else { r1 = ret.Error(1) } @@ -639,20 +613,6 @@ func (_m *Client) SequenceAt(ctx context.Context, accountAddress common.Address, return r0, r1 } -// SimulateTransaction provides a mock function with given fields: ctx, tx -func (_m *Client) SimulateTransaction(ctx context.Context, tx *types.Transaction) error { - ret := _m.Called(ctx, tx) - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, *types.Transaction) error); ok { - r0 = rf(ctx, tx) - } else { - r0 = ret.Error(0) - } - - return r0 -} - // SubscribeFilterLogs provides a mock function with given fields: ctx, q, ch func (_m *Client) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) { ret := _m.Called(ctx, q, ch) @@ -757,17 +717,17 @@ func (_m *Client) SuggestGasTipCap(ctx context.Context) (*big.Int, error) { return r0, r1 } -// TokenBalance provides a mock function with given fields: ctx, accountAddress, tokenAddress -func (_m *Client) TokenBalance(ctx context.Context, accountAddress common.Address, tokenAddress common.Address) (*big.Int, error) { - ret := _m.Called(ctx, accountAddress, tokenAddress) +// TokenBalance provides a mock function with given fields: ctx, address, contractAddress +func (_m *Client) TokenBalance(ctx context.Context, address common.Address, contractAddress common.Address) (*big.Int, error) { + ret := _m.Called(ctx, address, contractAddress) var r0 *big.Int var r1 error if rf, ok := ret.Get(0).(func(context.Context, common.Address, common.Address) (*big.Int, error)); ok { - return rf(ctx, accountAddress, tokenAddress) + return rf(ctx, address, contractAddress) } if rf, ok := ret.Get(0).(func(context.Context, common.Address, common.Address) *big.Int); ok { - r0 = rf(ctx, accountAddress, tokenAddress) + r0 = rf(ctx, address, contractAddress) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*big.Int) @@ -775,7 +735,7 @@ func (_m *Client) TokenBalance(ctx context.Context, accountAddress common.Addres } if rf, ok := ret.Get(1).(func(context.Context, common.Address, common.Address) error); ok { - r1 = rf(ctx, accountAddress, tokenAddress) + r1 = rf(ctx, address, contractAddress) } else { r1 = ret.Error(1) } diff --git a/core/chains/evm/client/null_client.go b/core/chains/evm/client/null_client.go index adfd4eacc00..394f792eeaa 100644 --- a/core/chains/evm/client/null_client.go +++ b/core/chains/evm/client/null_client.go @@ -131,11 +131,6 @@ func (nc *NullClient) SendTransaction(ctx context.Context, tx *types.Transaction return nil } -func (nc *NullClient) SimulateTransaction(ctx context.Context, tx *types.Transaction) error { - nc.lggr.Debug("SimulateTransaction") - return nil -} - func (nc *NullClient) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error) { nc.lggr.Debug("PendingCodeAt") return nil, nil @@ -181,11 +176,6 @@ func (nc *NullClient) BalanceAt(ctx context.Context, account common.Address, blo return big.NewInt(0), nil } -func (nc *NullClient) FilterEvents(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) { - nc.lggr.Debug("FilterEvents") - return nil, nil -} - func (nc *NullClient) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) { nc.lggr.Debug("FilterLogs") return nil, nil diff --git a/core/chains/evm/client/send_only_node_test.go b/core/chains/evm/client/send_only_node_test.go index de0ecd98e96..b37ee142533 100644 --- a/core/chains/evm/client/send_only_node_test.go +++ b/core/chains/evm/client/send_only_node_test.go @@ -160,7 +160,7 @@ func TestBatchCallContext(t *testing.T) { mock.MatchedBy( func(b []rpc.BatchElem) bool { return len(b) == 2 && - b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == blockNum && b[0].Args[1] == true + b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == blockNum && b[0].Args[1].(bool) })).Return(nil).Once().Return(nil) s.SetEthClient(mockBatchSender, nil) diff --git a/core/chains/evm/client/simulated_backend_client.go b/core/chains/evm/client/simulated_backend_client.go index df69de07e6e..74b7aa54ece 100644 --- a/core/chains/evm/client/simulated_backend_client.go +++ b/core/chains/evm/client/simulated_backend_client.go @@ -111,10 +111,6 @@ func (c *SimulatedBackendClient) CallContext(ctx context.Context, result interfa } } -func (c *SimulatedBackendClient) FilterEvents(ctx context.Context, q ethereum.FilterQuery) (logs []types.Log, err error) { - return c.b.FilterLogs(ctx, q) -} - // FilterLogs returns all logs that respect the passed filter query. func (c *SimulatedBackendClient) FilterLogs(ctx context.Context, q ethereum.FilterQuery) (logs []types.Log, err error) { return c.b.FilterLogs(ctx, q) @@ -405,10 +401,6 @@ func (c *SimulatedBackendClient) SendTransaction(ctx context.Context, tx *types. return err } -func (c *SimulatedBackendClient) SimulateTransaction(ctx context.Context, tx *types.Transaction) error { - panic("not implemented") -} - type revertError struct { error reason string diff --git a/core/chains/evm/config/chain_scoped.go b/core/chains/evm/config/chain_scoped.go index 00ed4e328c9..260043ba252 100644 --- a/core/chains/evm/config/chain_scoped.go +++ b/core/chains/evm/config/chain_scoped.go @@ -15,8 +15,11 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" ) -func NewTOMLChainScopedConfig(genCfg gencfg.AppConfig, chain *toml.EVMConfig, lggr logger.Logger) *ChainScoped { - return &ChainScoped{AppConfig: genCfg, cfg: chain, lggr: lggr} +func NewTOMLChainScopedConfig(genCfg gencfg.AppConfig, tomlConfig *toml.EVMConfig, lggr logger.Logger) *ChainScoped { + return &ChainScoped{ + AppConfig: genCfg, + evmConfig: &evmConfig{c: tomlConfig}, + lggr: lggr} } // ChainScoped implements config.ChainScopedConfig with a gencfg.BasicConfig and EVMConfig. @@ -24,7 +27,15 @@ type ChainScoped struct { gencfg.AppConfig lggr logger.Logger - cfg *toml.EVMConfig + evmConfig *evmConfig +} + +func (c *ChainScoped) EVM() EVM { + return c.evmConfig +} + +func (c *ChainScoped) BlockEmissionIdleWarningThreshold() time.Duration { + return c.EVM().NodeNoNewHeadsThreshold() } func (c *ChainScoped) Validate() (err error) { @@ -140,14 +151,6 @@ func (e *evmConfig) NodeNoNewHeadsThreshold() time.Duration { return e.c.NoNewHeadsThreshold.Duration() } -func (c *ChainScoped) EVM() EVM { - return &evmConfig{c: c.cfg} -} - -func (c *ChainScoped) BlockEmissionIdleWarningThreshold() time.Duration { - return c.EVM().NodeNoNewHeadsThreshold() -} - func (e *evmConfig) MinContractPayment() *assets.Link { return e.c.MinContractPayment } diff --git a/core/chains/evm/config/chain_scoped_gas_estimator.go b/core/chains/evm/config/chain_scoped_gas_estimator.go index ab637361e56..cc28ce75f03 100644 --- a/core/chains/evm/config/chain_scoped_gas_estimator.go +++ b/core/chains/evm/config/chain_scoped_gas_estimator.go @@ -25,7 +25,7 @@ func (g *gasEstimatorConfig) PriceMaxKey(addr gethcommon.Address) *assets.Wei { } chainSpecific := g.c.PriceMax - if keySpecific != nil && !keySpecific.IsZero() && keySpecific.Cmp(chainSpecific) < 0 { + if keySpecific != nil && keySpecific.Cmp(chainSpecific) < 0 { return keySpecific } diff --git a/core/chains/evm/config/config.go b/core/chains/evm/config/config.go index c0873682af4..05c65a8f997 100644 --- a/core/chains/evm/config/config.go +++ b/core/chains/evm/config/config.go @@ -124,6 +124,8 @@ type NodePool interface { SyncThreshold() uint32 } +// TODO BCF-2509 does the chainscopedconfig really need the entire app config? +// //go:generate mockery --quiet --name ChainScopedConfig --output ./mocks/ --case=underscore type ChainScopedConfig interface { config.AppConfig diff --git a/core/chains/evm/config/config_test.go b/core/chains/evm/config/config_test.go index d3240cf81f7..10984d45d1e 100644 --- a/core/chains/evm/config/config_test.go +++ b/core/chains/evm/config/config_test.go @@ -110,19 +110,30 @@ func TestChainScopedConfig(t *testing.T) { assert.Equal(t, val.String(), cfg3.EVM().GasEstimator().PriceMaxKey(addr).String()) }) t.Run("uses key-specific override value when set", func(t *testing.T) { - val := assets.GWei(250) - gcfg3 := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].KeySpecific = toml.KeySpecificConfig{ - {Key: ptr(ethkey.EIP55AddressFromAddress(addr)), - GasEstimator: toml.KeySpecificGasEstimator{ - PriceMax: val, - }, - }, - } - }) - cfg3 := evmtest.NewChainScopedConfig(t, gcfg3) + tests := []struct { + name string + val *assets.Wei + }{ + {"Test with 250 GWei", assets.GWei(250)}, + {"Test with 0 GWei", assets.GWei(0)}, + } - assert.Equal(t, val.String(), cfg3.EVM().GasEstimator().PriceMaxKey(addr).String()) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gcfg3 := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { + c.EVM[0].KeySpecific = toml.KeySpecificConfig{ + {Key: ptr(ethkey.EIP55AddressFromAddress(addr)), + GasEstimator: toml.KeySpecificGasEstimator{ + PriceMax: tt.val, + }, + }, + } + }) + cfg3 := evmtest.NewChainScopedConfig(t, gcfg3) + + assert.Equal(t, tt.val.String(), cfg3.EVM().GasEstimator().PriceMaxKey(addr).String()) + }) + } }) t.Run("uses key-specific override value when set and lower than chain specific config", func(t *testing.T) { keySpecificPrice := assets.GWei(900) diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index 2f89edc6526..fdfce23a877 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -133,7 +133,7 @@ func (cs EVMConfigs) Node(name string) (types.Node, error) { } } } - return types.Node{}, chains.ErrNotFound + return types.Node{}, fmt.Errorf("node %s: %w", name, chains.ErrNotFound) } func (cs EVMConfigs) NodeStatus(name string) (relaytypes.NodeStatus, error) { @@ -144,7 +144,7 @@ func (cs EVMConfigs) NodeStatus(name string) (relaytypes.NodeStatus, error) { } } } - return relaytypes.NodeStatus{}, chains.ErrNotFound + return relaytypes.NodeStatus{}, fmt.Errorf("node %s: %w", name, chains.ErrNotFound) } func legacyNode(n *Node, chainID *utils.Big) (v2 types.Node) { @@ -190,7 +190,7 @@ func (cs EVMConfigs) Nodes(chainID utils.Big) (ns []types.Node, err error) { id := chainID.String() nodes := cs.nodes(id) if nodes == nil { - err = chains.ErrNotFound + err = fmt.Errorf("no nodes: chain %s: %w", &chainID, chains.ErrNotFound) return } for _, n := range nodes { diff --git a/core/chains/evm/config/toml/defaults/BSC_Testnet.toml b/core/chains/evm/config/toml/defaults/BSC_Testnet.toml new file mode 100644 index 00000000000..f97dafa0648 --- /dev/null +++ b/core/chains/evm/config/toml/defaults/BSC_Testnet.toml @@ -0,0 +1,37 @@ +# BSC uses Clique consensus with ~3s block times +# Clique offers finality within (N/2)+1 blocks where N is number of signers +# There are 21 BSC validators so theoretically finality should occur after 21/2+1 = 11 blocks +ChainID = '97' +# Keeping this >> 11 because it's not expensive and gives us a safety margin +FinalityDepth = 50 +LinkContractAddress = '0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06' +LogPollInterval = '3s' +MinIncomingConfirmations = 3 +NoNewHeadsThreshold = '30s' +RPCBlockQueryDelay = 2 +Transactions.ResendAfterThreshold = '1m' + +[BalanceMonitor] +Enabled = true + +[GasEstimator] +PriceDefault = '5 gwei' +PriceMin = '1 gwei' +BumpMin = '5 gwei' +# 15s delay since feeds update every minute in volatile situations +BumpThreshold = 5 + +[GasEstimator.BlockHistory] +BlockHistorySize = 24 + +[HeadTracker] +HistoryDepth = 100 +SamplingInterval = '1s' + +[OCR] +DatabaseTimeout = '2s' +ContractTransmitterTransmitTimeout = '2s' +ObservationGracePeriod = '500ms' + +[NodePool] +SyncThreshold = 10 diff --git a/core/chains/evm/config/toml/defaults/Scroll_Mainnet.toml b/core/chains/evm/config/toml/defaults/Scroll_Mainnet.toml new file mode 100644 index 00000000000..b7d290feb89 --- /dev/null +++ b/core/chains/evm/config/toml/defaults/Scroll_Mainnet.toml @@ -0,0 +1,25 @@ +ChainID = '534352' +FinalityDepth = 1 +# extended time setting, due to sporadic block production rate +LogPollInterval = '30s' +MinIncomingConfirmations = 1 +# Scroll only emits blocks when a new tx is received, so this method of liveness detection is not useful +NoNewHeadsThreshold = '0' +OCR.ContractConfirmations = 1 + +[Transactions] +ResendAfterThreshold = '2m' + +[GasEstimator] +Mode = 'L2Suggested' +# Scroll uses the L2Suggested estimator; we don't want to place any limits on the minimum gas price +PriceMin = '0' +# Never bump gas on Scroll +BumpThreshold = 0 + +[GasEstimator.BlockHistory] +# Force an error if someone enables the estimator by accident; we never want to run the block history estimator on Scroll +BlockHistorySize = 0 + +[HeadTracker] +HistoryDepth = 50 diff --git a/core/chains/evm/config/toml/defaults/Scroll_Sepolia.toml b/core/chains/evm/config/toml/defaults/Scroll_Sepolia.toml new file mode 100644 index 00000000000..263f57c4c67 --- /dev/null +++ b/core/chains/evm/config/toml/defaults/Scroll_Sepolia.toml @@ -0,0 +1,25 @@ +ChainID = '534351' +FinalityDepth = 1 +# extended time setting, due to sporadic block production rate +LogPollInterval = '30s' +MinIncomingConfirmations = 1 +# Scroll only emits blocks when a new tx is received, so this method of liveness detection is not useful +NoNewHeadsThreshold = '0' +OCR.ContractConfirmations = 1 + +[Transactions] +ResendAfterThreshold = '2m' + +[GasEstimator] +Mode = 'L2Suggested' +# Scroll uses the L2Suggested estimator; we don't want to place any limits on the minimum gas price +PriceMin = '0' +# Never bump gas on Scroll +BumpThreshold = 0 + +[GasEstimator.BlockHistory] +# Force an error if someone enables the estimator by accident; we never want to run the block history estimator on Scroll +BlockHistorySize = 0 + +[HeadTracker] +HistoryDepth = 50 diff --git a/core/chains/evm/evm_txm.go b/core/chains/evm/evm_txm.go index 23d109c971d..d2f4178c7d9 100644 --- a/core/chains/evm/evm_txm.go +++ b/core/chains/evm/evm_txm.go @@ -22,7 +22,7 @@ func newEvmTxm( client evmclient.Client, lggr logger.Logger, logPoller logpoller.LogPoller, - opts ChainSetOpts, + opts ChainRelayExtenderConfig, ) (txm txmgr.TxManager, estimator gas.EvmFeeEstimator, err error, diff --git a/core/chains/evm/gas/block_history_estimator.go b/core/chains/evm/gas/block_history_estimator.go index 205c208e702..556c0b1715c 100644 --- a/core/chains/evm/gas/block_history_estimator.go +++ b/core/chains/evm/gas/block_history_estimator.go @@ -261,7 +261,8 @@ func (b *BlockHistoryEstimator) GetLegacyGas(_ context.Context, _ []byte, gasLim "Using Evm.GasEstimator.PriceDefault as fallback.", "blocks", b.getBlockHistoryNumbers()) gasPrice = b.eConfig.PriceDefault() } - gasPrice, chainSpecificGasLimit = capGasPrice(gasPrice, maxGasPriceWei, b.eConfig.PriceMax(), gasLimit, b.eConfig.LimitMultiplier()) + gasPrice = capGasPrice(gasPrice, maxGasPriceWei, b.eConfig.PriceMax()) + chainSpecificGasLimit, err = commonfee.ApplyMultiplier(gasLimit, b.eConfig.LimitMultiplier()) return } @@ -287,7 +288,7 @@ func (b *BlockHistoryEstimator) getTipCap() *assets.Wei { func (b *BlockHistoryEstimator) BumpLegacyGas(_ context.Context, originalGasPrice *assets.Wei, gasLimit uint32, maxGasPriceWei *assets.Wei, attempts []EvmPriorAttempt) (bumpedGasPrice *assets.Wei, chainSpecificGasLimit uint32, err error) { if b.bhConfig.CheckInclusionBlocks() > 0 { if err = b.checkConnectivity(attempts); err != nil { - if errors.Is(err, ErrConnectivity) { + if errors.Is(err, commonfee.ErrConnectivity) { b.logger.Criticalw(BumpingHaltedLabel, "err", err) b.SvcErrBuffer.Append(err) promBlockHistoryEstimatorConnectivityFailureCount.WithLabelValues(b.chainID.String(), "legacy").Inc() @@ -375,11 +376,11 @@ func (b *BlockHistoryEstimator) checkConnectivity(attempts []EvmPriorAttempt) er } } if sufficientFeeCap && attempt.DynamicFee.TipCap.Cmp(tipCap) > 0 { - return errors.Wrapf(ErrConnectivity, "transaction %s has tip cap of %s, which is above percentile=%d%% (percentile tip cap: %s) for blocks %d thru %d (checking %d blocks)", attempt.TxHash, attempt.DynamicFee.TipCap, percentile, tipCap, blockHistory[l-1].Number, blockHistory[0].Number, expectInclusionWithinBlocks) + return errors.Wrapf(commonfee.ErrConnectivity, "transaction %s has tip cap of %s, which is above percentile=%d%% (percentile tip cap: %s) for blocks %d thru %d (checking %d blocks)", attempt.TxHash, attempt.DynamicFee.TipCap, percentile, tipCap, blockHistory[l-1].Number, blockHistory[0].Number, expectInclusionWithinBlocks) } } else { if attempt.GasPrice.Cmp(gasPrice) > 0 { - return errors.Wrapf(ErrConnectivity, "transaction %s has gas price of %s, which is above percentile=%d%% (percentile price: %s) for blocks %d thru %d (checking %d blocks)", attempt.TxHash, attempt.GasPrice, percentile, gasPrice, blockHistory[l-1].Number, blockHistory[0].Number, expectInclusionWithinBlocks) + return errors.Wrapf(commonfee.ErrConnectivity, "transaction %s has gas price of %s, which is above percentile=%d%% (percentile price: %s) for blocks %d thru %d (checking %d blocks)", attempt.TxHash, attempt.GasPrice, percentile, gasPrice, blockHistory[l-1].Number, blockHistory[0].Number, expectInclusionWithinBlocks) } } @@ -395,7 +396,10 @@ func (b *BlockHistoryEstimator) GetDynamicFee(_ context.Context, gasLimit uint32 var feeCap *assets.Wei var tipCap *assets.Wei ok := b.IfStarted(func() { - chainSpecificGasLimit = commonfee.ApplyMultiplier(gasLimit, b.eConfig.LimitMultiplier()) + chainSpecificGasLimit, err = commonfee.ApplyMultiplier(gasLimit, b.eConfig.LimitMultiplier()) + if err != nil { + return + } b.priceMu.RLock() defer b.priceMu.RUnlock() tipCap = b.tipCap @@ -460,7 +464,7 @@ func calcFeeCap(latestAvailableBaseFeePerGas *assets.Wei, bufferBlocks int, tipC func (b *BlockHistoryEstimator) BumpDynamicFee(_ context.Context, originalFee DynamicFee, originalGasLimit uint32, maxGasPriceWei *assets.Wei, attempts []EvmPriorAttempt) (bumped DynamicFee, chainSpecificGasLimit uint32, err error) { if b.bhConfig.CheckInclusionBlocks() > 0 { if err = b.checkConnectivity(attempts); err != nil { - if errors.Is(err, ErrConnectivity) { + if errors.Is(err, commonfee.ErrConnectivity) { b.logger.Criticalw(BumpingHaltedLabel, "err", err) b.SvcErrBuffer.Append(err) promBlockHistoryEstimatorConnectivityFailureCount.WithLabelValues(b.chainID.String(), "eip1559").Inc() diff --git a/core/chains/evm/gas/block_history_estimator_test.go b/core/chains/evm/gas/block_history_estimator_test.go index 47d9cfa83ea..c44e68002d2 100644 --- a/core/chains/evm/gas/block_history_estimator_test.go +++ b/core/chains/evm/gas/block_history_estimator_test.go @@ -18,6 +18,7 @@ import ( "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" + commonfee "github.com/smartcontractkit/chainlink/v2/common/fee" "github.com/smartcontractkit/chainlink/v2/core/assets" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" @@ -82,8 +83,8 @@ func TestBlockHistoryEstimator_Start(t *testing.T) { ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(h, nil) ethClient.On("BatchCallContext", mock.Anything, mock.MatchedBy(func(b []rpc.BatchElem) bool { return len(b) == 2 && - b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == "0x2a" && b[0].Args[1] == true && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) && - b[1].Method == "eth_getBlockByNumber" && b[1].Args[0] == "0x29" && b[1].Args[1] == true && reflect.TypeOf(b[1].Result) == reflect.TypeOf(&evmtypes.Block{}) + b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == "0x2a" && b[0].Args[1].(bool) && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) && + b[1].Method == "eth_getBlockByNumber" && b[1].Args[0] == "0x29" && b[1].Args[1].(bool) && reflect.TypeOf(b[1].Result) == reflect.TypeOf(&evmtypes.Block{}) })).Return(nil).Run(func(args mock.Arguments) { elems := args.Get(1).([]rpc.BatchElem) elems[0].Result = &evmtypes.Block{ @@ -128,7 +129,7 @@ func TestBlockHistoryEstimator_Start(t *testing.T) { // First succeeds (42) ethClient.On("BatchCallContext", mock.Anything, mock.MatchedBy(func(b []rpc.BatchElem) bool { return len(b) == 1 && - b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == gas.Int64ToHex(42) && b[0].Args[1] == true && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) + b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == gas.Int64ToHex(42) && b[0].Args[1].(bool) && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) })).Return(nil).Run(func(args mock.Arguments) { elems := args.Get(1).([]rpc.BatchElem) elems[0].Result = &evmtypes.Block{ @@ -139,7 +140,7 @@ func TestBlockHistoryEstimator_Start(t *testing.T) { // Second fails (41) ethClient.On("BatchCallContext", mock.Anything, mock.MatchedBy(func(b []rpc.BatchElem) bool { return len(b) == 1 && - b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == gas.Int64ToHex(41) && b[0].Args[1] == true && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) + b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == gas.Int64ToHex(41) && b[0].Args[1].(bool) && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) })).Return(errors.Wrap(context.DeadlineExceeded, "some error message")).Once() err := bhe.Start(testutils.Context(t)) @@ -381,8 +382,8 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) { ethClient.On("BatchCallContext", mock.Anything, mock.MatchedBy(func(b []rpc.BatchElem) bool { return len(b) == 2 && - b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == gas.Int64ToHex(43) && b[0].Args[1] == true && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) && - b[1].Method == "eth_getBlockByNumber" && b[1].Args[0] == gas.Int64ToHex(42) && b[1].Args[1] == true && reflect.TypeOf(b[1].Result) == reflect.TypeOf(&evmtypes.Block{}) + b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == gas.Int64ToHex(43) && b[0].Args[1].(bool) && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) && + b[1].Method == "eth_getBlockByNumber" && b[1].Args[0] == gas.Int64ToHex(42) && b[1].Args[1].(bool) && reflect.TypeOf(b[1].Result) == reflect.TypeOf(&evmtypes.Block{}) })).Once().Return(nil).Run(func(args mock.Arguments) { elems := args.Get(1).([]rpc.BatchElem) elems[0].Result = &b43 @@ -391,7 +392,7 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) { }) ethClient.On("BatchCallContext", mock.Anything, mock.MatchedBy(func(b []rpc.BatchElem) bool { return len(b) == 1 && - b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == gas.Int64ToHex(41) && b[0].Args[1] == true && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) + b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == gas.Int64ToHex(41) && b[0].Args[1].(bool) && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) })).Once().Return(nil).Run(func(args mock.Arguments) { elems := args.Get(1).([]rpc.BatchElem) elems[0].Result = &b41 @@ -419,8 +420,8 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) { // 43 is skipped because it was already in the history ethClient.On("BatchCallContext", mock.Anything, mock.MatchedBy(func(b []rpc.BatchElem) bool { return len(b) == 2 && - b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == gas.Int64ToHex(44) && b[0].Args[1] == true && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) && - b[1].Method == "eth_getBlockByNumber" && b[1].Args[0] == gas.Int64ToHex(42) && b[1].Args[1] == true && reflect.TypeOf(b[1].Result) == reflect.TypeOf(&evmtypes.Block{}) + b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == gas.Int64ToHex(44) && b[0].Args[1].(bool) && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) && + b[1].Method == "eth_getBlockByNumber" && b[1].Args[0] == gas.Int64ToHex(42) && b[1].Args[1].(bool) && reflect.TypeOf(b[1].Result) == reflect.TypeOf(&evmtypes.Block{}) })).Once().Return(nil).Run(func(args mock.Arguments) { elems := args.Get(1).([]rpc.BatchElem) elems[0].Result = &b44 @@ -483,8 +484,8 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) { ethClient.On("BatchCallContext", mock.Anything, mock.MatchedBy(func(b []rpc.BatchElem) bool { return len(b) == 2 && - b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == gas.Int64ToHex(3) && b[0].Args[1] == true && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) && - b[1].Method == "eth_getBlockByNumber" && b[1].Args[0] == gas.Int64ToHex(2) && b[1].Args[1] == true && reflect.TypeOf(b[1].Result) == reflect.TypeOf(&evmtypes.Block{}) + b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == gas.Int64ToHex(3) && b[0].Args[1].(bool) && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) && + b[1].Method == "eth_getBlockByNumber" && b[1].Args[0] == gas.Int64ToHex(2) && b[1].Args[1].(bool) && reflect.TypeOf(b[1].Result) == reflect.TypeOf(&evmtypes.Block{}) })).Once().Return(nil).Run(func(args mock.Arguments) { elems := args.Get(1).([]rpc.BatchElem) elems[0].Result = &b3 @@ -550,8 +551,8 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) { ethClient.On("BatchCallContext", mock.Anything, mock.MatchedBy(func(b []rpc.BatchElem) bool { return len(b) == 2 && - b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == gas.Int64ToHex(3) && b[0].Args[1] == true && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) && - b[1].Method == "eth_getBlockByNumber" && b[1].Args[0] == gas.Int64ToHex(2) && b[1].Args[1] == true && reflect.TypeOf(b[1].Result) == reflect.TypeOf(&evmtypes.Block{}) + b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == gas.Int64ToHex(3) && b[0].Args[1].(bool) && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) && + b[1].Method == "eth_getBlockByNumber" && b[1].Args[0] == gas.Int64ToHex(2) && b[1].Args[1].(bool) && reflect.TypeOf(b[1].Result) == reflect.TypeOf(&evmtypes.Block{}) })).Once().Return(nil).Run(func(args mock.Arguments) { elems := args.Get(1).([]rpc.BatchElem) b2New := b2 @@ -662,8 +663,8 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) { ethClient.On("BatchCallContext", mock.Anything, mock.MatchedBy(func(b []rpc.BatchElem) bool { return len(b) == 2 && - b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == gas.Int64ToHex(43) && b[0].Args[1] == true && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) && - b[1].Method == "eth_getBlockByNumber" && b[1].Args[0] == gas.Int64ToHex(42) && b[1].Args[1] == true && reflect.TypeOf(b[1].Result) == reflect.TypeOf(&evmtypes.Block{}) + b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == gas.Int64ToHex(43) && b[0].Args[1].(bool) && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) && + b[1].Method == "eth_getBlockByNumber" && b[1].Args[0] == gas.Int64ToHex(42) && b[1].Args[1].(bool) && reflect.TypeOf(b[1].Result) == reflect.TypeOf(&evmtypes.Block{}) })).Once().Return(nil).Run(func(args mock.Arguments) { elems := args.Get(1).([]rpc.BatchElem) elems[0].Result = &b43 @@ -1815,9 +1816,9 @@ func TestBlockHistoryEstimator_UseDefaultPriceAsFallback(t *testing.T) { ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(h, nil) ethClient.On("BatchCallContext", mock.Anything, mock.MatchedBy(func(b []rpc.BatchElem) bool { return len(b) == 3 && - b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == gas.Int64ToHex(42) && b[0].Args[1] == true && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) && - b[1].Method == "eth_getBlockByNumber" && b[1].Args[0] == gas.Int64ToHex(41) && b[1].Args[1] == true && reflect.TypeOf(b[1].Result) == reflect.TypeOf(&evmtypes.Block{}) && - b[2].Method == "eth_getBlockByNumber" && b[2].Args[0] == gas.Int64ToHex(40) && b[1].Args[1] == true && reflect.TypeOf(b[2].Result) == reflect.TypeOf(&evmtypes.Block{}) + b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == gas.Int64ToHex(42) && b[0].Args[1].(bool) && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) && + b[1].Method == "eth_getBlockByNumber" && b[1].Args[0] == gas.Int64ToHex(41) && b[1].Args[1].(bool) && reflect.TypeOf(b[1].Result) == reflect.TypeOf(&evmtypes.Block{}) && + b[2].Method == "eth_getBlockByNumber" && b[2].Args[0] == gas.Int64ToHex(40) && b[1].Args[1].(bool) && reflect.TypeOf(b[2].Result) == reflect.TypeOf(&evmtypes.Block{}) })).Return(nil).Run(func(args mock.Arguments) { elems := args.Get(1).([]rpc.BatchElem) elems[0].Result = &evmtypes.Block{ @@ -1867,9 +1868,9 @@ func TestBlockHistoryEstimator_UseDefaultPriceAsFallback(t *testing.T) { ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(h, nil) ethClient.On("BatchCallContext", mock.Anything, mock.MatchedBy(func(b []rpc.BatchElem) bool { return len(b) == 3 && - b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == gas.Int64ToHex(42) && b[0].Args[1] == true && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) && - b[1].Method == "eth_getBlockByNumber" && b[1].Args[0] == gas.Int64ToHex(41) && b[1].Args[1] == true && reflect.TypeOf(b[1].Result) == reflect.TypeOf(&evmtypes.Block{}) && - b[2].Method == "eth_getBlockByNumber" && b[2].Args[0] == gas.Int64ToHex(40) && b[1].Args[1] == true && reflect.TypeOf(b[2].Result) == reflect.TypeOf(&evmtypes.Block{}) + b[0].Method == "eth_getBlockByNumber" && b[0].Args[0] == gas.Int64ToHex(42) && b[0].Args[1].(bool) && reflect.TypeOf(b[0].Result) == reflect.TypeOf(&evmtypes.Block{}) && + b[1].Method == "eth_getBlockByNumber" && b[1].Args[0] == gas.Int64ToHex(41) && b[1].Args[1].(bool) && reflect.TypeOf(b[1].Result) == reflect.TypeOf(&evmtypes.Block{}) && + b[2].Method == "eth_getBlockByNumber" && b[2].Args[0] == gas.Int64ToHex(40) && b[1].Args[1].(bool) && reflect.TypeOf(b[2].Result) == reflect.TypeOf(&evmtypes.Block{}) })).Return(nil).Run(func(args mock.Arguments) { elems := args.Get(1).([]rpc.BatchElem) elems[0].Result = &evmtypes.Block{ @@ -2154,7 +2155,7 @@ func TestBlockHistoryEstimator_CheckConnectivity(t *testing.T) { err := bhe.CheckConnectivity(attempts) require.Error(t, err) assert.Contains(t, err.Error(), fmt.Sprintf("transaction %s has gas price of 7 wei, which is above percentile=40%% (percentile price: 5 wei) for blocks 2 thru 0 (checking 3 blocks)", attempts[3].TxHash)) - require.ErrorIs(t, err, gas.ErrConnectivity) + require.ErrorIs(t, err, commonfee.ErrConnectivity) }) t.Run("fails check if one or more blocks has percentile price higher than any transaction gas price", func(t *testing.T) { @@ -2171,7 +2172,7 @@ func TestBlockHistoryEstimator_CheckConnectivity(t *testing.T) { err = bhe.CheckConnectivity(attempts) require.Error(t, err) assert.Contains(t, err.Error(), fmt.Sprintf("transaction %s has gas price of 3 wei, which is above percentile=5%% (percentile price: 2 wei) for blocks 2 thru 0 (checking 3 blocks)", attempts[1].TxHash)) - require.ErrorIs(t, err, gas.ErrConnectivity) + require.ErrorIs(t, err, commonfee.ErrConnectivity) }) }) @@ -2203,7 +2204,7 @@ func TestBlockHistoryEstimator_CheckConnectivity(t *testing.T) { err := bhe.CheckConnectivity(attempts) require.Error(t, err) assert.Contains(t, err.Error(), fmt.Sprintf("transaction %s has gas price of 10 wei, which is above percentile=60%% (percentile price: 7 wei) for blocks 3 thru 3 (checking 1 blocks)", attempts[1].TxHash)) - require.ErrorIs(t, err, gas.ErrConnectivity) + require.ErrorIs(t, err, commonfee.ErrConnectivity) }) attempts = []gas.EvmPriorAttempt{ @@ -2219,7 +2220,7 @@ func TestBlockHistoryEstimator_CheckConnectivity(t *testing.T) { err := bhe.CheckConnectivity(attempts) require.Error(t, err) assert.Contains(t, err.Error(), fmt.Sprintf("transaction %s has tip cap of 10 wei, which is above percentile=60%% (percentile tip cap: 6 wei) for blocks 3 thru 3 (checking 1 blocks)", attempts[0].TxHash)) - require.ErrorIs(t, err, gas.ErrConnectivity) + require.ErrorIs(t, err, commonfee.ErrConnectivity) }) }) @@ -2277,7 +2278,7 @@ func TestBlockHistoryEstimator_CheckConnectivity(t *testing.T) { err := bhe.CheckConnectivity(attempts) require.Error(t, err) assert.Contains(t, err.Error(), fmt.Sprintf("transaction %s has tip cap of 5 wei, which is above percentile=20%% (percentile tip cap: 4 wei) for blocks 2 thru 0 (checking 3 blocks)", attempts[2].TxHash)) - require.ErrorIs(t, err, gas.ErrConnectivity) + require.ErrorIs(t, err, commonfee.ErrConnectivity) bhCfg.CheckInclusionBlocksF = 3 bhCfg.CheckInclusionPercentileF = 5 @@ -2285,7 +2286,7 @@ func TestBlockHistoryEstimator_CheckConnectivity(t *testing.T) { err = bhe.CheckConnectivity(attempts) require.Error(t, err) assert.Contains(t, err.Error(), fmt.Sprintf("transaction %s has tip cap of 3 wei, which is above percentile=5%% (percentile tip cap: 2 wei) for blocks 2 thru 0 (checking 3 blocks)", attempts[1].TxHash)) - require.ErrorIs(t, err, gas.ErrConnectivity) + require.ErrorIs(t, err, commonfee.ErrConnectivity) }) t.Run("passes check if, for at least one block, feecap < tipcap+basefee, even if percentile is not reached", func(t *testing.T) { @@ -2335,7 +2336,7 @@ func TestBlockHistoryEstimator_Bumps(t *testing.T) { _, _, err := bhe.BumpLegacyGas(testutils.Context(t), assets.NewWeiI(42), 100000, maxGasPrice, attempts) require.Error(t, err) - assert.True(t, errors.Is(err, gas.ErrConnectivity)) + assert.True(t, errors.Is(err, commonfee.ErrConnectivity)) assert.Contains(t, err.Error(), fmt.Sprintf("transaction %s has gas price of 1 kwei, which is above percentile=10%% (percentile price: 1 wei) for blocks 1 thru 1 (checking 1 blocks)", attempts[0].TxHash)) }) @@ -2448,7 +2449,7 @@ func TestBlockHistoryEstimator_Bumps(t *testing.T) { _, _, err := bhe.BumpDynamicFee(testutils.Context(t), originalFee, 100000, maxGasPrice, attempts) require.Error(t, err) - assert.True(t, errors.Is(err, gas.ErrConnectivity)) + assert.True(t, errors.Is(err, commonfee.ErrConnectivity)) assert.Contains(t, err.Error(), fmt.Sprintf("transaction %s has tip cap of 25 wei, which is above percentile=10%% (percentile tip cap: 1 wei) for blocks 1 thru 1 (checking 1 blocks)", attempts[0].TxHash)) }) diff --git a/core/chains/evm/gas/fixed_price_estimator.go b/core/chains/evm/gas/fixed_price_estimator.go index b96a2e8b8cd..733dd179fec 100644 --- a/core/chains/evm/gas/fixed_price_estimator.go +++ b/core/chains/evm/gas/fixed_price_estimator.go @@ -4,7 +4,6 @@ import ( "context" "github.com/pkg/errors" - commonfee "github.com/smartcontractkit/chainlink/v2/common/fee" feetypes "github.com/smartcontractkit/chainlink/v2/common/fee/types" "github.com/smartcontractkit/chainlink/v2/core/assets" @@ -19,6 +18,13 @@ type fixedPriceEstimator struct { bhConfig fixedPriceEstimatorBlockHistoryConfig lggr logger.SugaredLogger } +type bumpConfig interface { + LimitMultiplier() float32 + PriceMax() *assets.Wei + BumpPercent() uint16 + BumpMin() *assets.Wei + TipCapDefault() *assets.Wei +} type fixedPriceEstimatorConfig interface { BumpThreshold() uint64 @@ -50,20 +56,42 @@ func (f *fixedPriceEstimator) Start(context.Context) error { } return nil } -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{} } -func (f *fixedPriceEstimator) Close() error { return nil } -func (f *fixedPriceEstimator) OnNewLongestChain(_ context.Context, _ *evmtypes.Head) {} -func (f *fixedPriceEstimator) GetLegacyGas(_ context.Context, _ []byte, gasLimit uint32, maxGasPriceWei *assets.Wei, _ ...feetypes.Opt) (gasPrice *assets.Wei, chainSpecificGasLimit uint32, err error) { - gasPrice = f.config.PriceDefault() - gasPrice, chainSpecificGasLimit = capGasPrice(gasPrice, maxGasPriceWei, f.config.PriceMax(), gasLimit, f.config.LimitMultiplier()) - return +func (f *fixedPriceEstimator) GetLegacyGas(_ context.Context, _ []byte, gasLimit uint32, maxGasPriceWei *assets.Wei, _ ...feetypes.Opt) (*assets.Wei, uint32, error) { + gasPrice := commonfee.CalculateFee(f.config.PriceDefault().ToInt(), maxGasPriceWei.ToInt(), f.config.PriceMax().ToInt()) + chainSpecificGasLimit, err := commonfee.ApplyMultiplier(gasLimit, f.config.LimitMultiplier()) + if err != nil { + return nil, 0, err + } + return assets.NewWei(gasPrice), chainSpecificGasLimit, nil } -func (f *fixedPriceEstimator) BumpLegacyGas(_ context.Context, originalGasPrice *assets.Wei, originalGasLimit uint32, maxGasPriceWei *assets.Wei, _ []EvmPriorAttempt) (gasPrice *assets.Wei, gasLimit uint32, err error) { - return BumpLegacyGasPriceOnly(f.config, f.lggr, f.config.PriceDefault(), originalGasPrice, originalGasLimit, maxGasPriceWei) +func (f *fixedPriceEstimator) BumpLegacyGas( + _ context.Context, + originalGasPrice *assets.Wei, + originalGasLimit uint32, + maxGasPriceWei *assets.Wei, + _ []EvmPriorAttempt, +) (*assets.Wei, uint32, error) { + gasPrice, err := commonfee.CalculateBumpedFee( + f.lggr, + f.config.PriceDefault().ToInt(), + originalGasPrice.ToInt(), + maxGasPriceWei.ToInt(), + f.config.PriceMax().ToInt(), + f.config.BumpMin().ToInt(), + f.config.BumpPercent(), + assets.FormatWei, + ) + if err != nil { + return nil, 0, err + } + + chainSpecificGasLimit, err := commonfee.ApplyMultiplier(originalGasLimit, f.config.LimitMultiplier()) + if err != nil { + return nil, 0, err + } + return assets.NewWei(gasPrice), chainSpecificGasLimit, err } func (f *fixedPriceEstimator) GetDynamicFee(_ context.Context, originalGasLimit uint32, maxGasPriceWei *assets.Wei) (d DynamicFee, chainSpecificGasLimit uint32, err error) { @@ -72,7 +100,10 @@ func (f *fixedPriceEstimator) GetDynamicFee(_ context.Context, originalGasLimit if gasTipCap == nil { return d, 0, errors.New("cannot calculate dynamic fee: EthGasTipCapDefault was not set") } - chainSpecificGasLimit = commonfee.ApplyMultiplier(originalGasLimit, f.config.LimitMultiplier()) + chainSpecificGasLimit, err = commonfee.ApplyMultiplier(originalGasLimit, f.config.LimitMultiplier()) + if err != nil { + return d, 0, err + } var feeCap *assets.Wei if f.config.BumpThreshold() == 0 { @@ -89,6 +120,28 @@ func (f *fixedPriceEstimator) GetDynamicFee(_ context.Context, originalGasLimit }, chainSpecificGasLimit, nil } -func (f *fixedPriceEstimator) BumpDynamicFee(_ context.Context, originalFee DynamicFee, originalGasLimit uint32, maxGasPriceWei *assets.Wei, _ []EvmPriorAttempt) (bumped DynamicFee, chainSpecificGasLimit uint32, err error) { - return BumpDynamicFeeOnly(f.config, f.bhConfig.EIP1559FeeCapBufferBlocks(), f.lggr, f.config.TipCapDefault(), nil, originalFee, originalGasLimit, maxGasPriceWei) +func (f *fixedPriceEstimator) BumpDynamicFee( + _ context.Context, + originalFee DynamicFee, + originalGasLimit uint32, + maxGasPriceWei *assets.Wei, + _ []EvmPriorAttempt, +) (bumped DynamicFee, chainSpecificGasLimit uint32, err error) { + + return BumpDynamicFeeOnly( + f.config, + f.bhConfig.EIP1559FeeCapBufferBlocks(), + f.lggr, + f.config.TipCapDefault(), + nil, + originalFee, + originalGasLimit, + maxGasPriceWei, + ) } + +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{} } +func (f *fixedPriceEstimator) Close() error { return nil } +func (f *fixedPriceEstimator) OnNewLongestChain(_ context.Context, _ *evmtypes.Head) {} diff --git a/core/chains/evm/gas/models.go b/core/chains/evm/gas/models.go index a9cbc0a924a..8b6580685b5 100644 --- a/core/chains/evm/gas/models.go +++ b/core/chains/evm/gas/models.go @@ -20,18 +20,9 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/config" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services" + bigmath "github.com/smartcontractkit/chainlink/v2/core/utils/big_math" ) -var ( - ErrBumpGasExceedsLimit = errors.New("gas bump exceeds limit") - ErrBump = errors.New("gas bump failed") - ErrConnectivity = errors.New("transaction propagation issue: transactions are not being mined") -) - -func IsBumpErr(err error) bool { - return err != nil && (errors.Is(err, ErrBumpGasExceedsLimit) || errors.Is(err, ErrBump) || errors.Is(err, ErrConnectivity)) -} - // EvmFeeEstimator provides a unified interface that wraps EvmEstimator and can determine if legacy or dynamic fee estimation should be used // //go:generate mockery --quiet --name EvmFeeEstimator --output ./mocks/ --case=underscore @@ -275,21 +266,13 @@ func HexToInt64(input interface{}) int64 { } } -type bumpConfig interface { - LimitMultiplier() float32 - PriceMax() *assets.Wei - BumpPercent() uint16 - BumpMin() *assets.Wei - TipCapDefault() *assets.Wei -} - // BumpLegacyGasPriceOnly will increase the price and apply multiplier to the gas limit func BumpLegacyGasPriceOnly(cfg bumpConfig, lggr logger.SugaredLogger, currentGasPrice, originalGasPrice *assets.Wei, originalGasLimit uint32, maxGasPriceWei *assets.Wei) (gasPrice *assets.Wei, chainSpecificGasLimit uint32, err error) { gasPrice, err = bumpGasPrice(cfg, lggr, currentGasPrice, originalGasPrice, maxGasPriceWei) if err != nil { return nil, 0, err } - chainSpecificGasLimit = commonfee.ApplyMultiplier(originalGasLimit, cfg.LimitMultiplier()) + chainSpecificGasLimit, err = commonfee.ApplyMultiplier(originalGasLimit, cfg.LimitMultiplier()) return } @@ -305,13 +288,13 @@ func bumpGasPrice(cfg bumpConfig, lggr logger.SugaredLogger, currentGasPrice, or bumpedGasPrice = maxBumpedFee(lggr, currentGasPrice, bumpedGasPrice, maxGasPrice, "gas price") if bumpedGasPrice.Cmp(maxGasPrice) > 0 { - return maxGasPrice, errors.Wrapf(ErrBumpGasExceedsLimit, "bumped gas price of %s would exceed configured max gas price of %s (original price was %s). %s", + return maxGasPrice, errors.Wrapf(commonfee.ErrBumpFeeExceedsLimit, "bumped gas price of %s would exceed configured max gas price of %s (original price was %s). %s", bumpedGasPrice.String(), maxGasPrice, originalGasPrice.String(), label.NodeConnectivityProblemWarning) } else if bumpedGasPrice.Cmp(originalGasPrice) == 0 { // NOTE: This really shouldn't happen since we enforce minimums for // EVM.GasEstimator.BumpPercent and EVM.GasEstimator.BumpMin in the config validation, // but it's here anyway for a "belts and braces" approach - return bumpedGasPrice, errors.Wrapf(ErrBump, "bumped gas price of %s is equal to original gas price of %s."+ + return bumpedGasPrice, errors.Wrapf(commonfee.ErrBump, "bumped gas price of %s is equal to original gas price of %s."+ " ACTION REQUIRED: This is a configuration error, you must increase either "+ "EVM.GasEstimator.BumpPercent or EVM.GasEstimator.BumpMin", bumpedGasPrice.String(), originalGasPrice.String()) } @@ -324,7 +307,7 @@ func BumpDynamicFeeOnly(config bumpConfig, feeCapBufferBlocks uint16, lggr logge if err != nil { return bumped, 0, err } - chainSpecificGasLimit = commonfee.ApplyMultiplier(originalGasLimit, config.LimitMultiplier()) + chainSpecificGasLimit, err = commonfee.ApplyMultiplier(originalGasLimit, config.LimitMultiplier()) return } @@ -347,13 +330,13 @@ func bumpDynamicFee(cfg bumpConfig, feeCapBufferBlocks uint16, lggr logger.Sugar bumpedTipCap = maxBumpedFee(lggr, currentTipCap, bumpedTipCap, maxGasPrice, "tip cap") if bumpedTipCap.Cmp(maxGasPrice) > 0 { - return bumpedFee, errors.Wrapf(ErrBumpGasExceedsLimit, "bumped tip cap of %s would exceed configured max gas price of %s (original fee: tip cap %s, fee cap %s). %s", + return bumpedFee, errors.Wrapf(commonfee.ErrBumpFeeExceedsLimit, "bumped tip cap of %s would exceed configured max gas price of %s (original fee: tip cap %s, fee cap %s). %s", bumpedTipCap.String(), maxGasPrice, originalFee.TipCap.String(), originalFee.FeeCap.String(), label.NodeConnectivityProblemWarning) } else if bumpedTipCap.Cmp(originalFee.TipCap) <= 0 { // NOTE: This really shouldn't happen since we enforce minimums for // EVM.GasEstimator.BumpPercent and EVM.GasEstimator.BumpMin in the config validation, // but it's here anyway for a "belts and braces" approach - return bumpedFee, errors.Wrapf(ErrBump, "bumped gas tip cap of %s is less than or equal to original gas tip cap of %s."+ + return bumpedFee, errors.Wrapf(commonfee.ErrBump, "bumped gas tip cap of %s is less than or equal to original gas tip cap of %s."+ " ACTION REQUIRED: This is a configuration error, you must increase either "+ "EVM.GasEstimator.BumpPercent or EVM.GasEstimator.BumpMin", bumpedTipCap.String(), originalFee.TipCap.String()) } @@ -361,10 +344,7 @@ func bumpDynamicFee(cfg bumpConfig, feeCapBufferBlocks uint16, lggr logger.Sugar // Always bump the FeeCap by at least the bump percentage (should be greater than or // equal to than geth's configured bump minimum which is 10%) // See: https://github.com/ethereum/go-ethereum/blob/bff330335b94af3643ac2fb809793f77de3069d4/core/tx_list.go#L298 - bumpedFeeCap := assets.MaxWei( - originalFee.FeeCap.AddPercentage(cfg.BumpPercent()), - originalFee.FeeCap.Add(cfg.BumpMin()), - ) + bumpedFeeCap := bumpFeePrice(originalFee.FeeCap, cfg.BumpPercent(), cfg.BumpMin()) if currentBaseFee != nil { if currentBaseFee.Cmp(maxGasPrice) > 0 { @@ -376,7 +356,7 @@ func bumpDynamicFee(cfg bumpConfig, feeCapBufferBlocks uint16, lggr logger.Sugar } if bumpedFeeCap.Cmp(maxGasPrice) > 0 { - return bumpedFee, errors.Wrapf(ErrBumpGasExceedsLimit, "bumped fee cap of %s would exceed configured max gas price of %s (original fee: tip cap %s, fee cap %s). %s", + return bumpedFee, errors.Wrapf(commonfee.ErrBumpFeeExceedsLimit, "bumped fee cap of %s would exceed configured max gas price of %s (original fee: tip cap %s, fee cap %s). %s", bumpedFeeCap.String(), maxGasPrice, originalFee.TipCap.String(), originalFee.FeeCap.String(), label.NodeConnectivityProblemWarning) } @@ -406,10 +386,10 @@ func maxBumpedFee(lggr logger.SugaredLogger, currentFeePrice, bumpedFeePrice, ma } func getMaxGasPrice(userSpecifiedMax, maxGasPriceWei *assets.Wei) *assets.Wei { - return assets.NewWei(commonfee.GetMaxFeePrice(userSpecifiedMax.ToInt(), maxGasPriceWei.ToInt())) + return assets.NewWei(bigmath.Min(userSpecifiedMax.ToInt(), maxGasPriceWei.ToInt())) } -func capGasPrice(calculatedGasPrice, userSpecifiedMax, maxGasPriceWei *assets.Wei, gasLimit uint32, multiplier float32) (*assets.Wei, uint32) { - maxGasPrice, chainSpecificGasLimit := commonfee.CapFeePrice(calculatedGasPrice.ToInt(), userSpecifiedMax.ToInt(), maxGasPriceWei.ToInt(), gasLimit, multiplier) - return assets.NewWei(maxGasPrice), chainSpecificGasLimit +func capGasPrice(calculatedGasPrice, userSpecifiedMax, maxGasPriceWei *assets.Wei) *assets.Wei { + maxGasPrice := commonfee.CalculateFee(calculatedGasPrice.ToInt(), userSpecifiedMax.ToInt(), maxGasPriceWei.ToInt()) + return assets.NewWei(maxGasPrice) } diff --git a/core/chains/evm/headtracker/head_broadcaster_test.go b/core/chains/evm/headtracker/head_broadcaster_test.go index aba9335b14b..c478920e00e 100644 --- a/core/chains/evm/headtracker/head_broadcaster_test.go +++ b/core/chains/evm/headtracker/head_broadcaster_test.go @@ -59,7 +59,8 @@ func TestHeadBroadcaster_Subscribe(t *testing.T) { chchHeaders <- args.Get(1).(chan<- *evmtypes.Head) }). Return(sub, nil) - ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(cltest.Head(1), nil) + ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(cltest.Head(1), nil).Once() + ethClient.On("HeadByHash", mock.Anything, mock.Anything).Return(cltest.Head(1), nil) sub.On("Unsubscribe").Return() sub.On("Err").Return(nil) diff --git a/core/chains/evm/headtracker/head_tracker_test.go b/core/chains/evm/headtracker/head_tracker_test.go index 7ae328ffbde..cf8399ceeda 100644 --- a/core/chains/evm/headtracker/head_tracker_test.go +++ b/core/chains/evm/headtracker/head_tracker_test.go @@ -247,6 +247,7 @@ func TestHeadTracker_CallsHeadTrackableCallbacks(t *testing.T) { func(ctx context.Context, ch chan<- *evmtypes.Head) error { return nil }, ) ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(cltest.Head(0), nil) + ethClient.On("HeadByHash", mock.Anything, mock.Anything).Return(cltest.Head(0), nil).Maybe() checker := &cltest.MockHeadTrackable{} ht := createHeadTrackerWithChecker(t, ethClient, config.EVM(), config.EVM().HeadTracker(), orm, checker) @@ -320,7 +321,8 @@ func TestHeadTracker_ResubscribeOnSubscriptionError(t *testing.T) { }, func(ctx context.Context, ch chan<- *evmtypes.Head) error { return nil }, ) - ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(cltest.Head(0), nil) + ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(cltest.Head(0), nil).Once() + ethClient.On("HeadByHash", mock.Anything, mock.Anything).Return(cltest.Head(0), nil).Maybe() checker := &cltest.MockHeadTrackable{} ht := createHeadTrackerWithChecker(t, ethClient, config.EVM(), config.EVM().HeadTracker(), orm, checker) @@ -367,9 +369,9 @@ func TestHeadTracker_Start_LoadsLatestChain(t *testing.T) { parentHash = heads[i].Hash } ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(heads[3], nil).Maybe() - ethClient.On("HeadByNumber", mock.Anything, big.NewInt(2)).Return(heads[2], nil).Maybe() - ethClient.On("HeadByNumber", mock.Anything, big.NewInt(1)).Return(heads[1], nil).Maybe() - ethClient.On("HeadByNumber", mock.Anything, big.NewInt(0)).Return(heads[0], nil).Maybe() + ethClient.On("HeadByHash", mock.Anything, heads[2].Hash).Return(heads[2], nil).Maybe() + ethClient.On("HeadByHash", mock.Anything, heads[1].Hash).Return(heads[1], nil).Maybe() + ethClient.On("HeadByHash", mock.Anything, heads[0].Hash).Return(heads[0], nil).Maybe() chchHeaders := make(chan evmtest.RawSub[*evmtypes.Head], 1) mockEth := &evmtest.MockEth{EthClient: ethClient} @@ -505,26 +507,22 @@ func TestHeadTracker_SwitchesToLongestChainWithHeadSamplingEnabled(t *testing.T) // This grotesque construction is the only way to do dynamic return values using // the mock package. We need dynamic returns because we're simulating reorgs. - latestHeadByNumber := make(map[int64]*evmtypes.Head) - latestHeadByNumberMu := new(sync.Mutex) + latestHeadByHash := make(map[gethCommon.Hash]*evmtypes.Head) + latestHeadByHashMu := new(sync.Mutex) - fnCall := ethClient.On("HeadByNumber", mock.Anything, mock.Anything) + fnCall := ethClient.On("HeadByHash", mock.Anything, mock.Anything).Maybe() fnCall.RunFn = func(args mock.Arguments) { - latestHeadByNumberMu.Lock() - defer latestHeadByNumberMu.Unlock() - num := args.Get(1).(*big.Int) - head, exists := latestHeadByNumber[num.Int64()] - if !exists { - head = cltest.Head(num.Int64()) - latestHeadByNumber[num.Int64()] = head - } + latestHeadByHashMu.Lock() + defer latestHeadByHashMu.Unlock() + hash := args.Get(1).(gethCommon.Hash) + head := latestHeadByHash[hash] fnCall.ReturnArguments = mock.Arguments{head, nil} } for _, h := range headSeq.Heads { - latestHeadByNumberMu.Lock() - latestHeadByNumber[h.Number] = h - latestHeadByNumberMu.Unlock() + latestHeadByHashMu.Lock() + latestHeadByHash[h.Hash] = h + latestHeadByHashMu.Unlock() headers.TrySend(h) } @@ -665,26 +663,22 @@ func TestHeadTracker_SwitchesToLongestChainWithHeadSamplingDisabled(t *testing.T // This grotesque construction is the only way to do dynamic return values using // the mock package. We need dynamic returns because we're simulating reorgs. - latestHeadByNumber := make(map[int64]*evmtypes.Head) - latestHeadByNumberMu := new(sync.Mutex) + latestHeadByHash := make(map[gethCommon.Hash]*evmtypes.Head) + latestHeadByHashMu := new(sync.Mutex) - fnCall := ethClient.On("HeadByNumber", mock.Anything, mock.Anything) + fnCall := ethClient.On("HeadByHash", mock.Anything, mock.Anything).Maybe() fnCall.RunFn = func(args mock.Arguments) { - latestHeadByNumberMu.Lock() - defer latestHeadByNumberMu.Unlock() - num := args.Get(1).(*big.Int) - head, exists := latestHeadByNumber[num.Int64()] - if !exists { - head = cltest.Head(num.Int64()) - latestHeadByNumber[num.Int64()] = head - } + latestHeadByHashMu.Lock() + defer latestHeadByHashMu.Unlock() + hash := args.Get(1).(gethCommon.Hash) + head := latestHeadByHash[hash] fnCall.ReturnArguments = mock.Arguments{head, nil} } for _, h := range headSeq.Heads { - latestHeadByNumberMu.Lock() - latestHeadByNumber[h.Number] = h - latestHeadByNumberMu.Unlock() + latestHeadByHashMu.Lock() + latestHeadByHash[h.Hash] = h + latestHeadByHashMu.Unlock() headers.TrySend(h) time.Sleep(testutils.TestInterval) } @@ -803,7 +797,7 @@ func TestHeadTracker_Backfill(t *testing.T) { ethClient := evmtest.NewEthClientMock(t) ethClient.On("ConfiguredChainID", mock.Anything).Return(cfg.DefaultChainID(), nil) - ethClient.On("HeadByNumber", mock.Anything, big.NewInt(10)). + ethClient.On("HeadByHash", mock.Anything, head10.Hash). Return(&head10, nil) ht := createHeadTrackerWithNeverSleeper(t, ethClient, cfg, orm) @@ -842,9 +836,9 @@ func TestHeadTracker_Backfill(t *testing.T) { ht := createHeadTrackerWithNeverSleeper(t, ethClient, cfg, orm) - ethClient.On("HeadByNumber", mock.Anything, big.NewInt(10)). + ethClient.On("HeadByHash", mock.Anything, head10.Hash). Return(&head10, nil) - ethClient.On("HeadByNumber", mock.Anything, big.NewInt(8)). + ethClient.On("HeadByHash", mock.Anything, head8.Hash). Return(&head8, nil) // Needs to be 8 because there are 8 heads in chain (15,14,13,12,11,10,9,8) @@ -890,7 +884,7 @@ func TestHeadTracker_Backfill(t *testing.T) { ethClient := evmtest.NewEthClientMock(t) ethClient.On("ConfiguredChainID", mock.Anything).Return(cfg.DefaultChainID(), nil) - ethClient.On("HeadByNumber", mock.Anything, big.NewInt(0)). + ethClient.On("HeadByHash", mock.Anything, head0.Hash). Return(&head0, nil) require.NoError(t, orm.IdempotentInsertHead(testutils.Context(t), &h1)) @@ -918,10 +912,10 @@ func TestHeadTracker_Backfill(t *testing.T) { ethClient := evmtest.NewEthClientMock(t) ethClient.On("ConfiguredChainID", mock.Anything).Return(cfg.DefaultChainID(), nil) - ethClient.On("HeadByNumber", mock.Anything, big.NewInt(10)). + ethClient.On("HeadByHash", mock.Anything, head10.Hash). Return(&head10, nil). Once() - ethClient.On("HeadByNumber", mock.Anything, big.NewInt(8)). + ethClient.On("HeadByHash", mock.Anything, head8.Hash). Return(nil, ethereum.NotFound). Once() @@ -949,9 +943,9 @@ func TestHeadTracker_Backfill(t *testing.T) { ethClient := evmtest.NewEthClientMock(t) ethClient.On("ConfiguredChainID", mock.Anything).Return(cfg.DefaultChainID(), nil) - ethClient.On("HeadByNumber", mock.Anything, big.NewInt(10)). + ethClient.On("HeadByHash", mock.Anything, head10.Hash). Return(&head10, nil) - ethClient.On("HeadByNumber", mock.Anything, big.NewInt(8)). + ethClient.On("HeadByHash", mock.Anything, head8.Hash). Return(nil, context.DeadlineExceeded) ht := createHeadTrackerWithNeverSleeper(t, ethClient, cfg, orm) @@ -966,6 +960,31 @@ func TestHeadTracker_Backfill(t *testing.T) { assert.Equal(t, 4, int(h.ChainLength())) assert.Equal(t, int64(9), h.EarliestInChain().BlockNumber()) }) + + t.Run("abandons backfill and returns error when fetching a block by hash fails, indicating a reorg", func(t *testing.T) { + db := pgtest.NewSqlxDB(t) + cfg := configtest.NewGeneralConfig(t, nil) + logger := logger.TestLogger(t) + orm := headtracker.NewORM(db, logger, cfg.Database(), cltest.FixtureChainID) + ethClient := evmtest.NewEthClientMock(t) + ethClient.On("ConfiguredChainID", mock.Anything).Return(cfg.DefaultChainID(), nil) + ethClient.On("HeadByHash", mock.Anything, h14.Hash).Return(&h14, nil).Once() + ethClient.On("HeadByHash", mock.Anything, h13.Hash).Return(&h13, nil).Once() + ethClient.On("HeadByHash", mock.Anything, h12.Hash).Return(nil, errors.New("not found")).Once() + + ht := createHeadTrackerWithNeverSleeper(t, ethClient, cfg, orm) + + err := ht.Backfill(ctx, &h15, 400) + + require.Error(t, err) + require.EqualError(t, err, "fetchAndSaveHead failed: not found") + + h := ht.headSaver.Chain(h14.Hash) + + // Should contain 14, 13 (15 was never added). When trying to get the parent of h13 by hash, a reorg happened and backfill exited. + assert.Equal(t, 2, int(h.ChainLength())) + assert.Equal(t, int64(13), h.EarliestInChain().BlockNumber()) + }) } func createHeadTracker(t *testing.T, ethClient evmclient.Client, config headtracker.Config, htConfig headtracker.HeadTrackerConfig, orm headtracker.ORM) *headTrackerUniverse { diff --git a/core/chains/evm/log/helpers_test.go b/core/chains/evm/log/helpers_test.go index b094c2884da..e11c9faaf46 100644 --- a/core/chains/evm/log/helpers_test.go +++ b/core/chains/evm/log/helpers_test.go @@ -39,6 +39,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/job" "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/srvctest" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -112,7 +113,7 @@ func (c broadcasterHelperCfg) newWithEthClient(t *testing.T, ethClient evmclient lb := log.NewTestBroadcaster(orm, ethClient, config.EVM(), lggr, c.highestSeenHead, mailMon) kst := cltest.NewKeyStore(t, c.db, globalConfig.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{ + cc := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{ Client: ethClient, GeneralConfig: globalConfig, DB: c.db, @@ -120,8 +121,9 @@ func (c broadcasterHelperCfg) newWithEthClient(t *testing.T, ethClient evmclient LogBroadcaster: &log.NullBroadcaster{}, MailMon: mailMon, }) - - pipelineHelper := cltest.NewJobPipelineV2(t, config.WebServer(), config.JobPipeline(), config.Database(), cc, c.db, kst, nil, nil) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(cc) + require.NoError(t, err) + pipelineHelper := cltest.NewJobPipelineV2(t, config.WebServer(), config.JobPipeline(), config.Database(), legacyChains, c.db, kst, nil, nil) return &broadcasterHelper{ t: t, diff --git a/core/chains/evm/logpoller/disabled.go b/core/chains/evm/logpoller/disabled.go index 939cc98558d..80a5550b0a5 100644 --- a/core/chains/evm/logpoller/disabled.go +++ b/core/chains/evm/logpoller/disabled.go @@ -33,9 +33,9 @@ func (disabled) Replay(ctx context.Context, fromBlock int64) error { return ErrD func (disabled) ReplayAsync(fromBlock int64) {} -func (disabled) RegisterFilter(filter Filter) error { return ErrDisabled } +func (disabled) RegisterFilter(filter Filter, qopts ...pg.QOpt) error { return ErrDisabled } -func (disabled) UnregisterFilter(name string, q pg.Queryer) error { return ErrDisabled } +func (disabled) UnregisterFilter(name string, qopts ...pg.QOpt) error { return ErrDisabled } func (disabled) LatestBlock(qopts ...pg.QOpt) (int64, error) { return -1, ErrDisabled } @@ -95,6 +95,6 @@ func (d disabled) IndexedLogsCreatedAfter(eventSig common.Hash, address common.A return nil, ErrDisabled } -func (d disabled) LatestBlockByEventSigsAddrsWithConfs(eventSigs []common.Hash, addresses []common.Address, confs int, qopts ...pg.QOpt) (int64, error) { +func (d disabled) LatestBlockByEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs int, qopts ...pg.QOpt) (int64, error) { return 0, ErrDisabled } diff --git a/core/chains/evm/logpoller/log_poller.go b/core/chains/evm/logpoller/log_poller.go index 0146d1d5f52..60767970289 100644 --- a/core/chains/evm/logpoller/log_poller.go +++ b/core/chains/evm/logpoller/log_poller.go @@ -34,8 +34,8 @@ type LogPoller interface { services.ServiceCtx Replay(ctx context.Context, fromBlock int64) error ReplayAsync(fromBlock int64) - RegisterFilter(filter Filter) error - UnregisterFilter(name string, q pg.Queryer) error + RegisterFilter(filter Filter, qopts ...pg.QOpt) error + UnregisterFilter(name string, qopts ...pg.QOpt) error LatestBlock(qopts ...pg.QOpt) (int64, error) GetBlocksRange(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]LogPollerBlock, error) @@ -45,7 +45,7 @@ type LogPoller interface { LogsCreatedAfter(eventSig common.Hash, address common.Address, time time.Time, confs int, qopts ...pg.QOpt) ([]Log, error) LatestLogByEventSigWithConfs(eventSig common.Hash, address common.Address, confs int, qopts ...pg.QOpt) (*Log, error) LatestLogEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs int, qopts ...pg.QOpt) ([]Log, error) - LatestBlockByEventSigsAddrsWithConfs(eventSigs []common.Hash, addresses []common.Address, confs int, qopts ...pg.QOpt) (int64, error) + LatestBlockByEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs int, qopts ...pg.QOpt) (int64, error) // Content based querying IndexedLogs(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) @@ -200,7 +200,7 @@ func (filter *Filter) Contains(other *Filter) bool { // Generally speaking this is harmless. We enforce that EventSigs and Addresses are non-empty, // which means that anonymous events are not supported and log.Topics >= 1 always (log.Topics[0] is the event signature). // The filter may be unregistered later by Filter.Name -func (lp *logPoller) RegisterFilter(filter Filter) error { +func (lp *logPoller) RegisterFilter(filter Filter, qopts ...pg.QOpt) error { if len(filter.Addresses) == 0 { return errors.Errorf("at least one address must be specified") } @@ -232,7 +232,7 @@ func (lp *logPoller) RegisterFilter(filter Filter) error { lp.lggr.Debugw("Creating new filter", "filter", filter) } - if err := lp.orm.InsertFilter(filter); err != nil { + if err := lp.orm.InsertFilter(filter, qopts...); err != nil { return errors.Wrap(err, "RegisterFilter failed to save filter to db") } lp.filters[filter.Name] = filter @@ -240,7 +240,7 @@ func (lp *logPoller) RegisterFilter(filter Filter) error { return nil } -func (lp *logPoller) UnregisterFilter(name string, q pg.Queryer) error { +func (lp *logPoller) UnregisterFilter(name string, qopts ...pg.QOpt) error { lp.filterMu.Lock() defer lp.filterMu.Unlock() @@ -250,7 +250,7 @@ func (lp *logPoller) UnregisterFilter(name string, q pg.Queryer) error { return nil } - if err := lp.orm.DeleteFilter(name, pg.WithQueryer(q)); err != nil { + if err := lp.orm.DeleteFilter(name, qopts...); err != nil { return errors.Wrapf(err, "Failed to delete filter %s", name) } delete(lp.filters, name) @@ -994,8 +994,8 @@ func (lp *logPoller) LatestLogEventSigsAddrsWithConfs(fromBlock int64, eventSigs return lp.orm.SelectLatestLogEventSigsAddrsWithConfs(fromBlock, addresses, eventSigs, confs, qopts...) } -func (lp *logPoller) LatestBlockByEventSigsAddrsWithConfs(eventSigs []common.Hash, addresses []common.Address, confs int, qopts ...pg.QOpt) (int64, error) { - return lp.orm.SelectLatestBlockNumberEventSigsAddrsWithConfs(eventSigs, addresses, confs, qopts...) +func (lp *logPoller) LatestBlockByEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs int, qopts ...pg.QOpt) (int64, error) { + return lp.orm.SelectLatestBlockNumberEventSigsAddrsWithConfs(fromBlock, eventSigs, addresses, confs, qopts...) } // GetBlocksRange tries to get the specified block numbers from the log pollers diff --git a/core/chains/evm/logpoller/log_poller_internal_test.go b/core/chains/evm/logpoller/log_poller_internal_test.go index c1daf448afa..13ec0262391 100644 --- a/core/chains/evm/logpoller/log_poller_internal_test.go +++ b/core/chains/evm/logpoller/log_poller_internal_test.go @@ -11,14 +11,11 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/jackc/pgconn" "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" - "go.uber.org/zap/zaptest/observer" - "golang.org/x/exp/slices" evmclimocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" @@ -58,14 +55,13 @@ func TestLogPoller_RegisterFilter(t *testing.T) { db := pgtest.NewSqlxDB(t) orm := NewORM(chainID, db, lggr, pgtest.NewQConfig(true)) - lp := NewLogPoller(orm, nil, lggr, time.Hour, 1, 1, 2, 1000) db.Close() db = pgtest.NewSqlxDB(t) orm = NewORM(chainID, db, lggr, pgtest.NewQConfig(true)) // Set up a test chain with a log emitting contract deployed. - lp = NewLogPoller(orm, nil, lggr, time.Hour, 1, 1, 2, 1000) + lp := NewLogPoller(orm, nil, lggr, time.Hour, 1, 1, 2, 1000) // We expect a zero Filter if nothing registered yet. f := lp.Filter(nil, nil, nil) @@ -101,7 +97,7 @@ func TestLogPoller_RegisterFilter(t *testing.T) { validateFiltersTable(t, lp, orm) // Removing non-existence Filter should log error but return nil - err = lp.UnregisterFilter("Filter doesn't exist", nil) + err = lp.UnregisterFilter("Filter doesn't exist") require.NoError(t, err) require.Equal(t, observedLogs.Len(), 1) require.Contains(t, observedLogs.TakeAll()[0].Entry.Message, "not found") @@ -115,16 +111,16 @@ func TestLogPoller_RegisterFilter(t *testing.T) { require.True(t, ok, "'Emitter Log 1 + 2 dupe' Filter missing") // Removing an existing Filter should remove it from both memory and db - err = lp.UnregisterFilter("Emitter Log 1 + 2", nil) + err = lp.UnregisterFilter("Emitter Log 1 + 2") require.NoError(t, err) _, ok = lp.filters["Emitter Log 1 + 2"] require.False(t, ok, "'Emitter Log 1 Filter' should have been removed by UnregisterFilter()") require.Len(t, lp.filters, 2) validateFiltersTable(t, lp, orm) - err = lp.UnregisterFilter("Emitter Log 1 + 2 dupe", nil) + err = lp.UnregisterFilter("Emitter Log 1 + 2 dupe") require.NoError(t, err) - err = lp.UnregisterFilter("Emitter Log 1", nil) + err = lp.UnregisterFilter("Emitter Log 1") require.NoError(t, err) assert.Len(t, lp.filters, 0) filters, err := lp.orm.LoadFilters() @@ -138,26 +134,6 @@ func TestLogPoller_RegisterFilter(t *testing.T) { assert.Len(t, lp.Filter(nil, nil, nil).Topics[0], 0) } -func assertForeignConstraintError(t *testing.T, observedLog observer.LoggedEntry, - table string, constraint string) { - - assert.Equal(t, "SQL ERROR", observedLog.Entry.Message) - - i := slices.IndexFunc(observedLog.Context, func(f zapcore.Field) bool { - return f.Key == "err" - }) - require.GreaterOrEqual(t, i, 0) - field := observedLog.Context[i] - require.Equal(t, zapcore.ErrorType, field.Type) - err, ok := field.Interface.(error) - var pgErr *pgconn.PgError - require.True(t, errors.As(err, &pgErr)) - require.True(t, ok) - assert.Equal(t, "23503", pgErr.SQLState()) // foreign key constraint violation code - assert.Equal(t, table, pgErr.TableName) - assert.Equal(t, constraint, pgErr.ConstraintName) -} - func TestLogPoller_ConvertLogs(t *testing.T) { t.Parallel() lggr := logger.TestLogger(t) diff --git a/core/chains/evm/logpoller/log_poller_test.go b/core/chains/evm/logpoller/log_poller_test.go index e639e1cbf71..17df4dc6291 100644 --- a/core/chains/evm/logpoller/log_poller_test.go +++ b/core/chains/evm/logpoller/log_poller_test.go @@ -223,10 +223,10 @@ func Test_BackupLogPoller(t *testing.T) { require.NoError(t, err) defer func() { - assert.NoError(t, th.LogPoller.UnregisterFilter("filter1", nil)) + assert.NoError(t, th.LogPoller.UnregisterFilter("filter1")) }() defer func() { - assert.NoError(t, th.LogPoller.UnregisterFilter("filter2", nil)) + assert.NoError(t, th.LogPoller.UnregisterFilter("filter2")) }() // generate some tx's with logs @@ -1098,8 +1098,6 @@ func TestTooManyLogResults(t *testing.T) { return []types.Log{}, nil // succeed when single block requested } return []types.Log{}, &clientErr // return "too many results" error if block range spans 4 or more blocks - - return logs, err }) lp.PollAndSaveLogs(ctx, 298) diff --git a/core/chains/evm/logpoller/mocks/log_poller.go b/core/chains/evm/logpoller/mocks/log_poller.go index 17e20529b3d..9e96947abc7 100644 --- a/core/chains/evm/logpoller/mocks/log_poller.go +++ b/core/chains/evm/logpoller/mocks/log_poller.go @@ -312,30 +312,30 @@ func (_m *LogPoller) LatestBlock(qopts ...pg.QOpt) (int64, error) { return r0, r1 } -// LatestBlockByEventSigsAddrsWithConfs provides a mock function with given fields: eventSigs, addresses, confs, qopts -func (_m *LogPoller) LatestBlockByEventSigsAddrsWithConfs(eventSigs []common.Hash, addresses []common.Address, confs int, qopts ...pg.QOpt) (int64, error) { +// LatestBlockByEventSigsAddrsWithConfs provides a mock function with given fields: fromBlock, eventSigs, addresses, confs, qopts +func (_m *LogPoller) LatestBlockByEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs int, qopts ...pg.QOpt) (int64, error) { _va := make([]interface{}, len(qopts)) for _i := range qopts { _va[_i] = qopts[_i] } var _ca []interface{} - _ca = append(_ca, eventSigs, addresses, confs) + _ca = append(_ca, fromBlock, eventSigs, addresses, confs) _ca = append(_ca, _va...) ret := _m.Called(_ca...) var r0 int64 var r1 error - if rf, ok := ret.Get(0).(func([]common.Hash, []common.Address, int, ...pg.QOpt) (int64, error)); ok { - return rf(eventSigs, addresses, confs, qopts...) + if rf, ok := ret.Get(0).(func(int64, []common.Hash, []common.Address, int, ...pg.QOpt) (int64, error)); ok { + return rf(fromBlock, eventSigs, addresses, confs, qopts...) } - if rf, ok := ret.Get(0).(func([]common.Hash, []common.Address, int, ...pg.QOpt) int64); ok { - r0 = rf(eventSigs, addresses, confs, qopts...) + if rf, ok := ret.Get(0).(func(int64, []common.Hash, []common.Address, int, ...pg.QOpt) int64); ok { + r0 = rf(fromBlock, eventSigs, addresses, confs, qopts...) } else { r0 = ret.Get(0).(int64) } - if rf, ok := ret.Get(1).(func([]common.Hash, []common.Address, int, ...pg.QOpt) error); ok { - r1 = rf(eventSigs, addresses, confs, qopts...) + if rf, ok := ret.Get(1).(func(int64, []common.Hash, []common.Address, int, ...pg.QOpt) error); ok { + r1 = rf(fromBlock, eventSigs, addresses, confs, qopts...) } else { r1 = ret.Error(1) } @@ -602,13 +602,20 @@ func (_m *LogPoller) Ready() error { return r0 } -// RegisterFilter provides a mock function with given fields: filter -func (_m *LogPoller) RegisterFilter(filter logpoller.Filter) error { - ret := _m.Called(filter) +// RegisterFilter provides a mock function with given fields: filter, qopts +func (_m *LogPoller) RegisterFilter(filter logpoller.Filter, qopts ...pg.QOpt) error { + _va := make([]interface{}, len(qopts)) + for _i := range qopts { + _va[_i] = qopts[_i] + } + var _ca []interface{} + _ca = append(_ca, filter) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) var r0 error - if rf, ok := ret.Get(0).(func(logpoller.Filter) error); ok { - r0 = rf(filter) + if rf, ok := ret.Get(0).(func(logpoller.Filter, ...pg.QOpt) error); ok { + r0 = rf(filter, qopts...) } else { r0 = ret.Error(0) } @@ -649,13 +656,20 @@ func (_m *LogPoller) Start(_a0 context.Context) error { return r0 } -// UnregisterFilter provides a mock function with given fields: name, q -func (_m *LogPoller) UnregisterFilter(name string, q pg.Queryer) error { - ret := _m.Called(name, q) +// UnregisterFilter provides a mock function with given fields: name, qopts +func (_m *LogPoller) UnregisterFilter(name string, qopts ...pg.QOpt) error { + _va := make([]interface{}, len(qopts)) + for _i := range qopts { + _va[_i] = qopts[_i] + } + var _ca []interface{} + _ca = append(_ca, name) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) var r0 error - if rf, ok := ret.Get(0).(func(string, pg.Queryer) error); ok { - r0 = rf(name, q) + if rf, ok := ret.Get(0).(func(string, ...pg.QOpt) error); ok { + r0 = rf(name, qopts...) } else { r0 = ret.Error(0) } diff --git a/core/chains/evm/logpoller/observability.go b/core/chains/evm/logpoller/observability.go index 7a04a005af2..f52d2878597 100644 --- a/core/chains/evm/logpoller/observability.go +++ b/core/chains/evm/logpoller/observability.go @@ -86,9 +86,9 @@ func (o *ObservedLogPoller) LatestLogEventSigsAddrsWithConfs(fromBlock int64, ev }) } -func (o *ObservedLogPoller) LatestBlockByEventSigsAddrsWithConfs(eventSigs []common.Hash, addresses []common.Address, confs int, qopts ...pg.QOpt) (int64, error) { +func (o *ObservedLogPoller) LatestBlockByEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs int, qopts ...pg.QOpt) (int64, error) { return withObservedQuery(o, "LatestBlockByEventSigsAddrsWithConfs", func() (int64, error) { - return o.LogPoller.LatestBlockByEventSigsAddrsWithConfs(eventSigs, addresses, confs, qopts...) + return o.LogPoller.LatestBlockByEventSigsAddrsWithConfs(fromBlock, eventSigs, addresses, confs, qopts...) }) } diff --git a/core/chains/evm/logpoller/orm.go b/core/chains/evm/logpoller/orm.go index ce8ce9edb95..e8ced08a1e7 100644 --- a/core/chains/evm/logpoller/orm.go +++ b/core/chains/evm/logpoller/orm.go @@ -308,7 +308,7 @@ func (o *ORM) SelectLatestLogEventSigsAddrsWithConfs(fromBlock int64, addresses event_sig = ANY($2) AND address = ANY($3) AND block_number > $4 AND - (block_number + $5) <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) + block_number <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $5 GROUP BY event_sig, address ) ORDER BY block_number ASC @@ -320,7 +320,7 @@ func (o *ORM) SelectLatestLogEventSigsAddrsWithConfs(fromBlock int64, addresses } // SelectLatestBlockNumberEventSigsAddrsWithConfs finds the latest block number that matches a list of Addresses and list of events. It returns 0 if there is no matching block -func (o *ORM) SelectLatestBlockNumberEventSigsAddrsWithConfs(eventSigs []common.Hash, addresses []common.Address, confs int, qopts ...pg.QOpt) (int64, error) { +func (o *ORM) SelectLatestBlockNumberEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs int, qopts ...pg.QOpt) (int64, error) { var blockNumber int64 sigs := concatBytes(eventSigs) addrs := concatBytes(addresses) @@ -331,8 +331,9 @@ func (o *ORM) SelectLatestBlockNumberEventSigsAddrsWithConfs(eventSigs []common. WHERE evm_chain_id = $1 AND event_sig = ANY($2) AND address = ANY($3) AND - (block_number + $4) <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1)`, - o.chainID.Int64(), sigs, addrs, confs) + block_number > $4 AND + block_number <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $5`, + o.chainID.Int64(), sigs, addrs, fromBlock, confs) if err != nil { return 0, err } @@ -348,7 +349,7 @@ func (o *ORM) SelectDataWordRange(address common.Address, eventSig common.Hash, AND address = $2 AND event_sig = $3 AND substring(data from 32*$4+1 for 32) >= $5 AND substring(data from 32*$4+1 for 32) <= $6 - AND (block_number + $7) <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) + AND block_number <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $7 ORDER BY (evm_logs.block_number, evm_logs.log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), wordIndex, wordValueMin.Bytes(), wordValueMax.Bytes(), confs) if err != nil { return nil, err @@ -364,7 +365,7 @@ func (o *ORM) SelectDataWordGreaterThan(address common.Address, eventSig common. WHERE evm_logs.evm_chain_id = $1 AND address = $2 AND event_sig = $3 AND substring(data from 32*$4+1 for 32) >= $5 - AND (block_number + $6) <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) + AND block_number <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $6 ORDER BY (evm_logs.block_number, evm_logs.log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), wordIndex, wordValueMin.Bytes(), confs) if err != nil { return nil, err @@ -384,7 +385,7 @@ func (o *ORM) SelectIndexLogsTopicGreaterThan(address common.Address, eventSig c WHERE evm_logs.evm_chain_id = $1 AND address = $2 AND event_sig = $3 AND topics[$4] >= $5 - AND (block_number + $6) <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) + AND block_number <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $6 ORDER BY (evm_logs.block_number, evm_logs.log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), topicIndex+1, topicValueMin.Bytes(), confs) if err != nil { return nil, err @@ -405,7 +406,7 @@ func (o *ORM) SelectIndexLogsTopicRange(address common.Address, eventSig common. AND address = $2 AND event_sig = $3 AND topics[$4] >= $5 AND topics[$4] <= $6 - AND (block_number + $7) <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) + AND block_number <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $7 ORDER BY (evm_logs.block_number, evm_logs.log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), topicIndex+1, topicValueMin.Bytes(), topicValueMax.Bytes(), confs) if err != nil { return nil, err @@ -427,7 +428,7 @@ func (o *ORM) SelectIndexedLogs(address common.Address, eventSig common.Hash, to WHERE evm_logs.evm_chain_id = $1 AND address = $2 AND event_sig = $3 AND topics[$4] = ANY($5) - AND (block_number + $6) <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) + AND block_number <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $6 ORDER BY (evm_logs.block_number, evm_logs.log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), topicIndex+1, topicValuesBytes, confs) if err != nil { return nil, err @@ -475,7 +476,7 @@ func (o *ORM) SelectIndexedLogsCreatedAfter(address common.Address, eventSig com AND address = $2 AND event_sig = $3 AND topics[$4] = ANY($5) AND created_at > $6 - AND (block_number + $7) <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) + AND block_number <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $7 ORDER BY created_at ASC`, utils.NewBig(o.chainID), address, eventSig.Bytes(), topicIndex+1, topicValuesBytes, after, confs) if err != nil { return nil, err @@ -499,7 +500,7 @@ func (o *ORM) SelectIndexedLogsWithSigsExcluding(sigA, sigB common.Hash, topicIn AND address = $2 AND event_sig = $3 AND block_number BETWEEN $6 AND $7 - AND (block_number + $8) <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) + AND block_number <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $8 EXCEPT @@ -512,7 +513,7 @@ func (o *ORM) SelectIndexedLogsWithSigsExcluding(sigA, sigB common.Hash, topicIn AND a.event_sig = $3 AND b.event_sig = $4 AND b.block_number BETWEEN $6 AND $7 - AND (b.block_number + $8) <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) + AND b.block_number <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $8 ORDER BY block_number,log_index ASC `, utils.NewBig(o.chainID), address, sigA.Bytes(), sigB.Bytes(), topicIndex+1, startBlock, endBlock, confs) diff --git a/core/chains/evm/logpoller/orm_test.go b/core/chains/evm/logpoller/orm_test.go index cab43f7991b..73128c311d8 100644 --- a/core/chains/evm/logpoller/orm_test.go +++ b/core/chains/evm/logpoller/orm_test.go @@ -1022,6 +1022,7 @@ func TestSelectLatestBlockNumberEventSigsAddrsWithConfs(t *testing.T) { events []common.Hash addrs []common.Address confs int + fromBlock int64 expectedBlockNumber int64 }{ { @@ -1029,6 +1030,7 @@ func TestSelectLatestBlockNumberEventSigsAddrsWithConfs(t *testing.T) { events: []common.Hash{event2}, addrs: []common.Address{address1}, confs: 0, + fromBlock: 0, expectedBlockNumber: 0, }, { @@ -1036,6 +1038,7 @@ func TestSelectLatestBlockNumberEventSigsAddrsWithConfs(t *testing.T) { events: []common.Hash{event2}, addrs: []common.Address{address2}, confs: 5, + fromBlock: 0, expectedBlockNumber: 0, }, { @@ -1043,6 +1046,7 @@ func TestSelectLatestBlockNumberEventSigsAddrsWithConfs(t *testing.T) { events: []common.Hash{event1}, addrs: []common.Address{address1}, confs: 0, + fromBlock: 0, expectedBlockNumber: 1, }, { @@ -1050,6 +1054,7 @@ func TestSelectLatestBlockNumberEventSigsAddrsWithConfs(t *testing.T) { events: []common.Hash{event1, event2}, addrs: []common.Address{address1, address2}, confs: 0, + fromBlock: 0, expectedBlockNumber: 3, }, { @@ -1057,12 +1062,29 @@ func TestSelectLatestBlockNumberEventSigsAddrsWithConfs(t *testing.T) { events: []common.Hash{event2}, addrs: []common.Address{address2}, confs: 1, + fromBlock: 0, expectedBlockNumber: 2, }, + { + name: "returns 0 if from block is not matching", + events: []common.Hash{event1, event2}, + addrs: []common.Address{address1, address2}, + confs: 0, + fromBlock: 3, + expectedBlockNumber: 0, + }, + { + name: "picks max block from two events when from block is lower", + events: []common.Hash{event1, event2}, + addrs: []common.Address{address1, address2}, + confs: 0, + fromBlock: 2, + expectedBlockNumber: 3, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - blockNumber, err := th.ORM.SelectLatestBlockNumberEventSigsAddrsWithConfs(tt.events, tt.addrs, tt.confs) + blockNumber, err := th.ORM.SelectLatestBlockNumberEventSigsAddrsWithConfs(tt.fromBlock, tt.events, tt.addrs, tt.confs) require.NoError(t, err) assert.Equal(t, tt.expectedBlockNumber, blockNumber) }) diff --git a/core/chains/evm/mocks/legacy_chain_container.go b/core/chains/evm/mocks/legacy_chain_container.go new file mode 100644 index 00000000000..fe906234f16 --- /dev/null +++ b/core/chains/evm/mocks/legacy_chain_container.go @@ -0,0 +1,165 @@ +// Code generated by mockery v2.28.1. DO NOT EDIT. + +package mocks + +import ( + evm "github.com/smartcontractkit/chainlink/v2/core/chains/evm" + mock "github.com/stretchr/testify/mock" + + types "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" +) + +// LegacyChainContainer is an autogenerated mock type for the LegacyChainContainer type +type LegacyChainContainer struct { + mock.Mock +} + +// ChainNodeConfigs provides a mock function with given fields: +func (_m *LegacyChainContainer) ChainNodeConfigs() types.Configs { + ret := _m.Called() + + var r0 types.Configs + if rf, ok := ret.Get(0).(func() types.Configs); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(types.Configs) + } + } + + return r0 +} + +// Default provides a mock function with given fields: +func (_m *LegacyChainContainer) Default() (evm.Chain, error) { + ret := _m.Called() + + var r0 evm.Chain + var r1 error + if rf, ok := ret.Get(0).(func() (evm.Chain, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() evm.Chain); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(evm.Chain) + } + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Get provides a mock function with given fields: id +func (_m *LegacyChainContainer) Get(id string) (evm.Chain, error) { + ret := _m.Called(id) + + var r0 evm.Chain + var r1 error + if rf, ok := ret.Get(0).(func(string) (evm.Chain, error)); ok { + return rf(id) + } + if rf, ok := ret.Get(0).(func(string) evm.Chain); ok { + r0 = rf(id) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(evm.Chain) + } + } + + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(id) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Len provides a mock function with given fields: +func (_m *LegacyChainContainer) Len() int { + ret := _m.Called() + + var r0 int + if rf, ok := ret.Get(0).(func() int); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(int) + } + + return r0 +} + +// List provides a mock function with given fields: ids +func (_m *LegacyChainContainer) List(ids ...string) ([]evm.Chain, error) { + _va := make([]interface{}, len(ids)) + for _i := range ids { + _va[_i] = ids[_i] + } + var _ca []interface{} + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 []evm.Chain + var r1 error + if rf, ok := ret.Get(0).(func(...string) ([]evm.Chain, error)); ok { + return rf(ids...) + } + if rf, ok := ret.Get(0).(func(...string) []evm.Chain); ok { + r0 = rf(ids...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]evm.Chain) + } + } + + if rf, ok := ret.Get(1).(func(...string) error); ok { + r1 = rf(ids...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SetDefault provides a mock function with given fields: _a0 +func (_m *LegacyChainContainer) SetDefault(_a0 evm.Chain) { + _m.Called(_a0) +} + +// Slice provides a mock function with given fields: +func (_m *LegacyChainContainer) Slice() []evm.Chain { + ret := _m.Called() + + var r0 []evm.Chain + if rf, ok := ret.Get(0).(func() []evm.Chain); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]evm.Chain) + } + } + + return r0 +} + +type mockConstructorTestingTNewLegacyChainContainer interface { + mock.TestingT + Cleanup(func()) +} + +// NewLegacyChainContainer creates a new instance of LegacyChainContainer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewLegacyChainContainer(t mockConstructorTestingTNewLegacyChainContainer) *LegacyChainContainer { + mock := &LegacyChainContainer{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/chains/evm/txmgr/broadcaster_test.go b/core/chains/evm/txmgr/broadcaster_test.go index b36d2e486e0..2e3a1e0f731 100644 --- a/core/chains/evm/txmgr/broadcaster_test.go +++ b/core/chains/evm/txmgr/broadcaster_test.go @@ -1486,7 +1486,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { // Do the thing retryable, err := eb2.ProcessUnstartedTxs(testutils.Context(t), fromAddress) require.Error(t, err) - require.Contains(t, err.Error(), "bumped gas price of 20 gwei is equal to original gas price of 20 gwei. ACTION REQUIRED: This is a configuration error, you must increase either EVM.GasEstimator.BumpPercent or EVM.GasEstimator.BumpMin") + require.Contains(t, err.Error(), "bumped fee price of 20 gwei is equal to original fee price of 20 gwei. ACTION REQUIRED: This is a configuration error, you must increase either FeeEstimator.BumpPercent or FeeEstimator.BumpMin") assert.True(t, retryable) // TEARDOWN: Clear out the unsent tx before the next test @@ -1870,13 +1870,6 @@ func TestEthBroadcaster_SyncNonce(t *testing.T) { } -func checkerToJson(t *testing.T, checker txmgr.TransmitCheckerSpec) *datatypes.JSON { - b, err := json.Marshal(checker) - require.NoError(t, err) - j := datatypes.JSON(b) - return &j -} - type testCheckerFactory struct { err error } diff --git a/core/chains/evm/txmgr/confirmer_test.go b/core/chains/evm/txmgr/confirmer_test.go index 3bdaf7e206e..3de0c1079bf 100644 --- a/core/chains/evm/txmgr/confirmer_test.go +++ b/core/chains/evm/txmgr/confirmer_test.go @@ -21,6 +21,7 @@ import ( "github.com/stretchr/testify/require" clienttypes "github.com/smartcontractkit/chainlink/v2/common/chains/client" + commonfee "github.com/smartcontractkit/chainlink/v2/common/fee" txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" txmgrtypes "github.com/smartcontractkit/chainlink/v2/common/txmgr/types" "github.com/smartcontractkit/chainlink/v2/core/assets" @@ -1642,7 +1643,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing kst := ksmocks.NewEth(t) estimator := gasmocks.NewEvmEstimator(t) - estimator.On("BumpLegacyGas", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, uint32(0), pkgerrors.Wrapf(gas.ErrConnectivity, "transaction...")) + estimator.On("BumpLegacyGas", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, uint32(0), pkgerrors.Wrapf(commonfee.ErrConnectivity, "transaction...")) ge := ccfg.EVM().GasEstimator() feeEstimator := gas.NewWrappedEvmEstimator(estimator, ge.EIP1559DynamicFees()) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, kst, feeEstimator) @@ -1686,7 +1687,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing kst := ksmocks.NewEth(t) estimator := gasmocks.NewEvmEstimator(t) - estimator.On("BumpDynamicFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.DynamicFee{}, uint32(0), pkgerrors.Wrapf(gas.ErrConnectivity, "transaction...")) + estimator.On("BumpDynamicFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.DynamicFee{}, uint32(0), pkgerrors.Wrapf(commonfee.ErrConnectivity, "transaction...")) // Create confirmer with necessary state ge := ccfg.EVM().GasEstimator() feeEstimator := gas.NewWrappedEvmEstimator(estimator, ge.EIP1559DynamicFees()) diff --git a/core/chains/evm/txmgr/resender_test.go b/core/chains/evm/txmgr/resender_test.go index 32523ab5c26..60b6bcdce20 100644 --- a/core/chains/evm/txmgr/resender_test.go +++ b/core/chains/evm/txmgr/resender_test.go @@ -67,10 +67,10 @@ func Test_EthResender_resendUnconfirmed(t *testing.T) { er := txmgr.NewEvmResender(lggr, txStore, txmgr.NewEvmTxmClient(ethClient), ethKeyStore, 100*time.Millisecond, ccfg.EVM(), ccfg.EVM().Transactions()) + var resentHex = make(map[string]struct{}) ethClient.On("BatchCallContextAll", mock.Anything, mock.MatchedBy(func(elems []rpc.BatchElem) bool { - resentHex := make([]string, len(elems)) - for i, elem := range elems { - resentHex[i] = elem.Args[0].(string) + for _, elem := range elems { + resentHex[elem.Args[0].(string)] = struct{}{} } assert.Len(t, elems, len(addr1TxesRawHex)+len(addr2TxesRawHex)+int(txConfig.MaxInFlight())) // All addr1TxesRawHex should be included @@ -78,12 +78,12 @@ func Test_EthResender_resendUnconfirmed(t *testing.T) { assert.Contains(t, resentHex, addr) } // All addr2TxesRawHex should be included - for _, addr := range addr1TxesRawHex { + for _, addr := range addr2TxesRawHex { assert.Contains(t, resentHex, addr) } // Up to limit EvmMaxInFlightTransactions addr3TxesRawHex should be included - for i, addr := range addr1TxesRawHex { - if i > int(txConfig.MaxInFlight()) { + for i, addr := range addr3TxesRawHex { + if i >= int(txConfig.MaxInFlight()) { // Above limit EvmMaxInFlightTransactions addr3TxesRawHex should NOT be included assert.NotContains(t, resentHex, addr) } else { diff --git a/core/chains/evm/txmgr/txmgr_test.go b/core/chains/evm/txmgr/txmgr_test.go index 99138e3c1e8..d127304c408 100644 --- a/core/chains/evm/txmgr/txmgr_test.go +++ b/core/chains/evm/txmgr/txmgr_test.go @@ -248,6 +248,7 @@ func TestTxm_CreateTransaction(t *testing.T) { pgtest.MustExec(t, db, `DELETE FROM eth_txes`) testDefaultSubID := uint64(2) testDefaultMaxLink := "1000000000000000000" + testDefaultMaxEth := "2000000000000000000" // max uint256 is 1.1579209e+77 testDefaultGlobalSubID := crypto.Keccak256Hash([]byte("sub id")).String() jobID := int32(25) @@ -258,6 +259,7 @@ func TestTxm_CreateTransaction(t *testing.T) { RequestID: &requestID, RequestTxHash: &requestTxHash, MaxLink: &testDefaultMaxLink, // 1e18 + MaxEth: &testDefaultMaxEth, // 2e18 SubID: &testDefaultSubID, GlobalSubID: &testDefaultGlobalSubID, } @@ -428,7 +430,7 @@ type transactionsConfig struct { e *evmConfig } -func (_ *transactionsConfig) ForwardersEnabled() bool { return true } +func (*transactionsConfig) ForwardersEnabled() bool { return true } func (t *transactionsConfig) MaxInFlight() uint32 { return t.e.maxInFlight } func (t *transactionsConfig) MaxQueued() uint64 { return t.e.maxQueued } func (t *transactionsConfig) ReaperInterval() time.Duration { return t.e.reaperInterval } diff --git a/core/chains/evm/types/types_test.go b/core/chains/evm/types/types_test.go index 09a6d553a79..f285849ce92 100644 --- a/core/chains/evm/types/types_test.go +++ b/core/chains/evm/types/types_test.go @@ -228,8 +228,10 @@ func Test_AddressArrayScan(t *testing.T) { require.NoError(t, err) require.Len(t, addr1, 20) addr2, err := hex.DecodeString("56b9a2dc53736b361b72d900cdf9f78f9406fbbb") + require.NoError(t, err) require.Len(t, addr2, 20) toolong, err := hex.DecodeString("6b361b72d900cdf9f78f9406fbbb6b361b72d900cdf9f78f9406fbbb") + require.NoError(t, err) require.Len(t, toolong, 28) a := types.AddressArray{} @@ -244,8 +246,10 @@ func Test_HashArrayScan(t *testing.T) { require.NoError(t, err) require.Len(t, h1, 32) h2, err := hex.DecodeString("56b9a2dc53736b361b72d900cdf9f78f9406fbbb06fbbb6b361b7206fbbb6b36") + require.NoError(t, err) require.Len(t, h2, 32) tooshort, err := hex.DecodeString("6b361b72d900cdf9f78f9406fbbb6b361b72d900cdf9f78f9406fbbb") + require.NoError(t, err) require.Len(t, tooshort, 28) h := types.HashArray{} diff --git a/core/chains/solana/config.go b/core/chains/solana/config.go index 49f0ee4a1c3..e654a9029b1 100644 --- a/core/chains/solana/config.go +++ b/core/chains/solana/config.go @@ -113,7 +113,7 @@ func (cs SolanaConfigs) Node(name string) (soldb.Node, error) { } } } - return soldb.Node{}, chains.ErrNotFound + return soldb.Node{}, fmt.Errorf("node %s: %w", name, chains.ErrNotFound) } func (cs SolanaConfigs) nodes(chainID string) (ns SolanaNodes) { @@ -128,7 +128,7 @@ func (cs SolanaConfigs) nodes(chainID string) (ns SolanaNodes) { func (cs SolanaConfigs) Nodes(chainID string) (ns []soldb.Node, err error) { nodes := cs.nodes(chainID) if nodes == nil { - err = chains.ErrNotFound + err = fmt.Errorf("no nodes: chain %s: %w", chainID, chains.ErrNotFound) return } for _, n := range nodes { @@ -148,7 +148,7 @@ func (cs SolanaConfigs) NodeStatus(name string) (types.NodeStatus, error) { } } } - return types.NodeStatus{}, chains.ErrNotFound + return types.NodeStatus{}, fmt.Errorf("node %s: %w", name, chains.ErrNotFound) } func (cs SolanaConfigs) NodeStatuses(chainIDs ...string) (ns []types.NodeStatus, err error) { diff --git a/core/chains/starknet/config.go b/core/chains/starknet/config.go index 1c306e7b342..c555028c6fb 100644 --- a/core/chains/starknet/config.go +++ b/core/chains/starknet/config.go @@ -112,7 +112,7 @@ func (cs StarknetConfigs) Node(name string) (n db.Node, err error) { } } } - err = chains.ErrNotFound + err = fmt.Errorf("node %s: %w", name, chains.ErrNotFound) return } @@ -128,7 +128,7 @@ func (cs StarknetConfigs) nodes(chainID string) (ns StarknetNodes) { func (cs StarknetConfigs) Nodes(chainID string) (ns []db.Node, err error) { nodes := cs.nodes(chainID) if nodes == nil { - err = chains.ErrNotFound + err = fmt.Errorf("no nodes: chain %s: %w", chainID, chains.ErrNotFound) return } for _, n := range nodes { @@ -148,7 +148,7 @@ func (cs StarknetConfigs) NodeStatus(name string) (n types.NodeStatus, err error } } } - err = chains.ErrNotFound + err = fmt.Errorf("node %s: %w", name, chains.ErrNotFound) return } diff --git a/core/cmd/cosmos_transaction_commands.go b/core/cmd/cosmos_transaction_commands.go index 2f8f7d8df89..7c53d1ff1da 100644 --- a/core/cmd/cosmos_transaction_commands.go +++ b/core/cmd/cosmos_transaction_commands.go @@ -21,8 +21,8 @@ func initCosmosTxSubCmd(s *Shell) cli.Command { Subcommands: []cli.Command{ { Name: "create", - Usage: "Send Atom from node Cosmos account to destination .", - Action: s.CosmosSendAtom, + Usage: "Send of from node Cosmos account to destination .", + Action: s.CosmosSendNativeToken, Flags: []cli.Flag{ cli.BoolFlag{ Name: "force", @@ -61,18 +61,24 @@ func (p *CosmosMsgPresenter) RenderTable(rt RendererTable) error { return nil } -// CosmosSendAtom transfers coins from the node's account to a specified address. -func (s *Shell) CosmosSendAtom(c *cli.Context) (err error) { +// CosmosSendNativeToken transfers coins from the node's account to a specified address. +func (s *Shell) CosmosSendNativeToken(c *cli.Context) (err error) { if c.NArg() < 3 { - return s.errorOut(errors.New("three arguments expected: amount, fromAddress and toAddress")) + return s.errorOut(errors.New("four arguments expected: token, amount, fromAddress and toAddress")) } - amount, err := sdk.NewDecFromStr(c.Args().Get(0)) + err = sdk.ValidateDenom(c.Args().Get(0)) if err != nil { - return s.errorOut(fmt.Errorf("invalid coin: %w", err)) + return s.errorOut(fmt.Errorf("invalid native token: %w", err)) } - unparsedFromAddress := c.Args().Get(1) + amount, err := sdk.NewDecFromStr(c.Args().Get(1)) + if err != nil { + return s.errorOut(multierr.Combine( + fmt.Errorf("invalid coin: %w", err))) + } + + unparsedFromAddress := c.Args().Get(2) fromAddress, err := sdk.AccAddressFromBech32(unparsedFromAddress) if err != nil { return s.errorOut(multierr.Combine( @@ -80,7 +86,7 @@ func (s *Shell) CosmosSendAtom(c *cli.Context) (err error) { unparsedFromAddress), err)) } - unparsedDestinationAddress := c.Args().Get(2) + unparsedDestinationAddress := c.Args().Get(3) destinationAddress, err := sdk.AccAddressFromBech32(unparsedDestinationAddress) if err != nil { return s.errorOut(multierr.Combine( @@ -98,6 +104,7 @@ func (s *Shell) CosmosSendAtom(c *cli.Context) (err error) { FromAddress: fromAddress, Amount: amount, CosmosChainID: chainID, + Token: c.Args().Get(0), AllowHigherAmounts: c.IsSet("force"), } diff --git a/core/cmd/cosmos_transaction_commands_test.go b/core/cmd/cosmos_transaction_commands_test.go index f95f2bdf40a..11b89c5232a 100644 --- a/core/cmd/cosmos_transaction_commands_test.go +++ b/core/cmd/cosmos_transaction_commands_test.go @@ -1,9 +1,10 @@ -//go:build integration && wasmd +//go:build integration package cmd_test import ( "flag" + "os" "strconv" "testing" "time" @@ -14,9 +15,13 @@ import ( "github.com/urfave/cli" cosmosclient "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/client" + coscfg "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/config" cosmosdb "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/db" "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/denom" + "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/params" + "github.com/smartcontractkit/chainlink-relay/pkg/utils" + "github.com/smartcontractkit/chainlink/v2/core/chains/cosmos" "github.com/smartcontractkit/chainlink/v2/core/chains/cosmos/cosmostxm" "github.com/smartcontractkit/chainlink/v2/core/cmd" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" @@ -27,25 +32,46 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/cosmoskey" ) +var nativeToken = "cosm" + +func TestMain(m *testing.M) { + + params.InitCosmosSdk( + /* bech32Prefix= */ "wasm", + /* token= */ nativeToken, + ) + + code := m.Run() + os.Exit(code) +} + func TestShell_SendCosmosCoins(t *testing.T) { // TODO(BCI-978): cleanup once SetupLocalCosmosNode is updated chainID := cosmostest.RandomChainID() - accounts, _, _ := cosmosclient.SetupLocalCosmosNode(t, chainID) + cosmosChain := coscfg.Chain{} + cosmosChain.SetDefaults() + accounts, _, url := cosmosclient.SetupLocalCosmosNode(t, chainID, *cosmosChain.FeeToken) require.Greater(t, len(accounts), 1) - app := cosmosStartNewApplication(t) + nodes := cosmos.CosmosNodes{ + &coscfg.Node{ + Name: ptr("random"), + TendermintURL: utils.MustParseURL(url), + }, + } + chainConfig := cosmos.CosmosConfig{ChainID: &chainID, Enabled: ptr(true), Chain: cosmosChain, Nodes: nodes} + app := cosmosStartNewApplication(t, &chainConfig) from := accounts[0] to := accounts[1] require.NoError(t, app.GetKeyStore().Cosmos().Add(cosmoskey.Raw(from.PrivateKey.Bytes()).Key())) - - chain, err := app.GetChains().Cosmos.Chain(testutils.Context(t), chainID) + chain, err := app.GetRelayers().LegacyCosmosChains().Get(chainID) require.NoError(t, err) reader, err := chain.Reader("") require.NoError(t, err) require.Eventually(t, func() bool { - coin, err := reader.Balance(from.Address, "uatom") + coin, err := reader.Balance(from.Address, *cosmosChain.FeeToken) if !assert.NoError(t, err) { return false } @@ -67,21 +93,21 @@ func TestShell_SendCosmosCoins(t *testing.T) { {amount: "30.000001"}, {amount: "1000", expErr: "is too low for this transaction to be executed:"}, {amount: "0", expErr: "amount must be greater than zero:"}, - {amount: "asdf", expErr: "invalid coin: failed to set decimal string:"}, + {amount: "asdf", expErr: "invalid coin: failed to set decimal string"}, } { tt := tt t.Run(tt.amount, func(t *testing.T) { - startBal, err := reader.Balance(from.Address, "uatom") + startBal, err := reader.Balance(from.Address, *cosmosChain.FeeToken) require.NoError(t, err) set := flag.NewFlagSet("sendcosmoscoins", 0) - cltest.FlagSetApplyFromAction(client.CosmosSendAtom, set, "cosmos") + cltest.FlagSetApplyFromAction(client.CosmosSendNativeToken, set, "cosmos") require.NoError(t, set.Set("id", chainID)) - require.NoError(t, set.Parse([]string{tt.amount, from.Address.String(), to.Address.String()})) + require.NoError(t, set.Parse([]string{nativeToken, tt.amount, from.Address.String(), to.Address.String()})) c := cli.NewContext(cliapp, set, nil) - err = client.CosmosSendAtom(c) + err = client.CosmosSendNativeToken(c) if tt.expErr == "" { require.NoError(t, err) } else { @@ -130,11 +156,11 @@ func TestShell_SendCosmosCoins(t *testing.T) { } // Check balance - endBal, err := reader.Balance(from.Address, "uatom") + endBal, err := reader.Balance(from.Address, *cosmosChain.FeeToken) require.NoError(t, err) if assert.NotNil(t, startBal) && assert.NotNil(t, endBal) { diff := startBal.Sub(*endBal).Amount - sent, err := denom.ConvertDecCoinToDenom(sdk.NewDecCoinFromDec("atom", sdk.MustNewDecFromStr(tt.amount)), "uatom") + sent, err := denom.ConvertDecCoinToDenom(sdk.NewDecCoinFromDec(nativeToken, sdk.MustNewDecFromStr(tt.amount)), *cosmosChain.FeeToken) require.NoError(t, err) if assert.True(t, diff.IsInt64()) && assert.True(t, sent.Amount.IsInt64()) { require.Greater(t, diff.Int64(), sent.Amount.Int64()) diff --git a/core/cmd/eth_keys_commands.go b/core/cmd/eth_keys_commands.go index 0462cd5ca82..e5f1f025966 100644 --- a/core/cmd/eth_keys_commands.go +++ b/core/cmd/eth_keys_commands.go @@ -169,7 +169,7 @@ func (ps EthKeyPresenters) RenderTable(rt RendererTable) error { // ListETHKeys renders the active account address with its ETH & LINK balance func (s *Shell) ListETHKeys(_ *cli.Context) (err error) { resp, err := s.HTTP.Get("/v2/keys/evm") - + if err != nil { return s.errorOut(err) } diff --git a/core/cmd/helpers_test.go b/core/cmd/helpers_test.go index 1a79deaa928..460576ce6a2 100644 --- a/core/cmd/helpers_test.go +++ b/core/cmd/helpers_test.go @@ -11,5 +11,3 @@ func (s *Shell) CheckRemoteBuildCompatibility(lggr logger.Logger, onlyWarn bool, func (s *Shell) ConfigV2Str(userOnly bool) (string, error) { return s.configV2Str(userOnly) } - -type RelayerFactory = relayerFactory diff --git a/core/cmd/ocr2vrf_configure_commands.go b/core/cmd/ocr2vrf_configure_commands.go index 590776135e1..01bfd89c32b 100644 --- a/core/cmd/ocr2vrf_configure_commands.go +++ b/core/cmd/ocr2vrf_configure_commands.go @@ -338,7 +338,11 @@ func setupKeystore(cli *Shell, app chainlink.Application, keyStore keystore.Mast } if cli.Config.EVMEnabled() { - for _, ch := range app.GetChains().EVM.Chains() { + chains, err := app.GetRelayers().LegacyEVMChains().List() + if err != nil { + return fmt.Errorf("failed to get legacy evm chains") + } + for _, ch := range chains { if err = keyStore.Eth().EnsureKeys(ch.ID()); err != nil { return errors.Wrap(err, "failed to ensure keystore keys") } diff --git a/core/cmd/shell.go b/core/cmd/shell.go index 42ede9b39ed..4215e36b496 100644 --- a/core/cmd/shell.go +++ b/core/cmd/shell.go @@ -23,7 +23,6 @@ import ( "github.com/Masterminds/semver/v3" "github.com/getsentry/sentry-go" "github.com/gin-gonic/gin" - "github.com/pelletier/go-toml/v2" "github.com/pkg/errors" "github.com/urfave/cli" "go.uber.org/multierr" @@ -33,15 +32,10 @@ import ( "github.com/smartcontractkit/sqlx" "github.com/smartcontractkit/chainlink-relay/pkg/loop" - pkgsolana "github.com/smartcontractkit/chainlink-solana/pkg/solana" - pkgstarknet "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/build" - "github.com/smartcontractkit/chainlink/v2/core/chains/cosmos" "github.com/smartcontractkit/chainlink/v2/core/chains/evm" - "github.com/smartcontractkit/chainlink/v2/core/chains/solana" - "github.com/smartcontractkit/chainlink/v2/core/chains/starknet" "github.com/smartcontractkit/chainlink/v2/core/config" - "github.com/smartcontractkit/chainlink/v2/core/config/env" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/logger/audit" "github.com/smartcontractkit/chainlink/v2/core/services" @@ -49,7 +43,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/services/periodicbackup" "github.com/smartcontractkit/chainlink/v2/core/services/pg" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/services/versioning" "github.com/smartcontractkit/chainlink/v2/core/services/webhook" "github.com/smartcontractkit/chainlink/v2/core/sessions" @@ -151,62 +144,52 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G dbListener := cfg.Database().Listener() eventBroadcaster := pg.NewEventBroadcaster(cfg.Database().URL(), dbListener.MinReconnectInterval(), dbListener.MaxReconnectDuration(), appLggr, cfg.AppID()) - ccOpts := evm.ChainSetOpts{ - Config: cfg, - Logger: appLggr, - DB: db, - KeyStore: keyStore.Eth(), - EventBroadcaster: eventBroadcaster, - MailMon: mailMon, - } - loopRegistry := plugins.NewLoopRegistry(appLggr.Named("LoopRegistry")) - var chains chainlink.Chains - chains.EVM, err = evm.NewTOMLChainSet(ctx, ccOpts) - if err != nil { - return nil, errors.Wrap(err, "failed to load EVM chainset") + // create the relayer-chain interoperators from application configuration + relayerFactory := chainlink.RelayerFactory{ + Logger: appLggr, + DB: db, + QConfig: cfg.Database(), + LoopRegistry: loopRegistry, + GRPCOpts: grpcOpts, + } + + evmFactoryCfg := chainlink.EVMFactoryConfig{ + CSAETHKeystore: keyStore, + RelayerConfig: evm.RelayerConfig{AppConfig: cfg, EventBroadcaster: eventBroadcaster, MailMon: mailMon}, } + // evm always enabled for backward compatibility + // TODO BCF-2510 this needs to change in order to clear the path for EVM extraction + initOps := []chainlink.CoreRelayerChainInitFunc{chainlink.InitEVM(ctx, relayerFactory, evmFactoryCfg)} if cfg.CosmosEnabled() { - cosmosLggr := appLggr.Named("Cosmos") - opts := cosmos.ChainSetOpts{ - Config: cfg, - Logger: cosmosLggr, - DB: db, - KeyStore: keyStore.Cosmos(), + cosmosCfg := chainlink.CosmosFactoryConfig{ + Keystore: keyStore.Cosmos(), + CosmosConfigs: cfg.CosmosConfigs(), EventBroadcaster: eventBroadcaster, } - cfgs := cfg.CosmosConfigs() - opts.Configs = cosmos.NewConfigs(cfgs) - chains.Cosmos, err = cosmos.NewChainSet(opts, cfgs) - if err != nil { - return nil, errors.Wrap(err, "failed to load Cosmos chainset") - } - } - - rf := relayerFactory{ - Logger: appLggr, - DB: db, - GeneralConfig: cfg, - LoopRegistry: loopRegistry, - GRPCOpts: grpcOpts, + initOps = append(initOps, chainlink.InitCosmos(ctx, relayerFactory, cosmosCfg)) } - if cfg.SolanaEnabled() { - var err2 error - chains.Solana, err2 = rf.NewSolana(keyStore.Solana()) - if err2 != nil { - return nil, fmt.Errorf("failed to setup Solana relayer: %w", err2) + solanaCfg := chainlink.SolanaFactoryConfig{ + Keystore: keyStore.Solana(), + SolanaConfigs: cfg.SolanaConfigs(), } + initOps = append(initOps, chainlink.InitSolana(ctx, relayerFactory, solanaCfg)) } - if cfg.StarkNetEnabled() { - var err2 error - chains.StarkNet, err2 = rf.NewStarkNet(keyStore.StarkNet()) - if err2 != nil { - return nil, fmt.Errorf("failed to setup StarkNet relayer: %w", err2) + starkCfg := chainlink.StarkNetFactoryConfig{ + Keystore: keyStore.StarkNet(), + StarknetConfigs: cfg.StarknetConfigs(), } + initOps = append(initOps, chainlink.InitStarknet(ctx, relayerFactory, starkCfg)) + + } + + relayChainInterops, err := chainlink.NewCoreRelayerChainInteroperators(initOps...) + if err != nil { + return nil, err } // Configure and optionally start the audit log forwarder service @@ -219,127 +202,24 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G unrestrictedClient := clhttp.NewUnrestrictedHTTPClient() externalInitiatorManager := webhook.NewExternalInitiatorManager(db, unrestrictedClient, appLggr, cfg.Database()) return chainlink.NewApplication(chainlink.ApplicationOpts{ - Config: cfg, - SqlxDB: db, - KeyStore: keyStore, - Chains: chains, - EventBroadcaster: eventBroadcaster, - MailMon: mailMon, - Logger: appLggr, - AuditLogger: auditLogger, - ExternalInitiatorManager: externalInitiatorManager, - Version: static.Version, - RestrictedHTTPClient: restrictedClient, - UnrestrictedHTTPClient: unrestrictedClient, - SecretGenerator: chainlink.FilePersistedSecretGenerator{}, - LoopRegistry: loopRegistry, - GRPCOpts: grpcOpts, + Config: cfg, + SqlxDB: db, + KeyStore: keyStore, + RelayerChainInteroperators: relayChainInterops, + EventBroadcaster: eventBroadcaster, + MailMon: mailMon, + Logger: appLggr, + AuditLogger: auditLogger, + ExternalInitiatorManager: externalInitiatorManager, + Version: static.Version, + RestrictedHTTPClient: restrictedClient, + UnrestrictedHTTPClient: unrestrictedClient, + SecretGenerator: chainlink.FilePersistedSecretGenerator{}, + LoopRegistry: loopRegistry, + GRPCOpts: grpcOpts, }) } -type relayerFactory struct { - logger.Logger - *sqlx.DB - chainlink.GeneralConfig - *plugins.LoopRegistry - loop.GRPCOpts -} - -func (r relayerFactory) NewSolana(ks keystore.Solana) (loop.Relayer, error) { - var ( - solanaRelayer loop.Relayer - ids []string - solLggr = r.Logger.Named("Solana") - cfgs = r.SolanaConfigs() - signer = &keystore.SolanaSigner{ks} - ) - for _, c := range cfgs { - c := c - ids = append(ids, *c.ChainID) - } - - if cmdName := env.SolanaPluginCmd.Get(); cmdName != "" { - // setup the solana relayer to be a LOOP - tomls, err := toml.Marshal(struct { - Solana solana.SolanaConfigs - }{Solana: cfgs}) - if err != nil { - return nil, fmt.Errorf("failed to marshal Solana configs: %w", err) - } - - solCmdFn, err := plugins.NewCmdFactory(r.Register, plugins.CmdConfig{ - ID: solLggr.Name(), - Cmd: cmdName, - }) - if err != nil { - return nil, fmt.Errorf("failed to create Solana LOOP command: %w", err) - } - solanaRelayer = loop.NewRelayerService(solLggr, r.GRPCOpts, solCmdFn, string(tomls), signer) - } else { - // fallback to embedded chainset - opts := solana.ChainSetOpts{ - Logger: solLggr, - KeyStore: signer, - Configs: solana.NewConfigs(cfgs), - } - chainSet, err := solana.NewChainSet(opts, cfgs) - if err != nil { - return nil, fmt.Errorf("failed to load Solana chainset: %w", err) - } - solanaRelayer = relay.NewRelayerAdapter(pkgsolana.NewRelayer(solLggr, chainSet), chainSet) - } - return solanaRelayer, nil -} - -func (r relayerFactory) NewStarkNet(ks keystore.StarkNet) (loop.Relayer, error) { - var ( - starknetRelayer loop.Relayer - ids []string - starkLggr = r.Logger.Named("StarkNet") - cfgs = r.StarknetConfigs() - loopKs = &keystore.StarknetLooppSigner{StarkNet: ks} - ) - for _, c := range cfgs { - c := c - ids = append(ids, *c.ChainID) - } - - if cmdName := env.StarknetPluginCmd.Get(); cmdName != "" { - // setup the starknet relayer to be a LOOP - tomls, err := toml.Marshal(struct { - Starknet starknet.StarknetConfigs - }{Starknet: cfgs}) - if err != nil { - return nil, fmt.Errorf("failed to marshal StarkNet configs: %w", err) - } - - starknetCmdFn, err := plugins.NewCmdFactory(r.Register, plugins.CmdConfig{ - ID: starkLggr.Name(), - Cmd: cmdName, - }) - if err != nil { - return nil, fmt.Errorf("failed to create StarkNet LOOP command: %w", err) - } - // the starknet relayer service has a delicate keystore dependency. the value that is passed to NewRelayerService must - // be compatible with instantiating a starknet transaction manager KeystoreAdapter within the LOOPp executable. - starknetRelayer = loop.NewRelayerService(starkLggr, r.GRPCOpts, starknetCmdFn, string(tomls), loopKs) - } else { - // fallback to embedded chainset - opts := starknet.ChainSetOpts{ - Logger: starkLggr, - KeyStore: loopKs, - Configs: starknet.NewConfigs(cfgs), - } - chainSet, err := starknet.NewChainSet(opts, cfgs) - if err != nil { - return nil, fmt.Errorf("failed to load StarkNet chainset: %w", err) - } - starknetRelayer = relay.NewRelayerAdapter(pkgstarknet.NewRelayer(starkLggr, chainSet), chainSet) - } - return starknetRelayer, nil - -} - // handleNodeVersioning is a setup-time helper to encapsulate version changes and db migration func handleNodeVersioning(db *sqlx.DB, appLggr logger.Logger, rootDir string, cfg config.Database, healthReportPort uint16) error { var err error diff --git a/core/cmd/shell_local.go b/core/cmd/shell_local.go index 8323bbfbdc3..cd4f170523b 100644 --- a/core/cmd/shell_local.go +++ b/core/cmd/shell_local.go @@ -373,12 +373,13 @@ func (s *Shell) runNode(c *cli.Context) error { return errors.Wrap(err, "error authenticating keystore") } - evmChainSet := app.GetChains().EVM + legacyEVMChains := app.GetRelayers().LegacyEVMChains() + // By passing in a function we can be lazy trying to look up a default // chain - if there are no existing keys, there is no need to check for // a chain ID DefaultEVMChainIDFunc := func() (*big.Int, error) { - def, err2 := evmChainSet.Default() + def, err2 := legacyEVMChains.Default() if err2 != nil { return nil, errors.Wrap(err2, "cannot get default EVM chain ID; no default EVM chain available") } @@ -390,8 +391,11 @@ func (s *Shell) runNode(c *cli.Context) error { if err != nil { return errors.Wrap(err, "error migrating keystore") } - - for _, ch := range evmChainSet.Chains() { + chainList, err := legacyEVMChains.List() + if err != nil { + return fmt.Errorf("error listing legacy evm chains: %w", err) + } + for _, ch := range chainList { if ch.Config().EVM().AutoCreateKey() { lggr.Debugf("AutoCreateKey=true, will ensure EVM key for chain %s", ch.ID()) err2 := app.GetKeyStore().Eth().EnsureKeys(ch.ID()) @@ -607,7 +611,10 @@ func (s *Shell) RebroadcastTransactions(c *cli.Context) (err error) { return s.errorOut(errors.Wrap(err, "fatal error instantiating application")) } - chain, err := app.GetChains().EVM.Get(chainID) + // TODO: BCF-2511 once the dust settles on BCF-2440/1 evaluate how the + // [loop.Relayer] interface needs to be extended to support programming similar to + // this pattern but in a chain-agnostic way + chain, err := app.GetRelayers().LegacyEVMChains().Get(chainID.String()) if err != nil { return s.errorOut(err) } diff --git a/core/cmd/shell_local_test.go b/core/cmd/shell_local_test.go index c2bc543f87a..db170d267d5 100644 --- a/core/cmd/shell_local_test.go +++ b/core/cmd/shell_local_test.go @@ -9,21 +9,27 @@ import ( "time" clienttypes "github.com/smartcontractkit/chainlink/v2/common/chains/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm" "github.com/smartcontractkit/chainlink/v2/core/cmd" cmdMocks "github.com/smartcontractkit/chainlink/v2/core/cmd/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "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" configtest "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest/v2" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/logger/audit" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + chainlinkmocks "github.com/smartcontractkit/chainlink/v2/core/services/chainlink/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" + evmrelayer "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/sessions" "github.com/smartcontractkit/chainlink/v2/core/store/dialects" "github.com/smartcontractkit/chainlink/v2/core/store/models" "github.com/smartcontractkit/chainlink/v2/core/utils" + "github.com/smartcontractkit/chainlink/v2/plugins" gethTypes "github.com/ethereum/go-ethereum/core/types" "github.com/google/uuid" @@ -33,6 +39,25 @@ import ( "github.com/urfave/cli" ) +func genTestEVMRelayers(t *testing.T, opts evm.ChainRelayExtenderConfig, ks evmrelayer.CSAETHKeystore) *chainlink.CoreRelayerChainInteroperators { + f := chainlink.RelayerFactory{ + Logger: opts.Logger, + DB: opts.DB, + QConfig: opts.AppConfig.Database(), + LoopRegistry: plugins.NewLoopRegistry(opts.Logger), + } + + relayers, err := chainlink.NewCoreRelayerChainInteroperators(chainlink.InitEVM(testutils.Context(t), f, chainlink.EVMFactoryConfig{ + RelayerConfig: opts.RelayerConfig, + CSAETHKeystore: ks, + })) + if err != nil { + t.Fatal(err) + } + return relayers + +} + func TestShell_RunNodeWithPasswords(t *testing.T) { tests := []struct { name string @@ -50,11 +75,28 @@ func TestShell_RunNodeWithPasswords(t *testing.T) { s.Password.Keystore = models.NewSecret("dummy") c.EVM[0].Nodes[0].Name = ptr("fake") c.EVM[0].Nodes[0].HTTPURL = models.MustParseURL("http://fake.com") + c.EVM[0].Nodes[0].WSURL = models.MustParseURL("WSS://fake.com/ws") + // seems to be needed for config validate + c.Insecure.OCRDevelopmentMode = nil }) db := pgtest.NewSqlxDB(t) keyStore := cltest.NewKeyStore(t, db, cfg.Database()) sessionORM := sessions.NewORM(db, time.Minute, logger.TestLogger(t), cfg.Database(), audit.NoopLogger) + lggr := logger.TestLogger(t) + + opts := evm.ChainRelayExtenderConfig{ + Logger: lggr, + DB: db, + KeyStore: keyStore.Eth(), + RelayerConfig: evm.RelayerConfig{ + AppConfig: cfg, + EventBroadcaster: pg.NewNullEventBroadcaster(), + MailMon: &utils.MailboxMonitor{}, + }, + } + testRelayers := genTestEVMRelayers(t, opts, keyStore) + // Purge the fixture users to test assumption of single admin // initialUser user created above pgtest.MustExec(t, db, "DELETE FROM users;") @@ -62,7 +104,7 @@ func TestShell_RunNodeWithPasswords(t *testing.T) { app := mocks.NewApplication(t) app.On("SessionORM").Return(sessionORM).Maybe() app.On("GetKeyStore").Return(keyStore).Maybe() - app.On("GetChains").Return(chainlink.Chains{EVM: cltest.NewChainSetMockWithOneChain(t, evmtest.NewEthClientMock(t), evmtest.NewChainScopedConfig(t, cfg))}).Maybe() + app.On("GetRelayers").Return(testRelayers).Maybe() app.On("Start", mock.Anything).Maybe().Return(nil) app.On("Stop").Maybe().Return(nil) app.On("ID").Maybe().Return(uuid.New()) @@ -73,7 +115,6 @@ func TestShell_RunNodeWithPasswords(t *testing.T) { cltest.MustInsertRandomKey(t, keyStore.Eth()) apiPrompt := cltest.NewMockAPIInitializer(t) - lggr := logger.TestLogger(t) client := cmd.Shell{ Config: cfg, @@ -131,6 +172,8 @@ func TestShell_RunNodeWithAPICredentialsFile(t *testing.T) { c.EVM[0].Nodes[0].Name = ptr("fake") c.EVM[0].Nodes[0].WSURL = models.MustParseURL("WSS://fake.com/ws") c.EVM[0].Nodes[0].HTTPURL = models.MustParseURL("http://fake.com") + // seems to be needed for config validate + c.Insecure.OCRDevelopmentMode = nil }) db := pgtest.NewSqlxDB(t) sessionORM := sessions.NewORM(db, time.Minute, logger.TestLogger(t), cfg.Database(), audit.NoopLogger) @@ -148,10 +191,23 @@ func TestShell_RunNodeWithAPICredentialsFile(t *testing.T) { ethClient.On("Dial", mock.Anything).Return(nil).Maybe() ethClient.On("BalanceAt", mock.Anything, mock.Anything, mock.Anything).Return(big.NewInt(10), nil).Maybe() + lggr := logger.TestLogger(t) + opts := evm.ChainRelayExtenderConfig{ + Logger: lggr, + DB: db, + KeyStore: keyStore.Eth(), + RelayerConfig: evm.RelayerConfig{ + AppConfig: cfg, + EventBroadcaster: pg.NewNullEventBroadcaster(), + + MailMon: &utils.MailboxMonitor{}, + }, + } + testRelayers := genTestEVMRelayers(t, opts, keyStore) app := mocks.NewApplication(t) app.On("SessionORM").Return(sessionORM) app.On("GetKeyStore").Return(keyStore) - app.On("GetChains").Return(chainlink.Chains{EVM: cltest.NewChainSetMockWithOneChain(t, ethClient, evmtest.NewChainScopedConfig(t, cfg))}).Maybe() + app.On("GetRelayers").Return(testRelayers).Maybe() app.On("Start", mock.Anything).Maybe().Return(nil) app.On("Stop").Maybe().Return(nil) app.On("ID").Maybe().Return(uuid.New()) @@ -159,7 +215,6 @@ func TestShell_RunNodeWithAPICredentialsFile(t *testing.T) { prompter := cmdMocks.NewPrompter(t) apiPrompt := cltest.NewMockAPIInitializer(t) - lggr := logger.TestLogger(t) client := cmd.Shell{ Config: cfg, @@ -214,8 +269,8 @@ func TestShell_DiskMaxSizeBeforeRotateOptionDisablesAsExpected(t *testing.T) { } assert.NoError(t, os.MkdirAll(cfg.Dir, os.FileMode(0700))) - lggr, close := cfg.New() - t.Cleanup(func() { assert.NoError(t, close()) }) + lggr, closeFn := cfg.New() + t.Cleanup(func() { assert.NoError(t, closeFn()) }) // Tries to create a log file by logging. The log file won't be created if there's no logging happening. lggr.Debug("Trying to create a log file by logging.") @@ -235,22 +290,28 @@ func TestShell_RebroadcastTransactions_Txm(t *testing.T) { // evm config is used in this test. but if set, it must be pass config validation. // simplest to make it nil c.EVM = nil + // seems to be needed for config validate + c.Insecure.OCRDevelopmentMode = nil }) keyStore := cltest.NewKeyStore(t, sqlxDB, config.Database()) - _, fromAddress := cltest.MustInsertRandomKey(t, keyStore.Eth(), 0) + _, fromAddress := cltest.MustInsertRandomKey(t, keyStore.Eth()) txStore := cltest.NewTestTxStore(t, sqlxDB, config.Database()) cltest.MustInsertConfirmedEthTxWithLegacyAttempt(t, txStore, 7, 42, fromAddress) + lggr := logger.TestLogger(t) + app := mocks.NewApplication(t) app.On("GetSqlxDB").Return(sqlxDB) app.On("GetKeyStore").Return(keyStore) app.On("ID").Maybe().Return(uuid.New()) ethClient := evmtest.NewEthClientMockWithDefaultChain(t) - app.On("GetChains").Return(chainlink.Chains{EVM: cltest.NewChainSetMockWithOneChain(t, ethClient, evmtest.NewChainScopedConfig(t, config))}).Maybe() - ethClient.On("Dial", mock.Anything).Return(nil) + legacy := cltest.NewLegacyChainsWithMockChain(t, ethClient, config) - lggr := logger.TestLogger(t) + mockRelayerChainInteroperators := chainlinkmocks.NewRelayerChainInteroperators(t) + mockRelayerChainInteroperators.On("LegacyEVMChains").Return(legacy, nil) + app.On("GetRelayers").Return(mockRelayerChainInteroperators).Maybe() + ethClient.On("Dial", mock.Anything).Return(nil) client := cmd.Shell{ Config: config, @@ -308,6 +369,8 @@ func TestShell_RebroadcastTransactions_OutsideRange_Txm(t *testing.T) { // evm config is used in this test. but if set, it must be pass config validation. // simplest to make it nil c.EVM = nil + // seems to be needed for config validate + c.Insecure.OCRDevelopmentMode = nil }) keyStore := cltest.NewKeyStore(t, sqlxDB, config.Database()) @@ -317,15 +380,19 @@ func TestShell_RebroadcastTransactions_OutsideRange_Txm(t *testing.T) { txStore := cltest.NewTestTxStore(t, sqlxDB, config.Database()) cltest.MustInsertConfirmedEthTxWithLegacyAttempt(t, txStore, int64(test.nonce), 42, fromAddress) + lggr := logger.TestLogger(t) + app := mocks.NewApplication(t) app.On("GetSqlxDB").Return(sqlxDB) app.On("GetKeyStore").Return(keyStore) app.On("ID").Maybe().Return(uuid.New()) ethClient := evmtest.NewEthClientMockWithDefaultChain(t) ethClient.On("Dial", mock.Anything).Return(nil) - app.On("GetChains").Return(chainlink.Chains{EVM: cltest.NewChainSetMockWithOneChain(t, ethClient, evmtest.NewChainScopedConfig(t, config))}).Maybe() + legacy := cltest.NewLegacyChainsWithMockChain(t, ethClient, config) - lggr := logger.TestLogger(t) + mockRelayerChainInteroperators := chainlinkmocks.NewRelayerChainInteroperators(t) + mockRelayerChainInteroperators.On("LegacyEVMChains").Return(legacy, nil) + app.On("GetRelayers").Return(mockRelayerChainInteroperators).Maybe() client := cmd.Shell{ Config: config, @@ -377,7 +444,10 @@ func TestShell_RebroadcastTransactions_AddressCheck(t *testing.T) { config, sqlxDB := heavyweight.FullTestDBV2(t, "rebroadcasttransactions_outsiderange", func(c *chainlink.Config, s *chainlink.Secrets) { c.Database.Dialect = dialects.Postgres + c.EVM = nil + // seems to be needed for config validate + c.Insecure.OCRDevelopmentMode = nil }) keyStore := cltest.NewKeyStore(t, sqlxDB, config.Database()) @@ -385,22 +455,25 @@ func TestShell_RebroadcastTransactions_AddressCheck(t *testing.T) { _, fromAddress := cltest.MustInsertRandomKey(t, keyStore.Eth(), 0) if !test.enableAddress { - err := keyStore.Eth().Disable(fromAddress, big.NewInt(0)) - require.NoError(t, err) + err := keyStore.Eth().Disable(fromAddress, testutils.FixtureChainID) + require.NoError(t, err, "failed to disable test key") } + lggr := logger.TestLogger(t) + app := mocks.NewApplication(t) app.On("GetSqlxDB").Maybe().Return(sqlxDB) app.On("GetKeyStore").Return(keyStore) app.On("ID").Maybe().Return(uuid.New()) ethClient := evmtest.NewEthClientMockWithDefaultChain(t) ethClient.On("Dial", mock.Anything).Return(nil) - app.On("GetChains").Return(chainlink.Chains{EVM: cltest.NewChainSetMockWithOneChain(t, ethClient, evmtest.NewChainScopedConfig(t, config))}).Maybe() + legacy := cltest.NewLegacyChainsWithMockChain(t, ethClient, config) + mockRelayerChainInteroperators := chainlinkmocks.NewRelayerChainInteroperators(t) + mockRelayerChainInteroperators.On("LegacyEVMChains").Return(legacy, nil) + app.On("GetRelayers").Return(mockRelayerChainInteroperators).Maybe() ethClient.On("SendTransactionReturnCode", mock.Anything, mock.Anything, mock.Anything).Maybe().Return(clienttypes.Successful, nil) - lggr := logger.TestLogger(t) - client := cmd.Shell{ Config: config, AppFactory: cltest.InstanceAppFactory{App: app}, @@ -410,6 +483,7 @@ func TestShell_RebroadcastTransactions_AddressCheck(t *testing.T) { } set := flag.NewFlagSet("test", 0) + set.Set("evmChainID", testutils.SimulatedChainID.String()) cltest.FlagSetApplyFromAction(client.RebroadcastTransactions, set, "") require.NoError(t, set.Set("address", fromAddress.Hex())) diff --git a/core/cmd/shell_test.go b/core/cmd/shell_test.go index b371156e9de..733c0058f37 100644 --- a/core/cmd/shell_test.go +++ b/core/cmd/shell_test.go @@ -12,6 +12,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + solcfg "github.com/smartcontractkit/chainlink-solana/pkg/solana/config" + "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/config" + stkcfg "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/config" + "github.com/smartcontractkit/chainlink/v2/core/chains/solana" + "github.com/smartcontractkit/chainlink/v2/core/chains/starknet" "github.com/smartcontractkit/chainlink/v2/core/cmd" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" @@ -19,6 +24,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/logger/audit" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/mocks" "github.com/smartcontractkit/chainlink/v2/core/sessions" "github.com/smartcontractkit/chainlink/v2/plugins" @@ -336,18 +342,30 @@ func TestSetupSolanaRelayer(t *testing.T) { lggr := logger.TestLogger(t) reg := plugins.NewLoopRegistry(lggr) ks := mocks.NewSolana(t) - rf := cmd.RelayerFactory{ - Logger: lggr, - DB: pgtest.NewSqlxDB(t), - GeneralConfig: configtest.NewGeneralConfig(t, nil), - LoopRegistry: reg, + tConfig := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { + c.Solana = solana.SolanaConfigs{ + &solana.SolanaConfig{ + ChainID: ptr[string]("solana-id-1"), + Enabled: new(bool), + Chain: solcfg.Chain{}, + Nodes: []*solcfg.Node{}, + }, + } + }) + + rf := chainlink.RelayerFactory{ + Logger: lggr, + DB: pgtest.NewSqlxDB(t), + QConfig: tConfig.Database(), + LoopRegistry: reg, } // not parallel; shared state t.Run("no plugin", func(t *testing.T) { - relayer, err := rf.NewSolana(ks) + relayers, err := rf.NewSolana(ks, tConfig.SolanaConfigs()) require.NoError(t, err) - require.NotNil(t, relayer) + require.NotNil(t, relayers) + require.Len(t, relayers, 1) // no using plugin, so registry should be empty require.Len(t, reg.List(), 0) }) @@ -355,9 +373,10 @@ func TestSetupSolanaRelayer(t *testing.T) { t.Run("plugin", func(t *testing.T) { t.Setenv("CL_SOLANA_CMD", "phony_solana_cmd") - relayer, err := rf.NewSolana(ks) + relayers, err := rf.NewSolana(ks, tConfig.SolanaConfigs()) require.NoError(t, err) - require.NotNil(t, relayer) + require.NotNil(t, relayers) + require.Len(t, relayers, 1) // make sure registry has the plugin require.Len(t, reg.List(), 1) }) @@ -368,18 +387,29 @@ func TestSetupStarkNetRelayer(t *testing.T) { lggr := logger.TestLogger(t) reg := plugins.NewLoopRegistry(lggr) ks := mocks.NewStarkNet(t) - rf := cmd.RelayerFactory{ - Logger: lggr, - DB: pgtest.NewSqlxDB(t), - GeneralConfig: configtest.NewGeneralConfig(t, nil), - LoopRegistry: reg, + tConfig := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { + c.Starknet = starknet.StarknetConfigs{ + &starknet.StarknetConfig{ + ChainID: ptr[string]("starknet-id-1"), + Enabled: new(bool), + Chain: stkcfg.Chain{}, + Nodes: []*config.Node{}, + }, + } + }) + rf := chainlink.RelayerFactory{ + Logger: lggr, + DB: pgtest.NewSqlxDB(t), + QConfig: tConfig.Database(), + LoopRegistry: reg, } // not parallel; shared state t.Run("no plugin", func(t *testing.T) { - relayer, err := rf.NewStarkNet(ks) + relayers, err := rf.NewStarkNet(ks, tConfig.StarknetConfigs()) require.NoError(t, err) - require.NotNil(t, relayer) + require.NotNil(t, relayers) + require.Len(t, relayers, 1) // no using plugin, so registry should be empty require.Len(t, reg.List(), 0) }) @@ -387,9 +417,10 @@ func TestSetupStarkNetRelayer(t *testing.T) { t.Run("plugin", func(t *testing.T) { t.Setenv("CL_STARKNET_CMD", "phony_starknet_cmd") - relayer, err := rf.NewStarkNet(ks) + relayers, err := rf.NewStarkNet(ks, tConfig.StarknetConfigs()) require.NoError(t, err) - require.NotNil(t, relayer) + require.NotNil(t, relayers) + require.Len(t, relayers, 1) // make sure registry has the plugin require.Len(t, reg.List(), 1) }) diff --git a/core/config/docs/chains-cosmos.toml b/core/config/docs/chains-cosmos.toml index 1a5155f3cd6..3281c6c27a6 100644 --- a/core/config/docs/chains-cosmos.toml +++ b/core/config/docs/chains-cosmos.toml @@ -3,6 +3,8 @@ ChainID = 'Malaga-420' # Example # Enabled enables this chain. Enabled = true # Default +# Bech32Prefix is the human-readable prefix for addresses on this Cosmos chain. See https://docs.cosmos.network/v0.47/spec/addresses/bech32. +Bech32Prefix = 'wasm' # Default # BlockRate is the average time between blocks. BlockRate = '6s' # Default # BlocksUntilTxTimeout is the number of blocks to wait before giving up on the tx getting confirmed. @@ -11,8 +13,8 @@ BlocksUntilTxTimeout = 30 # Default ConfirmPollPeriod = '1s' # Default # FallbackGasPrice sets a fallback gas price to use when the estimator is not available. FallbackGasPrice = '0.015' # Default -# FCDURL sets the FCD (Full Client Daemon) URL. -FCDURL = 'http://cosmos.com' # Example +# FeeToken is the token denomination which is being used to pay gas fees on this chain. +FeeToken = 'ucosm' # Default # GasLimitMultiplier scales the estimated gas limit. GasLimitMultiplier = '1.5' # Default # MaxMsgsPerBatch limits the numbers of mesages per transaction batch. diff --git a/core/config/docs/core.toml b/core/config/docs/core.toml index 39f35047ae0..7253cbd1aad 100644 --- a/core/config/docs/core.toml +++ b/core/config/docs/core.toml @@ -303,6 +303,8 @@ DatabaseTimeout = '10s' # Default KeyBundleID = '7a5f66bbe6594259325bf2b4f5b1a9c900000000000000000000000000000000' # Example # CaptureEATelemetry toggles collecting extra information from External Adaptares CaptureEATelemetry = false # Default +# CaptureAutomationCustomTelemetry toggles collecting automation specific telemetry +CaptureAutomationCustomTelemetry = false # Default # DefaultTransactionQueueDepth controls the queue size for `DropOldestStrategy` in OCR2. Set to 0 to use `SendEvery` strategy instead. DefaultTransactionQueueDepth = 1 # Default # SimulateTransactions enables transaction simulation for OCR2. diff --git a/core/config/ocr2_config.go b/core/config/ocr2_config.go index 6b522ea79eb..a2ea79741b4 100644 --- a/core/config/ocr2_config.go +++ b/core/config/ocr2_config.go @@ -20,4 +20,5 @@ type OCR2 interface { CaptureEATelemetry() bool DefaultTransactionQueueDepth() uint32 SimulateTransactions() bool + CaptureAutomationCustomTelemetry() bool } diff --git a/core/config/toml/types.go b/core/config/toml/types.go index 471d444339c..5aedcf4deb6 100644 --- a/core/config/toml/types.go +++ b/core/config/toml/types.go @@ -793,6 +793,7 @@ type OCR2 struct { DatabaseTimeout *models.Duration KeyBundleID *models.Sha256Hash CaptureEATelemetry *bool + CaptureAutomationCustomTelemetry *bool DefaultTransactionQueueDepth *uint32 SimulateTransactions *bool TraceLogging *bool @@ -826,6 +827,9 @@ func (o *OCR2) setFrom(f *OCR2) { if v := f.CaptureEATelemetry; v != nil { o.CaptureEATelemetry = v } + if v := f.CaptureAutomationCustomTelemetry; v != nil { + o.CaptureAutomationCustomTelemetry = v + } if v := f.DefaultTransactionQueueDepth; v != nil { o.DefaultTransactionQueueDepth = v } diff --git a/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go b/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go index 65b5efd18da..d86c07f1705 100644 --- a/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go +++ b/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go @@ -30,16 +30,21 @@ var ( _ = abi.ConvertType ) +type TermsOfServiceAllowListConfig struct { + Enabled bool + SignerPublicKey common.Address +} + var TermsOfServiceAllowListMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouterOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RecipientIsBlocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustBeSet\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"}],\"name\":\"acceptTermsOfService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"blockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfigHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"config\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"}],\"name\":\"getEthSignedMessageHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"getMessageHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"isAllowedSender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"isBlockedSender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"unblockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b506040516200114238038062001142833981016040819052620000349162000164565b81816001600160a01b0382166200005e57604051632530e88560e11b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038416179055620000848162000099565b80516020909101206000555062000292915050565b60008082806020019051810190620000b291906200024f565b6040805180820182528315158082526001600160a01b0384166020928301819052600680546001600160a81b031916610100600160a81b031984161761010090920291909117905591519182529294509092507f22aa8545955b447cb49ea37e67de742e750839c633ded8c9b5b09614843b229f910160405180910390a1505050565b6001600160a01b03811681146200014b57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156200017857600080fd5b8251620001858162000135565b602084810151919350906001600160401b0380821115620001a557600080fd5b818601915086601f830112620001ba57600080fd5b815181811115620001cf57620001cf6200014e565b604051601f8201601f19908116603f01168101908382118183101715620001fa57620001fa6200014e565b8160405282815289868487010111156200021357600080fd5b600093505b8284101562000237578484018601518185018701529285019262000218565b60008684830101528096505050505050509250929050565b600080604083850312156200026357600080fd5b825180151581146200027457600080fd5b6020840151909250620002878162000135565b809150509250929050565b610ea080620002a26000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c806382184c7b11610076578063a5e1d61d1161005b578063a5e1d61d14610158578063be8c97b01461017b578063fa5408011461018e57600080fd5b806382184c7b1461013d5780639883c10d1461015057600080fd5b8063354497aa116100a7578063354497aa146100f657806347663acb1461010957806380e8a1511461011c57600080fd5b8063181f5a77146100c35780632179d447146100e1575b600080fd5b6100cb6101ef565b6040516100d89190610af2565b60405180910390f35b6100f46100ef366004610b83565b61020f565b005b6100f4610104366004610c44565b61044c565b6100f4610117366004610d13565b6104b3565b61012f61012a366004610d30565b6105b9565b6040519081526020016100d8565b6100f461014b366004610d13565b610617565b60005461012f565b61016b610166366004610d13565b610725565b60405190151581526020016100d8565b61016b610189366004610d13565b610749565b61012f61019c366004610d69565b6040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b6060604051806060016040528060288152602001610e6c60289139905090565b61021a600484610769565b15610251576040517f62b7a34d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061025d85856105b9565b905060006102b8826040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905060006102fc8286868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061079b92505050565b60065490915073ffffffffffffffffffffffffffffffffffffffff8083166101009092041614610358576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b63ffffffff333b1615801590816103a557503373ffffffffffffffffffffffffffffffffffffffff89161415806103a557503373ffffffffffffffffffffffffffffffffffffffff881614155b156103dc576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8080156103ff57503373ffffffffffffffffffffffffffffffffffffffff881614155b15610436576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610441600288610838565b505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461049d576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104a68161085a565b8051602090910120600055565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610522573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105469190610d82565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517fa0f0a44600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105b5600482610930565b5050565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b1660348201526000906048016040516020818303038152906040528051906020012090505b92915050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610686573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106aa9190610d82565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461070e576040517fa0f0a44600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610719600282610930565b506105b5600482610838565b60065460009060ff161515810361073e57506000919050565b610611600483610769565b60065460009060ff161515810361076257506001919050565b6106116002835b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b9392505050565b6000806000806107aa85610952565b6040805160008152602081018083528b905260ff8316918101919091526060810184905260808101839052929550909350915060019060a0016020604051602081039080840390855afa158015610805573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00151979650505050505050565b60006107948373ffffffffffffffffffffffffffffffffffffffff84166109b0565b600080828060200190518101906108719190610d9f565b60408051808201825283151580825273ffffffffffffffffffffffffffffffffffffffff84166020928301819052600680547fffffffffffffffffffffff000000000000000000000000000000000000000000167fffffffffffffffffffffff0000000000000000000000000000000000000000ff84161761010090920291909117905591519182529294509092507f22aa8545955b447cb49ea37e67de742e750839c633ded8c9b5b09614843b229f910160405180910390a1505050565b60006107948373ffffffffffffffffffffffffffffffffffffffff84166109ff565b60008060008351604114610992576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505060208101516040820151606090920151909260009190911a90565b60008181526001830160205260408120546109f757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610611565b506000610611565b60008181526001830160205260408120548015610ae8576000610a23600183610dd3565b8554909150600090610a3790600190610dd3565b9050818114610a9c576000866000018281548110610a5757610a57610e0d565b9060005260206000200154905080876000018481548110610a7a57610a7a610e0d565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610aad57610aad610e3c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610611565b6000915050610611565b600060208083528351808285015260005b81811015610b1f57858101830151858201604001528201610b03565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114610b8057600080fd5b50565b60008060008060608587031215610b9957600080fd5b8435610ba481610b5e565b93506020850135610bb481610b5e565b9250604085013567ffffffffffffffff80821115610bd157600080fd5b818701915087601f830112610be557600080fd5b813581811115610bf457600080fd5b886020828501011115610c0657600080fd5b95989497505060200194505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610c5657600080fd5b813567ffffffffffffffff80821115610c6e57600080fd5b818401915084601f830112610c8257600080fd5b813581811115610c9457610c94610c15565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610cda57610cda610c15565b81604052828152876020848701011115610cf357600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208284031215610d2557600080fd5b813561079481610b5e565b60008060408385031215610d4357600080fd5b8235610d4e81610b5e565b91506020830135610d5e81610b5e565b809150509250929050565b600060208284031215610d7b57600080fd5b5035919050565b600060208284031215610d9457600080fd5b815161079481610b5e565b60008060408385031215610db257600080fd5b82518015158114610dc257600080fd5b6020840151909250610d5e81610b5e565b81810381811115610611577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe46756e6374696f6e73205465726d73206f66205365727669636520416c6c6f77204c697374207631a164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowList.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidUsage\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RecipientIsBlocked\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"AddedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"BlockedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structTermsOfServiceAllowList.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"UnblockedAccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"}],\"name\":\"acceptTermsOfService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"blockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAllowedSenders\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowList.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"getMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"hasAccess\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"isBlockedSender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"unblockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowList.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b50604051620012c4380380620012c4833981016040819052620000349162000269565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d9565b505050620000d2816200018460201b60201c565b50620002ea565b336001600160a01b03821603620001335760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200018e6200020b565b805160058054602080850180516001600160a81b0319909316941515610100600160a81b03198116959095176101006001600160a01b039485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a910160405180910390a150565b6000546001600160a01b03163314620002675760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b6000604082840312156200027c57600080fd5b604080519081016001600160401b0381118282101715620002ad57634e487b7160e01b600052604160045260246000fd5b60405282518015158114620002c157600080fd5b815260208301516001600160a01b0381168114620002de57600080fd5b60208201529392505050565b610fca80620002fa6000396000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c806382184c7b1161008c578063a39b06e311610066578063a39b06e3146101b8578063a5e1d61d146101d9578063c3f909d4146101ec578063f2fde38b1461024b57600080fd5b806382184c7b1461016a57806389f9a2c41461017d5780638da5cb5b1461019057600080fd5b80636b14daf8116100bd5780636b14daf81461012a57806379ba50971461014d578063817ef62e1461015557600080fd5b8063181f5a77146100e45780633908c4d41461010257806347663acb14610117575b600080fd5b6100ec61025e565b6040516100f99190610c4f565b60405180910390f35b610115610110366004610ce4565b61027a565b005b610115610125366004610d45565b6104f0565b61013d610138366004610d60565b61057b565b60405190151581526020016100f9565b6101156105a5565b61015d6106a7565b6040516100f99190610de3565b610115610178366004610d45565b6106b8565b61011561018b366004610e3d565b61074b565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f9565b6101cb6101c6366004610ec6565b610806565b6040519081526020016100f9565b61013d6101e7366004610d45565b610864565b60408051808201825260008082526020918201528151808301835260055460ff8116151580835273ffffffffffffffffffffffffffffffffffffffff6101009092048216928401928352845190815291511691810191909152016100f9565b610115610259366004610d45565b6108a5565b6040518060600160405280602c8152602001610f92602c913981565b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602052604090205460ff16156102da576040517f62b7a34d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102e68686610806565b6040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c810191909152605c01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815282825280516020918201206005546000855291840180845281905260ff8616928401929092526060830187905260808301869052909250610100900473ffffffffffffffffffffffffffffffffffffffff169060019060a0016020604051602081039080840390855afa1580156103c0573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff1614610417576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff861614158061045c57503373ffffffffffffffffffffffffffffffffffffffff87161480159061045c5750333b155b15610493576040517f381cfcbd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61049e6002866108b9565b5060405173ffffffffffffffffffffffffffffffffffffffff861681527f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db49060200160405180910390a1505050505050565b6104f86108db565b73ffffffffffffffffffffffffffffffffffffffff811660008181526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905590519182527f28bbd0761309a99e8fb5e5d02ada0b7b2db2e5357531ff5dbfc205c3f5b6592b91015b60405180910390a150565b60055460009060ff166105905750600161059e565b61059b60028561095e565b90505b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461062b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60606106b3600261098d565b905090565b6106c06108db565b6106cb60028261099a565b5073ffffffffffffffffffffffffffffffffffffffff811660008181526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590519182527f337cd0f3f594112b6d830afb510072d3b08556b446514f73b8109162fd1151e19101610570565b6107536108db565b805160058054602080850180517fffffffffffffffffffffff0000000000000000000000000000000000000000009093169415157fffffffffffffffffffffff0000000000000000000000000000000000000000ff81169590951761010073ffffffffffffffffffffffffffffffffffffffff9485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a9101610570565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b1660348201526000906048016040516020818303038152906040528051906020012090505b92915050565b60055460009060ff1661087957506000919050565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526004602052604090205460ff1690565b6108ad6108db565b6108b6816109bc565b50565b600061059e8373ffffffffffffffffffffffffffffffffffffffff8416610ab1565b60005473ffffffffffffffffffffffffffffffffffffffff16331461095c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610622565b565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561059e565b6060600061059e83610b00565b600061059e8373ffffffffffffffffffffffffffffffffffffffff8416610b5c565b3373ffffffffffffffffffffffffffffffffffffffff821603610a3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610622565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000818152600183016020526040812054610af85750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561085e565b50600061085e565b606081600001805480602002602001604051908101604052809291908181526020018280548015610b5057602002820191906000526020600020905b815481526020019060010190808311610b3c575b50505050509050919050565b60008181526001830160205260408120548015610c45576000610b80600183610ef9565b8554909150600090610b9490600190610ef9565b9050818114610bf9576000866000018281548110610bb457610bb4610f33565b9060005260206000200154905080876000018481548110610bd757610bd7610f33565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610c0a57610c0a610f62565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061085e565b600091505061085e565b600060208083528351808285015260005b81811015610c7c57858101830151858201604001528201610c60565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610cdf57600080fd5b919050565b600080600080600060a08688031215610cfc57600080fd5b610d0586610cbb565b9450610d1360208701610cbb565b93506040860135925060608601359150608086013560ff81168114610d3757600080fd5b809150509295509295909350565b600060208284031215610d5757600080fd5b61059e82610cbb565b600080600060408486031215610d7557600080fd5b610d7e84610cbb565b9250602084013567ffffffffffffffff80821115610d9b57600080fd5b818601915086601f830112610daf57600080fd5b813581811115610dbe57600080fd5b876020828501011115610dd057600080fd5b6020830194508093505050509250925092565b6020808252825182820181905260009190848201906040850190845b81811015610e3157835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610dff565b50909695505050505050565b600060408284031215610e4f57600080fd5b6040516040810181811067ffffffffffffffff82111715610e99577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405282358015158114610eac57600080fd5b8152610eba60208401610cbb565b60208201529392505050565b60008060408385031215610ed957600080fd5b610ee283610cbb565b9150610ef060208401610cbb565b90509250929050565b8181038181111561085e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe46756e6374696f6e73205465726d73206f66205365727669636520416c6c6f77204c6973742076312e302e30a164736f6c6343000813000a", } var TermsOfServiceAllowListABI = TermsOfServiceAllowListMetaData.ABI var TermsOfServiceAllowListBin = TermsOfServiceAllowListMetaData.Bin -func DeployTermsOfServiceAllowList(auth *bind.TransactOpts, backend bind.ContractBackend, router common.Address, config []byte) (common.Address, *types.Transaction, *TermsOfServiceAllowList, error) { +func DeployTermsOfServiceAllowList(auth *bind.TransactOpts, backend bind.ContractBackend, config TermsOfServiceAllowListConfig) (common.Address, *types.Transaction, *TermsOfServiceAllowList, error) { parsed, err := TermsOfServiceAllowListMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -48,7 +53,7 @@ func DeployTermsOfServiceAllowList(auth *bind.TransactOpts, backend bind.Contrac return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TermsOfServiceAllowListBin), backend, router, config) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TermsOfServiceAllowListBin), backend, config) if err != nil { return common.Address{}, nil, nil, err } @@ -171,53 +176,53 @@ func (_TermsOfServiceAllowList *TermsOfServiceAllowListTransactorRaw) Transact(o return _TermsOfServiceAllowList.Contract.contract.Transact(opts, method, params...) } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) GetConfigHash(opts *bind.CallOpts) ([32]byte, error) { +func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) GetAllAllowedSenders(opts *bind.CallOpts) ([]common.Address, error) { var out []interface{} - err := _TermsOfServiceAllowList.contract.Call(opts, &out, "getConfigHash") + err := _TermsOfServiceAllowList.contract.Call(opts, &out, "getAllAllowedSenders") if err != nil { - return *new([32]byte), err + return *new([]common.Address), err } - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) return out0, err } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) GetConfigHash() ([32]byte, error) { - return _TermsOfServiceAllowList.Contract.GetConfigHash(&_TermsOfServiceAllowList.CallOpts) +func (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) GetAllAllowedSenders() ([]common.Address, error) { + return _TermsOfServiceAllowList.Contract.GetAllAllowedSenders(&_TermsOfServiceAllowList.CallOpts) } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListCallerSession) GetConfigHash() ([32]byte, error) { - return _TermsOfServiceAllowList.Contract.GetConfigHash(&_TermsOfServiceAllowList.CallOpts) +func (_TermsOfServiceAllowList *TermsOfServiceAllowListCallerSession) GetAllAllowedSenders() ([]common.Address, error) { + return _TermsOfServiceAllowList.Contract.GetAllAllowedSenders(&_TermsOfServiceAllowList.CallOpts) } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) GetEthSignedMessageHash(opts *bind.CallOpts, messageHash [32]byte) ([32]byte, error) { +func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) GetConfig(opts *bind.CallOpts) (TermsOfServiceAllowListConfig, error) { var out []interface{} - err := _TermsOfServiceAllowList.contract.Call(opts, &out, "getEthSignedMessageHash", messageHash) + err := _TermsOfServiceAllowList.contract.Call(opts, &out, "getConfig") if err != nil { - return *new([32]byte), err + return *new(TermsOfServiceAllowListConfig), err } - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out0 := *abi.ConvertType(out[0], new(TermsOfServiceAllowListConfig)).(*TermsOfServiceAllowListConfig) return out0, err } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) GetEthSignedMessageHash(messageHash [32]byte) ([32]byte, error) { - return _TermsOfServiceAllowList.Contract.GetEthSignedMessageHash(&_TermsOfServiceAllowList.CallOpts, messageHash) +func (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) GetConfig() (TermsOfServiceAllowListConfig, error) { + return _TermsOfServiceAllowList.Contract.GetConfig(&_TermsOfServiceAllowList.CallOpts) } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListCallerSession) GetEthSignedMessageHash(messageHash [32]byte) ([32]byte, error) { - return _TermsOfServiceAllowList.Contract.GetEthSignedMessageHash(&_TermsOfServiceAllowList.CallOpts, messageHash) +func (_TermsOfServiceAllowList *TermsOfServiceAllowListCallerSession) GetConfig() (TermsOfServiceAllowListConfig, error) { + return _TermsOfServiceAllowList.Contract.GetConfig(&_TermsOfServiceAllowList.CallOpts) } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) GetMessageHash(opts *bind.CallOpts, acceptor common.Address, recipient common.Address) ([32]byte, error) { +func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) GetMessage(opts *bind.CallOpts, acceptor common.Address, recipient common.Address) ([32]byte, error) { var out []interface{} - err := _TermsOfServiceAllowList.contract.Call(opts, &out, "getMessageHash", acceptor, recipient) + err := _TermsOfServiceAllowList.contract.Call(opts, &out, "getMessage", acceptor, recipient) if err != nil { return *new([32]byte), err @@ -229,17 +234,17 @@ func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) GetMessageHash(op } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) GetMessageHash(acceptor common.Address, recipient common.Address) ([32]byte, error) { - return _TermsOfServiceAllowList.Contract.GetMessageHash(&_TermsOfServiceAllowList.CallOpts, acceptor, recipient) +func (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) GetMessage(acceptor common.Address, recipient common.Address) ([32]byte, error) { + return _TermsOfServiceAllowList.Contract.GetMessage(&_TermsOfServiceAllowList.CallOpts, acceptor, recipient) } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListCallerSession) GetMessageHash(acceptor common.Address, recipient common.Address) ([32]byte, error) { - return _TermsOfServiceAllowList.Contract.GetMessageHash(&_TermsOfServiceAllowList.CallOpts, acceptor, recipient) +func (_TermsOfServiceAllowList *TermsOfServiceAllowListCallerSession) GetMessage(acceptor common.Address, recipient common.Address) ([32]byte, error) { + return _TermsOfServiceAllowList.Contract.GetMessage(&_TermsOfServiceAllowList.CallOpts, acceptor, recipient) } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) IsAllowedSender(opts *bind.CallOpts, sender common.Address) (bool, error) { +func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) HasAccess(opts *bind.CallOpts, user common.Address, arg1 []byte) (bool, error) { var out []interface{} - err := _TermsOfServiceAllowList.contract.Call(opts, &out, "isAllowedSender", sender) + err := _TermsOfServiceAllowList.contract.Call(opts, &out, "hasAccess", user, arg1) if err != nil { return *new(bool), err @@ -251,12 +256,12 @@ func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) IsAllowedSender(o } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) IsAllowedSender(sender common.Address) (bool, error) { - return _TermsOfServiceAllowList.Contract.IsAllowedSender(&_TermsOfServiceAllowList.CallOpts, sender) +func (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) HasAccess(user common.Address, arg1 []byte) (bool, error) { + return _TermsOfServiceAllowList.Contract.HasAccess(&_TermsOfServiceAllowList.CallOpts, user, arg1) } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListCallerSession) IsAllowedSender(sender common.Address) (bool, error) { - return _TermsOfServiceAllowList.Contract.IsAllowedSender(&_TermsOfServiceAllowList.CallOpts, sender) +func (_TermsOfServiceAllowList *TermsOfServiceAllowListCallerSession) HasAccess(user common.Address, arg1 []byte) (bool, error) { + return _TermsOfServiceAllowList.Contract.HasAccess(&_TermsOfServiceAllowList.CallOpts, user, arg1) } func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) IsBlockedSender(opts *bind.CallOpts, sender common.Address) (bool, error) { @@ -281,6 +286,28 @@ func (_TermsOfServiceAllowList *TermsOfServiceAllowListCallerSession) IsBlockedS return _TermsOfServiceAllowList.Contract.IsBlockedSender(&_TermsOfServiceAllowList.CallOpts, sender) } +func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TermsOfServiceAllowList.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 (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) Owner() (common.Address, error) { + return _TermsOfServiceAllowList.Contract.Owner(&_TermsOfServiceAllowList.CallOpts) +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListCallerSession) Owner() (common.Address, error) { + return _TermsOfServiceAllowList.Contract.Owner(&_TermsOfServiceAllowList.CallOpts) +} + func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { var out []interface{} err := _TermsOfServiceAllowList.contract.Call(opts, &out, "typeAndVersion") @@ -303,16 +330,28 @@ func (_TermsOfServiceAllowList *TermsOfServiceAllowListCallerSession) TypeAndVer return _TermsOfServiceAllowList.Contract.TypeAndVersion(&_TermsOfServiceAllowList.CallOpts) } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListTransactor) AcceptTermsOfService(opts *bind.TransactOpts, acceptor common.Address, recipient common.Address, proof []byte) (*types.Transaction, error) { - return _TermsOfServiceAllowList.contract.Transact(opts, "acceptTermsOfService", acceptor, recipient, proof) +func (_TermsOfServiceAllowList *TermsOfServiceAllowListTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TermsOfServiceAllowList.contract.Transact(opts, "acceptOwnership") +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) AcceptOwnership() (*types.Transaction, error) { + return _TermsOfServiceAllowList.Contract.AcceptOwnership(&_TermsOfServiceAllowList.TransactOpts) +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _TermsOfServiceAllowList.Contract.AcceptOwnership(&_TermsOfServiceAllowList.TransactOpts) } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) AcceptTermsOfService(acceptor common.Address, recipient common.Address, proof []byte) (*types.Transaction, error) { - return _TermsOfServiceAllowList.Contract.AcceptTermsOfService(&_TermsOfServiceAllowList.TransactOpts, acceptor, recipient, proof) +func (_TermsOfServiceAllowList *TermsOfServiceAllowListTransactor) AcceptTermsOfService(opts *bind.TransactOpts, acceptor common.Address, recipient common.Address, r [32]byte, s [32]byte, v uint8) (*types.Transaction, error) { + return _TermsOfServiceAllowList.contract.Transact(opts, "acceptTermsOfService", acceptor, recipient, r, s, v) } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListTransactorSession) AcceptTermsOfService(acceptor common.Address, recipient common.Address, proof []byte) (*types.Transaction, error) { - return _TermsOfServiceAllowList.Contract.AcceptTermsOfService(&_TermsOfServiceAllowList.TransactOpts, acceptor, recipient, proof) +func (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) AcceptTermsOfService(acceptor common.Address, recipient common.Address, r [32]byte, s [32]byte, v uint8) (*types.Transaction, error) { + return _TermsOfServiceAllowList.Contract.AcceptTermsOfService(&_TermsOfServiceAllowList.TransactOpts, acceptor, recipient, r, s, v) +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListTransactorSession) AcceptTermsOfService(acceptor common.Address, recipient common.Address, r [32]byte, s [32]byte, v uint8) (*types.Transaction, error) { + return _TermsOfServiceAllowList.Contract.AcceptTermsOfService(&_TermsOfServiceAllowList.TransactOpts, acceptor, recipient, r, s, v) } func (_TermsOfServiceAllowList *TermsOfServiceAllowListTransactor) BlockSender(opts *bind.TransactOpts, sender common.Address) (*types.Transaction, error) { @@ -327,16 +366,16 @@ func (_TermsOfServiceAllowList *TermsOfServiceAllowListTransactorSession) BlockS return _TermsOfServiceAllowList.Contract.BlockSender(&_TermsOfServiceAllowList.TransactOpts, sender) } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListTransactor) SetConfig(opts *bind.TransactOpts, config []byte) (*types.Transaction, error) { - return _TermsOfServiceAllowList.contract.Transact(opts, "setConfig", config) +func (_TermsOfServiceAllowList *TermsOfServiceAllowListTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _TermsOfServiceAllowList.contract.Transact(opts, "transferOwnership", to) } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) SetConfig(config []byte) (*types.Transaction, error) { - return _TermsOfServiceAllowList.Contract.SetConfig(&_TermsOfServiceAllowList.TransactOpts, config) +func (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _TermsOfServiceAllowList.Contract.TransferOwnership(&_TermsOfServiceAllowList.TransactOpts, to) } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListTransactorSession) SetConfig(config []byte) (*types.Transaction, error) { - return _TermsOfServiceAllowList.Contract.SetConfig(&_TermsOfServiceAllowList.TransactOpts, config) +func (_TermsOfServiceAllowList *TermsOfServiceAllowListTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _TermsOfServiceAllowList.Contract.TransferOwnership(&_TermsOfServiceAllowList.TransactOpts, to) } func (_TermsOfServiceAllowList *TermsOfServiceAllowListTransactor) UnblockSender(opts *bind.TransactOpts, sender common.Address) (*types.Transaction, error) { @@ -351,8 +390,20 @@ func (_TermsOfServiceAllowList *TermsOfServiceAllowListTransactorSession) Unbloc return _TermsOfServiceAllowList.Contract.UnblockSender(&_TermsOfServiceAllowList.TransactOpts, sender) } -type TermsOfServiceAllowListConfigSetIterator struct { - Event *TermsOfServiceAllowListConfigSet +func (_TermsOfServiceAllowList *TermsOfServiceAllowListTransactor) UpdateConfig(opts *bind.TransactOpts, config TermsOfServiceAllowListConfig) (*types.Transaction, error) { + return _TermsOfServiceAllowList.contract.Transact(opts, "updateConfig", config) +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) UpdateConfig(config TermsOfServiceAllowListConfig) (*types.Transaction, error) { + return _TermsOfServiceAllowList.Contract.UpdateConfig(&_TermsOfServiceAllowList.TransactOpts, config) +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListTransactorSession) UpdateConfig(config TermsOfServiceAllowListConfig) (*types.Transaction, error) { + return _TermsOfServiceAllowList.Contract.UpdateConfig(&_TermsOfServiceAllowList.TransactOpts, config) +} + +type TermsOfServiceAllowListAddedAccessIterator struct { + Event *TermsOfServiceAllowListAddedAccess contract *bind.BoundContract event string @@ -363,7 +414,7 @@ type TermsOfServiceAllowListConfigSetIterator struct { fail error } -func (it *TermsOfServiceAllowListConfigSetIterator) Next() bool { +func (it *TermsOfServiceAllowListAddedAccessIterator) Next() bool { if it.fail != nil { return false @@ -372,7 +423,7 @@ func (it *TermsOfServiceAllowListConfigSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(TermsOfServiceAllowListConfigSet) + it.Event = new(TermsOfServiceAllowListAddedAccess) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -387,7 +438,7 @@ func (it *TermsOfServiceAllowListConfigSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(TermsOfServiceAllowListConfigSet) + it.Event = new(TermsOfServiceAllowListAddedAccess) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -402,32 +453,32 @@ func (it *TermsOfServiceAllowListConfigSetIterator) Next() bool { } } -func (it *TermsOfServiceAllowListConfigSetIterator) Error() error { +func (it *TermsOfServiceAllowListAddedAccessIterator) Error() error { return it.fail } -func (it *TermsOfServiceAllowListConfigSetIterator) Close() error { +func (it *TermsOfServiceAllowListAddedAccessIterator) Close() error { it.sub.Unsubscribe() return nil } -type TermsOfServiceAllowListConfigSet struct { - Enabled bool - Raw types.Log +type TermsOfServiceAllowListAddedAccess struct { + User common.Address + Raw types.Log } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) FilterConfigSet(opts *bind.FilterOpts) (*TermsOfServiceAllowListConfigSetIterator, error) { +func (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) FilterAddedAccess(opts *bind.FilterOpts) (*TermsOfServiceAllowListAddedAccessIterator, error) { - logs, sub, err := _TermsOfServiceAllowList.contract.FilterLogs(opts, "ConfigSet") + logs, sub, err := _TermsOfServiceAllowList.contract.FilterLogs(opts, "AddedAccess") if err != nil { return nil, err } - return &TermsOfServiceAllowListConfigSetIterator{contract: _TermsOfServiceAllowList.contract, event: "ConfigSet", logs: logs, sub: sub}, nil + return &TermsOfServiceAllowListAddedAccessIterator{contract: _TermsOfServiceAllowList.contract, event: "AddedAccess", logs: logs, sub: sub}, nil } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *TermsOfServiceAllowListConfigSet) (event.Subscription, error) { +func (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) WatchAddedAccess(opts *bind.WatchOpts, sink chan<- *TermsOfServiceAllowListAddedAccess) (event.Subscription, error) { - logs, sub, err := _TermsOfServiceAllowList.contract.WatchLogs(opts, "ConfigSet") + logs, sub, err := _TermsOfServiceAllowList.contract.WatchLogs(opts, "AddedAccess") if err != nil { return nil, err } @@ -437,8 +488,8 @@ func (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) WatchConfigSet( select { case log := <-logs: - event := new(TermsOfServiceAllowListConfigSet) - if err := _TermsOfServiceAllowList.contract.UnpackLog(event, "ConfigSet", log); err != nil { + event := new(TermsOfServiceAllowListAddedAccess) + if err := _TermsOfServiceAllowList.contract.UnpackLog(event, "AddedAccess", log); err != nil { return err } event.Raw = log @@ -459,59 +510,748 @@ func (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) WatchConfigSet( }), nil } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) ParseConfigSet(log types.Log) (*TermsOfServiceAllowListConfigSet, error) { - event := new(TermsOfServiceAllowListConfigSet) - if err := _TermsOfServiceAllowList.contract.UnpackLog(event, "ConfigSet", log); err != nil { +func (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) ParseAddedAccess(log types.Log) (*TermsOfServiceAllowListAddedAccess, error) { + event := new(TermsOfServiceAllowListAddedAccess) + if err := _TermsOfServiceAllowList.contract.UnpackLog(event, "AddedAccess", log); err != nil { return nil, err } event.Raw = log return event, nil } -func (_TermsOfServiceAllowList *TermsOfServiceAllowList) ParseLog(log types.Log) (generated.AbigenLog, error) { - switch log.Topics[0] { - case _TermsOfServiceAllowList.abi.Events["ConfigSet"].ID: - return _TermsOfServiceAllowList.ParseConfigSet(log) +type TermsOfServiceAllowListBlockedAccessIterator struct { + Event *TermsOfServiceAllowListBlockedAccess - default: - return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TermsOfServiceAllowListBlockedAccessIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TermsOfServiceAllowListBlockedAccess) + 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(TermsOfServiceAllowListBlockedAccess) + 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 (TermsOfServiceAllowListConfigSet) Topic() common.Hash { - return common.HexToHash("0x22aa8545955b447cb49ea37e67de742e750839c633ded8c9b5b09614843b229f") +func (it *TermsOfServiceAllowListBlockedAccessIterator) Error() error { + return it.fail } -func (_TermsOfServiceAllowList *TermsOfServiceAllowList) Address() common.Address { - return _TermsOfServiceAllowList.address +func (it *TermsOfServiceAllowListBlockedAccessIterator) Close() error { + it.sub.Unsubscribe() + return nil } -type TermsOfServiceAllowListInterface interface { - GetConfigHash(opts *bind.CallOpts) ([32]byte, error) +type TermsOfServiceAllowListBlockedAccess struct { + User common.Address + Raw types.Log +} - GetEthSignedMessageHash(opts *bind.CallOpts, messageHash [32]byte) ([32]byte, error) +func (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) FilterBlockedAccess(opts *bind.FilterOpts) (*TermsOfServiceAllowListBlockedAccessIterator, error) { - GetMessageHash(opts *bind.CallOpts, acceptor common.Address, recipient common.Address) ([32]byte, error) + logs, sub, err := _TermsOfServiceAllowList.contract.FilterLogs(opts, "BlockedAccess") + if err != nil { + return nil, err + } + return &TermsOfServiceAllowListBlockedAccessIterator{contract: _TermsOfServiceAllowList.contract, event: "BlockedAccess", logs: logs, sub: sub}, nil +} - IsAllowedSender(opts *bind.CallOpts, sender common.Address) (bool, error) +func (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) WatchBlockedAccess(opts *bind.WatchOpts, sink chan<- *TermsOfServiceAllowListBlockedAccess) (event.Subscription, error) { - IsBlockedSender(opts *bind.CallOpts, sender common.Address) (bool, error) + logs, sub, err := _TermsOfServiceAllowList.contract.WatchLogs(opts, "BlockedAccess") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: - TypeAndVersion(opts *bind.CallOpts) (string, error) + event := new(TermsOfServiceAllowListBlockedAccess) + if err := _TermsOfServiceAllowList.contract.UnpackLog(event, "BlockedAccess", 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 +} - AcceptTermsOfService(opts *bind.TransactOpts, acceptor common.Address, recipient common.Address, proof []byte) (*types.Transaction, error) +func (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) ParseBlockedAccess(log types.Log) (*TermsOfServiceAllowListBlockedAccess, error) { + event := new(TermsOfServiceAllowListBlockedAccess) + if err := _TermsOfServiceAllowList.contract.UnpackLog(event, "BlockedAccess", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} - BlockSender(opts *bind.TransactOpts, sender common.Address) (*types.Transaction, error) +type TermsOfServiceAllowListConfigUpdatedIterator struct { + Event *TermsOfServiceAllowListConfigUpdated - SetConfig(opts *bind.TransactOpts, config []byte) (*types.Transaction, error) + contract *bind.BoundContract + event string - UnblockSender(opts *bind.TransactOpts, sender common.Address) (*types.Transaction, error) + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TermsOfServiceAllowListConfigUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TermsOfServiceAllowListConfigUpdated) + 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(TermsOfServiceAllowListConfigUpdated) + 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 *TermsOfServiceAllowListConfigUpdatedIterator) Error() error { + return it.fail +} + +func (it *TermsOfServiceAllowListConfigUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TermsOfServiceAllowListConfigUpdated struct { + Config TermsOfServiceAllowListConfig + Raw types.Log +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) FilterConfigUpdated(opts *bind.FilterOpts) (*TermsOfServiceAllowListConfigUpdatedIterator, error) { + + logs, sub, err := _TermsOfServiceAllowList.contract.FilterLogs(opts, "ConfigUpdated") + if err != nil { + return nil, err + } + return &TermsOfServiceAllowListConfigUpdatedIterator{contract: _TermsOfServiceAllowList.contract, event: "ConfigUpdated", logs: logs, sub: sub}, nil +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) WatchConfigUpdated(opts *bind.WatchOpts, sink chan<- *TermsOfServiceAllowListConfigUpdated) (event.Subscription, error) { + + logs, sub, err := _TermsOfServiceAllowList.contract.WatchLogs(opts, "ConfigUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TermsOfServiceAllowListConfigUpdated) + if err := _TermsOfServiceAllowList.contract.UnpackLog(event, "ConfigUpdated", 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 (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) ParseConfigUpdated(log types.Log) (*TermsOfServiceAllowListConfigUpdated, error) { + event := new(TermsOfServiceAllowListConfigUpdated) + if err := _TermsOfServiceAllowList.contract.UnpackLog(event, "ConfigUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TermsOfServiceAllowListOwnershipTransferRequestedIterator struct { + Event *TermsOfServiceAllowListOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TermsOfServiceAllowListOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TermsOfServiceAllowListOwnershipTransferRequested) + 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(TermsOfServiceAllowListOwnershipTransferRequested) + 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 *TermsOfServiceAllowListOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *TermsOfServiceAllowListOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TermsOfServiceAllowListOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TermsOfServiceAllowListOwnershipTransferRequestedIterator, 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 := _TermsOfServiceAllowList.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &TermsOfServiceAllowListOwnershipTransferRequestedIterator{contract: _TermsOfServiceAllowList.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *TermsOfServiceAllowListOwnershipTransferRequested, 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 := _TermsOfServiceAllowList.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(TermsOfServiceAllowListOwnershipTransferRequested) + if err := _TermsOfServiceAllowList.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 (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) ParseOwnershipTransferRequested(log types.Log) (*TermsOfServiceAllowListOwnershipTransferRequested, error) { + event := new(TermsOfServiceAllowListOwnershipTransferRequested) + if err := _TermsOfServiceAllowList.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TermsOfServiceAllowListOwnershipTransferredIterator struct { + Event *TermsOfServiceAllowListOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TermsOfServiceAllowListOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TermsOfServiceAllowListOwnershipTransferred) + 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(TermsOfServiceAllowListOwnershipTransferred) + 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 *TermsOfServiceAllowListOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *TermsOfServiceAllowListOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TermsOfServiceAllowListOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TermsOfServiceAllowListOwnershipTransferredIterator, 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 := _TermsOfServiceAllowList.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &TermsOfServiceAllowListOwnershipTransferredIterator{contract: _TermsOfServiceAllowList.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *TermsOfServiceAllowListOwnershipTransferred, 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 := _TermsOfServiceAllowList.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(TermsOfServiceAllowListOwnershipTransferred) + if err := _TermsOfServiceAllowList.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 (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) ParseOwnershipTransferred(log types.Log) (*TermsOfServiceAllowListOwnershipTransferred, error) { + event := new(TermsOfServiceAllowListOwnershipTransferred) + if err := _TermsOfServiceAllowList.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TermsOfServiceAllowListUnblockedAccessIterator struct { + Event *TermsOfServiceAllowListUnblockedAccess + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TermsOfServiceAllowListUnblockedAccessIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TermsOfServiceAllowListUnblockedAccess) + 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(TermsOfServiceAllowListUnblockedAccess) + 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 *TermsOfServiceAllowListUnblockedAccessIterator) Error() error { + return it.fail +} + +func (it *TermsOfServiceAllowListUnblockedAccessIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TermsOfServiceAllowListUnblockedAccess struct { + User common.Address + Raw types.Log +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) FilterUnblockedAccess(opts *bind.FilterOpts) (*TermsOfServiceAllowListUnblockedAccessIterator, error) { + + logs, sub, err := _TermsOfServiceAllowList.contract.FilterLogs(opts, "UnblockedAccess") + if err != nil { + return nil, err + } + return &TermsOfServiceAllowListUnblockedAccessIterator{contract: _TermsOfServiceAllowList.contract, event: "UnblockedAccess", logs: logs, sub: sub}, nil +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) WatchUnblockedAccess(opts *bind.WatchOpts, sink chan<- *TermsOfServiceAllowListUnblockedAccess) (event.Subscription, error) { + + logs, sub, err := _TermsOfServiceAllowList.contract.WatchLogs(opts, "UnblockedAccess") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TermsOfServiceAllowListUnblockedAccess) + if err := _TermsOfServiceAllowList.contract.UnpackLog(event, "UnblockedAccess", 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 (_TermsOfServiceAllowList *TermsOfServiceAllowListFilterer) ParseUnblockedAccess(log types.Log) (*TermsOfServiceAllowListUnblockedAccess, error) { + event := new(TermsOfServiceAllowListUnblockedAccess) + if err := _TermsOfServiceAllowList.contract.UnpackLog(event, "UnblockedAccess", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowList) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _TermsOfServiceAllowList.abi.Events["AddedAccess"].ID: + return _TermsOfServiceAllowList.ParseAddedAccess(log) + case _TermsOfServiceAllowList.abi.Events["BlockedAccess"].ID: + return _TermsOfServiceAllowList.ParseBlockedAccess(log) + case _TermsOfServiceAllowList.abi.Events["ConfigUpdated"].ID: + return _TermsOfServiceAllowList.ParseConfigUpdated(log) + case _TermsOfServiceAllowList.abi.Events["OwnershipTransferRequested"].ID: + return _TermsOfServiceAllowList.ParseOwnershipTransferRequested(log) + case _TermsOfServiceAllowList.abi.Events["OwnershipTransferred"].ID: + return _TermsOfServiceAllowList.ParseOwnershipTransferred(log) + case _TermsOfServiceAllowList.abi.Events["UnblockedAccess"].ID: + return _TermsOfServiceAllowList.ParseUnblockedAccess(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (TermsOfServiceAllowListAddedAccess) Topic() common.Hash { + return common.HexToHash("0x87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db4") +} + +func (TermsOfServiceAllowListBlockedAccess) Topic() common.Hash { + return common.HexToHash("0x337cd0f3f594112b6d830afb510072d3b08556b446514f73b8109162fd1151e1") +} + +func (TermsOfServiceAllowListConfigUpdated) Topic() common.Hash { + return common.HexToHash("0x0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a") +} + +func (TermsOfServiceAllowListOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (TermsOfServiceAllowListOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (TermsOfServiceAllowListUnblockedAccess) Topic() common.Hash { + return common.HexToHash("0x28bbd0761309a99e8fb5e5d02ada0b7b2db2e5357531ff5dbfc205c3f5b6592b") +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowList) Address() common.Address { + return _TermsOfServiceAllowList.address +} + +type TermsOfServiceAllowListInterface interface { + GetAllAllowedSenders(opts *bind.CallOpts) ([]common.Address, error) + + GetConfig(opts *bind.CallOpts) (TermsOfServiceAllowListConfig, error) + + GetMessage(opts *bind.CallOpts, acceptor common.Address, recipient common.Address) ([32]byte, error) + + HasAccess(opts *bind.CallOpts, user common.Address, arg1 []byte) (bool, error) + + IsBlockedSender(opts *bind.CallOpts, sender common.Address) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + AcceptTermsOfService(opts *bind.TransactOpts, acceptor common.Address, recipient common.Address, r [32]byte, s [32]byte, v uint8) (*types.Transaction, error) + + BlockSender(opts *bind.TransactOpts, sender common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + UnblockSender(opts *bind.TransactOpts, sender common.Address) (*types.Transaction, error) + + UpdateConfig(opts *bind.TransactOpts, config TermsOfServiceAllowListConfig) (*types.Transaction, error) + + FilterAddedAccess(opts *bind.FilterOpts) (*TermsOfServiceAllowListAddedAccessIterator, error) + + WatchAddedAccess(opts *bind.WatchOpts, sink chan<- *TermsOfServiceAllowListAddedAccess) (event.Subscription, error) + + ParseAddedAccess(log types.Log) (*TermsOfServiceAllowListAddedAccess, error) + + FilterBlockedAccess(opts *bind.FilterOpts) (*TermsOfServiceAllowListBlockedAccessIterator, error) + + WatchBlockedAccess(opts *bind.WatchOpts, sink chan<- *TermsOfServiceAllowListBlockedAccess) (event.Subscription, error) + + ParseBlockedAccess(log types.Log) (*TermsOfServiceAllowListBlockedAccess, error) + + FilterConfigUpdated(opts *bind.FilterOpts) (*TermsOfServiceAllowListConfigUpdatedIterator, error) + + WatchConfigUpdated(opts *bind.WatchOpts, sink chan<- *TermsOfServiceAllowListConfigUpdated) (event.Subscription, error) + + ParseConfigUpdated(log types.Log) (*TermsOfServiceAllowListConfigUpdated, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TermsOfServiceAllowListOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *TermsOfServiceAllowListOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*TermsOfServiceAllowListOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TermsOfServiceAllowListOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *TermsOfServiceAllowListOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*TermsOfServiceAllowListOwnershipTransferred, error) - FilterConfigSet(opts *bind.FilterOpts) (*TermsOfServiceAllowListConfigSetIterator, error) + FilterUnblockedAccess(opts *bind.FilterOpts) (*TermsOfServiceAllowListUnblockedAccessIterator, error) - WatchConfigSet(opts *bind.WatchOpts, sink chan<- *TermsOfServiceAllowListConfigSet) (event.Subscription, error) + WatchUnblockedAccess(opts *bind.WatchOpts, sink chan<- *TermsOfServiceAllowListUnblockedAccess) (event.Subscription, error) - ParseConfigSet(log types.Log) (*TermsOfServiceAllowListConfigSet, error) + ParseUnblockedAccess(log types.Log) (*TermsOfServiceAllowListUnblockedAccess, error) ParseLog(log types.Log) (generated.AbigenLog, error) diff --git a/core/gethwrappers/functions/generated/functions_client/functions_client.go b/core/gethwrappers/functions/generated/functions_client/functions_client.go index 2bfb9bb981c..b6d8a383d16 100644 --- a/core/gethwrappers/functions/generated/functions_client/functions_client.go +++ b/core/gethwrappers/functions/generated/functions_client/functions_client.go @@ -31,7 +31,7 @@ var ( ) var FunctionsClientMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"OnlyRouterCanFufill\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestSent\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"handleOracleFulfillment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[],\"name\":\"OnlyRouterCanFulfill\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestSent\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"handleOracleFulfillment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", } var FunctionsClientABI = FunctionsClientMetaData.ABI diff --git a/core/gethwrappers/functions/generated/functions_client_example/functions_client_example.go b/core/gethwrappers/functions/generated/functions_client_example/functions_client_example.go index 728dcec7f84..6dc02520146 100644 --- a/core/gethwrappers/functions/generated/functions_client_example/functions_client_example.go +++ b/core/gethwrappers/functions/generated/functions_client_example/functions_client_example.go @@ -31,8 +31,8 @@ var ( ) var FunctionsClientExampleMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyArgs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySource\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoInlineSecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyRouterCanFufill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"UnexpectedRequestID\",\"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\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestSent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_GAS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"handleOracleFulfillment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastError\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastErrorLength\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastRequestId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastResponse\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastResponseLength\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"source\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedSecretsReferences\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"args\",\"type\":\"string[]\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"jobId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b50604051620019ed380380620019ed833981016040819052620000349162000198565b600080546001600160a01b0319166001600160a01b038316178155339081906001600160a01b038216620000af5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600180546001600160a01b0319166001600160a01b0384811691909117909155811615620000e257620000e281620000ec565b50505050620001ca565b336001600160a01b03821603620001465760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000a6565b600280546001600160a01b0319166001600160a01b03838116918217909255600154604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b600060208284031215620001ab57600080fd5b81516001600160a01b0381168114620001c357600080fd5b9392505050565b61181380620001da6000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80636d9809a011610081578063b48cffea1161005b578063b48cffea14610182578063f2fde38b14610192578063fc2a88c3146101a557600080fd5b80636d9809a01461014857806379ba5097146101525780638da5cb5b1461015a57600080fd5b80632c29166b116100b25780632c29166b146100ff5780635fa353e71461012c57806362747e421461013f57600080fd5b80630ca76175146100ce57806329f0de3f146100e3575b600080fd5b6100e16100dc36600461125f565b6101ae565b005b6100ec60055481565b6040519081526020015b60405180910390f35b60065461011790640100000000900463ffffffff1681565b60405163ffffffff90911681526020016100f6565b6100e161013a366004611332565b61020f565b6100ec60045481565b6101176201117081565b6100e1610319565b60015460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f6565b6006546101179063ffffffff1681565b6100e16101a0366004611416565b61041f565b6100ec60035481565b60005473ffffffffffffffffffffffffffffffffffffffff1633146101ff576040517f5099014100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61020a838383610433565b505050565b610217610501565b6102586040805160e0810190915280600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b61029a89898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506105849050565b85156102e2576102e287878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506105959050565b83156102fc576102fc6102f5858761144c565b82906105df565b61030b81846201117085610622565b600355505050505050505050565b60025473ffffffffffffffffffffffffffffffffffffffff16331461039f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560028054909116905560405173ffffffffffffffffffffffffffffffffffffffff909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b610427610501565b61043081610646565b50565b8260035414610471576040517fd068bf5b00000000000000000000000000000000000000000000000000000000815260048101849052602401610396565b61047a8261073c565b6004558151600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff9092169190911790556104bc8161073c565b600555516006805463ffffffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff9092169190911790555050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610396565b565b61059182600080846107c4565b5050565b80516000036105d0576040517fe889636f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016020830152608090910152565b805160000361061a576040517ffe936cb700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a090910152565b60008061062e8661085b565b905061063c81868686610bcc565b9695505050505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036106c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610396565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600154604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b600080600060209050602084511015610753575082515b60005b818110156107bb57610769816008611542565b85828151811061077b5761077b611559565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c9290921791806107b381611588565b915050610756565b50909392505050565b80516000036107ff576040517f22ce3edd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83836002811115610812576108126114e4565b90816002811115610825576108256114e4565b9052506040840182801561083b5761083b6114e4565b9081801561084b5761084b6114e4565b9052506060909301929092525050565b6060610865611116565b805161087390610100610ca5565b506108b3816040518060400160405280600c81526020017f636f64654c6f636174696f6e0000000000000000000000000000000000000000815250610d1f565b6108d281846000015160028111156108cd576108cd6114e4565b610d38565b610911816040518060400160405280600881526020017f6c616e6775616765000000000000000000000000000000000000000000000000815250610d1f565b61092b81846040015160008111156108cd576108cd6114e4565b61096a816040518060400160405280600681526020017f736f757263650000000000000000000000000000000000000000000000000000815250610d1f565b610978818460600151610d1f565b60a08301515115610a1e576109c2816040518060400160405280600481526020017f6172677300000000000000000000000000000000000000000000000000000000815250610d1f565b6109cb81610d71565b60005b8360a0015151811015610a1457610a02828560a0015183815181106109f5576109f5611559565b6020026020010151610d1f565b80610a0c81611588565b9150506109ce565b50610a1e81610d95565b60808301515115610b1e57600083602001516002811115610a4157610a416114e4565b03610a78576040517fa80d31f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ab7816040518060400160405280600f81526020017f736563726574734c6f636174696f6e0000000000000000000000000000000000815250610d1f565b610ad181846020015160028111156108cd576108cd6114e4565b610b10816040518060400160405280600781526020017f7365637265747300000000000000000000000000000000000000000000000000815250610d1f565b610b1e818460800151610db3565b60c08301515115610bc457610b68816040518060400160405280600981526020017f6279746573417267730000000000000000000000000000000000000000000000815250610d1f565b610b7181610d71565b60005b8360c0015151811015610bba57610ba8828560c001518381518110610b9b57610b9b611559565b6020026020010151610db3565b80610bb281611588565b915050610b74565b50610bc481610d95565b515192915050565b600080546040517f461d276200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063461d276290610c2c9087908990600190899089906004016115c0565b6020604051808303816000875af1158015610c4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6f9190611660565b60405190915081907f1131472297a800fee664d1d89cfa8f7676ff07189ecc53f80bbb5f4969099db890600090a2949350505050565b604080518082019091526060815260006020820152610cc5602083611679565b15610ced57610cd5602083611679565b610ce09060206116b4565b610cea90836116c7565b91505b602080840183905260405180855260008152908184010181811015610d1157600080fd5b604052508290505b92915050565b610d2c8260038351610dbc565b815161020a9082610ee3565b8151610d459060c2610f0b565b506105918282604051602001610d5d91815260200190565b604051602081830303815290604052610db3565b610d7c816004610f74565b600181602001818151610d8f91906116c7565b90525050565b610da0816007610f74565b600181602001818151610d8f91906116b4565b610d2c82600283515b60178167ffffffffffffffff1611610de9578251610de39060e0600585901b168317610f0b565b50505050565b60ff8167ffffffffffffffff1611610e2b578251610e12906018611fe0600586901b1617610f0b565b508251610de39067ffffffffffffffff83166001610f8b565b61ffff8167ffffffffffffffff1611610e6e578251610e55906019611fe0600586901b1617610f0b565b508251610de39067ffffffffffffffff83166002610f8b565b63ffffffff8167ffffffffffffffff1611610eb3578251610e9a90601a611fe0600586901b1617610f0b565b508251610de39067ffffffffffffffff83166004610f8b565b8251610eca90601b611fe0600586901b1617610f0b565b508251610de39067ffffffffffffffff83166008610f8b565b604080518082019091526060815260006020820152610f0483838451611010565b9392505050565b6040805180820190915260608152600060208201528251516000610f308260016116c7565b905084602001518210610f5157610f5185610f4c836002611542565b6110ff565b8451602083820101858153508051821115610f6a578181525b5093949350505050565b815161020a90601f611fe0600585901b1617610f0b565b6040805180820190915260608152600060208201528351516000610faf82856116c7565b90508560200151811115610fcc57610fcc86610f4c836002611542565b60006001610fdc866101006117fa565b610fe691906116b4565b90508651828101878319825116178152508051831115611004578281525b50959695505050505050565b604080518082019091526060815260006020820152825182111561103357600080fd5b835151600061104284836116c7565b9050856020015181111561105f5761105f86610f4c836002611542565b855180518382016020019160009180851115611079578482525b505050602086015b602086106110b957805182526110986020836116c7565b91506110a56020826116c7565b90506110b26020876116b4565b9550611081565b5181517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208890036101000a0190811690199190911617905250849150509392505050565b815161110b8383610ca5565b50610de38382610ee3565b604051806040016040528061113e604051806040016040528060608152602001600081525090565b8152602001600081525090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156111c1576111c161114b565b604052919050565b600067ffffffffffffffff8311156111e3576111e361114b565b61121460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8601160161117a565b905082815283838301111561122857600080fd5b828260208301376000602084830101529392505050565b600082601f83011261125057600080fd5b610f04838335602085016111c9565b60008060006060848603121561127457600080fd5b83359250602084013567ffffffffffffffff8082111561129357600080fd5b61129f8783880161123f565b935060408601359150808211156112b557600080fd5b506112c28682870161123f565b9150509250925092565b60008083601f8401126112de57600080fd5b50813567ffffffffffffffff8111156112f657600080fd5b60208301915083602082850101111561130e57600080fd5b9250929050565b803567ffffffffffffffff8116811461132d57600080fd5b919050565b60008060008060008060008060a0898b03121561134e57600080fd5b883567ffffffffffffffff8082111561136657600080fd5b6113728c838d016112cc565b909a50985060208b013591508082111561138b57600080fd5b6113978c838d016112cc565b909850965060408b01359150808211156113b057600080fd5b818b0191508b601f8301126113c457600080fd5b8135818111156113d357600080fd5b8c60208260051b85010111156113e857600080fd5b60208301965080955050505061140060608a01611315565b9150608089013590509295985092959890939650565b60006020828403121561142857600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610f0457600080fd5b600067ffffffffffffffff808411156114675761146761114b565b8360051b602061147881830161117a565b86815291850191818101903684111561149057600080fd5b865b848110156114d8578035868111156114aa5760008081fd5b880136601f8201126114bc5760008081fd5b6114ca3682358784016111c9565b845250918301918301611492565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610d1957610d19611513565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036115b9576115b9611513565b5060010190565b67ffffffffffffffff861681526000602060a08184015286518060a085015260005b818110156115fe5788810183015185820160c0015282016115e2565b50600060c0828601015260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010192505050611647604083018661ffff169052565b63ffffffff939093166060820152608001529392505050565b60006020828403121561167257600080fd5b5051919050565b6000826116af577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b81810381811115610d1957610d19611513565b80820180821115610d1957610d19611513565b600181815b8085111561173357817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561171957611719611513565b8085161561172657918102915b93841c93908002906116df565b509250929050565b60008261174a57506001610d19565b8161175757506000610d19565b816001811461176d576002811461177757611793565b6001915050610d19565b60ff84111561178857611788611513565b50506001821b610d19565b5060208310610133831016604e8410600b84101617156117b6575081810a610d19565b6117c083836116da565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156117f2576117f2611513565b029392505050565b6000610f04838361173b56fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyArgs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySource\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoInlineSecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyRouterCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"UnexpectedRequestID\",\"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\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestSent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_GAS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"handleOracleFulfillment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastError\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastErrorLength\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastRequestId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastResponse\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastResponseLength\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"source\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedSecretsReferences\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"args\",\"type\":\"string[]\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"jobId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b5060405162001a7638038062001a76833981016040819052620000349162000180565b6001600160a01b0381166080523380600081620000985760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000cb57620000cb81620000d5565b50505050620001b2565b336001600160a01b038216036200012f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008f565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019357600080fd5b81516001600160a01b0381168114620001ab57600080fd5b9392505050565b6080516118a1620001d5600039600081816101c60152610a2a01526118a16000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80636d9809a011610081578063b1e217491161005b578063b1e2174914610182578063f2fde38b1461018b578063f7b4c06f1461019e57600080fd5b80636d9809a01461014857806379ba5097146101525780638da5cb5b1461015a57600080fd5b806342748b2a116100b257806342748b2a146100ff5780634b0795a81461012c5780635fa353e71461013557600080fd5b80630ca76175146100ce5780633944ea3a146100e3575b600080fd5b6100e16100dc3660046112ed565b6101ae565b005b6100ec60035481565b6040519081526020015b60405180910390f35b60055461011790640100000000900463ffffffff1681565b60405163ffffffff90911681526020016100f6565b6100ec60045481565b6100e16101433660046113c0565b61022d565b6101176201117081565b6100e1610347565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f6565b6100ec60025481565b6100e16101993660046114a4565b610449565b6005546101179063ffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461021d576040517fc6829f8300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61022883838361045d565b505050565b61023561052b565b61027e6040805161010081019091528060008152602001600081526020016000815260200160608152602001606081526020016060815260200160608152602001606081525090565b6102c089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506105ae9050565b85156103085761030887878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506105bf9050565b83156103225761032261031b85876114da565b8290610609565b61033961032e8261064c565b846201117085610a25565b600255505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61045161052b565b61045a81610b04565b50565b826002541461049b576040517fd068bf5b000000000000000000000000000000000000000000000000000000008152600481018490526024016103c4565b6104a482610bf9565b6003558151600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff9092169190911790556104e681610bf9565b600455516005805463ffffffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff9092169190911790555050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103c4565b565b6105bb8260008084610c7b565b5050565b80516000036105fa576040517fe889636f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016020830152608090910152565b8051600003610644576040517ffe936cb700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c090910152565b6060600061065b610100610d12565b90506106a56040518060400160405280600c81526020017f636f64654c6f636174696f6e000000000000000000000000000000000000000081525082610d3390919063ffffffff16565b82516106c39060028111156106bc576106bc611572565b8290610d4c565b60408051808201909152600881527f6c616e67756167650000000000000000000000000000000000000000000000006020820152610702908290610d33565b60408301516107199080156106bc576106bc611572565b60408051808201909152600681527f736f7572636500000000000000000000000000000000000000000000000000006020820152610758908290610d33565b6060830151610768908290610d33565b60a083015151156107c25760408051808201909152601081527f726571756573745369676e61747572650000000000000000000000000000000060208201526107b2908290610d33565b60a08301516107c2908290610d81565b60c0830151511561086f5760408051808201909152600481527f6172677300000000000000000000000000000000000000000000000000000000602082015261080c908290610d33565b61081581610d8e565b60005b8360c0015151811015610865576108558460c00151828151811061083e5761083e6115a1565b602002602001015183610d3390919063ffffffff16565b61085e816115ff565b9050610818565b5061086f81610db2565b608083015151156109705760008360200151600281111561089257610892611572565b036108c9576040517fa80d31f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201909152600f81527f736563726574734c6f636174696f6e00000000000000000000000000000000006020820152610908908290610d33565b610921836020015160028111156106bc576106bc611572565b60408051808201909152600781527f73656372657473000000000000000000000000000000000000000000000000006020820152610960908290610d33565b6080830151610970908290610d81565b60e08301515115610a1d5760408051808201909152600981527f627974657341726773000000000000000000000000000000000000000000000060208201526109ba908290610d33565b6109c381610d8e565b60005b8360e0015151811015610a1357610a038460e0015182815181106109ec576109ec6115a1565b602002602001015183610d8190919063ffffffff16565b610a0c816115ff565b90506109c6565b50610a1d81610db2565b515192915050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663461d27628688600188886040518663ffffffff1660e01b8152600401610a8a959493929190611637565b6020604051808303816000875af1158015610aa9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610acd91906116d7565b60405190915081907f1131472297a800fee664d1d89cfa8f7676ff07189ecc53f80bbb5f4969099db890600090a295945050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603610b83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103c4565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008060209050602083511015610c0e575081515b60005b81811015610c7457610c248160086116f0565b848281518110610c3657610c366115a1565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c9290921791610c6d816115ff565b9050610c11565b5050919050565b8051600003610cb6576040517f22ce3edd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83836002811115610cc957610cc9611572565b90816002811115610cdc57610cdc611572565b90525060408401828015610cf257610cf2611572565b90818015610d0257610d02611572565b9052506060909301929092525050565b610d1a6111a4565b8051610d269083610dd0565b5060006020820152919050565b610d408260038351610e4a565b81516102289082610f71565b8151610d599060c2610f99565b506105bb8282604051602001610d7191815260200190565b6040516020818303038152906040525b610d408260028351610e4a565b610d99816004611002565b600181602001818151610dac9190611707565b90525050565b610dbd816007611002565b600181602001818151610dac919061171a565b604080518082019091526060815260006020820152610df060208361172d565b15610e1857610e0060208361172d565b610e0b90602061171a565b610e159083611707565b91505b602080840183905260405180855260008152908184010181811015610e3c57600080fd5b604052508290505b92915050565b60178167ffffffffffffffff1611610e77578251610e719060e0600585901b168317610f99565b50505050565b60ff8167ffffffffffffffff1611610eb9578251610ea0906018611fe0600586901b1617610f99565b508251610e719067ffffffffffffffff83166001611019565b61ffff8167ffffffffffffffff1611610efc578251610ee3906019611fe0600586901b1617610f99565b508251610e719067ffffffffffffffff83166002611019565b63ffffffff8167ffffffffffffffff1611610f41578251610f2890601a611fe0600586901b1617610f99565b508251610e719067ffffffffffffffff83166004611019565b8251610f5890601b611fe0600586901b1617610f99565b508251610e719067ffffffffffffffff83166008611019565b604080518082019091526060815260006020820152610f928383845161109e565b9392505050565b6040805180820190915260608152600060208201528251516000610fbe826001611707565b905084602001518210610fdf57610fdf85610fda8360026116f0565b61118d565b8451602083820101858153508051821115610ff8578181525b5093949350505050565b815161022890601f611fe0600585901b1617610f99565b604080518082019091526060815260006020820152835151600061103d8285611707565b9050856020015181111561105a5761105a86610fda8360026116f0565b6000600161106a86610100611888565b611074919061171a565b90508651828101878319825116178152508051831115611092578281525b50959695505050505050565b60408051808201909152606081526000602082015282518211156110c157600080fd5b83515160006110d08483611707565b905085602001518111156110ed576110ed86610fda8360026116f0565b855180518382016020019160009180851115611107578482525b505050602086015b602086106111475780518252611126602083611707565b9150611133602082611707565b905061114060208761171a565b955061110f565b5181517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208890036101000a0190811690199190911617905250849150509392505050565b81516111998383610dd0565b50610e718382610f71565b60405180604001604052806111cc604051806040016040528060608152602001600081525090565b8152602001600081525090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561124f5761124f6111d9565b604052919050565b600067ffffffffffffffff831115611271576112716111d9565b6112a260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f86011601611208565b90508281528383830111156112b657600080fd5b828260208301376000602084830101529392505050565b600082601f8301126112de57600080fd5b610f9283833560208501611257565b60008060006060848603121561130257600080fd5b83359250602084013567ffffffffffffffff8082111561132157600080fd5b61132d878388016112cd565b9350604086013591508082111561134357600080fd5b50611350868287016112cd565b9150509250925092565b60008083601f84011261136c57600080fd5b50813567ffffffffffffffff81111561138457600080fd5b60208301915083602082850101111561139c57600080fd5b9250929050565b803567ffffffffffffffff811681146113bb57600080fd5b919050565b60008060008060008060008060a0898b0312156113dc57600080fd5b883567ffffffffffffffff808211156113f457600080fd5b6114008c838d0161135a565b909a50985060208b013591508082111561141957600080fd5b6114258c838d0161135a565b909850965060408b013591508082111561143e57600080fd5b818b0191508b601f83011261145257600080fd5b81358181111561146157600080fd5b8c60208260051b850101111561147657600080fd5b60208301965080955050505061148e60608a016113a3565b9150608089013590509295985092959890939650565b6000602082840312156114b657600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610f9257600080fd5b600067ffffffffffffffff808411156114f5576114f56111d9565b8360051b6020611506818301611208565b86815291850191818101903684111561151e57600080fd5b865b84811015611566578035868111156115385760008081fd5b880136601f82011261154a5760008081fd5b611558368235878401611257565b845250918301918301611520565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611630576116306115d0565b5060010190565b67ffffffffffffffff861681526000602060a08184015286518060a085015260005b818110156116755788810183015185820160c001528201611659565b50600060c0828601015260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116850101925050506116be604083018661ffff169052565b63ffffffff939093166060820152608001529392505050565b6000602082840312156116e957600080fd5b5051919050565b8082028115828204841417610e4457610e446115d0565b80820180821115610e4457610e446115d0565b81810381811115610e4457610e446115d0565b600082611763577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b600181815b808511156117c157817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156117a7576117a76115d0565b808516156117b457918102915b93841c939080029061176d565b509250929050565b6000826117d857506001610e44565b816117e557506000610e44565b81600181146117fb576002811461180557611821565b6001915050610e44565b60ff841115611816576118166115d0565b50506001821b610e44565b5060208310610133831016604e8410600b8410161715611844575081810a610e44565b61184e8383611768565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115611880576118806115d0565b029392505050565b6000610f9283836117c956fea164736f6c6343000813000a", } var FunctionsClientExampleABI = FunctionsClientExampleMetaData.ABI @@ -193,75 +193,75 @@ func (_FunctionsClientExample *FunctionsClientExampleCallerSession) MAXCALLBACKG return _FunctionsClientExample.Contract.MAXCALLBACKGAS(&_FunctionsClientExample.CallOpts) } -func (_FunctionsClientExample *FunctionsClientExampleCaller) LastError(opts *bind.CallOpts) ([32]byte, error) { +func (_FunctionsClientExample *FunctionsClientExampleCaller) Owner(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _FunctionsClientExample.contract.Call(opts, &out, "lastError") + err := _FunctionsClientExample.contract.Call(opts, &out, "owner") if err != nil { - return *new([32]byte), err + return *new(common.Address), err } - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) return out0, err } -func (_FunctionsClientExample *FunctionsClientExampleSession) LastError() ([32]byte, error) { - return _FunctionsClientExample.Contract.LastError(&_FunctionsClientExample.CallOpts) +func (_FunctionsClientExample *FunctionsClientExampleSession) Owner() (common.Address, error) { + return _FunctionsClientExample.Contract.Owner(&_FunctionsClientExample.CallOpts) } -func (_FunctionsClientExample *FunctionsClientExampleCallerSession) LastError() ([32]byte, error) { - return _FunctionsClientExample.Contract.LastError(&_FunctionsClientExample.CallOpts) +func (_FunctionsClientExample *FunctionsClientExampleCallerSession) Owner() (common.Address, error) { + return _FunctionsClientExample.Contract.Owner(&_FunctionsClientExample.CallOpts) } -func (_FunctionsClientExample *FunctionsClientExampleCaller) LastErrorLength(opts *bind.CallOpts) (uint32, error) { +func (_FunctionsClientExample *FunctionsClientExampleCaller) SLastError(opts *bind.CallOpts) ([32]byte, error) { var out []interface{} - err := _FunctionsClientExample.contract.Call(opts, &out, "lastErrorLength") + err := _FunctionsClientExample.contract.Call(opts, &out, "s_lastError") if err != nil { - return *new(uint32), err + return *new([32]byte), err } - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) return out0, err } -func (_FunctionsClientExample *FunctionsClientExampleSession) LastErrorLength() (uint32, error) { - return _FunctionsClientExample.Contract.LastErrorLength(&_FunctionsClientExample.CallOpts) +func (_FunctionsClientExample *FunctionsClientExampleSession) SLastError() ([32]byte, error) { + return _FunctionsClientExample.Contract.SLastError(&_FunctionsClientExample.CallOpts) } -func (_FunctionsClientExample *FunctionsClientExampleCallerSession) LastErrorLength() (uint32, error) { - return _FunctionsClientExample.Contract.LastErrorLength(&_FunctionsClientExample.CallOpts) +func (_FunctionsClientExample *FunctionsClientExampleCallerSession) SLastError() ([32]byte, error) { + return _FunctionsClientExample.Contract.SLastError(&_FunctionsClientExample.CallOpts) } -func (_FunctionsClientExample *FunctionsClientExampleCaller) LastRequestId(opts *bind.CallOpts) ([32]byte, error) { +func (_FunctionsClientExample *FunctionsClientExampleCaller) SLastErrorLength(opts *bind.CallOpts) (uint32, error) { var out []interface{} - err := _FunctionsClientExample.contract.Call(opts, &out, "lastRequestId") + err := _FunctionsClientExample.contract.Call(opts, &out, "s_lastErrorLength") if err != nil { - return *new([32]byte), err + return *new(uint32), err } - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) return out0, err } -func (_FunctionsClientExample *FunctionsClientExampleSession) LastRequestId() ([32]byte, error) { - return _FunctionsClientExample.Contract.LastRequestId(&_FunctionsClientExample.CallOpts) +func (_FunctionsClientExample *FunctionsClientExampleSession) SLastErrorLength() (uint32, error) { + return _FunctionsClientExample.Contract.SLastErrorLength(&_FunctionsClientExample.CallOpts) } -func (_FunctionsClientExample *FunctionsClientExampleCallerSession) LastRequestId() ([32]byte, error) { - return _FunctionsClientExample.Contract.LastRequestId(&_FunctionsClientExample.CallOpts) +func (_FunctionsClientExample *FunctionsClientExampleCallerSession) SLastErrorLength() (uint32, error) { + return _FunctionsClientExample.Contract.SLastErrorLength(&_FunctionsClientExample.CallOpts) } -func (_FunctionsClientExample *FunctionsClientExampleCaller) LastResponse(opts *bind.CallOpts) ([32]byte, error) { +func (_FunctionsClientExample *FunctionsClientExampleCaller) SLastRequestId(opts *bind.CallOpts) ([32]byte, error) { var out []interface{} - err := _FunctionsClientExample.contract.Call(opts, &out, "lastResponse") + err := _FunctionsClientExample.contract.Call(opts, &out, "s_lastRequestId") if err != nil { return *new([32]byte), err @@ -273,56 +273,56 @@ func (_FunctionsClientExample *FunctionsClientExampleCaller) LastResponse(opts * } -func (_FunctionsClientExample *FunctionsClientExampleSession) LastResponse() ([32]byte, error) { - return _FunctionsClientExample.Contract.LastResponse(&_FunctionsClientExample.CallOpts) +func (_FunctionsClientExample *FunctionsClientExampleSession) SLastRequestId() ([32]byte, error) { + return _FunctionsClientExample.Contract.SLastRequestId(&_FunctionsClientExample.CallOpts) } -func (_FunctionsClientExample *FunctionsClientExampleCallerSession) LastResponse() ([32]byte, error) { - return _FunctionsClientExample.Contract.LastResponse(&_FunctionsClientExample.CallOpts) +func (_FunctionsClientExample *FunctionsClientExampleCallerSession) SLastRequestId() ([32]byte, error) { + return _FunctionsClientExample.Contract.SLastRequestId(&_FunctionsClientExample.CallOpts) } -func (_FunctionsClientExample *FunctionsClientExampleCaller) LastResponseLength(opts *bind.CallOpts) (uint32, error) { +func (_FunctionsClientExample *FunctionsClientExampleCaller) SLastResponse(opts *bind.CallOpts) ([32]byte, error) { var out []interface{} - err := _FunctionsClientExample.contract.Call(opts, &out, "lastResponseLength") + err := _FunctionsClientExample.contract.Call(opts, &out, "s_lastResponse") if err != nil { - return *new(uint32), err + return *new([32]byte), err } - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) return out0, err } -func (_FunctionsClientExample *FunctionsClientExampleSession) LastResponseLength() (uint32, error) { - return _FunctionsClientExample.Contract.LastResponseLength(&_FunctionsClientExample.CallOpts) +func (_FunctionsClientExample *FunctionsClientExampleSession) SLastResponse() ([32]byte, error) { + return _FunctionsClientExample.Contract.SLastResponse(&_FunctionsClientExample.CallOpts) } -func (_FunctionsClientExample *FunctionsClientExampleCallerSession) LastResponseLength() (uint32, error) { - return _FunctionsClientExample.Contract.LastResponseLength(&_FunctionsClientExample.CallOpts) +func (_FunctionsClientExample *FunctionsClientExampleCallerSession) SLastResponse() ([32]byte, error) { + return _FunctionsClientExample.Contract.SLastResponse(&_FunctionsClientExample.CallOpts) } -func (_FunctionsClientExample *FunctionsClientExampleCaller) Owner(opts *bind.CallOpts) (common.Address, error) { +func (_FunctionsClientExample *FunctionsClientExampleCaller) SLastResponseLength(opts *bind.CallOpts) (uint32, error) { var out []interface{} - err := _FunctionsClientExample.contract.Call(opts, &out, "owner") + err := _FunctionsClientExample.contract.Call(opts, &out, "s_lastResponseLength") if err != nil { - return *new(common.Address), err + return *new(uint32), err } - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) return out0, err } -func (_FunctionsClientExample *FunctionsClientExampleSession) Owner() (common.Address, error) { - return _FunctionsClientExample.Contract.Owner(&_FunctionsClientExample.CallOpts) +func (_FunctionsClientExample *FunctionsClientExampleSession) SLastResponseLength() (uint32, error) { + return _FunctionsClientExample.Contract.SLastResponseLength(&_FunctionsClientExample.CallOpts) } -func (_FunctionsClientExample *FunctionsClientExampleCallerSession) Owner() (common.Address, error) { - return _FunctionsClientExample.Contract.Owner(&_FunctionsClientExample.CallOpts) +func (_FunctionsClientExample *FunctionsClientExampleCallerSession) SLastResponseLength() (uint32, error) { + return _FunctionsClientExample.Contract.SLastResponseLength(&_FunctionsClientExample.CallOpts) } func (_FunctionsClientExample *FunctionsClientExampleTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { @@ -938,17 +938,17 @@ func (_FunctionsClientExample *FunctionsClientExample) Address() common.Address type FunctionsClientExampleInterface interface { MAXCALLBACKGAS(opts *bind.CallOpts) (uint32, error) - LastError(opts *bind.CallOpts) ([32]byte, error) + Owner(opts *bind.CallOpts) (common.Address, error) - LastErrorLength(opts *bind.CallOpts) (uint32, error) + SLastError(opts *bind.CallOpts) ([32]byte, error) - LastRequestId(opts *bind.CallOpts) ([32]byte, error) + SLastErrorLength(opts *bind.CallOpts) (uint32, error) - LastResponse(opts *bind.CallOpts) ([32]byte, error) + SLastRequestId(opts *bind.CallOpts) ([32]byte, error) - LastResponseLength(opts *bind.CallOpts) (uint32, error) + SLastResponse(opts *bind.CallOpts) ([32]byte, error) - Owner(opts *bind.CallOpts) (common.Address, error) + SLastResponseLength(opts *bind.CallOpts) (uint32, error) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) diff --git a/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go b/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go index 9f4ce45fb6b..3de584ddb22 100644 --- a/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go +++ b/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go @@ -30,45 +30,56 @@ var ( _ = abi.ConvertType ) -type FunctionsBillingCommitment struct { - SubscriptionId uint64 - Client common.Address - CallbackGasLimit uint32 - ExpectedGasPrice *big.Int - Don common.Address - DonFee *big.Int - AdminFee *big.Int - EstimatedTotalCostJuels *big.Int - GasOverhead *big.Int - Timestamp *big.Int -} - -type IFunctionsBillingRequestBilling struct { - SubscriptionId uint64 - Client common.Address - CallbackGasLimit uint32 - ExpectedGasPrice *big.Int -} - -type IFunctionsCoordinatorRequest struct { - SubscriptionId uint64 - Data []byte - DataVersion uint16 - CallbackGasLimit uint32 - Caller common.Address - SubscriptionOwner common.Address +type FunctionsBillingConfig struct { + MaxCallbackGasLimit uint32 + FeedStalenessSeconds uint32 + GasOverheadBeforeCallback uint32 + GasOverheadAfterCallback uint32 + RequestTimeoutSeconds uint32 + DonFee *big.Int + MaxSupportedRequestDataVersion uint16 + FulfillmentGasPriceOverEstimationBP uint32 + FallbackNativePerUnitLink *big.Int +} + +type FunctionsResponseCommitment struct { + RequestId [32]byte + Coordinator common.Address + EstimatedTotalCostJuels *big.Int + Client common.Address + SubscriptionId uint64 + CallbackGasLimit uint32 + AdminFee *big.Int + DonFee *big.Int + GasOverheadBeforeCallback *big.Int + GasOverheadAfterCallback *big.Int + TimeoutTimestamp uint32 +} + +type FunctionsResponseRequestMeta struct { + Data []byte + Flags [32]byte + RequestingContract common.Address + AvailableBalance *big.Int + AdminFee *big.Int + SubscriptionId uint64 + InitiatedRequests uint64 + CallbackGasLimit uint32 + DataVersion uint16 + CompletedRequests uint64 + SubscriptionOwner common.Address } var FunctionsCoordinatorMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"linkToNativeFeed\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyPublicKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyRequestData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentReportData\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoTransmittersSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouterOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReportInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustBeSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedPublicKeyChange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedRequestDataVersion\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"signerPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"transmitterPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalCost\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"enumFulfillResult\",\"name\":\"result\",\"type\":\"uint8\"}],\"name\":\"BillingEnd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"expectedGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"don\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"donFee\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"adminFee\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structFunctionsBilling.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"name\":\"BillingStart\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"donFee\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"CostExceedsCommitment\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"InsufficientGasProvided\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"InvalidRequestID\",\"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\":\"OCRConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"}],\"name\":\"OracleRequest\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"OracleResponse\",\"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\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestTimedOut\",\"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\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"deleteCommitment\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"node\",\"type\":\"address\"}],\"name\":\"deleteNodePublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"}],\"name\":\"estimateCost\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"expectedGasPrice\",\"type\":\"uint256\"}],\"internalType\":\"structIFunctionsBilling.RequestBilling\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"getAdminFee\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllNodePublicKeys\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"linkPriceFeed\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfigHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"config\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"expectedGasPrice\",\"type\":\"uint256\"}],\"internalType\":\"structIFunctionsBilling.RequestBilling\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"getDONFee\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDONPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeedData\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getThresholdPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"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\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"}],\"internalType\":\"structIFunctionsCoordinator.Request\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"sendRequest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"uint96\",\"name\":\"estimatedCost\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"config\",\"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\"},{\"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\":\"bytes\",\"name\":\"donPublicKey\",\"type\":\"bytes\"}],\"name\":\"setDONPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"node\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"publicKey\",\"type\":\"bytes\"}],\"name\":\"setNodePublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"thresholdPublicKey\",\"type\":\"bytes\"}],\"name\":\"setThresholdPublicKey\",\"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\":\"transmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b50604051620058c7380380620058c783398101604081905262000034916200042a565b828282828260013380600081620000925760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c557620000c58162000153565b50505015156080526001600160a01b038216620000f557604051632530e88560e11b815260040160405180910390fd5b600980546001600160a01b0319166001600160a01b0384161790556200011b81620001fe565b805160209091012060085550600a80546001600160a01b0319166001600160a01b039290921691909117905550620005f29350505050565b336001600160a01b03821603620001ad5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000089565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080600080600080600080888060200190518101906200022091906200053a565b975097509750975097509750975097506000841362000256576040516321ea67b360e11b81526004810185905260240162000089565b604080516101008101825263ffffffff808b168083528a8216602084018190528983168486018190528b841660608601819052938916608086018190526001600160601b03891660a0870181905260c087018c905261ffff891660e0909701879052600c8054600160a01b9092026001600160a01b03600160801b909402939093166001600160801b036c0100000000000000000000000090980263ffffffff60601b196801000000000000000090960295909516600160401b600160801b03196401000000009097026001600160401b0319909416909717929092179490941694909417919091179390931691909117919091179055600d869055600e805461ffff19169091179055517fd09395baf4d99e44ce1b8e96a4396a3f896d0fd5e4517993f28ce0a6fb42e22790620003e4908a908a9089908b908a908990899063ffffffff97881681529587166020870152938616604086015291909416606084015260808301939093526001600160601b039290921660a082015261ffff9190911660c082015260e00190565b60405180910390a1505050505050505050565b80516001600160a01b03811681146200040f57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b6000806000606084860312156200044057600080fd5b6200044b84620003f7565b602085810151919450906001600160401b03808211156200046b57600080fd5b818701915087601f8301126200048057600080fd5b81518181111562000495576200049562000414565b604051601f8201601f19908116603f01168101908382118183101715620004c057620004c062000414565b816040528281528a86848701011115620004d957600080fd5b600093505b82841015620004fd5784840186015181850187015292850192620004de565b60008684830101528097505050505050506200051c60408501620003f7565b90509250925092565b805163ffffffff811681146200040f57600080fd5b600080600080600080600080610100898b0312156200055857600080fd5b620005638962000525565b97506200057360208a0162000525565b96506200058360408a0162000525565b95506200059360608a0162000525565b945060808901519350620005aa60a08a0162000525565b60c08a01519093506001600160601b0381168114620005c857600080fd5b60e08a015190925061ffff81168114620005e157600080fd5b809150509295985092959890939650565b6080516152b96200060e600039600061142c01526152b96000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c806381ff7048116100ee578063b1dc65a411610097578063d328a91e11610071578063d328a91e14610481578063de9dfa4614610489578063e3d0e7121461049c578063f2fde38b146104af57600080fd5b8063b1dc65a4146103ce578063c3f909d4146103e1578063d227d2451461046e57600080fd5b80639883c10d116100c85780639883c10d14610394578063af1296d3146103a6578063afcb95d7146103ae57600080fd5b806381ff70481461031957806385b214cf146103495780638da5cb5b1461036c57600080fd5b8063533989871161015b5780637f15e166116101355780637f15e166146102d657806380756031146102e957806381411834146102fc57806381f1b9381461031157600080fd5b806353398987146102a557806366316d8d146102bb57806379ba5097146102ce57600080fd5b806326ceabac1161018c57806326ceabac1461024f578063354497aa14610262578063466557181461027557600080fd5b8063083a5466146101b35780630a33e0a5146101c8578063181f5a771461020d575b600080fd5b6101c66101c1366004613d55565b6104c2565b005b6101db6101d6366004613d97565b610517565b604080519485526bffffffffffffffffffffffff90931660208501529183015260608201526080015b60405180910390f35b60408051808201909152601881527f46756e6374696f6e7320436f6f7264696e61746f72207631000000000000000060208201525b6040516102049190613e36565b6101c661025d366004613e6b565b61073d565b6101c6610270366004613f94565b6107df565b610288610283366004614004565b610846565b6040516bffffffffffffffffffffffff9091168152602001610204565b6102ad610876565b60405161020492919061412b565b6101c66102c93660046141d5565b610b25565b6101c6610ca3565b6101c66102e4366004613d55565b610da5565b6101c66102f736600461420e565b610df5565b610304610eac565b6040516102049190614263565b610242610f1b565b6004546002546040805163ffffffff80851682526401000000009094049093166020840152820152606001610204565b61035c610357366004614276565b610fec565b6040519015158152602001610204565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610204565b6008545b604051908152602001610204565b6103986111d6565b604080516001815260006020820181905291810191909152606001610204565b6101c66103dc3660046142d4565b6112b9565b600c54600d54600a54600e546040805163ffffffff80871682526401000000008704811660208301526c010000000000000000000000008704811692820192909252606081019490945268010000000000000000909404909316608083015273ffffffffffffffffffffffffffffffffffffffff1660a082015261ffff90911660c082015260e001610204565b61028861047c36600461438b565b6119ea565b610242611b6f565b610288610497366004614004565b611bc6565b6101c66104aa3660046144ad565b611c61565b6101c66104bd366004613e6b565b612645565b6104ca612656565b6000819003610505576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601361051282848361461b565b505050565b60095460009081908190819073ffffffffffffffffffffffffffffffffffffffff163314610571576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61057e6020860186614736565b90506000036105b8576040517ec1cfc000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101909152600090806105d4602089018961479b565b67ffffffffffffffff1681526020016105f360a0890160808a01613e6b565b73ffffffffffffffffffffffffffffffffffffffff16815260200161061e6080890160608a016147b8565b63ffffffff1681523a60209182015290915061068b9061064090880188614736565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610685925050506060890160408a016147e5565b836126d9565b929750909550935091506106a560a0870160808801613e6b565b73ffffffffffffffffffffffffffffffffffffffff16857fb108b073fa485003d66284614f1c3b4feb3f47ffc88f7873bf3b2ec4bb8939bc326106eb60208b018b61479b565b6106fb60c08c0160a08d01613e6b565b61070860208d018d614736565b8d604001602081019061071b91906147e5565b60405161072d96959493929190614802565b60405180910390a3509193509193565b60005473ffffffffffffffffffffffffffffffffffffffff1633148061077857503373ffffffffffffffffffffffffffffffffffffffff8216145b6107ae576040517fed6dd19b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526012602052604081206107dc91613c9a565b50565b60095473ffffffffffffffffffffffffffffffffffffffff163314610830576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61083981612d03565b8051602090910120600855565b600c547401000000000000000000000000000000000000000090046bffffffffffffffffffffffff165b92915050565b60608060003073ffffffffffffffffffffffffffffffffffffffff1663814118346040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108c6573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261090c91908101906148fa565b90506000815167ffffffffffffffff81111561092a5761092a613e88565b60405190808252806020026020018201604052801561095d57816020015b60608152602001906001900390816109485790505b50905060005b8251811015610b1b57601260008483815181106109825761098261492f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080546109cf9061457a565b9050600003610a0a576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60126000848381518110610a2057610a2061492f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054610a6d9061457a565b80601f0160208091040260200160405190810160405280929190818152602001828054610a999061457a565b8015610ae65780601f10610abb57610100808354040283529160200191610ae6565b820191906000526020600020905b815481529060010190602001808311610ac957829003601f168201915b5050505050828281518110610afd57610afd61492f565b60200260200101819052508080610b139061498d565b915050610963565b5090939092509050565b610b2d612fb0565b806bffffffffffffffffffffffff16600003610b635750336000908152600f60205260409020546bffffffffffffffffffffffff165b336000908152600f60205260409020546bffffffffffffffffffffffff80831691161015610bbd576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600f602052604081208054839290610bea9084906bffffffffffffffffffffffff166149c5565b82546101009290920a6bffffffffffffffffffffffff8181021990931691831602179091556009546040517f66316d8d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015292851660248201529116915081906366316d8d90604401600060405180830381600087803b158015610c8657600080fd5b505af1158015610c9a573d6000803e3d6000fd5b50505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d29576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610dad612656565b6000819003610de8576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601161051282848361461b565b60005473ffffffffffffffffffffffffffffffffffffffff16331480610e405750610e1f33613149565b8015610e4057503373ffffffffffffffffffffffffffffffffffffffff8416145b610e76576040517fed6dd19b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000908152601260205260409020610ea682848361461b565b50505050565b60606007805480602002602001604051908101604052809291908181526020018280548015610f1157602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610ee6575b5050505050905090565b606060138054610f2a9061457a565b9050600003610f65576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60138054610f729061457a565b80601f0160208091040260200160405190810160405280929190818152602001828054610f9e9061457a565b8015610f115780601f10610fc057610100808354040283529160200191610f11565b820191906000526020600020905b815481529060010190602001808311610fce57509395945050505050565b60095460009073ffffffffffffffffffffffffffffffffffffffff163314611040576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600b6020908152604091829020825161014081018452815467ffffffffffffffff8116825268010000000000000000810473ffffffffffffffffffffffffffffffffffffffff908116948301949094527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169381019390935260018101546060840152600281015491821660808401819052740100000000000000000000000000000000000000009092046bffffffffffffffffffffffff90811660a0850152600382015480821660c08601526c0100000000000000000000000090041660e084015260048101546101008401526005015461012083015261114e5750600092915050565b6000838152600b602052604080822082815560018101839055600281018390556003810180547fffffffffffffffff000000000000000000000000000000000000000000000000169055600481018390556005018290555184917ff1ca1e9147be737b04a2b018a79405f687a97de8dd8a2559bbe62357343af41491a260019150505b919050565b600c54600a54604080517ffeaf968c0000000000000000000000000000000000000000000000000000000081529051600093640100000000900463ffffffff1692831515928592839273ffffffffffffffffffffffffffffffffffffffff169163feaf968c9160048083019260a09291908290030181865afa158015611260573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112849190614a0b565b509350509250508280156112a6575061129d8142614a5b565b8463ffffffff16105b156112b157600d5491505b509392505050565b60005a604080516020601f8b018190048102820181019092528981529192508a3591818c01359161130f91849163ffffffff851691908e908e908190840183828082843760009201919091525061325d92505050565b611345576040517f0be3632800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805183815262ffffff600884901c1660208201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925290831461141a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f636f6e666967446967657374206d69736d6174636800000000000000000000006044820152606401610d20565b6114288b8b8b8b8b8b613266565b60007f000000000000000000000000000000000000000000000000000000000000000015611485576002826020015183604001516114669190614a6e565b6114709190614ab6565b61147b906001614a6e565b60ff16905061149b565b6020820151611495906001614a6e565b60ff1690505b888114611504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e6174757265730000000000006044820152606401610d20565b88871461156d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f7369676e617475726573206f7574206f6620726567697374726174696f6e00006044820152606401610d20565b3360009081526005602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156115b0576115b0614ad8565b60028111156115c1576115c1614ad8565b90525090506002816020015160028111156115de576115de614ad8565b14801561162557506007816000015160ff16815481106116005761160061492f565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b61168b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f756e617574686f72697a6564207472616e736d697474657200000000000000006044820152606401610d20565b5050505050611698613cd4565b6000808a8a6040516116ab929190614b07565b6040519081900381206116c2918e90602001614b17565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120838301909252600080845290830152915060005b898110156119cc57600060018489846020811061172b5761172b61492f565b61173891901a601b614a6e565b8e8e8681811061174a5761174a61492f565b905060200201358d8d878181106117635761176361492f565b90506020020135604051600081526020016040526040516117a0949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156117c2573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526005602090815290849020838501909452835460ff8082168552929650929450840191610100900416600281111561184257611842614ad8565b600281111561185357611853614ad8565b905250925060018360200151600281111561187057611870614ad8565b146118d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e00006044820152606401610d20565b8251600090879060ff16601f81106118f1576118f161492f565b602002015173ffffffffffffffffffffffffffffffffffffffff1614611973576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6e6f6e2d756e69717565207369676e61747572650000000000000000000000006044820152606401610d20565b8086846000015160ff16601f811061198d5761198d61492f565b73ffffffffffffffffffffffffffffffffffffffff90921660209290920201526119b8600186614a6e565b945050806119c59061498d565b905061170c565b5050506119dd833383858e8e613314565b5050505050505050505050565b60006301c9c3808363ffffffff161115611a4457600c546040517ff5d7e01e00000000000000000000000000000000000000000000000000000000815263ffffffff80861660048301529091166024820152604401610d20565b620f4240821115611a81576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060405180608001604052808867ffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018563ffffffff1681526020018481525090506000611b0f87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250869250610846915050565b90506000611b5488888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250611bc6915050565b9050611b62868684846135b9565b9998505050505050505050565b606060118054611b7e9061457a565b9050600003611bb9576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60118054610f729061457a565b600954604080517f2a905ccc000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691632a905ccc9160048083019260209291908290030181865afa158015611c36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c5a9190614b2b565b9392505050565b855185518560ff16601f831115611cd4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e657273000000000000000000000000000000006044820152606401610d20565b60008111611d3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610d20565b818314611dcc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610d20565b611dd7816003614b48565b8311611e3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610d20565b611e47612656565b6040805160c0810182528a8152602081018a905260ff89169181018290526060810188905267ffffffffffffffff8716608082015260a0810186905290611e8e90886136ef565b6006541561204357600654600090611ea890600190614a5b565b9050600060068281548110611ebf57611ebf61492f565b60009182526020822001546007805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110611ef957611ef961492f565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526005909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090811690915592909116808452922080549091169055600680549192509080611f7957611f79614b5f565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690550190556007805480611fe257611fe2614b5f565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611e8e915050565b60005b8151518110156124a8576000600560008460000151848151811061206c5761206c61492f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff1660028111156120b6576120b6614ad8565b1461211d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610d20565b6040805180820190915260ff8216815260016020820152825180516005916000918590811061214e5761214e61492f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016176101008360028111156121ef576121ef614ad8565b0217905550600091506121ff9050565b60056000846020015184815181106122195761221961492f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff16600281111561226357612263614ad8565b146122ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610d20565b6040805180820190915260ff8216815260208101600281525060056000846020015184815181106122fd576122fd61492f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561239e5761239e614ad8565b0217905550508251805160069250839081106123bc576123bc61492f565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90931692909217909155820151805160079190839081106124385761243861492f565b60209081029190910181015182546001810184556000938452919092200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790556124a18161498d565b9050612046565b506040810151600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600480547fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff811664010000000063ffffffff43811682029283178555908304811693600193909260009261253a928692908216911617614b8e565b92506101000a81548163ffffffff021916908363ffffffff1602179055506125994630600460009054906101000a900463ffffffff1663ffffffff16856000015186602001518760400151886060015189608001518a60a0015161370c565b6002819055825180516003805460ff909216610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff90921691909117905560045460208501516040808701516060880151608089015160a08a015193517f324b4d5fd31c5865202bc49f712eb9fcdf22bcc3b89f8c721f3134ae6c081a0998612638988b98919763ffffffff909216969095919491939192614bab565b60405180910390a16119dd565b61264d612656565b6107dc816137b7565b60005473ffffffffffffffffffffffffffffffffffffffff1633146126d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610d20565b565b600e5460009081908190819061ffff9081169087161115612726576040517fdada758700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c54604086015163ffffffff9182169116111561278857604085810151600c5491517ff5d7e01e00000000000000000000000000000000000000000000000000000000815263ffffffff918216600482015291166024820152604401610d20565b60006127948887610846565b905060006127a28988611bc6565b905060006127ba8860400151896060015185856135b9565b60095489516040517fa47c769600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015291925073ffffffffffffffffffffffffffffffffffffffff16906000908190839063a47c769690602401600060405180830381865afa15801561283d573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526128839190810190614c31565b50505060208d01518d516040517f674603d000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316600482015267ffffffffffffffff90911660248201529294509092506000919085169063674603d090604401606060405180830381865afa158015612914573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129389190614cbd565b509150506bffffffffffffffffffffffff851661295583856149c5565b6bffffffffffffffffffffffff16101561299b576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612a1a308e602001518f600001518560016129b89190614d0f565b6040805173ffffffffffffffffffffffffffffffffffffffff958616602080830191909152949095168582015267ffffffffffffffff928316606086015291166080808501919091528151808503909101815260a09093019052815191012090565b905060006040518061014001604052808f6000015167ffffffffffffffff1681526020018f6020015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6040015163ffffffff1681526020018f6060015181526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018a6bffffffffffffffffffffffff168152602001896bffffffffffffffffffffffff168152602001886bffffffffffffffffffffffff168152602001600c600001600c9054906101000a900463ffffffff16600c60000160089054906101000a900463ffffffff16612b069190614b8e565b63ffffffff9081168252426020928301526000858152600b835260409081902084518154948601518684015167ffffffffffffffff9092167fffffffff00000000000000000000000000000000000000000000000000000000909616959095176801000000000000000073ffffffffffffffffffffffffffffffffffffffff96871602177bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c0100000000000000000000000000000000000000000000000000000000919094160292909217825560608401516001830155608084015160a08501519316740100000000000000000000000000000000000000006bffffffffffffffffffffffff9485160217600283015560c084015160038301805460e08701519286167fffffffffffffffff000000000000000000000000000000000000000000000000909116176c0100000000000000000000000092909516919091029390931790925561010083015160048201556101208301516005909101555190915082907f9fadc54f9c9b79290fa97f2c9deb97ee080d1f8ae4f00deb1fb83cedd1ee542290612cb3908490614d30565b60405180910390a250600c54909f959e5063ffffffff6c01000000000000000000000000820481169e50700100000000000000000000000000000000909104169b50939950505050505050505050565b60008060008060008060008088806020019051810190612d239190614e32565b9750975097509750975097509750975060008413612d70576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101859052602401610d20565b604080516101008101825263ffffffff808b168083528a8216602084018190528983168486018190528b841660608601819052938916608086018190526bffffffffffffffffffffffff891660a0870181905260c087018c905261ffff891660e0909701879052600c80547401000000000000000000000000000000000000000090920273ffffffffffffffffffffffffffffffffffffffff700100000000000000000000000000000000909402939093166fffffffffffffffffffffffffffffffff6c010000000000000000000000009098027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff68010000000000000000909602959095167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff6401000000009097027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909416909717929092179490941694909417919091179390931691909117919091179055600d869055600e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169091179055517fd09395baf4d99e44ce1b8e96a4396a3f896d0fd5e4517993f28ce0a6fb42e22790612f9d908a908a9089908b908a908990899063ffffffff97881681529587166020870152938616604086015291909416606084015260808301939093526bffffffffffffffffffffffff9290921660a082015261ffff9190911660c082015260e00190565b60405180910390a1505050505050505050565b6000612fba610eac565b90508051600003612ff7576040517f30274b3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051601054600091613016916bffffffffffffffffffffffff16614ed8565b905060005b82518160ff1610156130ea5781600f6000858460ff16815181106130415761304161492f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a90046bffffffffffffffffffffffff166130a99190614f03565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080806130e290614f28565b91505061301b565b5081516130f79082614f47565b601080546000906131179084906bffffffffffffffffffffffff166149c5565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505050565b6000803073ffffffffffffffffffffffffffffffffffffffff1663814118346040518163ffffffff1660e01b8152600401600060405180830381865afa158015613197573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526131dd91908101906148fa565b905060005b8151811015613253578373ffffffffffffffffffffffffffffffffffffffff168282815181106132145761321461492f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603613241575060019392505050565b8061324b8161498d565b9150506131e2565b5060009392505050565b60019392505050565b6000613273826020614b48565b61327e856020614b48565b61328a88610144614f77565b6132949190614f77565b61329e9190614f77565b6132a9906000614f77565b9050368114610c9a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d6174636800000000000000006044820152606401610d20565b606080806133248486018661500a565b82519295509093509150158061333c57508151835114155b8061334957508051835114155b15613380576040517f0be3632800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b83518110156135ad5760006133e48583815181106133a3576133a361492f565b60200260200101518584815181106133bd576133bd61492f565b60200260200101518585815181106133d7576133d761492f565b60200260200101516138ac565b905060008160068111156133fa576133fa614ad8565b14806134175750600181600681111561341557613415614ad8565b145b156134725784828151811061342e5761342e61492f565b60209081029190910181015160405133815290917fc708e0440951fd63499c0f7a73819b469ee5dd3ecc356c0ab4eb7f18389009d9910160405180910390a261359a565b600281600681111561348657613486614ad8565b036134d65784828151811061349d5761349d61492f565b60200260200101517fa1c120e327c9ad8b075793878c88d59b8934b97ae37117faa3bb21616237f7be60405160405180910390a261359a565b60038160068111156134ea576134ea614ad8565b0361353a578482815181106135015761350161492f565b60200260200101517f357a60574f143e144d62ddc89636fee45ba5e2f8c9a30b9f91e28f8dfe5a56e060405160405180910390a261359a565b600581600681111561354e5761354e614ad8565b0361359a578482815181106135655761356561492f565b60200260200101517f689f49eacf6db85082542f4b7873f4a519744a4e093fd002310545bfb4354cc860405160405180910390a25b50806135a58161498d565b915050613383565b50505050505050505050565b6000806135c46111d6565b905060008113613603576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101829052602401610d20565b600c5460009087906136399063ffffffff6c01000000000000000000000000820481169168010000000000000000900416614b8e565b6136439190614b8e565b63ffffffff1690506000828261366189670de0b6b3a7640000614b48565b61366b9190614b48565b61367591906150e7565b905060006136946bffffffffffffffffffffffff808816908916614f77565b90506136ac816b033b2e3c9fd0803ce8000000614a5b565b8211156136e5576040517fe80fa38100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b628183614f77565b60006136f9610eac565b51111561370857613708612fb0565b5050565b6000808a8a8a8a8a8a8a8a8a604051602001613730999897969594939291906150fb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613836576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610d20565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000838152600b60209081526040808320815161014081018352815467ffffffffffffffff8116825268010000000000000000810473ffffffffffffffffffffffffffffffffffffffff908116958301959095527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169281019290925260018101546060830152600281015492831660808301819052740100000000000000000000000000000000000000009093046bffffffffffffffffffffffff90811660a0840152600382015480821660c08501526c0100000000000000000000000090041660e0830152600481015461010083015260050154610120820152906139bb576002915050611c5a565b6000858152600b6020526040812081815560018101829055600281018290556003810180547fffffffffffffffff00000000000000000000000000000000000000000000000016905560048101829055600501819055613a196111d6565b905060008113613a58576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101829052602401610d20565b600081613a6d3a670de0b6b3a7640000614b48565b613a7791906150e7565b9050600083610100015182613a8c9190614b48565b905060008460a0015182613aa09190614f03565b6009546040517f3fd67e0500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff169060009081908390633fd67e0590613b08908f908f908f908c908b903390600401615190565b60408051808303816000875af1158015613b26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b4a9190615201565b9092509050613b598186614f03565b336000908152600f6020526040812080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff93841617905560a08a0151601080549193909291613bb991859116614f03565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508b7f30e1e299f390e4f3fa75e4489fed477e86183937a4a21a0ae7b137a4dff0353589600001518a60a001518489613c1f9190614f03565b60c08d015160a08e0151613c33888d614f03565b613c3d9190614f03565b613c479190614f03565b8760ff166006811115613c5c57613c5c614ad8565b604051613c6d959493929190615230565b60405180910390a28160ff166006811115613c8a57613c8a614ad8565b9c9b505050505050505050505050565b508054613ca69061457a565b6000825580601f10613cb6575050565b601f0160209004906000526020600020908101906107dc9190613cf3565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613d085760008155600101613cf4565b5090565b60008083601f840112613d1e57600080fd5b50813567ffffffffffffffff811115613d3657600080fd5b602083019150836020828501011115613d4e57600080fd5b9250929050565b60008060208385031215613d6857600080fd5b823567ffffffffffffffff811115613d7f57600080fd5b613d8b85828601613d0c565b90969095509350505050565b600060208284031215613da957600080fd5b813567ffffffffffffffff811115613dc057600080fd5b820160c08185031215611c5a57600080fd5b6000815180845260005b81811015613df857602081850181015186830182015201613ddc565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611c5a6020830184613dd2565b73ffffffffffffffffffffffffffffffffffffffff811681146107dc57600080fd5b600060208284031215613e7d57600080fd5b8135611c5a81613e49565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613efe57613efe613e88565b604052919050565b600082601f830112613f1757600080fd5b813567ffffffffffffffff811115613f3157613f31613e88565b613f6260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613eb7565b818152846020838601011115613f7757600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215613fa657600080fd5b813567ffffffffffffffff811115613fbd57600080fd5b613fc984828501613f06565b949350505050565b67ffffffffffffffff811681146107dc57600080fd5b80356111d181613fd1565b63ffffffff811681146107dc57600080fd5b60008082840360a081121561401857600080fd5b833567ffffffffffffffff8082111561403057600080fd5b61403c87838801613f06565b945060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08401121561406e57600080fd5b6040519250608083019150828210818311171561408d5761408d613e88565b50604052602084013561409f81613fd1565b815260408401356140af81613e49565b602082015260608401356140c281613ff2565b60408201526080939093013560608401525092909150565b600081518084526020808501945080840160005b8381101561412057815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016140ee565b509495945050505050565b60408152600061413e60408301856140da565b6020838203818501528185518084528284019150828160051b85010183880160005b838110156141ac577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe087840301855261419a838351613dd2565b94860194925090850190600101614160565b50909998505050505050505050565b6bffffffffffffffffffffffff811681146107dc57600080fd5b600080604083850312156141e857600080fd5b82356141f381613e49565b91506020830135614203816141bb565b809150509250929050565b60008060006040848603121561422357600080fd5b833561422e81613e49565b9250602084013567ffffffffffffffff81111561424a57600080fd5b61425686828701613d0c565b9497909650939450505050565b602081526000611c5a60208301846140da565b60006020828403121561428857600080fd5b5035919050565b60008083601f8401126142a157600080fd5b50813567ffffffffffffffff8111156142b957600080fd5b6020830191508360208260051b8501011115613d4e57600080fd5b60008060008060008060008060e0898b0312156142f057600080fd5b606089018a81111561430157600080fd5b8998503567ffffffffffffffff8082111561431b57600080fd5b6143278c838d01613d0c565b909950975060808b013591508082111561434057600080fd5b61434c8c838d0161428f565b909750955060a08b013591508082111561436557600080fd5b506143728b828c0161428f565b999c989b50969995989497949560c00135949350505050565b6000806000806000608086880312156143a357600080fd5b85356143ae81613fd1565b9450602086013567ffffffffffffffff8111156143ca57600080fd5b6143d688828901613d0c565b90955093505060408601356143ea81613ff2565b949793965091946060013592915050565b600067ffffffffffffffff82111561441557614415613e88565b5060051b60200190565b600082601f83011261443057600080fd5b81356020614445614440836143fb565b613eb7565b82815260059290921b8401810191818101908684111561446457600080fd5b8286015b8481101561448857803561447b81613e49565b8352918301918301614468565b509695505050505050565b60ff811681146107dc57600080fd5b80356111d181614493565b60008060008060008060c087890312156144c657600080fd5b863567ffffffffffffffff808211156144de57600080fd5b6144ea8a838b0161441f565b9750602089013591508082111561450057600080fd5b61450c8a838b0161441f565b965061451a60408a016144a2565b9550606089013591508082111561453057600080fd5b61453c8a838b01613f06565b945061454a60808a01613fe7565b935060a089013591508082111561456057600080fd5b5061456d89828a01613f06565b9150509295509295509295565b600181811c9082168061458e57607f821691505b6020821081036145c7577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111561051257600081815260208120601f850160051c810160208610156145f45750805b601f850160051c820191505b8181101561461357828155600101614600565b505050505050565b67ffffffffffffffff83111561463357614633613e88565b61464783614641835461457a565b836145cd565b6000601f84116001811461469957600085156146635750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561472f565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156146e857868501358255602094850194600190920191016146c8565b5086821015614723577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261476b57600080fd5b83018035915067ffffffffffffffff82111561478657600080fd5b602001915036819003821315613d4e57600080fd5b6000602082840312156147ad57600080fd5b8135611c5a81613fd1565b6000602082840312156147ca57600080fd5b8135611c5a81613ff2565b61ffff811681146107dc57600080fd5b6000602082840312156147f757600080fd5b8135611c5a816147d5565b600073ffffffffffffffffffffffffffffffffffffffff808916835267ffffffffffffffff8816602084015280871660408401525060a060608301528360a0830152838560c0840137600060c0858401015260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116830101905061ffff83166080830152979650505050505050565b600082601f8301126148a757600080fd5b815160206148b7614440836143fb565b82815260059290921b840181019181810190868411156148d657600080fd5b8286015b848110156144885780516148ed81613e49565b83529183019183016148da565b60006020828403121561490c57600080fd5b815167ffffffffffffffff81111561492357600080fd5b613fc984828501614896565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036149be576149be61495e565b5060010190565b6bffffffffffffffffffffffff8281168282160390808211156149ea576149ea61495e565b5092915050565b805169ffffffffffffffffffff811681146111d157600080fd5b600080600080600060a08688031215614a2357600080fd5b614a2c866149f1565b9450602086015193506040860151925060608601519150614a4f608087016149f1565b90509295509295909350565b818103818111156108705761087061495e565b60ff81811683821601908111156108705761087061495e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600060ff831680614ac957614ac9614a87565b8060ff84160491505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8183823760009101908152919050565b828152606082602083013760800192915050565b600060208284031215614b3d57600080fd5b8151611c5a816141bb565b80820281158282048414176108705761087061495e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b63ffffffff8181168382160190808211156149ea576149ea61495e565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152614bdb8184018a6140da565b90508281036080840152614bef81896140da565b905060ff871660a084015282810360c0840152614c0c8187613dd2565b905067ffffffffffffffff851660e0840152828103610100840152613c8a8185613dd2565b600080600080600060a08688031215614c4957600080fd5b8551614c54816141bb565b6020870151909550614c65816141bb565b6040870151909450614c7681613e49565b6060870151909350614c8781613e49565b608087015190925067ffffffffffffffff811115614ca457600080fd5b614cb088828901614896565b9150509295509295909350565b600080600060608486031215614cd257600080fd5b83518015158114614ce257600080fd5b6020850151909350614cf381613fd1565b6040850151909250614d0481613fd1565b809150509250925092565b67ffffffffffffffff8181168382160190808211156149ea576149ea61495e565b815167ffffffffffffffff16815261014081016020830151614d6a602084018273ffffffffffffffffffffffffffffffffffffffff169052565b506040830151614d82604084018263ffffffff169052565b50606083015160608301526080830151614db4608084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a0830151614dd460a08401826bffffffffffffffffffffffff169052565b5060c0830151614df460c08401826bffffffffffffffffffffffff169052565b5060e0830151614e1460e08401826bffffffffffffffffffffffff169052565b50610100838101519083015261012092830151929091019190915290565b600080600080600080600080610100898b031215614e4f57600080fd5b8851614e5a81613ff2565b60208a0151909850614e6b81613ff2565b60408a0151909750614e7c81613ff2565b60608a0151909650614e8d81613ff2565b60808a015160a08b01519196509450614ea581613ff2565b60c08a0151909350614eb6816141bb565b60e08a0151909250614ec7816147d5565b809150509295985092959890939650565b60006bffffffffffffffffffffffff80841680614ef757614ef7614a87565b92169190910492915050565b6bffffffffffffffffffffffff8181168382160190808211156149ea576149ea61495e565b600060ff821660ff8103614f3e57614f3e61495e565b60010192915050565b6bffffffffffffffffffffffff818116838216028082169190828114614f6f57614f6f61495e565b505092915050565b808201808211156108705761087061495e565b600082601f830112614f9b57600080fd5b81356020614fab614440836143fb565b82815260059290921b84018101918181019086841115614fca57600080fd5b8286015b8481101561448857803567ffffffffffffffff811115614fee5760008081fd5b614ffc8986838b0101613f06565b845250918301918301614fce565b60008060006060848603121561501f57600080fd5b833567ffffffffffffffff8082111561503757600080fd5b818601915086601f83011261504b57600080fd5b8135602061505b614440836143fb565b82815260059290921b8401810191818101908a84111561507a57600080fd5b948201945b838610156150985785358252948201949082019061507f565b975050870135925050808211156150ae57600080fd5b6150ba87838801614f8a565b935060408601359150808211156150d057600080fd5b506150dd86828701614f8a565b9150509250925092565b6000826150f6576150f6614a87565b500490565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526151428285018b6140da565b91508382036080850152615156828a6140da565b915060ff881660a085015283820360c08501526151738288613dd2565b90861660e08501528381036101008501529050613c8a8185613dd2565b86815260c0602082015260006151a960c0830188613dd2565b82810360408401526151bb8188613dd2565b6bffffffffffffffffffffffff96871660608501529490951660808301525073ffffffffffffffffffffffffffffffffffffffff9190911660a090910152949350505050565b6000806040838503121561521457600080fd5b825161521f81614493565b6020840151909250614203816141bb565b67ffffffffffffffff861681526bffffffffffffffffffffffff858116602083015284811660408301528316606082015260a081016007831061529c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b826080830152969550505050505056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"linkToNativeFeed\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyPublicKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentReportData\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoTransmittersSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouterOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReportInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustBeSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedPublicKeyChange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedRequestDataVersion\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"CommitmentDeleted\",\"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\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"indexed\":false,\"internalType\":\"structFunctionsBilling.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"callbackGasLimit\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"name\":\"OracleRequest\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"OracleResponse\",\"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\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"deleteCommitment\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"node\",\"type\":\"address\"}],\"name\":\"deleteNodePublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"gasPriceGwei\",\"type\":\"uint256\"}],\"name\":\"estimateCost\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminFee\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllNodePublicKeys\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"getDONFee\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDONPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getThresholdPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWeiPerUnitLink\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"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\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracleWithdrawAll\",\"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\":\"_onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"_offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"_offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"donPublicKey\",\"type\":\"bytes\"}],\"name\":\"setDONPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"node\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"publicKey\",\"type\":\"bytes\"}],\"name\":\"setNodePublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"thresholdPublicKey\",\"type\":\"bytes\"}],\"name\":\"setThresholdPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"availableBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"initiatedRequests\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint64\",\"name\":\"completedRequests\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"}],\"internalType\":\"structFunctionsResponse.RequestMeta\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"startRequest\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"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\":\"transmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60c06040523480156200001157600080fd5b50604051620056fb380380620056fb83398101604081905262000034916200044f565b8282828260013380600081620000915760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c457620000c48162000140565b50505015156080526001600160a01b038116620000f457604051632530e88560e11b815260040160405180910390fd5b6001600160a01b0390811660a052600b80549183166c01000000000000000000000000026001600160601b039092169190911790556200013482620001eb565b50505050505062000600565b336001600160a01b038216036200019a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000088565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620001f56200033a565b80516008805460208401516040808601516060870151608088015160a089015160c08a015163ffffffff998a166001600160401b031990981697909717640100000000968a16870217600160401b600160801b03191668010000000000000000948a169490940263ffffffff60601b1916939093176c010000000000000000000000009289169290920291909117600160801b600160e81b031916600160801b91881691909102600160a01b600160e81b03191617600160a01b6001600160481b03909216919091021761ffff60e81b1916600160e81b61ffff909416939093029290921790925560e084015161010085015193166001600160e01b0390931690910291909117600955517f5b6e2e1a03ea742ce04ca36d0175411a0772f99ef4ee84aeb9868a1ef6ddc82c906200032f90839062000558565b60405180910390a150565b6200034462000346565b565b6000546001600160a01b03163314620003445760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000088565b80516001600160a01b0381168114620003ba57600080fd5b919050565b60405161012081016001600160401b0381118282101715620003f157634e487b7160e01b600052604160045260246000fd5b60405290565b805163ffffffff81168114620003ba57600080fd5b80516001600160481b0381168114620003ba57600080fd5b805161ffff81168114620003ba57600080fd5b80516001600160e01b0381168114620003ba57600080fd5b60008060008385036101608112156200046757600080fd5b6200047285620003a2565b935061012080601f19830112156200048957600080fd5b62000493620003bf565b9150620004a360208701620003f7565b8252620004b360408701620003f7565b6020830152620004c660608701620003f7565b6040830152620004d960808701620003f7565b6060830152620004ec60a08701620003f7565b6080830152620004ff60c087016200040c565b60a08301526200051260e0870162000424565b60c083015261010062000527818801620003f7565b60e08401526200053982880162000437565b908301525091506200054f6101408501620003a2565b90509250925092565b815163ffffffff9081168252602080840151821690830152604080840151821690830152606080840151821690830152608080840151918216908301526101208201905060a0830151620005b760a08401826001600160481b03169052565b5060c0830151620005ce60c084018261ffff169052565b5060e0830151620005e760e084018263ffffffff169052565b50610100928301516001600160e01b0316919092015290565b60805160a0516150ab620006506000396000818161090901528181610cbe01528181610eec015281816112360152818161136d01528181611b5701526136a40152600061159501526150ab6000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c806381f1b938116100ee578063b1dc65a411610097578063d328a91e11610071578063d328a91e146105a3578063e3d0e712146105ab578063e4ddcea6146105be578063f2fde38b146105d457600080fd5b8063b1dc65a41461040e578063c3f909d414610421578063d227d2451461057357600080fd5b80638da5cb5b116100c85780638da5cb5b146103a6578063a631571e146103ce578063afcb95d7146103ee57600080fd5b806381f1b9381461030e57806381ff70481461031657806385b214cf1461038357600080fd5b806359b5b7ac1161015b5780637d480787116101355780637d480787146102cb5780637f15e166146102d357806380756031146102e657806381411834146102f957600080fd5b806359b5b7ac1461027857806366316d8d146102b057806379ba5097146102c357600080fd5b806326ceabac1161018c57806326ceabac1461022d5780632a905ccc14610240578063533989871461026257600080fd5b8063083a5466146101b3578063181f5a77146101c85780631bdf7f1b1461021a575b600080fd5b6101c66101c13660046139e6565b6105e7565b005b6102046040518060400160405280601c81526020017f46756e6374696f6e7320436f6f7264696e61746f722076312e302e300000000081525081565b6040516102119190613a8c565b60405180910390f35b6101c6610228366004613bef565b61063c565b6101c661023b366004613cd2565b61085f565b610248610905565b60405168ffffffffffffffffff9091168152602001610211565b61026a61099b565b604051610211929190613d40565b610248610286366004613e5e565b5060085474010000000000000000000000000000000000000000900468ffffffffffffffffff1690565b6101c66102be366004613ec0565b610bc2565b6101c6610d7b565b6101c6610e7d565b6101c66102e13660046139e6565b610fd5565b6101c66102f4366004613ef9565b611025565b6103016110dc565b6040516102119190613f4e565b61020461114b565b61036060015460025463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610211565b610396610391366004613f61565b61121c565b6040519015158152602001610211565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610211565b6103e16103dc366004613f7a565b6112fc565b60405161021191906140d9565b604080516001815260006020820181905291810191909152606001610211565b6101c661041c36600461412d565b61149c565b6105666040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081019190915250604080516101208101825260085463ffffffff8082168352640100000000808304821660208501526801000000000000000083048216948401949094526c0100000000000000000000000082048116606084015270010000000000000000000000000000000082048116608084015274010000000000000000000000000000000000000000820468ffffffffffffffffff1660a08401527d01000000000000000000000000000000000000000000000000000000000090910461ffff1660c083015260095490811660e0830152919091047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661010082015290565b60405161021191906141e4565b6105866105813660046142c7565b611b53565b6040516bffffffffffffffffffffffff9091168152602001610211565b610204611cb2565b6101c66105b93660046143e0565b611d09565b6105c6612735565b604051908152602001610211565b6101c66105e2366004613cd2565b612966565b6105ef612977565b600081900361062a576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e610637828483614546565b505050565b6106446129fa565b80516008805460208401516040808601516060870151608088015160a089015160c08a015163ffffffff998a167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090981697909717640100000000968a168702177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff1668010000000000000000948a16949094027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16939093176c0100000000000000000000000092891692909202919091177fffffff00000000000000000000000000ffffffffffffffffffffffffffffffff16700100000000000000000000000000000000918816919091027fffffff000000000000000000ffffffffffffffffffffffffffffffffffffffff16177401000000000000000000000000000000000000000068ffffffffffffffffff90921691909102177fff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167d01000000000000000000000000000000000000000000000000000000000061ffff909416939093029290921790925560e084015161010085015193167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90931690910291909117600955517f5b6e2e1a03ea742ce04ca36d0175411a0772f99ef4ee84aeb9868a1ef6ddc82c906108549083906141e4565b60405180910390a150565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061089d57503373ffffffffffffffffffffffffffffffffffffffff821614155b156108d4576040517fed6dd19b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604081206109029161392f565b50565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632a905ccc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610972573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610996919061466c565b905090565b60608060006006805480602002602001604051908101604052809291908181526020018280548015610a0357602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116109d8575b505050505090506000815167ffffffffffffffff811115610a2657610a26613aa6565b604051908082528060200260200182016040528015610a5957816020015b6060815260200190600190039081610a445790505b50905060005b8251811015610bb8576000600d6000858481518110610a8057610a80614689565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054610acd906144ad565b80601f0160208091040260200160405190810160405280929190818152602001828054610af9906144ad565b8015610b465780601f10610b1b57610100808354040283529160200191610b46565b820191906000526020600020905b815481529060010190602001808311610b2957829003601f168201915b505050505090508051600003610b88576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80838381518110610b9b57610b9b614689565b60200260200101819052505080610bb1906146e7565b9050610a5f565b5090939092509050565b610bca612a02565b806bffffffffffffffffffffffff16600003610c045750336000908152600a60205260409020546bffffffffffffffffffffffff16610c5e565b336000908152600a60205260409020546bffffffffffffffffffffffff80831691161015610c5e576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600a602052604081208054839290610c8b9084906bffffffffffffffffffffffff1661471f565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550610ce07f000000000000000000000000000000000000000000000000000000000000000090565b6040517f66316d8d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526bffffffffffffffffffffffff8416602483015291909116906366316d8d90604401600060405180830381600087803b158015610d5f57600080fd5b505af1158015610d73573d6000803e3d6000fd5b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610e01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e856129fa565b610e8d612a02565b6000610e976110dc565b905060005b8151811015610fd157336000908152600a6020526040902080547fffffffffffffffffffffffffffffffffffffffff00000000000000000000000081169091556bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166366316d8d848481518110610f3857610f38614689565b6020026020010151836040518363ffffffff1660e01b8152600401610f8d92919073ffffffffffffffffffffffffffffffffffffffff9290921682526bffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015610fa757600080fd5b505af1158015610fbb573d6000803e3d6000fd5b505050505080610fca906146e7565b9050610e9c565b5050565b610fdd612977565b6000819003611018576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c610637828483614546565b60005473ffffffffffffffffffffffffffffffffffffffff16331480611070575061104f33612bad565b801561107057503373ffffffffffffffffffffffffffffffffffffffff8416145b6110a6576040517fed6dd19b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000908152600d602052604090206110d6828483614546565b50505050565b6060600680548060200260200160405190810160405280929190818152602001828054801561114157602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611116575b5050505050905090565b6060600e805461115a906144ad565b9050600003611195576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e80546111a2906144ad565b80601f01602080910402602001604051908101604052809291908181526020018280546111ce906144ad565b80156111415780601f106111f057610100808354040283529160200191611141565b820191906000526020600020905b8154815290600101906020018083116111fe57509395945050505050565b60003373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461128d576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600760205260409020546112a857506000919050565b60008281526007602052604080822091909155517f8a4b97add3359bd6bcf5e82874363670eb5ad0f7615abddbd0ed0a3a98f0f416906112eb9084815260200190565b60405180910390a15060015b919050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091523373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146113c4576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113d56113d083614744565b612c96565b90506113e76060830160408401613cd2565b815173ffffffffffffffffffffffffffffffffffffffff91909116907fbf50768ccf13bd0110ca6d53a9c4f1f3271abdd4c24a56878863ed25b20598ff3261143560c0870160a08801614831565b61144761016088016101408901613cd2565b611451888061484e565b6114636101208b016101008c016148b3565b60208b01356114796101008d0160e08e016148ce565b8b60405161148f999897969594939291906148eb565b60405180910390a3919050565b60005a604080518b3580825262ffffff6020808f0135600881901c929092169084015293945092917fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16040805160608101825260025480825260035460ff80821660208501526101009091041692820192909252908314611583576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f636f6e666967446967657374206d69736d6174636800000000000000000000006044820152606401610df8565b6115918b8b8b8b8b8b6130a6565b60007f0000000000000000000000000000000000000000000000000000000000000000156115ee576002826020015183604001516115cf9190614993565b6115d991906149db565b6115e4906001614993565b60ff169050611604565b60208201516115fe906001614993565b60ff1690505b88811461166d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e6174757265730000000000006044820152606401610df8565b8887146116d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f7369676e617475726573206f7574206f6620726567697374726174696f6e00006044820152606401610df8565b3360009081526004602090815260408083208151808301909252805460ff80821684529293919291840191610100909104166002811115611719576117196149fd565b600281111561172a5761172a6149fd565b9052509050600281602001516002811115611747576117476149fd565b14801561178e57506006816000015160ff168154811061176957611769614689565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b6117f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f756e617574686f72697a6564207472616e736d697474657200000000000000006044820152606401610df8565b5050505050611801613969565b6000808a8a604051611814929190614a2c565b60405190819003812061182b918e90602001614a3c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120838301909252600080845290830152915060005b89811015611b3557600060018489846020811061189457611894614689565b6118a191901a601b614993565b8e8e868181106118b3576118b3614689565b905060200201358d8d878181106118cc576118cc614689565b9050602002013560405160008152602001604052604051611909949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561192b573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526004602090815290849020838501909452835460ff808216855292965092945084019161010090041660028111156119ab576119ab6149fd565b60028111156119bc576119bc6149fd565b90525092506001836020015160028111156119d9576119d96149fd565b14611a40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e00006044820152606401610df8565b8251600090879060ff16601f8110611a5a57611a5a614689565b602002015173ffffffffffffffffffffffffffffffffffffffff1614611adc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6e6f6e2d756e69717565207369676e61747572650000000000000000000000006044820152606401610df8565b8086846000015160ff16601f8110611af657611af6614689565b73ffffffffffffffffffffffffffffffffffffffff9092166020929092020152611b21600186614993565b94505080611b2e906146e7565b9050611875565b505050611b46833383858e8e61315d565b5050505050505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006040517f10fc49c100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8816600482015263ffffffff8516602482015273ffffffffffffffffffffffffffffffffffffffff91909116906310fc49c19060440160006040518083038186803b158015611bf357600080fd5b505afa158015611c07573d6000803e3d6000fd5b505050620f42408311159050611c49576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611c53610905565b90506000611c9687878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061028692505050565b9050611ca48585838561332b565b925050505b95945050505050565b6060600c8054611cc1906144ad565b9050600003611cfc576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c80546111a2906144ad565b855185518560ff16601f831115611d7c576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e657273000000000000000000000000000000006044820152606401610df8565b80600003611de6576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610df8565b818314611e74576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610df8565b611e7f816003614a50565b8311611ee7576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610df8565b611eef612977565b6040805160c0810182528a8152602081018a905260ff89169181018290526060810188905267ffffffffffffffff8716608082015260a0810186905290611f369088613415565b600554156120eb57600554600090611f5090600190614a67565b9050600060058281548110611f6757611f67614689565b60009182526020822001546006805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110611fa157611fa1614689565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526004909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009081169091559290911680845292208054909116905560058054919250908061202157612021614a7a565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055600680548061208a5761208a614a7a565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611f36915050565b60005b815151811015612552576000600460008460000151848151811061211457612114614689565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff16600281111561215e5761215e6149fd565b146121c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610df8565b6040805180820190915260ff821681526001602082015282518051600491600091859081106121f6576121f6614689565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115612297576122976149fd565b0217905550600091506122a79050565b60046000846020015184815181106122c1576122c1614689565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff16600281111561230b5761230b6149fd565b14612372576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610df8565b6040805180820190915260ff8216815260208101600281525060046000846020015184815181106123a5576123a5614689565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115612446576124466149fd565b02179055505082518051600592508390811061246457612464614689565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90931692909217909155820151805160069190839081106124e0576124e0614689565b60209081029190910181015182546001810184556000938452919092200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790558061254a816146e7565b9150506120ee565b506040810151600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff8116780100000000000000000000000000000000000000000000000063ffffffff438116820292909217808555920481169291829160149161260a91849174010000000000000000000000000000000000000000900416614aa9565b92506101000a81548163ffffffff021916908363ffffffff1602179055506126694630600160149054906101000a900463ffffffff1663ffffffff16856000015186602001518760400151886060015189608001518a60a0015161342e565b600281905582518051600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff9093169290920291909117905560015460208501516040808701516060880151608089015160a08a015193517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0598612720988b9891977401000000000000000000000000000000000000000090920463ffffffff16969095919491939192614ac6565b60405180910390a15050505050505050505050565b604080516101208101825260085463ffffffff8082168352640100000000808304821660208501526801000000000000000083048216848601526c010000000000000000000000008084048316606086015270010000000000000000000000000000000084048316608086015274010000000000000000000000000000000000000000840468ffffffffffffffffff1660a0808701919091527d01000000000000000000000000000000000000000000000000000000000090940461ffff1660c086015260095492831660e086015291047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610100840152600b5484517ffeaf968c00000000000000000000000000000000000000000000000000000000815294516000958694859490930473ffffffffffffffffffffffffffffffffffffffff169263feaf968c926004808401938290030181865afa15801561289a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128be9190614b76565b5093505092505080426128d19190614a67565b836020015163ffffffff161080156128f357506000836020015163ffffffff16115b1561292257505061010001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16919050565b6000821361295f576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101839052602401610df8565b5092915050565b61296e612977565b610902816134d9565b60005473ffffffffffffffffffffffffffffffffffffffff1633146129f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610df8565b565b6129f8612977565b600b546bffffffffffffffffffffffff16600003612a1c57565b6000612a266110dc565b90508051600003612a63576040517f30274b3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600b54600091612a82916bffffffffffffffffffffffff16614bc6565b905060005b8251811015612b4e5781600a6000858481518110612aa757612aa7614689565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a90046bffffffffffffffffffffffff16612b0f9190614bf1565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080612b47906146e7565b9050612a87565b508151612b5b9082614c16565b600b8054600090612b7b9084906bffffffffffffffffffffffff1661471f565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505050565b6000806006805480602002602001604051908101604052809291908181526020018280548015612c1357602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612be8575b5050505050905060005b8151811015612c8c578373ffffffffffffffffffffffffffffffffffffffff16828281518110612c4f57612c4f614689565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603612c7c575060019392505050565b612c85816146e7565b9050612c1d565b5060009392505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810191909152604080516101208101825260085463ffffffff8082168352640100000000808304821660208501526801000000000000000083048216948401949094526c0100000000000000000000000082048116606084015270010000000000000000000000000000000082048116608084015274010000000000000000000000000000000000000000820468ffffffffffffffffff1660a08401527d01000000000000000000000000000000000000000000000000000000000090910461ffff90811660c0840181905260095492831660e0850152939091047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661010080840191909152850151919291161115612e2b576040517fdada758700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60085460009074010000000000000000000000000000000000000000900468ffffffffffffffffff1690506000612e6c8560e001513a84886080015161332b565b9050806bffffffffffffffffffffffff1685606001516bffffffffffffffffffffffff161015612ec8576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612f4b3087604001518860a001518960c001516001612ee99190614c3e565b6040805173ffffffffffffffffffffffffffffffffffffffff958616602080830191909152949095168582015267ffffffffffffffff928316606086015291166080808501919091528151808503909101815260a09093019052815191012090565b90506040518061016001604052808281526020013073ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff168152602001876040015173ffffffffffffffffffffffffffffffffffffffff1681526020018760a0015167ffffffffffffffff1681526020018760e0015163ffffffff168152602001876080015168ffffffffffffffffff1681526020018468ffffffffffffffffff168152602001856040015163ffffffff1664ffffffffff168152602001856060015163ffffffff1664ffffffffff168152602001856080015163ffffffff164261303d9190614c5f565b63ffffffff1681525094508460405160200161305991906140d9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600093845260079092529091205550919392505050565b60006130b3826020614a50565b6130be856020614a50565b6130ca88610144614c5f565b6130d49190614c5f565b6130de9190614c5f565b6130e9906000614c5f565b9050368114613154576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d6174636800000000000000006044820152606401610df8565b50505050505050565b60608080808061316f86880188614d4d565b845194995092975090955093509150158061318c57508351855114155b8061319957508251855114155b806131a657508151855114155b806131b357508051855114155b156131ea576040517f0be3632800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b855181101561331d57600061328287838151811061320d5761320d614689565b602002602001015187848151811061322757613227614689565b602002602001015187858151811061324157613241614689565b602002602001015187868151811061325b5761325b614689565b602002602001015187878151811061327557613275614689565b60200260200101516135ce565b90506000816006811115613298576132986149fd565b14806132b5575060018160068111156132b3576132b36149fd565b145b1561330c578682815181106132cc576132cc614689565b60209081029190910181015160405133815290917fc708e0440951fd63499c0f7a73819b469ee5dd3ecc356c0ab4eb7f18389009d9910160405180910390a25b50613316816146e7565b90506131ed565b505050505050505050505050565b600854600090819086906133639063ffffffff6c01000000000000000000000000820481169168010000000000000000900416614aa9565b61336d9190614aa9565b60095463ffffffff91821692506000916127109161338c911688614a50565b6133969190614e1f565b6133a09087614c5f565b905060006133ad8261385e565b905060006133c9846bffffffffffffffffffffffff8416614a50565b905060006133e568ffffffffffffffffff808916908a16614bf1565b90506134076134026bffffffffffffffffffffffff831684614c5f565b61388d565b9a9950505050505050505050565b600061341f6110dc565b511115610fd157610fd1612a02565b6000808a8a8a8a8a8a8a8a8a60405160200161345299989796959493929190614e33565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613558576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610df8565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080838060200190518101906135e59190614f09565b9050806040516020016135f891906140d9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008a815260079093529120541461364a576006915050611ca9565b600087815260076020526040902054613667576002915050611ca9565b60006136723a61385e565b9050600082610120015183610100015161368c9190614fd1565b61369d9064ffffffffff1683614c16565b90506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663330605298b8b878960e0015168ffffffffffffffffff16886136fc9190614bf1565b338b6040518763ffffffff1660e01b815260040161371f96959493929190614fef565b60408051808303816000875af115801561373d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613761919061506b565b9092509050600082600681111561377a5761377a6149fd565b148061379757506001826006811115613795576137956149fd565b145b156138505760008b8152600760205260408120556137b58184614bf1565b336000908152600a6020526040812080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff93841617905560e0870151600b805468ffffffffffffffffff9092169390929161382191859116614bf1565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b509998505050505050505050565b600061388761386b612735565b61387d84670de0b6b3a7640000614a50565b6134029190614e1f565b92915050565b60006bffffffffffffffffffffffff82111561392b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610df8565b5090565b50805461393b906144ad565b6000825580601f1061394b575050565b601f0160209004906000526020600020908101906109029190613988565b604051806103e00160405280601f906020820280368337509192915050565b5b8082111561392b5760008155600101613989565b60008083601f8401126139af57600080fd5b50813567ffffffffffffffff8111156139c757600080fd5b6020830191508360208285010111156139df57600080fd5b9250929050565b600080602083850312156139f957600080fd5b823567ffffffffffffffff811115613a1057600080fd5b613a1c8582860161399d565b90969095509350505050565b6000815180845260005b81811015613a4e57602081850181015186830182015201613a32565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000613a9f6020830184613a28565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610120810167ffffffffffffffff81118282101715613af957613af9613aa6565b60405290565b604051610160810167ffffffffffffffff81118282101715613af957613af9613aa6565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613b6a57613b6a613aa6565b604052919050565b63ffffffff8116811461090257600080fd5b80356112f781613b72565b68ffffffffffffffffff8116811461090257600080fd5b80356112f781613b8f565b803561ffff811681146112f757600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146112f757600080fd5b60006101208284031215613c0257600080fd5b613c0a613ad5565b613c1383613b84565b8152613c2160208401613b84565b6020820152613c3260408401613b84565b6040820152613c4360608401613b84565b6060820152613c5460808401613b84565b6080820152613c6560a08401613ba6565b60a0820152613c7660c08401613bb1565b60c0820152613c8760e08401613b84565b60e0820152610100613c9a818501613bc3565b908201529392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461090257600080fd5b80356112f781613ca5565b600060208284031215613ce457600080fd5b8135613a9f81613ca5565b600081518084526020808501945080840160005b83811015613d3557815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613d03565b509495945050505050565b604081526000613d536040830185613cef565b6020838203818501528185518084528284019150828160051b85010183880160005b83811015613dc1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0878403018552613daf838351613a28565b94860194925090850190600101613d75565b50909998505050505050505050565b600082601f830112613de157600080fd5b813567ffffffffffffffff811115613dfb57613dfb613aa6565b613e2c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613b23565b818152846020838601011115613e4157600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215613e7057600080fd5b813567ffffffffffffffff811115613e8757600080fd5b613e9384828501613dd0565b949350505050565b6bffffffffffffffffffffffff8116811461090257600080fd5b80356112f781613e9b565b60008060408385031215613ed357600080fd5b8235613ede81613ca5565b91506020830135613eee81613e9b565b809150509250929050565b600080600060408486031215613f0e57600080fd5b8335613f1981613ca5565b9250602084013567ffffffffffffffff811115613f3557600080fd5b613f418682870161399d565b9497909650939450505050565b602081526000613a9f6020830184613cef565b600060208284031215613f7357600080fd5b5035919050565b600060208284031215613f8c57600080fd5b813567ffffffffffffffff811115613fa357600080fd5b82016101608185031215613a9f57600080fd5b805182526020810151613fe1602084018273ffffffffffffffffffffffffffffffffffffffff169052565b50604081015161400160408401826bffffffffffffffffffffffff169052565b506060810151614029606084018273ffffffffffffffffffffffffffffffffffffffff169052565b506080810151614045608084018267ffffffffffffffff169052565b5060a081015161405d60a084018263ffffffff169052565b5060c081015161407a60c084018268ffffffffffffffffff169052565b5060e081015161409760e084018268ffffffffffffffffff169052565b506101008181015164ffffffffff81168483015250506101208181015164ffffffffff81168483015250506101408181015163ffffffff8116848301526110d6565b61016081016138878284613fb6565b60008083601f8401126140fa57600080fd5b50813567ffffffffffffffff81111561411257600080fd5b6020830191508360208260051b85010111156139df57600080fd5b60008060008060008060008060e0898b03121561414957600080fd5b606089018a81111561415a57600080fd5b8998503567ffffffffffffffff8082111561417457600080fd5b6141808c838d0161399d565b909950975060808b013591508082111561419957600080fd5b6141a58c838d016140e8565b909750955060a08b01359150808211156141be57600080fd5b506141cb8b828c016140e8565b999c989b50969995989497949560c00135949350505050565b815163ffffffff9081168252602080840151821690830152604080840151821690830152606080840151821690830152608080840151918216908301526101208201905060a083015161424460a084018268ffffffffffffffffff169052565b5060c083015161425a60c084018261ffff169052565b5060e083015161427260e084018263ffffffff169052565b50610100838101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116848301525b505092915050565b67ffffffffffffffff8116811461090257600080fd5b80356112f7816142a6565b6000806000806000608086880312156142df57600080fd5b85356142ea816142a6565b9450602086013567ffffffffffffffff81111561430657600080fd5b6143128882890161399d565b909550935050604086013561432681613b72565b949793965091946060013592915050565b600067ffffffffffffffff82111561435157614351613aa6565b5060051b60200190565b600082601f83011261436c57600080fd5b8135602061438161437c83614337565b613b23565b82815260059290921b840181019181810190868411156143a057600080fd5b8286015b848110156143c45780356143b781613ca5565b83529183019183016143a4565b509695505050505050565b803560ff811681146112f757600080fd5b60008060008060008060c087890312156143f957600080fd5b863567ffffffffffffffff8082111561441157600080fd5b61441d8a838b0161435b565b9750602089013591508082111561443357600080fd5b61443f8a838b0161435b565b965061444d60408a016143cf565b9550606089013591508082111561446357600080fd5b61446f8a838b01613dd0565b945061447d60808a016142bc565b935060a089013591508082111561449357600080fd5b506144a089828a01613dd0565b9150509295509295509295565b600181811c908216806144c157607f821691505b6020821081036144fa577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111561063757600081815260208120601f850160051c810160208610156145275750805b601f850160051c820191505b81811015610d7357828155600101614533565b67ffffffffffffffff83111561455e5761455e613aa6565b6145728361456c83546144ad565b83614500565b6000601f8411600181146145c4576000851561458e5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561465a565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561461357868501358255602094850194600190920191016145f3565b508682101561464e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b80516112f781613b8f565b60006020828403121561467e57600080fd5b8151613a9f81613b8f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614718576147186146b8565b5060010190565b6bffffffffffffffffffffffff82811682821603908082111561295f5761295f6146b8565b6000610160823603121561475757600080fd5b61475f613aff565b823567ffffffffffffffff81111561477657600080fd5b61478236828601613dd0565b8252506020830135602082015261479b60408401613cc7565b60408201526147ac60608401613eb5565b60608201526147bd60808401613ba6565b60808201526147ce60a084016142bc565b60a08201526147df60c084016142bc565b60c08201526147f060e08401613b84565b60e0820152610100614803818501613bb1565b908201526101206148158482016142bc565b90820152610140614827848201613cc7565b9082015292915050565b60006020828403121561484357600080fd5b8135613a9f816142a6565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261488357600080fd5b83018035915067ffffffffffffffff82111561489e57600080fd5b6020019150368190038213156139df57600080fd5b6000602082840312156148c557600080fd5b613a9f82613bb1565b6000602082840312156148e057600080fd5b8135613a9f81613b72565b73ffffffffffffffffffffffffffffffffffffffff8a8116825267ffffffffffffffff8a166020830152881660408201526102406060820181905281018690526000610260878982850137600083890182015261ffff8716608084015260a0830186905263ffffffff851660c0840152601f88017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016830101905061340760e0830184613fb6565b60ff8181168382160190811115613887576138876146b8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600060ff8316806149ee576149ee6149ac565b8060ff84160491505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8183823760009101908152919050565b828152606082602083013760800192915050565b8082028115828204841417613887576138876146b8565b81810381811115613887576138876146b8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b63ffffffff81811683821601908082111561295f5761295f6146b8565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152614af68184018a613cef565b90508281036080840152614b0a8189613cef565b905060ff871660a084015282810360c0840152614b278187613a28565b905067ffffffffffffffff851660e0840152828103610100840152614b4c8185613a28565b9c9b505050505050505050505050565b805169ffffffffffffffffffff811681146112f757600080fd5b600080600080600060a08688031215614b8e57600080fd5b614b9786614b5c565b9450602086015193506040860151925060608601519150614bba60808701614b5c565b90509295509295909350565b60006bffffffffffffffffffffffff80841680614be557614be56149ac565b92169190910492915050565b6bffffffffffffffffffffffff81811683821601908082111561295f5761295f6146b8565b6bffffffffffffffffffffffff81811683821602808216919082811461429e5761429e6146b8565b67ffffffffffffffff81811683821601908082111561295f5761295f6146b8565b80820180821115613887576138876146b8565b600082601f830112614c8357600080fd5b81356020614c9361437c83614337565b82815260059290921b84018101918181019086841115614cb257600080fd5b8286015b848110156143c45780358352918301918301614cb6565b600082601f830112614cde57600080fd5b81356020614cee61437c83614337565b82815260059290921b84018101918181019086841115614d0d57600080fd5b8286015b848110156143c457803567ffffffffffffffff811115614d315760008081fd5b614d3f8986838b0101613dd0565b845250918301918301614d11565b600080600080600060a08688031215614d6557600080fd5b853567ffffffffffffffff80821115614d7d57600080fd5b614d8989838a01614c72565b96506020880135915080821115614d9f57600080fd5b614dab89838a01614ccd565b95506040880135915080821115614dc157600080fd5b614dcd89838a01614ccd565b94506060880135915080821115614de357600080fd5b614def89838a01614ccd565b93506080880135915080821115614e0557600080fd5b50614e1288828901614ccd565b9150509295509295909350565b600082614e2e57614e2e6149ac565b500490565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614e7a8285018b613cef565b91508382036080850152614e8e828a613cef565b915060ff881660a085015283820360c0850152614eab8288613a28565b90861660e08501528381036101008501529050614b4c8185613a28565b80516112f781613ca5565b80516112f781613e9b565b80516112f7816142a6565b80516112f781613b72565b805164ffffffffff811681146112f757600080fd5b60006101608284031215614f1c57600080fd5b614f24613aff565b82518152614f3460208401614ec8565b6020820152614f4560408401614ed3565b6040820152614f5660608401614ec8565b6060820152614f6760808401614ede565b6080820152614f7860a08401614ee9565b60a0820152614f8960c08401614661565b60c0820152614f9a60e08401614661565b60e0820152610100614fad818501614ef4565b90820152610120614fbf848201614ef4565b90820152610140613c9a848201614ee9565b64ffffffffff81811683821601908082111561295f5761295f6146b8565b60006102008083526150038184018a613a28565b905082810360208401526150178189613a28565b6bffffffffffffffffffffffff88811660408601528716606085015273ffffffffffffffffffffffffffffffffffffffff861660808501529150615060905060a0830184613fb6565b979650505050505050565b6000806040838503121561507e57600080fd5b82516007811061508d57600080fd5b6020840151909250613eee81613e9b56fea164736f6c6343000813000a", } var FunctionsCoordinatorABI = FunctionsCoordinatorMetaData.ABI var FunctionsCoordinatorBin = FunctionsCoordinatorMetaData.Bin -func DeployFunctionsCoordinator(auth *bind.TransactOpts, backend bind.ContractBackend, router common.Address, config []byte, linkToNativeFeed common.Address) (common.Address, *types.Transaction, *FunctionsCoordinator, error) { +func DeployFunctionsCoordinator(auth *bind.TransactOpts, backend bind.ContractBackend, router common.Address, config FunctionsBillingConfig, linkToNativeFeed common.Address) (common.Address, *types.Transaction, *FunctionsCoordinator, error) { parsed, err := FunctionsCoordinatorMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -200,9 +211,9 @@ func (_FunctionsCoordinator *FunctionsCoordinatorTransactorRaw) Transact(opts *b return _FunctionsCoordinator.Contract.contract.Transact(opts, method, params...) } -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) EstimateCost(opts *bind.CallOpts, subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPrice *big.Int) (*big.Int, error) { +func (_FunctionsCoordinator *FunctionsCoordinatorCaller) EstimateCost(opts *bind.CallOpts, subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceGwei *big.Int) (*big.Int, error) { var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "estimateCost", subscriptionId, data, callbackGasLimit, gasPrice) + err := _FunctionsCoordinator.contract.Call(opts, &out, "estimateCost", subscriptionId, data, callbackGasLimit, gasPriceGwei) if err != nil { return *new(*big.Int), err @@ -214,17 +225,17 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCaller) EstimateCost(opts *bind } -func (_FunctionsCoordinator *FunctionsCoordinatorSession) EstimateCost(subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPrice *big.Int) (*big.Int, error) { - return _FunctionsCoordinator.Contract.EstimateCost(&_FunctionsCoordinator.CallOpts, subscriptionId, data, callbackGasLimit, gasPrice) +func (_FunctionsCoordinator *FunctionsCoordinatorSession) EstimateCost(subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceGwei *big.Int) (*big.Int, error) { + return _FunctionsCoordinator.Contract.EstimateCost(&_FunctionsCoordinator.CallOpts, subscriptionId, data, callbackGasLimit, gasPriceGwei) } -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) EstimateCost(subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPrice *big.Int) (*big.Int, error) { - return _FunctionsCoordinator.Contract.EstimateCost(&_FunctionsCoordinator.CallOpts, subscriptionId, data, callbackGasLimit, gasPrice) +func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) EstimateCost(subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceGwei *big.Int) (*big.Int, error) { + return _FunctionsCoordinator.Contract.EstimateCost(&_FunctionsCoordinator.CallOpts, subscriptionId, data, callbackGasLimit, gasPriceGwei) } -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetAdminFee(opts *bind.CallOpts, arg0 []byte, arg1 IFunctionsBillingRequestBilling) (*big.Int, error) { +func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetAdminFee(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "getAdminFee", arg0, arg1) + err := _FunctionsCoordinator.contract.Call(opts, &out, "getAdminFee") if err != nil { return *new(*big.Int), err @@ -236,12 +247,12 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetAdminFee(opts *bind. } -func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetAdminFee(arg0 []byte, arg1 IFunctionsBillingRequestBilling) (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetAdminFee(&_FunctionsCoordinator.CallOpts, arg0, arg1) +func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetAdminFee() (*big.Int, error) { + return _FunctionsCoordinator.Contract.GetAdminFee(&_FunctionsCoordinator.CallOpts) } -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetAdminFee(arg0 []byte, arg1 IFunctionsBillingRequestBilling) (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetAdminFee(&_FunctionsCoordinator.CallOpts, arg0, arg1) +func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetAdminFee() (*big.Int, error) { + return _FunctionsCoordinator.Contract.GetAdminFee(&_FunctionsCoordinator.CallOpts) } func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetAllNodePublicKeys(opts *bind.CallOpts) ([]common.Address, [][]byte, error) { @@ -267,66 +278,31 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetAllNodePublic return _FunctionsCoordinator.Contract.GetAllNodePublicKeys(&_FunctionsCoordinator.CallOpts) } -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetConfig(opts *bind.CallOpts) (GetConfig, - - error) { +func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetConfig(opts *bind.CallOpts) (FunctionsBillingConfig, error) { var out []interface{} err := _FunctionsCoordinator.contract.Call(opts, &out, "getConfig") - outstruct := new(GetConfig) if err != nil { - return *outstruct, err + return *new(FunctionsBillingConfig), err } - outstruct.MaxCallbackGasLimit = *abi.ConvertType(out[0], new(uint32)).(*uint32) - outstruct.FeedStalenessSeconds = *abi.ConvertType(out[1], new(uint32)).(*uint32) - outstruct.GasOverheadAfterCallback = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) - outstruct.FallbackNativePerUnitLink = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) - outstruct.GasOverheadBeforeCallback = *abi.ConvertType(out[4], new(uint32)).(*uint32) - outstruct.LinkPriceFeed = *abi.ConvertType(out[5], new(common.Address)).(*common.Address) - outstruct.MaxSupportedRequestDataVersion = *abi.ConvertType(out[6], new(uint16)).(*uint16) + out0 := *abi.ConvertType(out[0], new(FunctionsBillingConfig)).(*FunctionsBillingConfig) - return *outstruct, err + return out0, err } -func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetConfig() (GetConfig, - - error) { +func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetConfig() (FunctionsBillingConfig, error) { return _FunctionsCoordinator.Contract.GetConfig(&_FunctionsCoordinator.CallOpts) } -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetConfig() (GetConfig, - - error) { +func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetConfig() (FunctionsBillingConfig, error) { return _FunctionsCoordinator.Contract.GetConfig(&_FunctionsCoordinator.CallOpts) } -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetConfigHash(opts *bind.CallOpts) ([32]byte, error) { - var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "getConfigHash") - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetConfigHash() ([32]byte, error) { - return _FunctionsCoordinator.Contract.GetConfigHash(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetConfigHash() ([32]byte, error) { - return _FunctionsCoordinator.Contract.GetConfigHash(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetDONFee(opts *bind.CallOpts, arg0 []byte, arg1 IFunctionsBillingRequestBilling) (*big.Int, error) { +func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetDONFee(opts *bind.CallOpts, arg0 []byte) (*big.Int, error) { var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "getDONFee", arg0, arg1) + err := _FunctionsCoordinator.contract.Call(opts, &out, "getDONFee", arg0) if err != nil { return *new(*big.Int), err @@ -338,12 +314,12 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetDONFee(opts *bind.Ca } -func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetDONFee(arg0 []byte, arg1 IFunctionsBillingRequestBilling) (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetDONFee(&_FunctionsCoordinator.CallOpts, arg0, arg1) +func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetDONFee(arg0 []byte) (*big.Int, error) { + return _FunctionsCoordinator.Contract.GetDONFee(&_FunctionsCoordinator.CallOpts, arg0) } -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetDONFee(arg0 []byte, arg1 IFunctionsBillingRequestBilling) (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetDONFee(&_FunctionsCoordinator.CallOpts, arg0, arg1) +func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetDONFee(arg0 []byte) (*big.Int, error) { + return _FunctionsCoordinator.Contract.GetDONFee(&_FunctionsCoordinator.CallOpts, arg0) } func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetDONPublicKey(opts *bind.CallOpts) ([]byte, error) { @@ -368,48 +344,48 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetDONPublicKey( return _FunctionsCoordinator.Contract.GetDONPublicKey(&_FunctionsCoordinator.CallOpts) } -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetFeedData(opts *bind.CallOpts) (*big.Int, error) { +func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetThresholdPublicKey(opts *bind.CallOpts) ([]byte, error) { var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "getFeedData") + err := _FunctionsCoordinator.contract.Call(opts, &out, "getThresholdPublicKey") if err != nil { - return *new(*big.Int), err + return *new([]byte), err } - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) return out0, err } -func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetFeedData() (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetFeedData(&_FunctionsCoordinator.CallOpts) +func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetThresholdPublicKey() ([]byte, error) { + return _FunctionsCoordinator.Contract.GetThresholdPublicKey(&_FunctionsCoordinator.CallOpts) } -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetFeedData() (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetFeedData(&_FunctionsCoordinator.CallOpts) +func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetThresholdPublicKey() ([]byte, error) { + return _FunctionsCoordinator.Contract.GetThresholdPublicKey(&_FunctionsCoordinator.CallOpts) } -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetThresholdPublicKey(opts *bind.CallOpts) ([]byte, error) { +func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetWeiPerUnitLink(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "getThresholdPublicKey") + err := _FunctionsCoordinator.contract.Call(opts, &out, "getWeiPerUnitLink") if err != nil { - return *new([]byte), err + return *new(*big.Int), err } - out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) return out0, err } -func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetThresholdPublicKey() ([]byte, error) { - return _FunctionsCoordinator.Contract.GetThresholdPublicKey(&_FunctionsCoordinator.CallOpts) +func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetWeiPerUnitLink() (*big.Int, error) { + return _FunctionsCoordinator.Contract.GetWeiPerUnitLink(&_FunctionsCoordinator.CallOpts) } -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetThresholdPublicKey() ([]byte, error) { - return _FunctionsCoordinator.Contract.GetThresholdPublicKey(&_FunctionsCoordinator.CallOpts) +func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetWeiPerUnitLink() (*big.Int, error) { + return _FunctionsCoordinator.Contract.GetWeiPerUnitLink(&_FunctionsCoordinator.CallOpts) } func (_FunctionsCoordinator *FunctionsCoordinatorCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, @@ -588,40 +564,28 @@ func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) OracleWithdr return _FunctionsCoordinator.Contract.OracleWithdraw(&_FunctionsCoordinator.TransactOpts, recipient, amount) } -func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) SendRequest(opts *bind.TransactOpts, request IFunctionsCoordinatorRequest) (*types.Transaction, error) { - return _FunctionsCoordinator.contract.Transact(opts, "sendRequest", request) +func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) OracleWithdrawAll(opts *bind.TransactOpts) (*types.Transaction, error) { + return _FunctionsCoordinator.contract.Transact(opts, "oracleWithdrawAll") } -func (_FunctionsCoordinator *FunctionsCoordinatorSession) SendRequest(request IFunctionsCoordinatorRequest) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.SendRequest(&_FunctionsCoordinator.TransactOpts, request) +func (_FunctionsCoordinator *FunctionsCoordinatorSession) OracleWithdrawAll() (*types.Transaction, error) { + return _FunctionsCoordinator.Contract.OracleWithdrawAll(&_FunctionsCoordinator.TransactOpts) } -func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) SendRequest(request IFunctionsCoordinatorRequest) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.SendRequest(&_FunctionsCoordinator.TransactOpts, request) +func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) OracleWithdrawAll() (*types.Transaction, error) { + return _FunctionsCoordinator.Contract.OracleWithdrawAll(&_FunctionsCoordinator.TransactOpts) } -func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) SetConfig(opts *bind.TransactOpts, config []byte) (*types.Transaction, error) { - return _FunctionsCoordinator.contract.Transact(opts, "setConfig", config) +func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) SetConfig(opts *bind.TransactOpts, _signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) { + return _FunctionsCoordinator.contract.Transact(opts, "setConfig", _signers, _transmitters, _f, _onchainConfig, _offchainConfigVersion, _offchainConfig) } -func (_FunctionsCoordinator *FunctionsCoordinatorSession) SetConfig(config []byte) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.SetConfig(&_FunctionsCoordinator.TransactOpts, config) +func (_FunctionsCoordinator *FunctionsCoordinatorSession) SetConfig(_signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) { + return _FunctionsCoordinator.Contract.SetConfig(&_FunctionsCoordinator.TransactOpts, _signers, _transmitters, _f, _onchainConfig, _offchainConfigVersion, _offchainConfig) } -func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) SetConfig(config []byte) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.SetConfig(&_FunctionsCoordinator.TransactOpts, config) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) SetConfig0(opts *bind.TransactOpts, _signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) { - return _FunctionsCoordinator.contract.Transact(opts, "setConfig0", _signers, _transmitters, _f, _onchainConfig, _offchainConfigVersion, _offchainConfig) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) SetConfig0(_signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.SetConfig0(&_FunctionsCoordinator.TransactOpts, _signers, _transmitters, _f, _onchainConfig, _offchainConfigVersion, _offchainConfig) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) SetConfig0(_signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.SetConfig0(&_FunctionsCoordinator.TransactOpts, _signers, _transmitters, _f, _onchainConfig, _offchainConfigVersion, _offchainConfig) +func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) SetConfig(_signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) { + return _FunctionsCoordinator.Contract.SetConfig(&_FunctionsCoordinator.TransactOpts, _signers, _transmitters, _f, _onchainConfig, _offchainConfigVersion, _offchainConfig) } func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) SetDONPublicKey(opts *bind.TransactOpts, donPublicKey []byte) (*types.Transaction, error) { @@ -660,6 +624,18 @@ func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) SetThreshold return _FunctionsCoordinator.Contract.SetThresholdPublicKey(&_FunctionsCoordinator.TransactOpts, thresholdPublicKey) } +func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) StartRequest(opts *bind.TransactOpts, request FunctionsResponseRequestMeta) (*types.Transaction, error) { + return _FunctionsCoordinator.contract.Transact(opts, "startRequest", request) +} + +func (_FunctionsCoordinator *FunctionsCoordinatorSession) StartRequest(request FunctionsResponseRequestMeta) (*types.Transaction, error) { + return _FunctionsCoordinator.Contract.StartRequest(&_FunctionsCoordinator.TransactOpts, request) +} + +func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) StartRequest(request FunctionsResponseRequestMeta) (*types.Transaction, error) { + return _FunctionsCoordinator.Contract.StartRequest(&_FunctionsCoordinator.TransactOpts, request) +} + func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { return _FunctionsCoordinator.contract.Transact(opts, "transferOwnership", to) } @@ -684,8 +660,20 @@ func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) Transmit(rep return _FunctionsCoordinator.Contract.Transmit(&_FunctionsCoordinator.TransactOpts, reportContext, report, rs, ss, rawVs) } -type FunctionsCoordinatorBillingEndIterator struct { - Event *FunctionsCoordinatorBillingEnd +func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) UpdateConfig(opts *bind.TransactOpts, config FunctionsBillingConfig) (*types.Transaction, error) { + return _FunctionsCoordinator.contract.Transact(opts, "updateConfig", config) +} + +func (_FunctionsCoordinator *FunctionsCoordinatorSession) UpdateConfig(config FunctionsBillingConfig) (*types.Transaction, error) { + return _FunctionsCoordinator.Contract.UpdateConfig(&_FunctionsCoordinator.TransactOpts, config) +} + +func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) UpdateConfig(config FunctionsBillingConfig) (*types.Transaction, error) { + return _FunctionsCoordinator.Contract.UpdateConfig(&_FunctionsCoordinator.TransactOpts, config) +} + +type FunctionsCoordinatorCommitmentDeletedIterator struct { + Event *FunctionsCoordinatorCommitmentDeleted contract *bind.BoundContract event string @@ -696,7 +684,7 @@ type FunctionsCoordinatorBillingEndIterator struct { fail error } -func (it *FunctionsCoordinatorBillingEndIterator) Next() bool { +func (it *FunctionsCoordinatorCommitmentDeletedIterator) Next() bool { if it.fail != nil { return false @@ -705,7 +693,7 @@ func (it *FunctionsCoordinatorBillingEndIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(FunctionsCoordinatorBillingEnd) + it.Event = new(FunctionsCoordinatorCommitmentDeleted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -720,7 +708,7 @@ func (it *FunctionsCoordinatorBillingEndIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(FunctionsCoordinatorBillingEnd) + it.Event = new(FunctionsCoordinatorCommitmentDeleted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -735,47 +723,32 @@ func (it *FunctionsCoordinatorBillingEndIterator) Next() bool { } } -func (it *FunctionsCoordinatorBillingEndIterator) Error() error { +func (it *FunctionsCoordinatorCommitmentDeletedIterator) Error() error { return it.fail } -func (it *FunctionsCoordinatorBillingEndIterator) Close() error { +func (it *FunctionsCoordinatorCommitmentDeletedIterator) Close() error { it.sub.Unsubscribe() return nil } -type FunctionsCoordinatorBillingEnd struct { - RequestId [32]byte - SubscriptionId uint64 - SignerPayment *big.Int - TransmitterPayment *big.Int - TotalCost *big.Int - Result uint8 - Raw types.Log +type FunctionsCoordinatorCommitmentDeleted struct { + RequestId [32]byte + Raw types.Log } -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterBillingEnd(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorBillingEndIterator, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } +func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterCommitmentDeleted(opts *bind.FilterOpts) (*FunctionsCoordinatorCommitmentDeletedIterator, error) { - logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "BillingEnd", requestIdRule) + logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "CommitmentDeleted") if err != nil { return nil, err } - return &FunctionsCoordinatorBillingEndIterator{contract: _FunctionsCoordinator.contract, event: "BillingEnd", logs: logs, sub: sub}, nil + return &FunctionsCoordinatorCommitmentDeletedIterator{contract: _FunctionsCoordinator.contract, event: "CommitmentDeleted", logs: logs, sub: sub}, nil } -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchBillingEnd(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorBillingEnd, requestId [][32]byte) (event.Subscription, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } +func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchCommitmentDeleted(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorCommitmentDeleted) (event.Subscription, error) { - logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "BillingEnd", requestIdRule) + logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "CommitmentDeleted") if err != nil { return nil, err } @@ -785,8 +758,8 @@ func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchBillingEnd(opts select { case log := <-logs: - event := new(FunctionsCoordinatorBillingEnd) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "BillingEnd", log); err != nil { + event := new(FunctionsCoordinatorCommitmentDeleted) + if err := _FunctionsCoordinator.contract.UnpackLog(event, "CommitmentDeleted", log); err != nil { return err } event.Raw = log @@ -807,17 +780,17 @@ func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchBillingEnd(opts }), nil } -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseBillingEnd(log types.Log) (*FunctionsCoordinatorBillingEnd, error) { - event := new(FunctionsCoordinatorBillingEnd) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "BillingEnd", log); err != nil { +func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseCommitmentDeleted(log types.Log) (*FunctionsCoordinatorCommitmentDeleted, error) { + event := new(FunctionsCoordinatorCommitmentDeleted) + if err := _FunctionsCoordinator.contract.UnpackLog(event, "CommitmentDeleted", log); err != nil { return nil, err } event.Raw = log return event, nil } -type FunctionsCoordinatorBillingStartIterator struct { - Event *FunctionsCoordinatorBillingStart +type FunctionsCoordinatorConfigSetIterator struct { + Event *FunctionsCoordinatorConfigSet contract *bind.BoundContract event string @@ -828,7 +801,7 @@ type FunctionsCoordinatorBillingStartIterator struct { fail error } -func (it *FunctionsCoordinatorBillingStartIterator) Next() bool { +func (it *FunctionsCoordinatorConfigSetIterator) Next() bool { if it.fail != nil { return false @@ -837,7 +810,7 @@ func (it *FunctionsCoordinatorBillingStartIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(FunctionsCoordinatorBillingStart) + it.Event = new(FunctionsCoordinatorConfigSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -852,7 +825,7 @@ func (it *FunctionsCoordinatorBillingStartIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(FunctionsCoordinatorBillingStart) + it.Event = new(FunctionsCoordinatorConfigSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -867,43 +840,40 @@ func (it *FunctionsCoordinatorBillingStartIterator) Next() bool { } } -func (it *FunctionsCoordinatorBillingStartIterator) Error() error { +func (it *FunctionsCoordinatorConfigSetIterator) Error() error { return it.fail } -func (it *FunctionsCoordinatorBillingStartIterator) Close() error { +func (it *FunctionsCoordinatorConfigSetIterator) Close() error { it.sub.Unsubscribe() return nil } -type FunctionsCoordinatorBillingStart struct { - RequestId [32]byte - Commitment FunctionsBillingCommitment - Raw types.Log +type FunctionsCoordinatorConfigSet 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 (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterBillingStart(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorBillingStartIterator, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } +func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterConfigSet(opts *bind.FilterOpts) (*FunctionsCoordinatorConfigSetIterator, error) { - logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "BillingStart", requestIdRule) + logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "ConfigSet") if err != nil { return nil, err } - return &FunctionsCoordinatorBillingStartIterator{contract: _FunctionsCoordinator.contract, event: "BillingStart", logs: logs, sub: sub}, nil + return &FunctionsCoordinatorConfigSetIterator{contract: _FunctionsCoordinator.contract, event: "ConfigSet", logs: logs, sub: sub}, nil } -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchBillingStart(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorBillingStart, requestId [][32]byte) (event.Subscription, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } +func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorConfigSet) (event.Subscription, error) { - logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "BillingStart", requestIdRule) + logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "ConfigSet") if err != nil { return nil, err } @@ -913,8 +883,8 @@ func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchBillingStart(opt select { case log := <-logs: - event := new(FunctionsCoordinatorBillingStart) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "BillingStart", log); err != nil { + event := new(FunctionsCoordinatorConfigSet) + if err := _FunctionsCoordinator.contract.UnpackLog(event, "ConfigSet", log); err != nil { return err } event.Raw = log @@ -935,17 +905,17 @@ func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchBillingStart(opt }), nil } -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseBillingStart(log types.Log) (*FunctionsCoordinatorBillingStart, error) { - event := new(FunctionsCoordinatorBillingStart) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "BillingStart", log); err != nil { +func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseConfigSet(log types.Log) (*FunctionsCoordinatorConfigSet, error) { + event := new(FunctionsCoordinatorConfigSet) + if err := _FunctionsCoordinator.contract.UnpackLog(event, "ConfigSet", log); err != nil { return nil, err } event.Raw = log return event, nil } -type FunctionsCoordinatorConfigSetIterator struct { - Event *FunctionsCoordinatorConfigSet +type FunctionsCoordinatorConfigUpdatedIterator struct { + Event *FunctionsCoordinatorConfigUpdated contract *bind.BoundContract event string @@ -956,7 +926,7 @@ type FunctionsCoordinatorConfigSetIterator struct { fail error } -func (it *FunctionsCoordinatorConfigSetIterator) Next() bool { +func (it *FunctionsCoordinatorConfigUpdatedIterator) Next() bool { if it.fail != nil { return false @@ -965,7 +935,7 @@ func (it *FunctionsCoordinatorConfigSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(FunctionsCoordinatorConfigSet) + it.Event = new(FunctionsCoordinatorConfigUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -980,7 +950,7 @@ func (it *FunctionsCoordinatorConfigSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(FunctionsCoordinatorConfigSet) + it.Event = new(FunctionsCoordinatorConfigUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -995,38 +965,32 @@ func (it *FunctionsCoordinatorConfigSetIterator) Next() bool { } } -func (it *FunctionsCoordinatorConfigSetIterator) Error() error { +func (it *FunctionsCoordinatorConfigUpdatedIterator) Error() error { return it.fail } -func (it *FunctionsCoordinatorConfigSetIterator) Close() error { +func (it *FunctionsCoordinatorConfigUpdatedIterator) Close() error { it.sub.Unsubscribe() return nil } -type FunctionsCoordinatorConfigSet struct { - MaxCallbackGasLimit uint32 - FeedStalenessSeconds uint32 - GasOverheadBeforeCallback uint32 - GasOverheadAfterCallback uint32 - FallbackNativePerUnitLink *big.Int - DonFee *big.Int - MaxSupportedRequestDataVersion uint16 - Raw types.Log +type FunctionsCoordinatorConfigUpdated struct { + Config FunctionsBillingConfig + Raw types.Log } -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterConfigSet(opts *bind.FilterOpts) (*FunctionsCoordinatorConfigSetIterator, error) { +func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterConfigUpdated(opts *bind.FilterOpts) (*FunctionsCoordinatorConfigUpdatedIterator, error) { - logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "ConfigSet") + logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "ConfigUpdated") if err != nil { return nil, err } - return &FunctionsCoordinatorConfigSetIterator{contract: _FunctionsCoordinator.contract, event: "ConfigSet", logs: logs, sub: sub}, nil + return &FunctionsCoordinatorConfigUpdatedIterator{contract: _FunctionsCoordinator.contract, event: "ConfigUpdated", logs: logs, sub: sub}, nil } -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorConfigSet) (event.Subscription, error) { +func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchConfigUpdated(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorConfigUpdated) (event.Subscription, error) { - logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "ConfigSet") + logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "ConfigUpdated") if err != nil { return nil, err } @@ -1036,8 +1000,8 @@ func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchConfigSet(opts * select { case log := <-logs: - event := new(FunctionsCoordinatorConfigSet) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "ConfigSet", log); err != nil { + event := new(FunctionsCoordinatorConfigUpdated) + if err := _FunctionsCoordinator.contract.UnpackLog(event, "ConfigUpdated", log); err != nil { return err } event.Raw = log @@ -1058,17 +1022,17 @@ func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchConfigSet(opts * }), nil } -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseConfigSet(log types.Log) (*FunctionsCoordinatorConfigSet, error) { - event := new(FunctionsCoordinatorConfigSet) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "ConfigSet", log); err != nil { +func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseConfigUpdated(log types.Log) (*FunctionsCoordinatorConfigUpdated, error) { + event := new(FunctionsCoordinatorConfigUpdated) + if err := _FunctionsCoordinator.contract.UnpackLog(event, "ConfigUpdated", log); err != nil { return nil, err } event.Raw = log return event, nil } -type FunctionsCoordinatorCostExceedsCommitmentIterator struct { - Event *FunctionsCoordinatorCostExceedsCommitment +type FunctionsCoordinatorOracleRequestIterator struct { + Event *FunctionsCoordinatorOracleRequest contract *bind.BoundContract event string @@ -1079,7 +1043,7 @@ type FunctionsCoordinatorCostExceedsCommitmentIterator struct { fail error } -func (it *FunctionsCoordinatorCostExceedsCommitmentIterator) Next() bool { +func (it *FunctionsCoordinatorOracleRequestIterator) Next() bool { if it.fail != nil { return false @@ -1088,7 +1052,7 @@ func (it *FunctionsCoordinatorCostExceedsCommitmentIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(FunctionsCoordinatorCostExceedsCommitment) + it.Event = new(FunctionsCoordinatorOracleRequest) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1103,7 +1067,7 @@ func (it *FunctionsCoordinatorCostExceedsCommitmentIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(FunctionsCoordinatorCostExceedsCommitment) + it.Event = new(FunctionsCoordinatorOracleRequest) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1118,42 +1082,59 @@ func (it *FunctionsCoordinatorCostExceedsCommitmentIterator) Next() bool { } } -func (it *FunctionsCoordinatorCostExceedsCommitmentIterator) Error() error { +func (it *FunctionsCoordinatorOracleRequestIterator) Error() error { return it.fail } -func (it *FunctionsCoordinatorCostExceedsCommitmentIterator) Close() error { +func (it *FunctionsCoordinatorOracleRequestIterator) Close() error { it.sub.Unsubscribe() return nil } -type FunctionsCoordinatorCostExceedsCommitment struct { - RequestId [32]byte - Raw types.Log +type FunctionsCoordinatorOracleRequest struct { + RequestId [32]byte + RequestingContract common.Address + RequestInitiator common.Address + SubscriptionId uint64 + SubscriptionOwner common.Address + Data []byte + DataVersion uint16 + Flags [32]byte + CallbackGasLimit uint64 + Commitment FunctionsResponseCommitment + Raw types.Log } -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterCostExceedsCommitment(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorCostExceedsCommitmentIterator, error) { +func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterOracleRequest(opts *bind.FilterOpts, requestId [][32]byte, requestingContract []common.Address) (*FunctionsCoordinatorOracleRequestIterator, error) { var requestIdRule []interface{} for _, requestIdItem := range requestId { requestIdRule = append(requestIdRule, requestIdItem) } + var requestingContractRule []interface{} + for _, requestingContractItem := range requestingContract { + requestingContractRule = append(requestingContractRule, requestingContractItem) + } - logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "CostExceedsCommitment", requestIdRule) + logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "OracleRequest", requestIdRule, requestingContractRule) if err != nil { return nil, err } - return &FunctionsCoordinatorCostExceedsCommitmentIterator{contract: _FunctionsCoordinator.contract, event: "CostExceedsCommitment", logs: logs, sub: sub}, nil + return &FunctionsCoordinatorOracleRequestIterator{contract: _FunctionsCoordinator.contract, event: "OracleRequest", logs: logs, sub: sub}, nil } -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchCostExceedsCommitment(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorCostExceedsCommitment, requestId [][32]byte) (event.Subscription, error) { +func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchOracleRequest(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorOracleRequest, requestId [][32]byte, requestingContract []common.Address) (event.Subscription, error) { var requestIdRule []interface{} for _, requestIdItem := range requestId { requestIdRule = append(requestIdRule, requestIdItem) } + var requestingContractRule []interface{} + for _, requestingContractItem := range requestingContract { + requestingContractRule = append(requestingContractRule, requestingContractItem) + } - logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "CostExceedsCommitment", requestIdRule) + logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "OracleRequest", requestIdRule, requestingContractRule) if err != nil { return nil, err } @@ -1163,8 +1144,8 @@ func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchCostExceedsCommi select { case log := <-logs: - event := new(FunctionsCoordinatorCostExceedsCommitment) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "CostExceedsCommitment", log); err != nil { + event := new(FunctionsCoordinatorOracleRequest) + if err := _FunctionsCoordinator.contract.UnpackLog(event, "OracleRequest", log); err != nil { return err } event.Raw = log @@ -1185,17 +1166,17 @@ func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchCostExceedsCommi }), nil } -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseCostExceedsCommitment(log types.Log) (*FunctionsCoordinatorCostExceedsCommitment, error) { - event := new(FunctionsCoordinatorCostExceedsCommitment) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "CostExceedsCommitment", log); err != nil { +func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseOracleRequest(log types.Log) (*FunctionsCoordinatorOracleRequest, error) { + event := new(FunctionsCoordinatorOracleRequest) + if err := _FunctionsCoordinator.contract.UnpackLog(event, "OracleRequest", log); err != nil { return nil, err } event.Raw = log return event, nil } -type FunctionsCoordinatorInsufficientGasProvidedIterator struct { - Event *FunctionsCoordinatorInsufficientGasProvided +type FunctionsCoordinatorOracleResponseIterator struct { + Event *FunctionsCoordinatorOracleResponse contract *bind.BoundContract event string @@ -1206,7 +1187,7 @@ type FunctionsCoordinatorInsufficientGasProvidedIterator struct { fail error } -func (it *FunctionsCoordinatorInsufficientGasProvidedIterator) Next() bool { +func (it *FunctionsCoordinatorOracleResponseIterator) Next() bool { if it.fail != nil { return false @@ -1215,7 +1196,7 @@ func (it *FunctionsCoordinatorInsufficientGasProvidedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(FunctionsCoordinatorInsufficientGasProvided) + it.Event = new(FunctionsCoordinatorOracleResponse) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1230,7 +1211,7 @@ func (it *FunctionsCoordinatorInsufficientGasProvidedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(FunctionsCoordinatorInsufficientGasProvided) + it.Event = new(FunctionsCoordinatorOracleResponse) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1245,42 +1226,43 @@ func (it *FunctionsCoordinatorInsufficientGasProvidedIterator) Next() bool { } } -func (it *FunctionsCoordinatorInsufficientGasProvidedIterator) Error() error { +func (it *FunctionsCoordinatorOracleResponseIterator) Error() error { return it.fail } -func (it *FunctionsCoordinatorInsufficientGasProvidedIterator) Close() error { +func (it *FunctionsCoordinatorOracleResponseIterator) Close() error { it.sub.Unsubscribe() return nil } -type FunctionsCoordinatorInsufficientGasProvided struct { - RequestId [32]byte - Raw types.Log +type FunctionsCoordinatorOracleResponse struct { + RequestId [32]byte + Transmitter common.Address + Raw types.Log } -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterInsufficientGasProvided(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorInsufficientGasProvidedIterator, error) { +func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterOracleResponse(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorOracleResponseIterator, error) { var requestIdRule []interface{} for _, requestIdItem := range requestId { requestIdRule = append(requestIdRule, requestIdItem) } - logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "InsufficientGasProvided", requestIdRule) + logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "OracleResponse", requestIdRule) if err != nil { return nil, err } - return &FunctionsCoordinatorInsufficientGasProvidedIterator{contract: _FunctionsCoordinator.contract, event: "InsufficientGasProvided", logs: logs, sub: sub}, nil + return &FunctionsCoordinatorOracleResponseIterator{contract: _FunctionsCoordinator.contract, event: "OracleResponse", logs: logs, sub: sub}, nil } -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchInsufficientGasProvided(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorInsufficientGasProvided, requestId [][32]byte) (event.Subscription, error) { +func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchOracleResponse(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorOracleResponse, requestId [][32]byte) (event.Subscription, error) { var requestIdRule []interface{} for _, requestIdItem := range requestId { requestIdRule = append(requestIdRule, requestIdItem) } - logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "InsufficientGasProvided", requestIdRule) + logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "OracleResponse", requestIdRule) if err != nil { return nil, err } @@ -1290,8 +1272,8 @@ func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchInsufficientGasP select { case log := <-logs: - event := new(FunctionsCoordinatorInsufficientGasProvided) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "InsufficientGasProvided", log); err != nil { + event := new(FunctionsCoordinatorOracleResponse) + if err := _FunctionsCoordinator.contract.UnpackLog(event, "OracleResponse", log); err != nil { return err } event.Raw = log @@ -1312,17 +1294,17 @@ func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchInsufficientGasP }), nil } -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseInsufficientGasProvided(log types.Log) (*FunctionsCoordinatorInsufficientGasProvided, error) { - event := new(FunctionsCoordinatorInsufficientGasProvided) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "InsufficientGasProvided", log); err != nil { +func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseOracleResponse(log types.Log) (*FunctionsCoordinatorOracleResponse, error) { + event := new(FunctionsCoordinatorOracleResponse) + if err := _FunctionsCoordinator.contract.UnpackLog(event, "OracleResponse", log); err != nil { return nil, err } event.Raw = log return event, nil } -type FunctionsCoordinatorInvalidRequestIDIterator struct { - Event *FunctionsCoordinatorInvalidRequestID +type FunctionsCoordinatorOwnershipTransferRequestedIterator struct { + Event *FunctionsCoordinatorOwnershipTransferRequested contract *bind.BoundContract event string @@ -1333,7 +1315,7 @@ type FunctionsCoordinatorInvalidRequestIDIterator struct { fail error } -func (it *FunctionsCoordinatorInvalidRequestIDIterator) Next() bool { +func (it *FunctionsCoordinatorOwnershipTransferRequestedIterator) Next() bool { if it.fail != nil { return false @@ -1342,7 +1324,7 @@ func (it *FunctionsCoordinatorInvalidRequestIDIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(FunctionsCoordinatorInvalidRequestID) + it.Event = new(FunctionsCoordinatorOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1357,7 +1339,7 @@ func (it *FunctionsCoordinatorInvalidRequestIDIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(FunctionsCoordinatorInvalidRequestID) + it.Event = new(FunctionsCoordinatorOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1372,42 +1354,51 @@ func (it *FunctionsCoordinatorInvalidRequestIDIterator) Next() bool { } } -func (it *FunctionsCoordinatorInvalidRequestIDIterator) Error() error { +func (it *FunctionsCoordinatorOwnershipTransferRequestedIterator) Error() error { return it.fail } -func (it *FunctionsCoordinatorInvalidRequestIDIterator) Close() error { +func (it *FunctionsCoordinatorOwnershipTransferRequestedIterator) Close() error { it.sub.Unsubscribe() return nil } -type FunctionsCoordinatorInvalidRequestID struct { - RequestId [32]byte - Raw types.Log +type FunctionsCoordinatorOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log } -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterInvalidRequestID(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorInvalidRequestIDIterator, error) { +func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsCoordinatorOwnershipTransferRequestedIterator, error) { - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) + 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 := _FunctionsCoordinator.contract.FilterLogs(opts, "InvalidRequestID", requestIdRule) + logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } - return &FunctionsCoordinatorInvalidRequestIDIterator{contract: _FunctionsCoordinator.contract, event: "InvalidRequestID", logs: logs, sub: sub}, nil + return &FunctionsCoordinatorOwnershipTransferRequestedIterator{contract: _FunctionsCoordinator.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil } -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchInvalidRequestID(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorInvalidRequestID, requestId [][32]byte) (event.Subscription, error) { +func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) + 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 := _FunctionsCoordinator.contract.WatchLogs(opts, "InvalidRequestID", requestIdRule) + logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } @@ -1417,8 +1408,8 @@ func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchInvalidRequestID select { case log := <-logs: - event := new(FunctionsCoordinatorInvalidRequestID) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "InvalidRequestID", log); err != nil { + event := new(FunctionsCoordinatorOwnershipTransferRequested) + if err := _FunctionsCoordinator.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return err } event.Raw = log @@ -1439,17 +1430,17 @@ func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchInvalidRequestID }), nil } -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseInvalidRequestID(log types.Log) (*FunctionsCoordinatorInvalidRequestID, error) { - event := new(FunctionsCoordinatorInvalidRequestID) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "InvalidRequestID", log); err != nil { +func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseOwnershipTransferRequested(log types.Log) (*FunctionsCoordinatorOwnershipTransferRequested, error) { + event := new(FunctionsCoordinatorOwnershipTransferRequested) + if err := _FunctionsCoordinator.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return nil, err } event.Raw = log return event, nil } -type FunctionsCoordinatorOCRConfigSetIterator struct { - Event *FunctionsCoordinatorOCRConfigSet +type FunctionsCoordinatorOwnershipTransferredIterator struct { + Event *FunctionsCoordinatorOwnershipTransferred contract *bind.BoundContract event string @@ -1460,7 +1451,7 @@ type FunctionsCoordinatorOCRConfigSetIterator struct { fail error } -func (it *FunctionsCoordinatorOCRConfigSetIterator) Next() bool { +func (it *FunctionsCoordinatorOwnershipTransferredIterator) Next() bool { if it.fail != nil { return false @@ -1469,7 +1460,7 @@ func (it *FunctionsCoordinatorOCRConfigSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(FunctionsCoordinatorOCRConfigSet) + it.Event = new(FunctionsCoordinatorOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1484,7 +1475,7 @@ func (it *FunctionsCoordinatorOCRConfigSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(FunctionsCoordinatorOCRConfigSet) + it.Event = new(FunctionsCoordinatorOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1499,541 +1490,11 @@ func (it *FunctionsCoordinatorOCRConfigSetIterator) Next() bool { } } -func (it *FunctionsCoordinatorOCRConfigSetIterator) Error() error { +func (it *FunctionsCoordinatorOwnershipTransferredIterator) Error() error { return it.fail } -func (it *FunctionsCoordinatorOCRConfigSetIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsCoordinatorOCRConfigSet 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 (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterOCRConfigSet(opts *bind.FilterOpts) (*FunctionsCoordinatorOCRConfigSetIterator, error) { - - logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "OCRConfigSet") - if err != nil { - return nil, err - } - return &FunctionsCoordinatorOCRConfigSetIterator{contract: _FunctionsCoordinator.contract, event: "OCRConfigSet", logs: logs, sub: sub}, nil -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchOCRConfigSet(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorOCRConfigSet) (event.Subscription, error) { - - logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "OCRConfigSet") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsCoordinatorOCRConfigSet) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "OCRConfigSet", 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 (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseOCRConfigSet(log types.Log) (*FunctionsCoordinatorOCRConfigSet, error) { - event := new(FunctionsCoordinatorOCRConfigSet) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "OCRConfigSet", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsCoordinatorOracleRequestIterator struct { - Event *FunctionsCoordinatorOracleRequest - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsCoordinatorOracleRequestIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsCoordinatorOracleRequest) - 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(FunctionsCoordinatorOracleRequest) - 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 *FunctionsCoordinatorOracleRequestIterator) Error() error { - return it.fail -} - -func (it *FunctionsCoordinatorOracleRequestIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsCoordinatorOracleRequest struct { - RequestId [32]byte - RequestingContract common.Address - RequestInitiator common.Address - SubscriptionId uint64 - SubscriptionOwner common.Address - Data []byte - DataVersion uint16 - Raw types.Log -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterOracleRequest(opts *bind.FilterOpts, requestId [][32]byte, requestingContract []common.Address) (*FunctionsCoordinatorOracleRequestIterator, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - var requestingContractRule []interface{} - for _, requestingContractItem := range requestingContract { - requestingContractRule = append(requestingContractRule, requestingContractItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "OracleRequest", requestIdRule, requestingContractRule) - if err != nil { - return nil, err - } - return &FunctionsCoordinatorOracleRequestIterator{contract: _FunctionsCoordinator.contract, event: "OracleRequest", logs: logs, sub: sub}, nil -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchOracleRequest(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorOracleRequest, requestId [][32]byte, requestingContract []common.Address) (event.Subscription, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - var requestingContractRule []interface{} - for _, requestingContractItem := range requestingContract { - requestingContractRule = append(requestingContractRule, requestingContractItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "OracleRequest", requestIdRule, requestingContractRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsCoordinatorOracleRequest) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "OracleRequest", 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 (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseOracleRequest(log types.Log) (*FunctionsCoordinatorOracleRequest, error) { - event := new(FunctionsCoordinatorOracleRequest) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "OracleRequest", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsCoordinatorOracleResponseIterator struct { - Event *FunctionsCoordinatorOracleResponse - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsCoordinatorOracleResponseIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsCoordinatorOracleResponse) - 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(FunctionsCoordinatorOracleResponse) - 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 *FunctionsCoordinatorOracleResponseIterator) Error() error { - return it.fail -} - -func (it *FunctionsCoordinatorOracleResponseIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsCoordinatorOracleResponse struct { - RequestId [32]byte - Transmitter common.Address - Raw types.Log -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterOracleResponse(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorOracleResponseIterator, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "OracleResponse", requestIdRule) - if err != nil { - return nil, err - } - return &FunctionsCoordinatorOracleResponseIterator{contract: _FunctionsCoordinator.contract, event: "OracleResponse", logs: logs, sub: sub}, nil -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchOracleResponse(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorOracleResponse, requestId [][32]byte) (event.Subscription, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "OracleResponse", 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(FunctionsCoordinatorOracleResponse) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "OracleResponse", 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 (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseOracleResponse(log types.Log) (*FunctionsCoordinatorOracleResponse, error) { - event := new(FunctionsCoordinatorOracleResponse) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "OracleResponse", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsCoordinatorOwnershipTransferRequestedIterator struct { - Event *FunctionsCoordinatorOwnershipTransferRequested - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsCoordinatorOwnershipTransferRequestedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsCoordinatorOwnershipTransferRequested) - 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(FunctionsCoordinatorOwnershipTransferRequested) - 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 *FunctionsCoordinatorOwnershipTransferRequestedIterator) Error() error { - return it.fail -} - -func (it *FunctionsCoordinatorOwnershipTransferRequestedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsCoordinatorOwnershipTransferRequested struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsCoordinatorOwnershipTransferRequestedIterator, 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 := _FunctionsCoordinator.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) - if err != nil { - return nil, err - } - return &FunctionsCoordinatorOwnershipTransferRequestedIterator{contract: _FunctionsCoordinator.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorOwnershipTransferRequested, 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 := _FunctionsCoordinator.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(FunctionsCoordinatorOwnershipTransferRequested) - if err := _FunctionsCoordinator.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 (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseOwnershipTransferRequested(log types.Log) (*FunctionsCoordinatorOwnershipTransferRequested, error) { - event := new(FunctionsCoordinatorOwnershipTransferRequested) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsCoordinatorOwnershipTransferredIterator struct { - Event *FunctionsCoordinatorOwnershipTransferred - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsCoordinatorOwnershipTransferredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsCoordinatorOwnershipTransferred) - 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(FunctionsCoordinatorOwnershipTransferred) - 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 *FunctionsCoordinatorOwnershipTransferredIterator) Error() error { - return it.fail -} - -func (it *FunctionsCoordinatorOwnershipTransferredIterator) Close() error { +func (it *FunctionsCoordinatorOwnershipTransferredIterator) Close() error { it.sub.Unsubscribe() return nil } @@ -2114,133 +1575,6 @@ func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseOwnershipTransfe return event, nil } -type FunctionsCoordinatorRequestTimedOutIterator struct { - Event *FunctionsCoordinatorRequestTimedOut - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsCoordinatorRequestTimedOutIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsCoordinatorRequestTimedOut) - 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(FunctionsCoordinatorRequestTimedOut) - 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 *FunctionsCoordinatorRequestTimedOutIterator) Error() error { - return it.fail -} - -func (it *FunctionsCoordinatorRequestTimedOutIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsCoordinatorRequestTimedOut struct { - RequestId [32]byte - Raw types.Log -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterRequestTimedOut(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorRequestTimedOutIterator, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "RequestTimedOut", requestIdRule) - if err != nil { - return nil, err - } - return &FunctionsCoordinatorRequestTimedOutIterator{contract: _FunctionsCoordinator.contract, event: "RequestTimedOut", logs: logs, sub: sub}, nil -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchRequestTimedOut(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorRequestTimedOut, requestId [][32]byte) (event.Subscription, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "RequestTimedOut", 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(FunctionsCoordinatorRequestTimedOut) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "RequestTimedOut", 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 (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseRequestTimedOut(log types.Log) (*FunctionsCoordinatorRequestTimedOut, error) { - event := new(FunctionsCoordinatorRequestTimedOut) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "RequestTimedOut", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - type FunctionsCoordinatorTransmittedIterator struct { Event *FunctionsCoordinatorTransmitted @@ -2359,15 +1693,6 @@ func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseTransmitted(log return event, nil } -type GetConfig struct { - MaxCallbackGasLimit uint32 - FeedStalenessSeconds uint32 - GasOverheadAfterCallback *big.Int - FallbackNativePerUnitLink *big.Int - GasOverheadBeforeCallback uint32 - LinkPriceFeed common.Address - MaxSupportedRequestDataVersion uint16 -} type LatestConfigDetails struct { ConfigCount uint32 BlockNumber uint32 @@ -2381,20 +1706,12 @@ type LatestConfigDigestAndEpoch struct { func (_FunctionsCoordinator *FunctionsCoordinator) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { - case _FunctionsCoordinator.abi.Events["BillingEnd"].ID: - return _FunctionsCoordinator.ParseBillingEnd(log) - case _FunctionsCoordinator.abi.Events["BillingStart"].ID: - return _FunctionsCoordinator.ParseBillingStart(log) + case _FunctionsCoordinator.abi.Events["CommitmentDeleted"].ID: + return _FunctionsCoordinator.ParseCommitmentDeleted(log) case _FunctionsCoordinator.abi.Events["ConfigSet"].ID: return _FunctionsCoordinator.ParseConfigSet(log) - case _FunctionsCoordinator.abi.Events["CostExceedsCommitment"].ID: - return _FunctionsCoordinator.ParseCostExceedsCommitment(log) - case _FunctionsCoordinator.abi.Events["InsufficientGasProvided"].ID: - return _FunctionsCoordinator.ParseInsufficientGasProvided(log) - case _FunctionsCoordinator.abi.Events["InvalidRequestID"].ID: - return _FunctionsCoordinator.ParseInvalidRequestID(log) - case _FunctionsCoordinator.abi.Events["OCRConfigSet"].ID: - return _FunctionsCoordinator.ParseOCRConfigSet(log) + case _FunctionsCoordinator.abi.Events["ConfigUpdated"].ID: + return _FunctionsCoordinator.ParseConfigUpdated(log) case _FunctionsCoordinator.abi.Events["OracleRequest"].ID: return _FunctionsCoordinator.ParseOracleRequest(log) case _FunctionsCoordinator.abi.Events["OracleResponse"].ID: @@ -2403,8 +1720,6 @@ func (_FunctionsCoordinator *FunctionsCoordinator) ParseLog(log types.Log) (gene return _FunctionsCoordinator.ParseOwnershipTransferRequested(log) case _FunctionsCoordinator.abi.Events["OwnershipTransferred"].ID: return _FunctionsCoordinator.ParseOwnershipTransferred(log) - case _FunctionsCoordinator.abi.Events["RequestTimedOut"].ID: - return _FunctionsCoordinator.ParseRequestTimedOut(log) case _FunctionsCoordinator.abi.Events["Transmitted"].ID: return _FunctionsCoordinator.ParseTransmitted(log) @@ -2413,36 +1728,20 @@ func (_FunctionsCoordinator *FunctionsCoordinator) ParseLog(log types.Log) (gene } } -func (FunctionsCoordinatorBillingEnd) Topic() common.Hash { - return common.HexToHash("0x30e1e299f390e4f3fa75e4489fed477e86183937a4a21a0ae7b137a4dff03535") -} - -func (FunctionsCoordinatorBillingStart) Topic() common.Hash { - return common.HexToHash("0x9fadc54f9c9b79290fa97f2c9deb97ee080d1f8ae4f00deb1fb83cedd1ee5422") +func (FunctionsCoordinatorCommitmentDeleted) Topic() common.Hash { + return common.HexToHash("0x8a4b97add3359bd6bcf5e82874363670eb5ad0f7615abddbd0ed0a3a98f0f416") } func (FunctionsCoordinatorConfigSet) Topic() common.Hash { - return common.HexToHash("0xd09395baf4d99e44ce1b8e96a4396a3f896d0fd5e4517993f28ce0a6fb42e227") -} - -func (FunctionsCoordinatorCostExceedsCommitment) Topic() common.Hash { - return common.HexToHash("0x689f49eacf6db85082542f4b7873f4a519744a4e093fd002310545bfb4354cc8") -} - -func (FunctionsCoordinatorInsufficientGasProvided) Topic() common.Hash { - return common.HexToHash("0x357a60574f143e144d62ddc89636fee45ba5e2f8c9a30b9f91e28f8dfe5a56e0") -} - -func (FunctionsCoordinatorInvalidRequestID) Topic() common.Hash { - return common.HexToHash("0xa1c120e327c9ad8b075793878c88d59b8934b97ae37117faa3bb21616237f7be") + return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") } -func (FunctionsCoordinatorOCRConfigSet) Topic() common.Hash { - return common.HexToHash("0x324b4d5fd31c5865202bc49f712eb9fcdf22bcc3b89f8c721f3134ae6c081a09") +func (FunctionsCoordinatorConfigUpdated) Topic() common.Hash { + return common.HexToHash("0x5b6e2e1a03ea742ce04ca36d0175411a0772f99ef4ee84aeb9868a1ef6ddc82c") } func (FunctionsCoordinatorOracleRequest) Topic() common.Hash { - return common.HexToHash("0xb108b073fa485003d66284614f1c3b4feb3f47ffc88f7873bf3b2ec4bb8939bc") + return common.HexToHash("0xbf50768ccf13bd0110ca6d53a9c4f1f3271abdd4c24a56878863ed25b20598ff") } func (FunctionsCoordinatorOracleResponse) Topic() common.Hash { @@ -2457,10 +1756,6 @@ func (FunctionsCoordinatorOwnershipTransferred) Topic() common.Hash { return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") } -func (FunctionsCoordinatorRequestTimedOut) Topic() common.Hash { - return common.HexToHash("0xf1ca1e9147be737b04a2b018a79405f687a97de8dd8a2559bbe62357343af414") -} - func (FunctionsCoordinatorTransmitted) Topic() common.Hash { return common.HexToHash("0xb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62") } @@ -2470,26 +1765,22 @@ func (_FunctionsCoordinator *FunctionsCoordinator) Address() common.Address { } type FunctionsCoordinatorInterface interface { - EstimateCost(opts *bind.CallOpts, subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPrice *big.Int) (*big.Int, error) + EstimateCost(opts *bind.CallOpts, subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceGwei *big.Int) (*big.Int, error) - GetAdminFee(opts *bind.CallOpts, arg0 []byte, arg1 IFunctionsBillingRequestBilling) (*big.Int, error) + GetAdminFee(opts *bind.CallOpts) (*big.Int, error) GetAllNodePublicKeys(opts *bind.CallOpts) ([]common.Address, [][]byte, error) - GetConfig(opts *bind.CallOpts) (GetConfig, - - error) - - GetConfigHash(opts *bind.CallOpts) ([32]byte, error) + GetConfig(opts *bind.CallOpts) (FunctionsBillingConfig, error) - GetDONFee(opts *bind.CallOpts, arg0 []byte, arg1 IFunctionsBillingRequestBilling) (*big.Int, error) + GetDONFee(opts *bind.CallOpts, arg0 []byte) (*big.Int, error) GetDONPublicKey(opts *bind.CallOpts) ([]byte, error) - GetFeedData(opts *bind.CallOpts) (*big.Int, error) - GetThresholdPublicKey(opts *bind.CallOpts) ([]byte, error) + GetWeiPerUnitLink(opts *bind.CallOpts) (*big.Int, error) + LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, error) @@ -2512,11 +1803,9 @@ type FunctionsCoordinatorInterface interface { OracleWithdraw(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) - SendRequest(opts *bind.TransactOpts, request IFunctionsCoordinatorRequest) (*types.Transaction, error) + OracleWithdrawAll(opts *bind.TransactOpts) (*types.Transaction, error) - SetConfig(opts *bind.TransactOpts, config []byte) (*types.Transaction, error) - - SetConfig0(opts *bind.TransactOpts, _signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) + SetConfig(opts *bind.TransactOpts, _signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) SetDONPublicKey(opts *bind.TransactOpts, donPublicKey []byte) (*types.Transaction, error) @@ -2524,21 +1813,19 @@ type FunctionsCoordinatorInterface interface { SetThresholdPublicKey(opts *bind.TransactOpts, thresholdPublicKey []byte) (*types.Transaction, error) + StartRequest(opts *bind.TransactOpts, request FunctionsResponseRequestMeta) (*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) - FilterBillingEnd(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorBillingEndIterator, error) - - WatchBillingEnd(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorBillingEnd, requestId [][32]byte) (event.Subscription, error) - - ParseBillingEnd(log types.Log) (*FunctionsCoordinatorBillingEnd, error) + UpdateConfig(opts *bind.TransactOpts, config FunctionsBillingConfig) (*types.Transaction, error) - FilterBillingStart(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorBillingStartIterator, error) + FilterCommitmentDeleted(opts *bind.FilterOpts) (*FunctionsCoordinatorCommitmentDeletedIterator, error) - WatchBillingStart(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorBillingStart, requestId [][32]byte) (event.Subscription, error) + WatchCommitmentDeleted(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorCommitmentDeleted) (event.Subscription, error) - ParseBillingStart(log types.Log) (*FunctionsCoordinatorBillingStart, error) + ParseCommitmentDeleted(log types.Log) (*FunctionsCoordinatorCommitmentDeleted, error) FilterConfigSet(opts *bind.FilterOpts) (*FunctionsCoordinatorConfigSetIterator, error) @@ -2546,29 +1833,11 @@ type FunctionsCoordinatorInterface interface { ParseConfigSet(log types.Log) (*FunctionsCoordinatorConfigSet, error) - FilterCostExceedsCommitment(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorCostExceedsCommitmentIterator, error) - - WatchCostExceedsCommitment(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorCostExceedsCommitment, requestId [][32]byte) (event.Subscription, error) - - ParseCostExceedsCommitment(log types.Log) (*FunctionsCoordinatorCostExceedsCommitment, error) - - FilterInsufficientGasProvided(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorInsufficientGasProvidedIterator, error) - - WatchInsufficientGasProvided(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorInsufficientGasProvided, requestId [][32]byte) (event.Subscription, error) + FilterConfigUpdated(opts *bind.FilterOpts) (*FunctionsCoordinatorConfigUpdatedIterator, error) - ParseInsufficientGasProvided(log types.Log) (*FunctionsCoordinatorInsufficientGasProvided, error) + WatchConfigUpdated(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorConfigUpdated) (event.Subscription, error) - FilterInvalidRequestID(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorInvalidRequestIDIterator, error) - - WatchInvalidRequestID(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorInvalidRequestID, requestId [][32]byte) (event.Subscription, error) - - ParseInvalidRequestID(log types.Log) (*FunctionsCoordinatorInvalidRequestID, error) - - FilterOCRConfigSet(opts *bind.FilterOpts) (*FunctionsCoordinatorOCRConfigSetIterator, error) - - WatchOCRConfigSet(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorOCRConfigSet) (event.Subscription, error) - - ParseOCRConfigSet(log types.Log) (*FunctionsCoordinatorOCRConfigSet, error) + ParseConfigUpdated(log types.Log) (*FunctionsCoordinatorConfigUpdated, error) FilterOracleRequest(opts *bind.FilterOpts, requestId [][32]byte, requestingContract []common.Address) (*FunctionsCoordinatorOracleRequestIterator, error) @@ -2594,12 +1863,6 @@ type FunctionsCoordinatorInterface interface { ParseOwnershipTransferred(log types.Log) (*FunctionsCoordinatorOwnershipTransferred, error) - FilterRequestTimedOut(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorRequestTimedOutIterator, error) - - WatchRequestTimedOut(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorRequestTimedOut, requestId [][32]byte) (event.Subscription, error) - - ParseRequestTimedOut(log types.Log) (*FunctionsCoordinatorRequestTimedOut, error) - FilterTransmitted(opts *bind.FilterOpts) (*FunctionsCoordinatorTransmittedIterator, error) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorTransmitted) (event.Subscription, error) diff --git a/core/gethwrappers/functions/generated/functions_load_test_client/functions_load_test_client.go b/core/gethwrappers/functions/generated/functions_load_test_client/functions_load_test_client.go new file mode 100644 index 00000000000..90d1ac33533 --- /dev/null +++ b/core/gethwrappers/functions/generated/functions_load_test_client/functions_load_test_client.go @@ -0,0 +1,988 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package functions_load_test_client + +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 FunctionsLoadTestClientMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyArgs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySource\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoInlineSecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyRouterCanFulfill\",\"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\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestSent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_GAS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"handleOracleFulfillment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastError\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastErrorLength\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastRequestId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastResponse\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastResponseLength\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"source\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedSecretsReferences\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"args\",\"type\":\"string[]\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"jobId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b5060405162001a3d38038062001a3d833981016040819052620000349162000180565b6001600160a01b0381166080523380600081620000985760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000cb57620000cb81620000d5565b50505050620001b2565b336001600160a01b038216036200012f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008f565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019357600080fd5b81516001600160a01b0381168114620001ab57600080fd5b9392505050565b608051611868620001d5600039600081816101c601526109f101526118686000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80636d9809a011610081578063b1e217491161005b578063b1e2174914610182578063f2fde38b1461018b578063f7b4c06f1461019e57600080fd5b80636d9809a01461014857806379ba5097146101525780638da5cb5b1461015a57600080fd5b806342748b2a116100b257806342748b2a146100ff5780634b0795a81461012c5780635fa353e71461013557600080fd5b80630ca76175146100ce5780633944ea3a146100e3575b600080fd5b6100e16100dc3660046112b4565b6101ae565b005b6100ec60035481565b6040519081526020015b60405180910390f35b60055461011790640100000000900463ffffffff1681565b60405163ffffffff90911681526020016100f6565b6100ec60045481565b6100e1610143366004611387565b61022d565b6101176201117081565b6100e1610347565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f6565b6100ec60025481565b6100e161019936600461146b565b610449565b6005546101179063ffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461021d576040517fc6829f8300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61022883838361045d565b505050565b6102356104f2565b61027e6040805161010081019091528060008152602001600081526020016000815260200160608152602001606081526020016060815260200160608152602001606081525090565b6102c089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506105759050565b85156103085761030887878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506105869050565b83156103225761032261031b85876114a1565b82906105d0565b61033961032e82610613565b8462011170856109ec565b600255505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6104516104f2565b61045a81610acb565b50565b600283905561046b82610bc0565b6003558151600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff9092169190911790556104ad81610bc0565b600455516005805463ffffffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff9092169190911790555050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610573576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103c4565b565b6105828260008084610c42565b5050565b80516000036105c1576040517fe889636f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016020830152608090910152565b805160000361060b576040517ffe936cb700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c090910152565b60606000610622610100610cd9565b905061066c6040518060400160405280600c81526020017f636f64654c6f636174696f6e000000000000000000000000000000000000000081525082610cfa90919063ffffffff16565b825161068a90600281111561068357610683611539565b8290610d13565b60408051808201909152600881527f6c616e677561676500000000000000000000000000000000000000000000000060208201526106c9908290610cfa565b60408301516106e090801561068357610683611539565b60408051808201909152600681527f736f757263650000000000000000000000000000000000000000000000000000602082015261071f908290610cfa565b606083015161072f908290610cfa565b60a083015151156107895760408051808201909152601081527f726571756573745369676e6174757265000000000000000000000000000000006020820152610779908290610cfa565b60a0830151610789908290610d48565b60c083015151156108365760408051808201909152600481527f617267730000000000000000000000000000000000000000000000000000000060208201526107d3908290610cfa565b6107dc81610d55565b60005b8360c001515181101561082c5761081c8460c00151828151811061080557610805611568565b602002602001015183610cfa90919063ffffffff16565b610825816115c6565b90506107df565b5061083681610d79565b608083015151156109375760008360200151600281111561085957610859611539565b03610890576040517fa80d31f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201909152600f81527f736563726574734c6f636174696f6e000000000000000000000000000000000060208201526108cf908290610cfa565b6108e88360200151600281111561068357610683611539565b60408051808201909152600781527f73656372657473000000000000000000000000000000000000000000000000006020820152610927908290610cfa565b6080830151610937908290610d48565b60e083015151156109e45760408051808201909152600981527f62797465734172677300000000000000000000000000000000000000000000006020820152610981908290610cfa565b61098a81610d55565b60005b8360e00151518110156109da576109ca8460e0015182815181106109b3576109b3611568565b602002602001015183610d4890919063ffffffff16565b6109d3816115c6565b905061098d565b506109e481610d79565b515192915050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663461d27628688600188886040518663ffffffff1660e01b8152600401610a519594939291906115fe565b6020604051808303816000875af1158015610a70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a94919061169e565b60405190915081907f1131472297a800fee664d1d89cfa8f7676ff07189ecc53f80bbb5f4969099db890600090a295945050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603610b4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103c4565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008060209050602083511015610bd5575081515b60005b81811015610c3b57610beb8160086116b7565b848281518110610bfd57610bfd611568565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c9290921791610c34816115c6565b9050610bd8565b5050919050565b8051600003610c7d576040517f22ce3edd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83836002811115610c9057610c90611539565b90816002811115610ca357610ca3611539565b90525060408401828015610cb957610cb9611539565b90818015610cc957610cc9611539565b9052506060909301929092525050565b610ce161116b565b8051610ced9083610d97565b5060006020820152919050565b610d078260038351610e11565b81516102289082610f38565b8151610d209060c2610f60565b506105828282604051602001610d3891815260200190565b6040516020818303038152906040525b610d078260028351610e11565b610d60816004610fc9565b600181602001818151610d7391906116ce565b90525050565b610d84816007610fc9565b600181602001818151610d7391906116e1565b604080518082019091526060815260006020820152610db76020836116f4565b15610ddf57610dc76020836116f4565b610dd29060206116e1565b610ddc90836116ce565b91505b602080840183905260405180855260008152908184010181811015610e0357600080fd5b604052508290505b92915050565b60178167ffffffffffffffff1611610e3e578251610e389060e0600585901b168317610f60565b50505050565b60ff8167ffffffffffffffff1611610e80578251610e67906018611fe0600586901b1617610f60565b508251610e389067ffffffffffffffff83166001610fe0565b61ffff8167ffffffffffffffff1611610ec3578251610eaa906019611fe0600586901b1617610f60565b508251610e389067ffffffffffffffff83166002610fe0565b63ffffffff8167ffffffffffffffff1611610f08578251610eef90601a611fe0600586901b1617610f60565b508251610e389067ffffffffffffffff83166004610fe0565b8251610f1f90601b611fe0600586901b1617610f60565b508251610e389067ffffffffffffffff83166008610fe0565b604080518082019091526060815260006020820152610f5983838451611065565b9392505050565b6040805180820190915260608152600060208201528251516000610f858260016116ce565b905084602001518210610fa657610fa685610fa18360026116b7565b611154565b8451602083820101858153508051821115610fbf578181525b5093949350505050565b815161022890601f611fe0600585901b1617610f60565b604080518082019091526060815260006020820152835151600061100482856116ce565b905085602001518111156110215761102186610fa18360026116b7565b600060016110318661010061184f565b61103b91906116e1565b90508651828101878319825116178152508051831115611059578281525b50959695505050505050565b604080518082019091526060815260006020820152825182111561108857600080fd5b835151600061109784836116ce565b905085602001518111156110b4576110b486610fa18360026116b7565b8551805183820160200191600091808511156110ce578482525b505050602086015b6020861061110e57805182526110ed6020836116ce565b91506110fa6020826116ce565b90506111076020876116e1565b95506110d6565b5181517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208890036101000a0190811690199190911617905250849150509392505050565b81516111608383610d97565b50610e388382610f38565b6040518060400160405280611193604051806040016040528060608152602001600081525090565b8152602001600081525090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611216576112166111a0565b604052919050565b600067ffffffffffffffff831115611238576112386111a0565b61126960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116016111cf565b905082815283838301111561127d57600080fd5b828260208301376000602084830101529392505050565b600082601f8301126112a557600080fd5b610f598383356020850161121e565b6000806000606084860312156112c957600080fd5b83359250602084013567ffffffffffffffff808211156112e857600080fd5b6112f487838801611294565b9350604086013591508082111561130a57600080fd5b5061131786828701611294565b9150509250925092565b60008083601f84011261133357600080fd5b50813567ffffffffffffffff81111561134b57600080fd5b60208301915083602082850101111561136357600080fd5b9250929050565b803567ffffffffffffffff8116811461138257600080fd5b919050565b60008060008060008060008060a0898b0312156113a357600080fd5b883567ffffffffffffffff808211156113bb57600080fd5b6113c78c838d01611321565b909a50985060208b01359150808211156113e057600080fd5b6113ec8c838d01611321565b909850965060408b013591508082111561140557600080fd5b818b0191508b601f83011261141957600080fd5b81358181111561142857600080fd5b8c60208260051b850101111561143d57600080fd5b60208301965080955050505061145560608a0161136a565b9150608089013590509295985092959890939650565b60006020828403121561147d57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610f5957600080fd5b600067ffffffffffffffff808411156114bc576114bc6111a0565b8360051b60206114cd8183016111cf565b8681529185019181810190368411156114e557600080fd5b865b8481101561152d578035868111156114ff5760008081fd5b880136601f8201126115115760008081fd5b61151f36823587840161121e565b8452509183019183016114e7565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036115f7576115f7611597565b5060010190565b67ffffffffffffffff861681526000602060a08184015286518060a085015260005b8181101561163c5788810183015185820160c001528201611620565b50600060c0828601015260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010192505050611685604083018661ffff169052565b63ffffffff939093166060820152608001529392505050565b6000602082840312156116b057600080fd5b5051919050565b8082028115828204841417610e0b57610e0b611597565b80820180821115610e0b57610e0b611597565b81810381811115610e0b57610e0b611597565b60008261172a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b600181815b8085111561178857817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561176e5761176e611597565b8085161561177b57918102915b93841c9390800290611734565b509250929050565b60008261179f57506001610e0b565b816117ac57506000610e0b565b81600181146117c257600281146117cc576117e8565b6001915050610e0b565b60ff8411156117dd576117dd611597565b50506001821b610e0b565b5060208310610133831016604e8410600b841016171561180b575081810a610e0b565b611815838361172f565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561184757611847611597565b029392505050565b6000610f59838361179056fea164736f6c6343000813000a", +} + +var FunctionsLoadTestClientABI = FunctionsLoadTestClientMetaData.ABI + +var FunctionsLoadTestClientBin = FunctionsLoadTestClientMetaData.Bin + +func DeployFunctionsLoadTestClient(auth *bind.TransactOpts, backend bind.ContractBackend, router common.Address) (common.Address, *types.Transaction, *FunctionsLoadTestClient, error) { + parsed, err := FunctionsLoadTestClientMetaData.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(FunctionsLoadTestClientBin), backend, router) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &FunctionsLoadTestClient{FunctionsLoadTestClientCaller: FunctionsLoadTestClientCaller{contract: contract}, FunctionsLoadTestClientTransactor: FunctionsLoadTestClientTransactor{contract: contract}, FunctionsLoadTestClientFilterer: FunctionsLoadTestClientFilterer{contract: contract}}, nil +} + +type FunctionsLoadTestClient struct { + address common.Address + abi abi.ABI + FunctionsLoadTestClientCaller + FunctionsLoadTestClientTransactor + FunctionsLoadTestClientFilterer +} + +type FunctionsLoadTestClientCaller struct { + contract *bind.BoundContract +} + +type FunctionsLoadTestClientTransactor struct { + contract *bind.BoundContract +} + +type FunctionsLoadTestClientFilterer struct { + contract *bind.BoundContract +} + +type FunctionsLoadTestClientSession struct { + Contract *FunctionsLoadTestClient + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type FunctionsLoadTestClientCallerSession struct { + Contract *FunctionsLoadTestClientCaller + CallOpts bind.CallOpts +} + +type FunctionsLoadTestClientTransactorSession struct { + Contract *FunctionsLoadTestClientTransactor + TransactOpts bind.TransactOpts +} + +type FunctionsLoadTestClientRaw struct { + Contract *FunctionsLoadTestClient +} + +type FunctionsLoadTestClientCallerRaw struct { + Contract *FunctionsLoadTestClientCaller +} + +type FunctionsLoadTestClientTransactorRaw struct { + Contract *FunctionsLoadTestClientTransactor +} + +func NewFunctionsLoadTestClient(address common.Address, backend bind.ContractBackend) (*FunctionsLoadTestClient, error) { + abi, err := abi.JSON(strings.NewReader(FunctionsLoadTestClientABI)) + if err != nil { + return nil, err + } + contract, err := bindFunctionsLoadTestClient(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &FunctionsLoadTestClient{address: address, abi: abi, FunctionsLoadTestClientCaller: FunctionsLoadTestClientCaller{contract: contract}, FunctionsLoadTestClientTransactor: FunctionsLoadTestClientTransactor{contract: contract}, FunctionsLoadTestClientFilterer: FunctionsLoadTestClientFilterer{contract: contract}}, nil +} + +func NewFunctionsLoadTestClientCaller(address common.Address, caller bind.ContractCaller) (*FunctionsLoadTestClientCaller, error) { + contract, err := bindFunctionsLoadTestClient(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &FunctionsLoadTestClientCaller{contract: contract}, nil +} + +func NewFunctionsLoadTestClientTransactor(address common.Address, transactor bind.ContractTransactor) (*FunctionsLoadTestClientTransactor, error) { + contract, err := bindFunctionsLoadTestClient(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &FunctionsLoadTestClientTransactor{contract: contract}, nil +} + +func NewFunctionsLoadTestClientFilterer(address common.Address, filterer bind.ContractFilterer) (*FunctionsLoadTestClientFilterer, error) { + contract, err := bindFunctionsLoadTestClient(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &FunctionsLoadTestClientFilterer{contract: contract}, nil +} + +func bindFunctionsLoadTestClient(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := FunctionsLoadTestClientMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _FunctionsLoadTestClient.Contract.FunctionsLoadTestClientCaller.contract.Call(opts, result, method, params...) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.FunctionsLoadTestClientTransactor.contract.Transfer(opts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.FunctionsLoadTestClientTransactor.contract.Transact(opts, method, params...) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _FunctionsLoadTestClient.Contract.contract.Call(opts, result, method, params...) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.contract.Transfer(opts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.contract.Transact(opts, method, params...) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) MAXCALLBACKGAS(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _FunctionsLoadTestClient.contract.Call(opts, &out, "MAX_CALLBACK_GAS") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) MAXCALLBACKGAS() (uint32, error) { + return _FunctionsLoadTestClient.Contract.MAXCALLBACKGAS(&_FunctionsLoadTestClient.CallOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) MAXCALLBACKGAS() (uint32, error) { + return _FunctionsLoadTestClient.Contract.MAXCALLBACKGAS(&_FunctionsLoadTestClient.CallOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _FunctionsLoadTestClient.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 (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) Owner() (common.Address, error) { + return _FunctionsLoadTestClient.Contract.Owner(&_FunctionsLoadTestClient.CallOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) Owner() (common.Address, error) { + return _FunctionsLoadTestClient.Contract.Owner(&_FunctionsLoadTestClient.CallOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) SLastError(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _FunctionsLoadTestClient.contract.Call(opts, &out, "s_lastError") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SLastError() ([32]byte, error) { + return _FunctionsLoadTestClient.Contract.SLastError(&_FunctionsLoadTestClient.CallOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) SLastError() ([32]byte, error) { + return _FunctionsLoadTestClient.Contract.SLastError(&_FunctionsLoadTestClient.CallOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) SLastErrorLength(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _FunctionsLoadTestClient.contract.Call(opts, &out, "s_lastErrorLength") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SLastErrorLength() (uint32, error) { + return _FunctionsLoadTestClient.Contract.SLastErrorLength(&_FunctionsLoadTestClient.CallOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) SLastErrorLength() (uint32, error) { + return _FunctionsLoadTestClient.Contract.SLastErrorLength(&_FunctionsLoadTestClient.CallOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) SLastRequestId(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _FunctionsLoadTestClient.contract.Call(opts, &out, "s_lastRequestId") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SLastRequestId() ([32]byte, error) { + return _FunctionsLoadTestClient.Contract.SLastRequestId(&_FunctionsLoadTestClient.CallOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) SLastRequestId() ([32]byte, error) { + return _FunctionsLoadTestClient.Contract.SLastRequestId(&_FunctionsLoadTestClient.CallOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) SLastResponse(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _FunctionsLoadTestClient.contract.Call(opts, &out, "s_lastResponse") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SLastResponse() ([32]byte, error) { + return _FunctionsLoadTestClient.Contract.SLastResponse(&_FunctionsLoadTestClient.CallOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) SLastResponse() ([32]byte, error) { + return _FunctionsLoadTestClient.Contract.SLastResponse(&_FunctionsLoadTestClient.CallOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) SLastResponseLength(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _FunctionsLoadTestClient.contract.Call(opts, &out, "s_lastResponseLength") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SLastResponseLength() (uint32, error) { + return _FunctionsLoadTestClient.Contract.SLastResponseLength(&_FunctionsLoadTestClient.CallOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) SLastResponseLength() (uint32, error) { + return _FunctionsLoadTestClient.Contract.SLastResponseLength(&_FunctionsLoadTestClient.CallOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _FunctionsLoadTestClient.contract.Transact(opts, "acceptOwnership") +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) AcceptOwnership() (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.AcceptOwnership(&_FunctionsLoadTestClient.TransactOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.AcceptOwnership(&_FunctionsLoadTestClient.TransactOpts) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactor) HandleOracleFulfillment(opts *bind.TransactOpts, requestId [32]byte, response []byte, err []byte) (*types.Transaction, error) { + return _FunctionsLoadTestClient.contract.Transact(opts, "handleOracleFulfillment", requestId, response, err) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) HandleOracleFulfillment(requestId [32]byte, response []byte, err []byte) (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.HandleOracleFulfillment(&_FunctionsLoadTestClient.TransactOpts, requestId, response, err) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactorSession) HandleOracleFulfillment(requestId [32]byte, response []byte, err []byte) (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.HandleOracleFulfillment(&_FunctionsLoadTestClient.TransactOpts, requestId, response, err) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactor) SendRequest(opts *bind.TransactOpts, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) { + return _FunctionsLoadTestClient.contract.Transact(opts, "sendRequest", source, encryptedSecretsReferences, args, subscriptionId, jobId) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SendRequest(source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.SendRequest(&_FunctionsLoadTestClient.TransactOpts, source, encryptedSecretsReferences, args, subscriptionId, jobId) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactorSession) SendRequest(source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.SendRequest(&_FunctionsLoadTestClient.TransactOpts, source, encryptedSecretsReferences, args, subscriptionId, jobId) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _FunctionsLoadTestClient.contract.Transact(opts, "transferOwnership", to) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.TransferOwnership(&_FunctionsLoadTestClient.TransactOpts, to) +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _FunctionsLoadTestClient.Contract.TransferOwnership(&_FunctionsLoadTestClient.TransactOpts, to) +} + +type FunctionsLoadTestClientOwnershipTransferRequestedIterator struct { + Event *FunctionsLoadTestClientOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *FunctionsLoadTestClientOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(FunctionsLoadTestClientOwnershipTransferRequested) + 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(FunctionsLoadTestClientOwnershipTransferRequested) + 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 *FunctionsLoadTestClientOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *FunctionsLoadTestClientOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type FunctionsLoadTestClientOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsLoadTestClientOwnershipTransferRequestedIterator, 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 := _FunctionsLoadTestClient.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &FunctionsLoadTestClientOwnershipTransferRequestedIterator{contract: _FunctionsLoadTestClient.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsLoadTestClientOwnershipTransferRequested, 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 := _FunctionsLoadTestClient.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(FunctionsLoadTestClientOwnershipTransferRequested) + if err := _FunctionsLoadTestClient.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 (_FunctionsLoadTestClient *FunctionsLoadTestClientFilterer) ParseOwnershipTransferRequested(log types.Log) (*FunctionsLoadTestClientOwnershipTransferRequested, error) { + event := new(FunctionsLoadTestClientOwnershipTransferRequested) + if err := _FunctionsLoadTestClient.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type FunctionsLoadTestClientOwnershipTransferredIterator struct { + Event *FunctionsLoadTestClientOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *FunctionsLoadTestClientOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(FunctionsLoadTestClientOwnershipTransferred) + 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(FunctionsLoadTestClientOwnershipTransferred) + 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 *FunctionsLoadTestClientOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *FunctionsLoadTestClientOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type FunctionsLoadTestClientOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsLoadTestClientOwnershipTransferredIterator, 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 := _FunctionsLoadTestClient.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &FunctionsLoadTestClientOwnershipTransferredIterator{contract: _FunctionsLoadTestClient.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *FunctionsLoadTestClientOwnershipTransferred, 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 := _FunctionsLoadTestClient.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(FunctionsLoadTestClientOwnershipTransferred) + if err := _FunctionsLoadTestClient.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 (_FunctionsLoadTestClient *FunctionsLoadTestClientFilterer) ParseOwnershipTransferred(log types.Log) (*FunctionsLoadTestClientOwnershipTransferred, error) { + event := new(FunctionsLoadTestClientOwnershipTransferred) + if err := _FunctionsLoadTestClient.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type FunctionsLoadTestClientRequestFulfilledIterator struct { + Event *FunctionsLoadTestClientRequestFulfilled + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *FunctionsLoadTestClientRequestFulfilledIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(FunctionsLoadTestClientRequestFulfilled) + 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(FunctionsLoadTestClientRequestFulfilled) + 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 *FunctionsLoadTestClientRequestFulfilledIterator) Error() error { + return it.fail +} + +func (it *FunctionsLoadTestClientRequestFulfilledIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type FunctionsLoadTestClientRequestFulfilled struct { + Id [32]byte + Raw types.Log +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientFilterer) FilterRequestFulfilled(opts *bind.FilterOpts, id [][32]byte) (*FunctionsLoadTestClientRequestFulfilledIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _FunctionsLoadTestClient.contract.FilterLogs(opts, "RequestFulfilled", idRule) + if err != nil { + return nil, err + } + return &FunctionsLoadTestClientRequestFulfilledIterator{contract: _FunctionsLoadTestClient.contract, event: "RequestFulfilled", logs: logs, sub: sub}, nil +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientFilterer) WatchRequestFulfilled(opts *bind.WatchOpts, sink chan<- *FunctionsLoadTestClientRequestFulfilled, id [][32]byte) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _FunctionsLoadTestClient.contract.WatchLogs(opts, "RequestFulfilled", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(FunctionsLoadTestClientRequestFulfilled) + if err := _FunctionsLoadTestClient.contract.UnpackLog(event, "RequestFulfilled", 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 (_FunctionsLoadTestClient *FunctionsLoadTestClientFilterer) ParseRequestFulfilled(log types.Log) (*FunctionsLoadTestClientRequestFulfilled, error) { + event := new(FunctionsLoadTestClientRequestFulfilled) + if err := _FunctionsLoadTestClient.contract.UnpackLog(event, "RequestFulfilled", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type FunctionsLoadTestClientRequestSentIterator struct { + Event *FunctionsLoadTestClientRequestSent + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *FunctionsLoadTestClientRequestSentIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(FunctionsLoadTestClientRequestSent) + 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(FunctionsLoadTestClientRequestSent) + 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 *FunctionsLoadTestClientRequestSentIterator) Error() error { + return it.fail +} + +func (it *FunctionsLoadTestClientRequestSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type FunctionsLoadTestClientRequestSent struct { + Id [32]byte + Raw types.Log +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientFilterer) FilterRequestSent(opts *bind.FilterOpts, id [][32]byte) (*FunctionsLoadTestClientRequestSentIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _FunctionsLoadTestClient.contract.FilterLogs(opts, "RequestSent", idRule) + if err != nil { + return nil, err + } + return &FunctionsLoadTestClientRequestSentIterator{contract: _FunctionsLoadTestClient.contract, event: "RequestSent", logs: logs, sub: sub}, nil +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClientFilterer) WatchRequestSent(opts *bind.WatchOpts, sink chan<- *FunctionsLoadTestClientRequestSent, id [][32]byte) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _FunctionsLoadTestClient.contract.WatchLogs(opts, "RequestSent", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(FunctionsLoadTestClientRequestSent) + if err := _FunctionsLoadTestClient.contract.UnpackLog(event, "RequestSent", 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 (_FunctionsLoadTestClient *FunctionsLoadTestClientFilterer) ParseRequestSent(log types.Log) (*FunctionsLoadTestClientRequestSent, error) { + event := new(FunctionsLoadTestClientRequestSent) + if err := _FunctionsLoadTestClient.contract.UnpackLog(event, "RequestSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClient) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _FunctionsLoadTestClient.abi.Events["OwnershipTransferRequested"].ID: + return _FunctionsLoadTestClient.ParseOwnershipTransferRequested(log) + case _FunctionsLoadTestClient.abi.Events["OwnershipTransferred"].ID: + return _FunctionsLoadTestClient.ParseOwnershipTransferred(log) + case _FunctionsLoadTestClient.abi.Events["RequestFulfilled"].ID: + return _FunctionsLoadTestClient.ParseRequestFulfilled(log) + case _FunctionsLoadTestClient.abi.Events["RequestSent"].ID: + return _FunctionsLoadTestClient.ParseRequestSent(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (FunctionsLoadTestClientOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (FunctionsLoadTestClientOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (FunctionsLoadTestClientRequestFulfilled) Topic() common.Hash { + return common.HexToHash("0x85e1543bf2f84fe80c6badbce3648c8539ad1df4d2b3d822938ca0538be727e6") +} + +func (FunctionsLoadTestClientRequestSent) Topic() common.Hash { + return common.HexToHash("0x1131472297a800fee664d1d89cfa8f7676ff07189ecc53f80bbb5f4969099db8") +} + +func (_FunctionsLoadTestClient *FunctionsLoadTestClient) Address() common.Address { + return _FunctionsLoadTestClient.address +} + +type FunctionsLoadTestClientInterface interface { + MAXCALLBACKGAS(opts *bind.CallOpts) (uint32, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SLastError(opts *bind.CallOpts) ([32]byte, error) + + SLastErrorLength(opts *bind.CallOpts) (uint32, error) + + SLastRequestId(opts *bind.CallOpts) ([32]byte, error) + + SLastResponse(opts *bind.CallOpts) ([32]byte, error) + + SLastResponseLength(opts *bind.CallOpts) (uint32, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + HandleOracleFulfillment(opts *bind.TransactOpts, requestId [32]byte, response []byte, err []byte) (*types.Transaction, error) + + SendRequest(opts *bind.TransactOpts, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsLoadTestClientOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsLoadTestClientOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*FunctionsLoadTestClientOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsLoadTestClientOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *FunctionsLoadTestClientOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*FunctionsLoadTestClientOwnershipTransferred, error) + + FilterRequestFulfilled(opts *bind.FilterOpts, id [][32]byte) (*FunctionsLoadTestClientRequestFulfilledIterator, error) + + WatchRequestFulfilled(opts *bind.WatchOpts, sink chan<- *FunctionsLoadTestClientRequestFulfilled, id [][32]byte) (event.Subscription, error) + + ParseRequestFulfilled(log types.Log) (*FunctionsLoadTestClientRequestFulfilled, error) + + FilterRequestSent(opts *bind.FilterOpts, id [][32]byte) (*FunctionsLoadTestClientRequestSentIterator, error) + + WatchRequestSent(opts *bind.WatchOpts, sink chan<- *FunctionsLoadTestClientRequestSent, id [][32]byte) (event.Subscription, error) + + ParseRequestSent(log types.Log) (*FunctionsLoadTestClientRequestSent, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/functions/generated/functions_router/functions_router.go b/core/gethwrappers/functions/generated/functions_router/functions_router.go index 27b57d922bc..83c3f9b6132 100644 --- a/core/gethwrappers/functions/generated/functions_router/functions_router.go +++ b/core/gethwrappers/functions/generated/functions_router/functions_router.go @@ -30,16 +30,53 @@ var ( _ = abi.ConvertType ) +type FunctionsResponseCommitment struct { + RequestId [32]byte + Coordinator common.Address + EstimatedTotalCostJuels *big.Int + Client common.Address + SubscriptionId uint64 + CallbackGasLimit uint32 + AdminFee *big.Int + DonFee *big.Int + GasOverheadBeforeCallback *big.Int + GasOverheadAfterCallback *big.Int + TimeoutTimestamp uint32 +} + +type FunctionsRouterConfig struct { + MaxConsumersPerSubscription uint16 + AdminFee *big.Int + HandleOracleFulfillmentSelector [4]byte + GasForCallExactCheck uint16 + MaxCallbackGasLimits []uint32 +} + +type IFunctionsSubscriptionsConsumer struct { + Allowed bool + InitiatedRequests uint64 + CompletedRequests uint64 +} + +type IFunctionsSubscriptionsSubscription struct { + Balance *big.Int + Owner common.Address + BlockedBalance *big.Int + ProposedOwner common.Address + Consumers []common.Address + Flags [32]byte +} + var FunctionsRouterMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"timelockBlocks\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"maximumTimelockBlocks\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"internalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"externalBalance\",\"type\":\"uint256\"}],\"name\":\"BalanceInvariantViolated\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConsumerRequestsInFlight\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"IdentifierIsReserved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfigData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProposal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"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\":\"OnlyCallableByRoute\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ProposedTimelockAboveMaximum\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RouteNotFound\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderMustAcceptTermsOfService\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TimelockInEffect\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"fromHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"toBytes\",\"type\":\"bytes\"}],\"name\":\"ConfigProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"adminFee\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"fromHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"toBytes\",\"type\":\"bytes\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"proposedContractSetId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetFromAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetToAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timelockEndBlock\",\"type\":\"uint256\"}],\"name\":\"ContractProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"proposedContractSetId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetFromAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetToAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"major\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minor\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"patch\",\"type\":\"uint16\"}],\"name\":\"ContractUpdated\",\"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\":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\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalCostJuels\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"}],\"name\":\"RequestEnd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"RequestStart\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"fundsRecipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fundsAmount\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"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\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"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\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"from\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"to\",\"type\":\"uint16\"}],\"name\":\"TimeLockProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"from\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"to\",\"type\":\"uint16\"}],\"name\":\"TimeLockUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"juelsPerGas\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"costWithoutFulfillment\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"fulfill\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"callbackGasCostJuels\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminFee\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfigHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"config\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getConsumer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"initiatedRequests\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"completedRequests\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"useProposed\",\"type\":\"bool\"}],\"name\":\"getContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"routeDestination\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"routeDestination\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMaxConsumers\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getProposedContractSet\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"blockedBalance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"requestedOwner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSubscriptionCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTotalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"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\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"proposeConfigUpdate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"proposedContractSetIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"proposedContractSetAddresses\",\"type\":\"address[]\"}],\"name\":\"proposeContractsUpdate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"blocks\",\"type\":\"uint16\"}],\"name\":\"proposeTimelockBlocks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"requestSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"requestIdsToTimeout\",\"type\":\"bytes32[]\"}],\"name\":\"timeoutRequests\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"togglePaused\",\"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\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updateContracts\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updateTimelockBlocks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"validateProposedContracts\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60806040526001805463ffffffff60a01b191690553480156200002157600080fd5b506040516200640a3803806200640a833981016040819052620000449162000322565b6000805460ff1916815582903390869086908590849081620000ad5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0380851661010002610100600160a81b031990921691909117909155811615620000e757620000e78162000198565b50506007805461ffff84811661ffff1991871662010000029190911663ffffffff19909216919091171790556000805260026020527fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b80546001600160a01b03191630179055620001588162000249565b8051602090910120600a555050601080546001600160a01b0390931661010002610100600160a81b03199093169290921790915550620004939350505050565b336001600160a01b03821603620001f25760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000a4565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929361010090910416917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080828060200190518101906200026291906200043d565b6040805180820182526001600160601b0384168082526001600160e01b031984166020928301819052601180546001600160801b03191683176c0100000000000000000000000060e088901c021790558351918252918101919091529294509092507fb2b9bfb736b0bfef266985352cfca2a114226362209f5a6e5a2a2ed14383ba57910160405180910390a1505050565b805161ffff811681146200030757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600080600080608085870312156200033957600080fd5b6200034485620002f4565b9350602062000355818701620002f4565b60408701519094506001600160a01b03811681146200037357600080fd5b60608701519093506001600160401b03808211156200039157600080fd5b818801915088601f830112620003a657600080fd5b815181811115620003bb57620003bb6200030c565b604051601f8201601f19908116603f01168101908382118183101715620003e657620003e66200030c565b816040528281528b86848701011115620003ff57600080fd5b600093505b8284101562000423578484018601518185018701529285019262000404565b600086848301015280965050505050505092959194509250565b600080604083850312156200045157600080fd5b82516001600160601b03811681146200046957600080fd5b60208401519092506001600160e01b0319811681146200048857600080fd5b809150509250929050565b615f6780620004a36000396000f3fe608060405234801561001057600080fd5b50600436106102c85760003560e01c8063823597401161017b578063b187bd26116100d8578063d7ae1d301161008c578063e82ad7d411610071578063e82ad7d41461070e578063eb523d6c14610721578063f2fde38b1461073457600080fd5b8063d7ae1d30146106e8578063e72f6e30146106fb57600080fd5b8063b734c0f4116100bd578063b734c0f4146106b6578063badc3eb6146106be578063c4614d61146106d557600080fd5b8063b187bd2614610698578063b5643858146106a357600080fd5b8063a21a23e41161012f578063a4c0ed3611610114578063a4c0ed361461064c578063a9c9a9181461065f578063aab396bd1461067257600080fd5b8063a21a23e414610620578063a47c76961461062857600080fd5b80638fde5317116101605780638fde5317146105fd5780639883c10d146106055780639f87fad71461060d57600080fd5b806382359740146105c75780638da5cb5b146105da57600080fd5b806354fd4d5011610229578063674603d0116101dd57806371ec28ac116101c257806371ec28ac1461059d5780637341c10c146105ac57806379ba5097146105bf57600080fd5b8063674603d0146104d05780636a6df79b1461056557600080fd5b806366316d8d1161020e57806366316d8d146104835780636641997014610496578063665871ec146104bd57600080fd5b806354fd4d50146104155780635c975abb1461046c57600080fd5b806336566f06116102805780633e871e4d116102655780633e871e4d146103a85780633fd67e05146103bb578063461d2762146103f457600080fd5b806336566f061461038d578063385de9ae1461039557600080fd5b806312b58349116102b157806312b58349146102f5578063181f5a77146103355780632a905ccc1461037757600080fd5b806302bcc5b6146102cd57806304c357cb146102e2575b600080fd5b6102e06102db366004615086565b610747565b005b6102e06102f03660046150c5565b6107c7565b600b546801000000000000000090046bffffffffffffffffffffffff165b6040516bffffffffffffffffffffffff90911681526020015b60405180910390f35b60408051808201909152601381527f46756e6374696f6e7320526f757465722076310000000000000000000000000060208201525b60405161032c919061515c565b6011546bffffffffffffffffffffffff16610313565b6102e0610aaf565b6102e06103a33660046151b8565b610ad4565b6102e06103b6366004615318565b610cb8565b6103ce6103c9366004615479565b610fcd565b6040805160ff90931683526bffffffffffffffffffffffff90911660208301520161032c565b610407610402366004615541565b611328565b60405190815260200161032c565b600180546040805192835261ffff740100000000000000000000000000000000000000008304811660208501527601000000000000000000000000000000000000000000009092049091169082015260600161032c565b60005460ff165b604051901515815260200161032c565b6102e06104913660046155bf565b6113c2565b600b5467ffffffffffffffff165b60405167ffffffffffffffff909116815260200161032c565b6102e06104cb3660046155f6565b611623565b61053d6104de36600461566b565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152600d6020908152604080832067ffffffffffffffff948516845290915290205460ff8116926101008204831692690100000000000000000090920490911690565b60408051931515845267ffffffffffffffff928316602085015291169082015260600161032c565b6105786105733660046156a3565b611a59565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161032c565b6040516064815260200161032c565b6102e06105ba3660046150c5565b611a6c565b6102e0611e05565b6102e06105d5366004615086565b611f27565b600054610100900473ffffffffffffffffffffffffffffffffffffffff16610578565b6102e0612196565b600a54610407565b6102e061061b3660046150c5565b61221a565b6104a4612817565b61063b610636366004615086565b612ae5565b60405161032c959493929190615719565b6102e061065a36600461576e565b612bd3565b61057861066d3660046157c8565b612e2f565b7fd8e0666292c202b1ce6a8ff0dd638652e662402ac53fbf9bd9d3bcc39d5eb097610407565b60005460ff16610473565b6102e06106b13660046157e1565b612e42565b6102e0612f5b565b6106c66131d1565b60405161032c939291906157fc565b61036a6106e33660046151b8565b6132ac565b6102e06106f63660046150c5565b6132c1565b6102e061070936600461585d565b613515565b61047361071c366004615086565b613729565b6102e061072f3660046157c8565b613734565b6102e061074236600461585d565b6139bd565b61074f6139ce565b67ffffffffffffffff81166000908152600c602052604090206001015473ffffffffffffffffffffffffffffffffffffffff16806107b9576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c38282613a54565b5050565b67ffffffffffffffff82166000908152600c6020526040902060010154829073ffffffffffffffffffffffffffffffffffffffff1680610833576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff82161461089f576040517fd8a3fb5200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024015b60405180910390fd5b60105460ff16156108dc576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109077fd8e0666292c202b1ce6a8ff0dd638652e662402ac53fbf9bd9d3bcc39d5eb0976000613e40565b6040517fbe8c97b000000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff919091169063be8c97b0906024016020604051808303816000875af1158015610975573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109999190615878565b15156000036109d6576040517f22906263000000000000000000000000000000000000000000000000000000008152336004820152602401610896565b67ffffffffffffffff84166000908152600c602052604090206002015473ffffffffffffffffffffffffffffffffffffffff848116911614610aa95767ffffffffffffffff84166000818152600c602090815260409182902060020180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff88169081179091558251338152918201527f69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be91015b60405180910390a25b50505050565b610ab76139ce565b60005460ff1615610acc57610aca613f42565b565b610aca613fbf565b610adc6139ce565b6000610ae9846000613e40565b905060003073ffffffffffffffffffffffffffffffffffffffff831603610b135750600a54610b87565b8173ffffffffffffffffffffffffffffffffffffffff16639883c10d6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610b60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b849190615895565b90505b8383604051610b979291906158ae565b60405180910390208103610bd7576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604051806060016040528082815260200185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250600754602090910190610c3e9062010000900461ffff16436158ed565b9052600086815260066020908152604090912082518155908201516001820190610c6890826159a1565b50604091820151600290910155517f0fcfd32a68209b42944376bc5f4bf72c41ba0f378cf60434f84390b82c9844cf90610ca9908790849088908890615abb565b60405180910390a15050505050565b610cc06139ce565b8151815181141580610cd25750600881115b15610d09576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818160ff161015610e40576000848260ff1681518110610d2e57610d2e615b16565b602002602001015190506000848360ff1681518110610d4f57610d4f615b16565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610dba575060008281526002602052604090205473ffffffffffffffffffffffffffffffffffffffff8281169116145b15610df1576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81610e2b576040517f4855c28800000000000000000000000000000000000000000000000000000000815260048101839052602401610896565b50508080610e3890615b45565b915050610d0c565b50600754600090610e5b9062010000900461ffff16436158ed565b604080516060810182528681526020808201879052918101839052865192935091600391610e8d918391890190614f79565b506020828101518051610ea69260018501920190614fc0565b506040820151816002015590505060005b84518160ff161015610fc6577f72a33d2f293a0a70fad221bb610d3d6b52aed2d840adae1fa721071fbd290cfd858260ff1681518110610ef957610ef9615b16565b602002602001015160026000888560ff1681518110610f1a57610f1a615b16565b6020026020010151815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16868460ff1681518110610f6657610f66615b16565b602002602001015185604051610fac949392919093845273ffffffffffffffffffffffffffffffffffffffff928316602085015291166040830152606082015260800190565b60405180910390a180610fbe81615b45565b915050610eb7565b5050505050565b601054600090819060ff161561100f576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000888152600f6020908152604091829020825161010081018452815473ffffffffffffffffffffffffffffffffffffffff90811680835260018401549182169483019490945274010000000000000000000000000000000000000000810467ffffffffffffffff16948201949094527c010000000000000000000000000000000000000000000000000000000090930463ffffffff16606084015260028101546bffffffffffffffffffffffff9081166080850152600382015460a0850152600482015460c08501526005909101541660e0830152331461111d576040517f8bec23e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081015173ffffffffffffffffffffffffffffffffffffffff1661114657600292505061131d565b8060c00151816060015163ffffffff1661116091906158ed565b5a101561117157600392505061131d565b80608001516bffffffffffffffffffffffff16611197826060015163ffffffff1661401a565b6111a19088615b64565b868360e001516111b19190615b94565b6111bb9190615b94565b6bffffffffffffffffffffffff1611156111d957600492505061131d565b6000898152600f60209081526040822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018390556002810180547fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009081169091556003820184905560048201849055600590910180549091169055606083015190830151919450849161127a918c918c918c916140bc565b805190915061128a57600161128d565b60005b935060006112b48360400151846080015185602001518660e001518c87602001518d61423a565b9050826040015167ffffffffffffffff168b7f526019d853b0b88e828dbdc124746afde5a47053256d2a0872a025ab145b05208360200151898987600001516112fd578e6112ff565b8f5b60405161130f9493929190615bc0565b60405180910390a351925050505b965096945050505050565b60105460009060ff1615611368576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113706144b7565b6113b78260008989898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92508a91506145249050565b979650505050505050565b60105460ff16156113ff576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806bffffffffffffffffffffffff16600003611447576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600e60205260409020546bffffffffffffffffffffffff808316911610156114a1576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600e6020526040812080548392906114ce9084906bffffffffffffffffffffffff16615c16565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080600b60088282829054906101000a90046bffffffffffffffffffffffff166115259190615c16565b82546bffffffffffffffffffffffff91821661010093840a90810290830219909116179092556010546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301529386166024820152919004909116915063a9059cbb906044016020604051808303816000875af11580156115c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ed9190615878565b6107c3576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60105460ff1615611660576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015611a5457600083838381811061167f5761167f615b16565b602090810292909201356000818152600f8452604090819020815161010081018352815473ffffffffffffffffffffffffffffffffffffffff908116825260018301549081169682019690965274010000000000000000000000000000000000000000860467ffffffffffffffff169281018390527c010000000000000000000000000000000000000000000000000000000090950463ffffffff16606086015260028101546bffffffffffffffffffffffff9081166080870152600382015460a0870152600482015460c08701526005909101541660e0850152909350905061176881614924565b67ffffffffffffffff81166000908152600c602052604090206001015473ffffffffffffffffffffffffffffffffffffffff163381146117ec576040517fd8a3fb5200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610896565b8260a0015142101561182a576040517fbcc4005500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82516040517f85b214cf0000000000000000000000000000000000000000000000000000000081526004810186905273ffffffffffffffffffffffffffffffffffffffff8216906385b214cf906024016020604051808303816000875af1158015611899573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118bd9190615878565b15611a3c57608084015167ffffffffffffffff84166000908152600c6020819052604090912080549091906119119084906c0100000000000000000000000090046bffffffffffffffffffffffff16615c16565b82546bffffffffffffffffffffffff9182166101009390930a92830291909202199091161790555060208085015173ffffffffffffffffffffffffffffffffffffffff166000908152600d8252604080822067ffffffffffffffff80881684529352902080546001926009916119969185916901000000000000000000900416615c3b565b825467ffffffffffffffff9182166101009390930a9283029190920219909116179055506000858152600f6020526040812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018290556002810180547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000908116909155600382018390556004820192909255600501805490911690555b50505050508080611a4c90615c5c565b915050611663565b505050565b6000611a658383613e40565b9392505050565b67ffffffffffffffff82166000908152600c6020526040902060010154829073ffffffffffffffffffffffffffffffffffffffff1680611ad8576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821614611b3f576040517fd8a3fb5200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610896565b60105460ff1615611b7c576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ba77fd8e0666292c202b1ce6a8ff0dd638652e662402ac53fbf9bd9d3bcc39d5eb0976000613e40565b6040517fbe8c97b000000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff919091169063be8c97b0906024016020604051808303816000875af1158015611c15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c399190615878565b1515600003611c76576040517f22906263000000000000000000000000000000000000000000000000000000008152336004820152602401610896565b67ffffffffffffffff84166000908152600c60205260409020600301547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c01611ceb576040517f05a48e0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000908152600d6020908152604080832067ffffffffffffffff8816845290915290205460ff16610aa95773ffffffffffffffffffffffffffffffffffffffff83166000818152600d6020908152604080832067ffffffffffffffff891680855290835281842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155600c84528285206003018054918201815585529383902090930180547fffffffffffffffffffffffff000000000000000000000000000000000000000016851790555192835290917f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e09101610aa0565b60015473ffffffffffffffffffffffffffffffffffffffff163314611e86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610896565b60008054336101008181027fffffffffffffffffffffff0000000000000000000000000000000000000000ff8416178455600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905560405173ffffffffffffffffffffffffffffffffffffffff919093041692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60105460ff1615611f64576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f8f7fd8e0666292c202b1ce6a8ff0dd638652e662402ac53fbf9bd9d3bcc39d5eb0976000613e40565b6040517fbe8c97b000000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff919091169063be8c97b0906024016020604051808303816000875af1158015611ffd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120219190615878565b151560000361205e576040517f22906263000000000000000000000000000000000000000000000000000000008152336004820152602401610896565b67ffffffffffffffff81166000908152600c60205260409020600181015460029091015473ffffffffffffffffffffffffffffffffffffffff91821691163381146120ed576040517fd084e97500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610896565b67ffffffffffffffff83166000818152600c6020908152604091829020600181018054337fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811790925560029092018054909216909155825173ffffffffffffffffffffffffffffffffffffffff87168152918201527f6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f0910160405180910390a2505050565b61219e6139ce565b6009544310156121da576040517fa93d035c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600854600780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffff16620100009283900461ffff16909202919091179055565b67ffffffffffffffff82166000908152600c6020526040902060010154829073ffffffffffffffffffffffffffffffffffffffff1680612286576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff8216146122ed576040517fd8a3fb5200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610896565b60105460ff161561232a576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123557fd8e0666292c202b1ce6a8ff0dd638652e662402ac53fbf9bd9d3bcc39d5eb0976000613e40565b6040517fbe8c97b000000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff919091169063be8c97b0906024016020604051808303816000875af11580156123c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e79190615878565b1515600003612424576040517f22906263000000000000000000000000000000000000000000000000000000008152336004820152602401610896565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600d6020908152604080832067ffffffffffffffff8089168552908352928190208151606081018352905460ff81161515808352610100820486169483019490945269010000000000000000009004909316908301526124f4576040517ff0019fe600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015273ffffffffffffffffffffffffffffffffffffffff85166024820152604401610896565b806040015167ffffffffffffffff16816020015167ffffffffffffffff1614612549576040517fbcc4005500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff85166000908152600c60209081526040808320600301805482518185028101850190935280835291929091908301828280156125c457602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612599575b505050505090506000600182516125db9190615c94565b905060005b8251811015612779578673ffffffffffffffffffffffffffffffffffffffff1683828151811061261257612612615b16565b602002602001015173ffffffffffffffffffffffffffffffffffffffff160361276757600083838151811061264957612649615b16565b6020026020010151905080600c60008b67ffffffffffffffff1667ffffffffffffffff168152602001908152602001600020600301838154811061268f5761268f615b16565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff949094169390931790925567ffffffffffffffff8b168152600c9091526040902060030180548061270957612709615ca7565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550612779565b8061277181615c5c565b9150506125e0565b5073ffffffffffffffffffffffffffffffffffffffff86166000818152600d6020908152604080832067ffffffffffffffff8c168085529083529281902080547fffffffffffffffffffffffffffffff00000000000000000000000000000000001690555192835290917f182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b910160405180910390a250505050505050565b60105460009060ff1615612857576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6128827fd8e0666292c202b1ce6a8ff0dd638652e662402ac53fbf9bd9d3bcc39d5eb0976000613e40565b6040517fbe8c97b000000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff919091169063be8c97b0906024016020604051808303816000875af11580156128f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129149190615878565b1515600003612951576040517f22906263000000000000000000000000000000000000000000000000000000008152336004820152602401610896565b600b805467ffffffffffffffff1690600061296b83615cd6565b82546101009290920a67ffffffffffffffff818102199093169183160217909155600b546040805160a081018252600080825260208083018281523384860190815260608501848152865185815280850188526080870190815297909816808552600c8452959093208451815492516bffffffffffffffffffffffff9081166c01000000000000000000000000027fffffffffffffffff000000000000000000000000000000000000000000000000909416911617919091178155915160018301805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff000000000000000000000000000000000000000091821617909155965160028401805491909216971696909617909555925180519296509094509192612aa0926003850192910190614fc0565b505060405133815267ffffffffffffffff831691507f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf9060200160405180910390a290565b6000806000806060612af686614924565b67ffffffffffffffff86166000908152600c6020908152604091829020805460018201546002830154600390930180548651818702810187019097528087526bffffffffffffffffffffffff8085169c506c01000000000000000000000000909404909316995073ffffffffffffffffffffffffffffffffffffffff9182169850921695509091830182828015612bc357602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612b98575b5050505050905091939590929450565b60105460ff1615612c10576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601054610100900473ffffffffffffffffffffffffffffffffffffffff163314612c66576040517f44b0e3c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114612ca0576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612cae82840184615086565b67ffffffffffffffff81166000908152600c602052604090206001015490915073ffffffffffffffffffffffffffffffffffffffff16612d1a576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600c6020526040812080546bffffffffffffffffffffffff1691869190612d518385615b94565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555084600b60088282829054906101000a90046bffffffffffffffffffffffff16612da89190615b94565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508167ffffffffffffffff167fd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f8828784612e0f91906158ed565b6040805192835260208301919091520160405180910390a2505050505050565b6000612e3c826000613e40565b92915050565b612e4a6139ce565b60075461ffff808316620100009092041603612e92576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60075461ffff9081169082161115612ed6576040517fe9a3062200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160608101825260075461ffff62010000909104811680835290841660208301529091820190612f0990436158ed565b9052805160088054602084015161ffff90811662010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009092169316929092179190911790556040015160095550565b612f636139ce565b600554431015612f9f576040517fa93d035c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160149054906101000a900461ffff166001612fbc9190615cfd565b600180547fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000061ffff9384160217908190557601000000000000000000000000000000000000000000009004161561304d57600180547fffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff1690555b60005b60035460ff821610156131ce57600060036000018260ff168154811061307857613078615b16565b6000918252602080832090910154808352600290915260408220546004805492945073ffffffffffffffffffffffffffffffffffffffff909116929160ff86169081106130c7576130c7615b16565b6000918252602080832091909101548583526002825260409283902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92831690811790915560018054855189815293881694840194909452828501829052606083015261ffff7401000000000000000000000000000000000000000084048116608084015276010000000000000000000000000000000000000000000090930490921660a082015291519092507ff17ce6b5bbeda6598ac50e505071ddbd27c188c5ecaf9126b42c951c9c4b61e99160c0908290030190a150505080806131c690615b45565b915050613050565b50565b6000606080600360020154600360000160036001018180548060200260200160405190810160405280929190818152602001828054801561323157602002820191906000526020600020905b81548152602001906001019080831161321d575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561329a57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161326f575b50505050509050925092509250909192565b60606132b984848461498d565b949350505050565b67ffffffffffffffff82166000908152600c6020526040902060010154829073ffffffffffffffffffffffffffffffffffffffff168061332d576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821614613394576040517fd8a3fb5200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610896565b60105460ff16156133d1576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6133fc7fd8e0666292c202b1ce6a8ff0dd638652e662402ac53fbf9bd9d3bcc39d5eb0976000613e40565b6040517fbe8c97b000000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff919091169063be8c97b0906024016020604051808303816000875af115801561346a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061348e9190615878565b15156000036134cb576040517f22906263000000000000000000000000000000000000000000000000000000008152336004820152602401610896565b6134d484614a5c565b1561350b576040517fb42f66e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610aa98484613a54565b61351d6139ce565b6010546040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152600091610100900473ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015613591573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135b59190615895565b600b549091506801000000000000000090046bffffffffffffffffffffffff1681811115613619576040517fa99da3020000000000000000000000000000000000000000000000000000000081526004810182905260248101839052604401610896565b81811015611a5457600061362d8284615c94565b6010546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152602482018490529293506101009091049091169063a9059cbb906044016020604051808303816000875af11580156136af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136d39190615878565b506040805173ffffffffffffffffffffffffffffffffffffffff86168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a150505050565b6000612e3c82614a5c565b61373c6139ce565b6000600660008381526020019081526020016000206040518060600160405290816000820154815260200160018201805461377690615900565b80601f01602080910402602001604051908101604052809291908181526020018280546137a290615900565b80156137ef5780601f106137c4576101008083540402835291602001916137ef565b820191906000526020600020905b8154815290600101906020018083116137d257829003601f168201915b5050505050815260200160028201548152505090508060400151431015613842576040517fa93d035c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81613867576138548160200151614bad565b6020808201518051910120600a5561390f565b613872826000613e40565b73ffffffffffffffffffffffffffffffffffffffff1663354497aa82602001516040518263ffffffff1660e01b81526004016138ae919061515c565b600060405180830381600087803b1580156138c857600080fd5b505af19250505080156138d9575060015b61390f576040517ffe680b2600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160169054906101000a900461ffff16600161392c9190615cfd565b6001805461ffff92909216760100000000000000000000000000000000000000000000027fffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff909216919091179055805160208201516040517fc07626096b49b0462a576c9a7878cf0675e784bb4832584c1289c11664e55f47926139b1928692615d18565b60405180910390a15050565b6139c56139ce565b6131ce81614c8b565b600054610100900473ffffffffffffffffffffffffffffffffffffffff163314610aca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610896565b60105460ff1615613a91576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff82166000908152600c60209081526040808320815160a08101835281546bffffffffffffffffffffffff80821683526c010000000000000000000000009091041681850152600182015473ffffffffffffffffffffffffffffffffffffffff908116828501526002830154166060820152600382018054845181870281018701909552808552919492936080860193909290830182828015613b7257602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311613b47575b5050509190925250508151919250600090505b826080015151811015613c2b57600d600084608001518381518110613bac57613bac615b16565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff89168252909252902080547fffffffffffffffffffffffffffffff000000000000000000000000000000000016905580613c2381615c5c565b915050613b85565b5067ffffffffffffffff84166000908152600c6020526040812080547fffffffffffffffff0000000000000000000000000000000000000000000000001681556001810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000908116909155600282018054909116905590613cb1600383018261503a565b505080600b60088282829054906101000a90046bffffffffffffffffffffffff16613cdc9190615c16565b82546bffffffffffffffffffffffff91821661010093840a90810290830219909116179092556010546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152938616602482015291900491909116915063a9059cbb906044016020604051808303816000875af1158015613d81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613da59190615878565b613ddb576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff851681526bffffffffffffffffffffffff8316602082015267ffffffffffffffff8616917fe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd498159101610aa0565b600081613e7f5760008381526002602052604090205473ffffffffffffffffffffffffffffffffffffffff168015613e79579050612e3c565b50613f0d565b60005b60035460ff82161015613f0b576003805460ff8316908110613ea657613ea6615b16565b90600052602060002001548403613ef9576004805460ff8316908110613ece57613ece615b16565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169150612e3c9050565b80613f0381615b45565b915050613e82565b505b6040517f80833e3300000000000000000000000000000000000000000000000000000000815260048101849052602401610896565b613f4a614d86565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b613fc76144b7565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258613f953390565b60006bffffffffffffffffffffffff8211156140b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610896565b5090565b60408051808201909152600080825260208201526011546040516000916c01000000000000000000000000900460e01b906140ff90899089908990602401615d40565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152601080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590506000805a6113888110156141bc57600080fd5b6113888103905086604082048203116141d457600080fd5b853b6141df57600080fd5b60008085516020870160008a8cf192505a601080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040805180820190915293151584529003602083015250979650505050505050565b604080518082019091526000808252602082015260006142598461401a565b6142639086615b64565b90506000816142728886615b94565b61427c9190615b94565b6040805180820182526bffffffffffffffffffffffff808616825280841660208084019190915267ffffffffffffffff8f166000908152600c9091529283208054929750939450849392916142d391859116615c16565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550818461430d9190615b94565b336000908152600e60205260408120805490919061433a9084906bffffffffffffffffffffffff16615b94565b82546101009290920a6bffffffffffffffffffffffff818102199093169183160217909155306000908152600e6020526040812080548b9450909261438191859116615b94565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555088600c60008c67ffffffffffffffff1667ffffffffffffffff168152602001908152602001600020600001600c8282829054906101000a90046bffffffffffffffffffffffff166144009190615c16565b82546bffffffffffffffffffffffff9182166101009390930a92830291909202199091161790555073ffffffffffffffffffffffffffffffffffffffff88166000908152600d6020908152604080832067ffffffffffffffff808f168552925290912080546001926009916144849185916901000000000000000000900416615c3b565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505050979650505050505050565b60005460ff1615610aca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610896565b600061452f85614924565b6145393386614df2565b60006145458888613e40565b6040805160c08101825267ffffffffffffffff891680825260208083018a905261ffff89168385015263ffffffff881660608401523360808401526000918252600c90528281206001015473ffffffffffffffffffffffffffffffffffffffff90811660a084015292517f0a33e0a5000000000000000000000000000000000000000000000000000000008152939450928392839290861691630a33e0a5916145f091600401615d6b565b6080604051808303816000875af115801561460f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146339190615df5565b92975090945092509050614648338a85614e8e565b6040518061010001604052808573ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018a67ffffffffffffffff1681526020018763ffffffff168152602001846bffffffffffffffffffffffff16815260200182426146c891906158ed565b8152602001838152602001601160000160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250600f600087815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550606082015181600101601c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160020160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555060a0820151816003015560c0820151816004015560e08201518160050160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055509050508867ffffffffffffffff168b867f7c720ccd20069b8311a6be4ba1cf3294d09eb247aa5d73a8502054b6e68a2f54600c60008e67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633328e8e8e60405161490e96959493929190615e33565b60405180910390a4505050509695505050505050565b67ffffffffffffffff81166000908152600c602052604090206001015473ffffffffffffffffffffffffffffffffffffffff166131ce576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606060008080806149a086880188615e97565b935093509350935060006149b989600187878787614524565b60408051602080825281830190925291925060208201818036833701905050955060005b6020811015614a4f578181602081106149f8576149f8615b16565b1a60f81b878281518110614a0e57614a0e615b16565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080614a4781615c5c565b9150506149dd565b5050505050509392505050565b67ffffffffffffffff81166000908152600c6020908152604080832060030180548251818502810185019093528083528493830182828015614ad457602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311614aa9575b5050505050905060005b8151811015614ba3576000600d6000848481518110614aff57614aff615b16565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff808a168352908452908290208251606081018452905460ff8116151582526101008104831694820185905269010000000000000000009004909116918101829052925014614b9057506001949350505050565b5080614b9b81615c5c565b915050614ade565b5060009392505050565b60008082806020019051810190614bc49190615f06565b6040805180820182526bffffffffffffffffffffffff84168082527fffffffff0000000000000000000000000000000000000000000000000000000084166020928301819052601180547fffffffffffffffffffffffffffffffff000000000000000000000000000000001683176c0100000000000000000000000060e088901c021790558351918252918101919091529294509092507fb2b9bfb736b0bfef266985352cfca2a114226362209f5a6e5a2a2ed14383ba57910160405180910390a1505050565b3373ffffffffffffffffffffffffffffffffffffffff821603614d0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610896565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929361010090910416917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005460ff16610aca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610896565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600d6020908152604080832067ffffffffffffffff8516845290915290205460ff166107c3576040517ff0019fe600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015273ffffffffffffffffffffffffffffffffffffffff83166024820152604401610896565b67ffffffffffffffff82166000908152600c602081905260409091208054839290614ed89084906c0100000000000000000000000090046bffffffffffffffffffffffff16615b94565b82546bffffffffffffffffffffffff91821661010093840a908102920219161790915573ffffffffffffffffffffffffffffffffffffffff85166000908152600d6020908152604080832067ffffffffffffffff8089168552925290912080546001945090928492614f4e928492900416615c3b565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505050565b828054828255906000526020600020908101928215614fb4579160200282015b82811115614fb4578251825591602001919060010190614f99565b506140b8929150615054565b828054828255906000526020600020908101928215614fb4579160200282015b82811115614fb457825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190614fe0565b50805460008255906000526020600020908101906131ce91905b5b808211156140b85760008155600101615055565b803567ffffffffffffffff8116811461508157600080fd5b919050565b60006020828403121561509857600080fd5b611a6582615069565b803573ffffffffffffffffffffffffffffffffffffffff8116811461508157600080fd5b600080604083850312156150d857600080fd5b6150e183615069565b91506150ef602084016150a1565b90509250929050565b6000815180845260005b8181101561511e57602081850181015186830182015201615102565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611a6560208301846150f8565b60008083601f84011261518157600080fd5b50813567ffffffffffffffff81111561519957600080fd5b6020830191508360208285010111156151b157600080fd5b9250929050565b6000806000604084860312156151cd57600080fd5b83359250602084013567ffffffffffffffff8111156151eb57600080fd5b6151f78682870161516f565b9497909650939450505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561527a5761527a615204565b604052919050565b600067ffffffffffffffff82111561529c5761529c615204565b5060051b60200190565b600082601f8301126152b757600080fd5b813560206152cc6152c783615282565b615233565b82815260059290921b840181019181810190868411156152eb57600080fd5b8286015b8481101561530d57615300816150a1565b83529183019183016152ef565b509695505050505050565b6000806040838503121561532b57600080fd5b823567ffffffffffffffff8082111561534357600080fd5b818501915085601f83011261535757600080fd5b813560206153676152c783615282565b82815260059290921b8401810191818101908984111561538657600080fd5b948201945b838610156153a45785358252948201949082019061538b565b965050860135925050808211156153ba57600080fd5b506153c7858286016152a6565b9150509250929050565b600082601f8301126153e257600080fd5b813567ffffffffffffffff8111156153fc576153fc615204565b61542d60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601615233565b81815284602083860101111561544257600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff811681146131ce57600080fd5b60008060008060008060c0878903121561549257600080fd5b86359550602087013567ffffffffffffffff808211156154b157600080fd5b6154bd8a838b016153d1565b965060408901359150808211156154d357600080fd5b506154e089828a016153d1565b94505060608701356154f18161545f565b925060808701356155018161545f565b915061550f60a088016150a1565b90509295509295509295565b803561ffff8116811461508157600080fd5b803563ffffffff8116811461508157600080fd5b60008060008060008060a0878903121561555a57600080fd5b61556387615069565b9550602087013567ffffffffffffffff81111561557f57600080fd5b61558b89828a0161516f565b909650945061559e90506040880161551b565b92506155ac6060880161552d565b9150608087013590509295509295509295565b600080604083850312156155d257600080fd5b6155db836150a1565b915060208301356155eb8161545f565b809150509250929050565b6000806020838503121561560957600080fd5b823567ffffffffffffffff8082111561562157600080fd5b818501915085601f83011261563557600080fd5b81358181111561564457600080fd5b8660208260051b850101111561565957600080fd5b60209290920196919550909350505050565b6000806040838503121561567e57600080fd5b615687836150a1565b91506150ef60208401615069565b80151581146131ce57600080fd5b600080604083850312156156b657600080fd5b8235915060208301356155eb81615695565b600081518084526020808501945080840160005b8381101561570e57815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016156dc565b509495945050505050565b6bffffffffffffffffffffffff86811682528516602082015273ffffffffffffffffffffffffffffffffffffffff84811660408301528316606082015260a0608082018190526000906113b7908301846156c8565b6000806000806060858703121561578457600080fd5b61578d856150a1565b935060208501359250604085013567ffffffffffffffff8111156157b057600080fd5b6157bc8782880161516f565b95989497509550505050565b6000602082840312156157da57600080fd5b5035919050565b6000602082840312156157f357600080fd5b611a658261551b565b6000606082018583526020606081850152818651808452608086019150828801935060005b8181101561583d57845183529383019391830191600101615821565b5050848103604086015261585181876156c8565b98975050505050505050565b60006020828403121561586f57600080fd5b611a65826150a1565b60006020828403121561588a57600080fd5b8151611a6581615695565b6000602082840312156158a757600080fd5b5051919050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115612e3c57612e3c6158be565b600181811c9082168061591457607f821691505b60208210810361594d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f821115611a5457600081815260208120601f850160051c8101602086101561597a5750805b601f850160051c820191505b8181101561599957828155600101615986565b505050505050565b815167ffffffffffffffff8111156159bb576159bb615204565b6159cf816159c98454615900565b84615953565b602080601f831160018114615a2257600084156159ec5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555615999565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015615a6f57888601518255948401946001909101908401615a50565b5085821015615aab57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b84815283602082015260606040820152816060820152818360808301376000818301608090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01601019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff821660ff8103615b5b57615b5b6158be565b60010192915050565b6bffffffffffffffffffffffff818116838216028082169190828114615b8c57615b8c6158be565b505092915050565b6bffffffffffffffffffffffff818116838216019080821115615bb957615bb96158be565b5092915050565b6bffffffffffffffffffffffff8516815273ffffffffffffffffffffffffffffffffffffffff8416602082015260ff83166040820152608060608201526000615c0c60808301846150f8565b9695505050505050565b6bffffffffffffffffffffffff828116828216039080821115615bb957615bb96158be565b67ffffffffffffffff818116838216019080821115615bb957615bb96158be565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615c8d57615c8d6158be565b5060010190565b81810381811115612e3c57612e3c6158be565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600067ffffffffffffffff808316818103615cf357615cf36158be565b6001019392505050565b61ffff818116838216019080821115615bb957615bb96158be565b838152826020820152606060408201526000615d3760608301846150f8565b95945050505050565b838152606060208201526000615d5960608301856150f8565b8281036040840152615c0c81856150f8565b6020815267ffffffffffffffff82511660208201526000602083015160c06040840152615d9b60e08401826150f8565b905061ffff604085015116606084015263ffffffff6060850151166080840152608084015173ffffffffffffffffffffffffffffffffffffffff80821660a08601528060a08701511660c086015250508091505092915050565b60008060008060808587031215615e0b57600080fd5b845193506020850151615e1d8161545f565b6040860151606090960151949790965092505050565b600073ffffffffffffffffffffffffffffffffffffffff8089168352808816602084015280871660408401525060c06060830152615e7460c08301866150f8565b905061ffff8416608083015263ffffffff831660a0830152979650505050505050565b60008060008060808587031215615ead57600080fd5b615eb685615069565b9350602085013567ffffffffffffffff811115615ed257600080fd5b615ede878288016153d1565b935050615eed6040860161551b565b9150615efb6060860161552d565b905092959194509250565b60008060408385031215615f1957600080fd5b8251615f248161545f565b60208401519092507fffffffff00000000000000000000000000000000000000000000000000000000811681146155eb57600080fdfea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotRemoveWithPendingRequests\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyRequestData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"limit\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"IdentifierIsReserved\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"currentBalanceJuels\",\"type\":\"uint96\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"value\",\"type\":\"uint8\"}],\"name\":\"InvalidGasFlagValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProposal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeSubscriptionOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RouteNotFound\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderMustAcceptTermsOfService\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TimeoutNotExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maximumConsumers\",\"type\":\"uint16\"}],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"totalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deductionAttempt\",\"type\":\"uint256\"}],\"name\":\"TotalBalanceInvariantViolated\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"indexed\":false,\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"proposedContractSetId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetFromAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetToAddress\",\"type\":\"address\"}],\"name\":\"ContractProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"ContractUpdated\",\"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\":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\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"}],\"name\":\"RequestNotProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalCostJuels\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"callbackReturnData\",\"type\":\"bytes\"}],\"name\":\"RequestProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"}],\"name\":\"RequestStart\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestTimedOut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"fundsRecipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fundsAmount\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"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\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"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\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_RETURN_BYTES\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"createSubscriptionWithConsumer\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"juelsPerGas\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"costWithoutCallback\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"name\":\"fulfill\",\"outputs\":[{\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminFee\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getConsumer\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"initiatedRequests\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"completedRequests\",\"type\":\"uint64\"}],\"internalType\":\"structIFunctionsSubscriptions.Consumer\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getFlags\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getProposedContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getProposedContractSet\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getSubscription\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"blockedBalance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"internalType\":\"structIFunctionsSubscriptions.Subscription\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSubscriptionCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTotalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"isValidCallbackGasLimit\",\"outputs\":[],\"stateMutability\":\"view\",\"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\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"ownerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"proposedContractSetIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"proposedContractSetAddresses\",\"type\":\"address[]\"}],\"name\":\"proposeContractsUpdate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"proposeSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequestToProposed\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"allowListId\",\"type\":\"bytes32\"}],\"name\":\"setAllowListId\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"name\":\"setFlags\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsResponse.Commitment[]\",\"name\":\"requestsToTimeoutByCommitment\",\"type\":\"tuple[]\"}],\"name\":\"timeoutRequests\",\"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\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updateContracts\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b5060405162006254380380620062548339810160408190526200003491620004df565b6001600160a01b0382166080526006805460ff191690553380600081620000a25760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600680546001600160a01b0380851661010002610100600160a81b031990921691909117909155811615620000dc57620000dc81620000f8565b505050620000f081620001aa60201b60201c565b50506200067b565b336001600160a01b03821603620001525760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000099565b600780546001600160a01b0319166001600160a01b03838116918217909255600654604051919261010090910416907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b620001b462000287565b8051600a80546020808501516040860151606087015161ffff908116600160781b0261ffff60781b1960e09390931c6b010000000000000000000000029290921665ffffffffffff60581b196001600160481b0390941662010000026001600160581b031990961691909716179390931716939093171781556080830151805184936200024792600b92910190620002ea565b509050507f049ce2e6e1420eb4b07b425e90129186833eb346bda40b37d5d921aad482f71c816040516200027c9190620005dd565b60405180910390a150565b60065461010090046001600160a01b03163314620002e85760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000099565b565b828054828255906000526020600020906007016008900481019282156200038e5791602002820160005b838211156200035a57835183826101000a81548163ffffffff021916908363ffffffff160217905550926020019260040160208160030104928301926001030262000314565b80156200038c5782816101000a81549063ffffffff02191690556004016020816003010492830192600103026200035a565b505b506200039c929150620003a0565b5090565b5b808211156200039c5760008155600101620003a1565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b0381118282101715620003f257620003f2620003b7565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620004235762000423620003b7565b604052919050565b805161ffff811681146200043e57600080fd5b919050565b600082601f8301126200045557600080fd5b815160206001600160401b03821115620004735762000473620003b7565b8160051b62000484828201620003f8565b92835284810182019282810190878511156200049f57600080fd5b83870192505b84831015620004d457825163ffffffff81168114620004c45760008081fd5b82529183019190830190620004a5565b979650505050505050565b60008060408385031215620004f357600080fd5b82516001600160a01b03811681146200050b57600080fd5b60208401519092506001600160401b03808211156200052957600080fd5b9084019060a082870312156200053e57600080fd5b62000548620003cd565b62000553836200042b565b815260208301516001600160481b03811681146200057057600080fd5b602082015260408301516001600160e01b0319811681146200059157600080fd5b6040820152620005a4606084016200042b565b6060820152608083015182811115620005bc57600080fd5b620005ca8882860162000443565b6080830152508093505050509250929050565b6020808252825161ffff90811683830152838201516001600160481b03166040808501919091528401516001600160e01b0319166060808501919091528401511660808084019190915283015160a080840152805160c0840181905260009291820190839060e08601905b808310156200067057835163ffffffff16825292840192600192909201919084019062000648565b509695505050505050565b608051615ba1620006b3600039600081816113b40152818161218701528181612a7f01528181612b4301526132be0152615ba16000f3fe608060405234801561001057600080fd5b50600436106102de5760003560e01c80637341c10c11610186578063aab396bd116100e3578063d7ae1d3011610097578063e82ad7d411610071578063e82ad7d4146106bf578063ea320e0b146106d2578063f2fde38b146106e557600080fd5b8063d7ae1d3014610686578063e72f6e3014610699578063e82622aa146106ac57600080fd5b8063badc3eb6116100c8578063badc3eb614610648578063c3f909d41461065e578063cc77470a1461067357600080fd5b8063aab396bd14610638578063b734c0f41461064057600080fd5b80639f87fad71161013a578063a47c76961161011f578063a47c7696146105f2578063a4c0ed3614610612578063a9c9a9181461062557600080fd5b80639f87fad7146105d7578063a21a23e4146105ea57600080fd5b8063823597401161016b57806382359740146105995780638456cb59146105ac5780638da5cb5b146105b457600080fd5b80637341c10c1461057e57806379ba50971461059157600080fd5b80633f4ba83a1161023f5780635c975abb116101f357806366419970116101cd57806366419970146104d6578063674603d0146104fd5780636a2215de1461054657600080fd5b80635c975abb146104995780635ed6dfba146104b057806366316d8d146104c357600080fd5b8063461d276211610224578063461d2762146104455780634b8832d31461045857806355fedefa1461046b57600080fd5b80633f4ba83a1461041c57806341db4ca31461042457600080fd5b80631ded3b36116102965780632a905ccc1161027b5780632a905ccc146103ba57806333060529146103e85780633e871e4d1461040957600080fd5b80631ded3b361461039457806321b60e7f146103a757600080fd5b806310fc49c1116102c757806310fc49c11461031857806312b583491461032b578063181f5a771461034b57600080fd5b806302bcc5b6146102e35780630c5d49cb146102f8575b600080fd5b6102f66102f136600461487a565b6106f8565b005b610300608481565b60405161ffff90911681526020015b60405180910390f35b6102f66103263660046148bb565b610757565b6000546040516bffffffffffffffffffffffff909116815260200161030f565b6103876040518060400160405280601781526020017f46756e6374696f6e7320526f757465722076312e302e3000000000000000000081525081565b60405161030f9190614962565b6102f66103a2366004614975565b610853565b6102f66103b5366004614b38565b610885565b600a5462010000900468ffffffffffffffffff1660405168ffffffffffffffffff909116815260200161030f565b6103fb6103f6366004614de4565b6109b2565b60405161030f929190614ecc565b6102f6610417366004614f59565b610d8a565b6102f661100f565b61043761043236600461505b565b611021565b60405190815260200161030f565b61043761045336600461505b565b611081565b6102f66104663660046150df565b61108d565b61043761047936600461487a565b67ffffffffffffffff166000908152600360208190526040909120015490565b60065460ff165b604051901515815260200161030f565b6102f66104be36600461510d565b6111db565b6102f66104d136600461510d565b6113fd565b60025467ffffffffffffffff165b60405167ffffffffffffffff909116815260200161030f565b61051061050b36600461513b565b61154f565b6040805182511515815260208084015167ffffffffffffffff90811691830191909152928201519092169082015260600161030f565b610559610554366004615169565b6115df565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161030f565b6102f661058c3660046150df565b61169e565b6102f6611852565b6102f66105a736600461487a565b611979565b6102f6611ac0565b600654610100900473ffffffffffffffffffffffffffffffffffffffff16610559565b6102f66105e53660046150df565b611ad0565b6104e4611ea5565b61060561060036600461487a565b612032565b60405161030f91906151d3565b6102f661062036600461525b565b612167565b610559610633366004615169565b6123b3565b600954610437565b6102f6612412565b61065061255e565b60405161030f9291906152b7565b61066661262e565b60405161030f919061530e565b6104e46106813660046153b8565b612763565b6102f66106943660046150df565b6129e3565b6102f66106a73660046153b8565b612a46565b6102f66106ba3660046153d5565b612bbf565b6104a06106cd36600461487a565b612e90565b6102f66106e0366004615169565b612fdf565b6102f66106f33660046153b8565b612fec565b610700612ffd565b61070981613005565b67ffffffffffffffff81166000908152600360205260409020546107549082906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1661307b565b50565b67ffffffffffffffff8216600090815260036020819052604082200154600b54911a9081106107bc576040517f45c108ce00000000000000000000000000000000000000000000000000000000815260ff821660048201526024015b60405180910390fd5b6000600a6001018260ff16815481106107d7576107d761544b565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1690508063ffffffff168363ffffffff16111561084d576040517f1d70f87a00000000000000000000000000000000000000000000000000000000815263ffffffff821660048201526024016107b3565b50505050565b61085b612ffd565b61086482613005565b67ffffffffffffffff90911660009081526003602081905260409091200155565b61088d613367565b8051600a80546020808501516040860151606087015161ffff9081166f01000000000000000000000000000000027fffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff60e09390931c6b01000000000000000000000002929092167fffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffff68ffffffffffffffffff90941662010000027fffffffffffffffffffffffffffffffffffffffffff0000000000000000000000909616919097161793909317169390931717815560808301518051849361097492600b929101906146c5565b509050507f049ce2e6e1420eb4b07b425e90129186833eb346bda40b37d5d921aad482f71c816040516109a7919061530e565b60405180910390a150565b6000806109bd6133ed565b826020015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a26576040517f8bec23e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8251600090815260056020526040902054610a885782516020840151604051600294507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610a78918890879061547a565b60405180910390a2506000610d7f565b8251600090815260056020908152604091829020549151610aab918691016154ac565b6040516020818303038152906040528051906020012014610b035782516020840151604051600694507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610a78918890879061547a565b8261012001518360a0015163ffffffff16610b1e9190615608565b64ffffffffff165a1015610b695782516020840151604051600494507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610a78918890879061547a565b6000610b7e8460a0015163ffffffff166133f5565b610b88908861562d565b9050600081878660c0015168ffffffffffffffffff16610ba89190615655565b610bb29190615655565b9050610bc18560800151612032565b600001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115610c395784516020860151604051600596507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610c25918a90899061547a565b60405180910390a25060009150610d7f9050565b84604001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115610c9e5784516020860151604051600396507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610c25918a90899061547a565b505082516000908152600560205260408120819055835160a08501516060860151610cce92918c918c9190613497565b8051909150610cde576001610ce1565b60005b92506000610d1b8560800151866040015187606001518860c0015168ffffffffffffffffff168c610d1588602001516133f5565b8d613626565b9050846080015167ffffffffffffffff1685600001517f64778f26c70b60a8d7e29e2451b3844302d959448401c0535b768ed88c6b505e836020015189888f8f8960400151604051610d729695949392919061567a565b60405180910390a3519150505b965096945050505050565b610d92613367565b8151815181141580610da45750600881115b15610ddb576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610ecd576000848281518110610dfa57610dfa61544b565b602002602001015190506000848381518110610e1857610e1861544b565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610e83575060008281526008602052604090205473ffffffffffffffffffffffffffffffffffffffff8281169116145b15610eba576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505080610ec6906156fd565b9050610dde565b506040805180820190915283815260208082018490528451600c91610ef6918391880190614770565b506020828101518051610f0f92600185019201906147ab565b5090505060005b835181101561084d577f8b052f0f4bf82fede7daffea71592b29d5ef86af1f3c7daaa0345dbb2f52f481848281518110610f5257610f5261544b565b602002602001015160086000878581518110610f7057610f7061544b565b6020026020010151815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16858481518110610fb957610fb961544b565b6020026020010151604051610ff79392919092835273ffffffffffffffffffffffffffffffffffffffff918216602084015216604082015260600190565b60405180910390a1611008816156fd565b9050610f16565b611017613367565b61101f6139a8565b565b60008061102d836115df565b905061107583828a8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508b9150613a259050565b98975050505050505050565b60008061102d836123b3565b6110956133ed565b61109e82613dce565b6110a6613e94565b73ffffffffffffffffffffffffffffffffffffffff8116158061110d575067ffffffffffffffff821660009081526003602052604090206001015473ffffffffffffffffffffffffffffffffffffffff8281166c0100000000000000000000000090920416145b15611144576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff821660008181526003602090815260409182902060010180546bffffffffffffffffffffffff166c0100000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8716908102919091179091558251338152918201527f69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be910160405180910390a25050565b6111e3612ffd565b806bffffffffffffffffffffffff166000036112195750306000908152600160205260409020546bffffffffffffffffffffffff165b306000908152600160205260409020546bffffffffffffffffffffffff908116908216811015611285576040517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff821660048201526024016107b3565b6000546bffffffffffffffffffffffff808416911610156112ee576000546040517fdda2b2160000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff918216600482015290831660248201526044016107b3565b306000908152600160205260408120805484929061131b9084906bffffffffffffffffffffffff16615735565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550816000808282829054906101000a90046bffffffffffffffffffffffff166113719190615735565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055506113f883836bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16613f9e9092919063ffffffff16565b505050565b6114056133ed565b806bffffffffffffffffffffffff1660000361144d576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600160205260409020546bffffffffffffffffffffffff9081169082168110156114b9576040517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff821660048201526024016107b3565b6000546bffffffffffffffffffffffff80841691161015611522576000546040517fdda2b2160000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff918216600482015290831660248201526044016107b3565b336000908152600160205260408120805484929061131b9084906bffffffffffffffffffffffff16615735565b60408051606080820183526000808352602080840182905292840181905273ffffffffffffffffffffffffffffffffffffffff861681526004835283812067ffffffffffffffff868116835290845290849020845192830185525460ff81161515835261010081048216938301939093526901000000000000000000909204909116918101919091525b92915050565b6000805b600c5460ff8216101561166857600c805460ff83169081106116075761160761544b565b9060005260206000200154830361165857600d805460ff831690811061162f5761162f61544b565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169392505050565b6116618161575a565b90506115e3565b506040517f80833e33000000000000000000000000000000000000000000000000000000008152600481018390526024016107b3565b6116a66133ed565b6116af82613dce565b6116b7613e94565b60006116c6600a5461ffff1690565b67ffffffffffffffff841660009081526003602052604090206002015490915061ffff82169003611729576040517fb72bc70300000000000000000000000000000000000000000000000000000000815261ffff821660048201526024016107b3565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260046020908152604080832067ffffffffffffffff8716845290915290205460ff161561177157505050565b73ffffffffffffffffffffffffffffffffffffffff8216600081815260046020908152604080832067ffffffffffffffff881680855290835281842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155600384528285206002018054918201815585529383902090930180547fffffffffffffffffffffffff000000000000000000000000000000000000000016851790555192835290917f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e091015b60405180910390a2505050565b60075473ffffffffffffffffffffffffffffffffffffffff1633146118d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107b3565b600680547fffffffffffffffffffffff0000000000000000000000000000000000000000ff81166101003381810292909217909355600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040519290910473ffffffffffffffffffffffffffffffffffffffff169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6119816133ed565b611989613e94565b67ffffffffffffffff81166000908152600360205260409020805460019091015473ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481169290910416338114611a29576040517f4e1d9f1800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016107b3565b67ffffffffffffffff831660008181526003602090815260409182902080546c01000000000000000000000000339081026bffffffffffffffffffffffff928316178355600190920180549091169055825173ffffffffffffffffffffffffffffffffffffffff87168152918201527f6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f09101611845565b611ac8613367565b61101f61402b565b611ad86133ed565b611ae182613dce565b611ae9613e94565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260046020908152604080832067ffffffffffffffff8087168552908352928190208151606081018352905460ff8116151580835261010082048616948301949094526901000000000000000000900490931690830152611b91576040517f71e8313700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806040015167ffffffffffffffff16816020015167ffffffffffffffff1614611be6576040517f06eb10c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8316600090815260036020908152604080832060020180548251818502810185019093528083529192909190830182828015611c6157602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611c36575b5050505050905060005b8151811015611e09578373ffffffffffffffffffffffffffffffffffffffff16828281518110611c9d57611c9d61544b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611df9578160018351611ccf9190615779565b81518110611cdf57611cdf61544b565b6020026020010151600360008767ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206002018281548110611d2257611d2261544b565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff949094169390931790925567ffffffffffffffff87168152600390915260409020600201805480611d9c57611d9c61578c565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055611e09565b611e02816156fd565b9050611c6b565b5073ffffffffffffffffffffffffffffffffffffffff8316600081815260046020908152604080832067ffffffffffffffff89168085529083529281902080547fffffffffffffffffffffffffffffff00000000000000000000000000000000001690555192835290917f182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b91015b60405180910390a250505050565b6000611eaf6133ed565b611eb7613e94565b60028054600090611ed19067ffffffffffffffff166157bb565b825467ffffffffffffffff8083166101009490940a93840293021916919091179091556040805160c0810182526000808252336020830152918101829052606081018290529192506080820190604051908082528060200260200182016040528015611f47578160200160208202803683370190505b5081526000602091820181905267ffffffffffffffff841681526003825260409081902083518484015173ffffffffffffffffffffffffffffffffffffffff9081166c010000000000000000000000009081026bffffffffffffffffffffffff9384161784559386015160608701519091169093029216919091176001820155608083015180519192611fe2926002850192909101906147ab565b5060a0919091015160039091015560405133815267ffffffffffffffff8216907f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf9060200160405180910390a290565b6040805160c0810182526000808252602082018190529181018290526060808201839052608082015260a081019190915261206c82613005565b67ffffffffffffffff8216600090815260036020908152604091829020825160c08101845281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c0100000000000000000000000092839004811684870152600185015491821684880152919004166060820152600282018054855181860281018601909652808652919492936080860193929083018282801561214d57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612122575b505050505081526020016003820154815250509050919050565b61216f6133ed565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146121de576040517f44b0e3c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114612218576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006122268284018461487a565b67ffffffffffffffff81166000908152600360205260409020549091506c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1661229f576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8116600090815260036020526040812080546bffffffffffffffffffffffff16918691906122d68385615655565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550846000808282829054906101000a90046bffffffffffffffffffffffff1661232c9190615655565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508167ffffffffffffffff167fd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f882878461239391906157e2565b6040805192835260208301919091520160405180910390a2505050505050565b60008181526008602052604081205473ffffffffffffffffffffffffffffffffffffffff16806115d9576040517f80833e33000000000000000000000000000000000000000000000000000000008152600481018490526024016107b3565b61241a613367565b60005b600c5481101561253d576000600c600001828154811061243f5761243f61544b565b906000526020600020015490506000600c60010183815481106124645761246461544b565b6000918252602080832091909101548483526008825260409283902054835186815273ffffffffffffffffffffffffffffffffffffffff91821693810193909352169181018290529091507ff8a6175bca1ba37d682089187edc5e20a859989727f10ca6bd9a5bc0de8caf949060600160405180910390a160009182526008602052604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055612536816156fd565b905061241d565b50600c600061254c8282614825565b61255a600183016000614825565b5050565b606080600c600001600c600101818054806020026020016040519081016040528092919081815260200182805480156125b657602002820191906000526020600020905b8154815260200190600101908083116125a2575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561261f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116125f4575b50505050509050915091509091565b6040805160a08101825260008082526020820181905291810182905260608082019290925260808101919091526040805160a081018252600a805461ffff808216845268ffffffffffffffffff620100008304166020808601919091527fffffffff000000000000000000000000000000000000000000000000000000006b010000000000000000000000840460e01b16858701526f01000000000000000000000000000000909204166060840152600b80548551818402810184019096528086529394929360808601939283018282801561275557602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116127185790505b505050505081525050905090565b600061276d6133ed565b612775613e94565b6002805460009061278f9067ffffffffffffffff166157bb565b825467ffffffffffffffff8083166101009490940a93840293021916919091179091556040805160c0810182526000808252336020830152918101829052606081018290529192506080820190604051908082528060200260200182016040528015612805578160200160208202803683370190505b5081526000602091820181905267ffffffffffffffff841681526003825260409081902083518484015173ffffffffffffffffffffffffffffffffffffffff9081166c010000000000000000000000009081026bffffffffffffffffffffffff93841617845593860151606087015190911690930292169190911760018201556080830151805191926128a0926002850192909101906147ab565b5060a0919091015160039182015567ffffffffffffffff82166000818152602092835260408082206002018054600180820183559184528584200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff891690811790915583526004855281832084845285529181902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169092179091555133815290917f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf910160405180910390a260405173ffffffffffffffffffffffffffffffffffffffff8316815267ffffffffffffffff8216907f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e09060200160405180910390a2919050565b6129eb6133ed565b6129f482613dce565b6129fc613e94565b612a0582612e90565b15612a3c576040517f06eb10c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61255a828261307b565b612a4e612ffd565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612adb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aff91906157f5565b6000549091506bffffffffffffffffffffffff16818110156113f8576000612b278284615779565b9050612b6a73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168583613f9e565b6040805173ffffffffffffffffffffffffffffffffffffffff86168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a150505050565b612bc76133ed565b60005b818110156113f8576000838383818110612be657612be661544b565b90506101600201803603810190612bfd919061580e565b80516080820151600082815260056020908152604091829020549151949550929391929091612c2e918691016154ac565b6040516020818303038152906040528051906020012014612c7b576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82610140015163ffffffff16421015612cc0576040517fa2376fe800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208301516040517f85b214cf0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff909116906385b214cf906024016020604051808303816000875af1158015612d33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d57919061582b565b5060408084015167ffffffffffffffff831660009081526003602052918220600101805491929091612d989084906bffffffffffffffffffffffff16615735565b82546bffffffffffffffffffffffff9182166101009390930a928302919092021990911617905550606083015173ffffffffffffffffffffffffffffffffffffffff16600090815260046020908152604080832067ffffffffffffffff808616855292529091208054600192600991612e20918591690100000000000000000090041661584d565b825467ffffffffffffffff9182166101009390930a9283029190920219909116179055506000828152600560205260408082208290555183917ff1ca1e9147be737b04a2b018a79405f687a97de8dd8a2559bbe62357343af41491a250505080612e89906156fd565b9050612bca565b67ffffffffffffffff8116600090815260036020908152604080832060020180548251818502810185019093528083528493830182828015612f0857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612edd575b5050505050905060005b8151811015612fd557600060046000848481518110612f3357612f3361544b565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff808a168352908452908290208251606081018452905460ff8116151582526101008104831694820185905269010000000000000000009004909116918101829052925014612fc457506001949350505050565b50612fce816156fd565b9050612f12565b5060009392505050565b612fe7613367565b600955565b612ff4613367565b61075481614086565b61101f613367565b67ffffffffffffffff81166000908152600360205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16610754576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff82166000908152600360209081526040808320815160c08101835281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481168488015260018501549182168487015291900416606082015260028201805484518187028101870190955280855291949293608086019390929083018282801561315c57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311613131575b505050918352505060039190910154602090910152805190915060005b82608001515181101561321d5760046000846080015183815181106131a0576131a061544b565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff89168252909252902080547fffffffffffffffffffffffffffffff0000000000000000000000000000000000169055613216816156fd565b9050613179565b5067ffffffffffffffff84166000908152600360205260408120818155600181018290559061324f6002830182614825565b5060006003919091018190558054829190819061327b9084906bffffffffffffffffffffffff16615735565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061330283826bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16613f9e9092919063ffffffff16565b6040805173ffffffffffffffffffffffffffffffffffffffff851681526bffffffffffffffffffffffff8316602082015267ffffffffffffffff8616917fe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd498159101611e97565b600654610100900473ffffffffffffffffffffffffffffffffffffffff16331461101f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107b3565b61101f614182565b60006bffffffffffffffffffffffff821115613493576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f362062697473000000000000000000000000000000000000000000000000000060648201526084016107b3565b5090565b60408051606080820183526000808352602083015291810191909152600a546040516000916b010000000000000000000000900460e01b906134e19089908990899060240161586e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009590951694909417909352600a548151608480825260c0820190935292945061ffff6f0100000000000000000000000000000090910416926000928392839282018180368337019050509050863b6135ac57600080fd5b5a848110156135ba57600080fd5b84900360408104810389106135ce57600080fd5b505a60008087516020890160008c8ef193505a900391503d60848111156135f3575060845b808252806000602084013e5060408051606081018252931515845260208401929092529082015298975050505050505050565b60408051808201909152600080825260208201526000613646848661562d565b90506000816136558886615655565b61365f9190615655565b67ffffffffffffffff8b166000908152600360205260409020549091506bffffffffffffffffffffffff808316911610156136f25767ffffffffffffffff8a16600090815260036020526040908190205490517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff90911660048201526024016107b3565b67ffffffffffffffff8a16600090815260036020526040812080548392906137299084906bffffffffffffffffffffffff16615735565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915567ffffffffffffffff8c166000908152600360205260409020600101548b82169116101590506137d65767ffffffffffffffff8a16600090815260036020526040908190205490517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff90911660048201526024016107b3565b67ffffffffffffffff8a16600090815260036020526040812060010180548b92906138109084906bffffffffffffffffffffffff16615735565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550818461384a9190615655565b33600090815260016020526040812080549091906138779084906bffffffffffffffffffffffff16615655565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915530600090815260016020526040812080548b945090926138be91859116615655565b82546bffffffffffffffffffffffff9182166101009390930a92830291909202199091161790555073ffffffffffffffffffffffffffffffffffffffff8816600090815260046020908152604080832067ffffffffffffffff808f16855292529091208054600192600991613942918591690100000000000000000090041661584d565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506040518060400160405280836bffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff1681525092505050979650505050505050565b6139b06141ef565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b6000613a2f6133ed565b613a3885613005565b613a42338661425b565b613a4c8583610757565b8351600003613a86576040517ec1cfc000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000613a9186612032565b90506000613a9f338861154f565b905060008873ffffffffffffffffffffffffffffffffffffffff1663a631571e6040518061016001604052808a8152602001613af58c67ffffffffffffffff166000908152600360208190526040909120015490565b815233602082015260408781015188519190920191613b1391615735565b6bffffffffffffffffffffffff168152602001600a60000160029054906101000a900468ffffffffffffffffff1668ffffffffffffffffff1681526020018b67ffffffffffffffff168152602001856020015167ffffffffffffffff1681526020018863ffffffff1681526020018961ffff168152602001856040015167ffffffffffffffff168152602001866020015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b8152600401613bd99190615899565b610160604051808303816000875af1158015613bf9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c1d91906159fe565b9050604051806101600160405280826000015181526020018a73ffffffffffffffffffffffffffffffffffffffff16815260200182604001516bffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018967ffffffffffffffff1681526020018663ffffffff168152602001600a60000160029054906101000a900468ffffffffffffffffff1668ffffffffffffffffff1681526020018260e0015168ffffffffffffffffff16815260200182610100015164ffffffffff16815260200182610120015164ffffffffff16815260200182610140015163ffffffff16815250604051602001613d2491906154ac565b60405160208183030381529060405280519060200120600560008360000151815260200190815260200160002081905550613d64338983604001516142cf565b8767ffffffffffffffff168a82600001517ff67aec45c9a7ede407974a3e0c3a743dffeab99ee3f2d4c9a8144c2ebf2c7ec9866020015133328d8d8d8a60400151604051613db89796959493929190615ad1565b60405180910390a4519998505050505050505050565b67ffffffffffffffff81166000908152600360205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1680613e45576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff82161461255a576040517f5a68151d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095460009081526008602052604090205473ffffffffffffffffffffffffffffffffffffffff1680613ec45750565b604080516000815260208101918290527f6b14daf80000000000000000000000000000000000000000000000000000000090915273ffffffffffffffffffffffffffffffffffffffff821690636b14daf890613f2590339060248101615b49565b602060405180830381865afa158015613f42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f66919061582b565b610754576040517f229062630000000000000000000000000000000000000000000000000000000081523360048201526024016107b3565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526113f89084906143aa565b614033614182565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586139fb3390565b3373ffffffffffffffffffffffffffffffffffffffff821603614105576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107b3565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600654604051919261010090910416907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b60065460ff161561101f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016107b3565b60065460ff1661101f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016107b3565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260046020908152604080832067ffffffffffffffff8516845290915290205460ff1661255a576040517f71e8313700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8216600090815260036020526040812060010180548392906143099084906bffffffffffffffffffffffff16615655565b82546bffffffffffffffffffffffff91821661010093840a908102920219161790915573ffffffffffffffffffffffffffffffffffffffff8516600090815260046020908152604080832067ffffffffffffffff808916855292529091208054600194509092849261437f92849290041661584d565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505050565b600061440c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166144b69092919063ffffffff16565b8051909150156113f8578080602001905181019061442a919061582b565b6113f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016107b3565b60606144c584846000856144cd565b949350505050565b60608247101561455f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016107b3565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516145889190615b78565b60006040518083038185875af1925050503d80600081146145c5576040519150601f19603f3d011682016040523d82523d6000602084013e6145ca565b606091505b50915091506145db878383876145e6565b979650505050505050565b6060831561467c5782516000036146755773ffffffffffffffffffffffffffffffffffffffff85163b614675576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107b3565b50816144c5565b6144c583838151156146915781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107b39190614962565b828054828255906000526020600020906007016008900481019282156147645791602002820160005b8382111561473257835183826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026146ee565b80156147625782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614732565b505b5061349392915061483f565b828054828255906000526020600020908101928215614764579160200282015b82811115614764578251825591602001919060010190614790565b828054828255906000526020600020908101928215614764579160200282015b8281111561476457825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906147cb565b508054600082559060005260206000209081019061075491905b5b808211156134935760008155600101614840565b67ffffffffffffffff8116811461075457600080fd5b803561487581614854565b919050565b60006020828403121561488c57600080fd5b813561489781614854565b9392505050565b63ffffffff8116811461075457600080fd5b80356148758161489e565b600080604083850312156148ce57600080fd5b82356148d981614854565b915060208301356148e98161489e565b809150509250929050565b60005b8381101561490f5781810151838201526020016148f7565b50506000910152565b600081518084526149308160208601602086016148f4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006148976020830184614918565b6000806040838503121561498857600080fd5b823561499381614854565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff811182821017156149f3576149f36149a1565b60405290565b604051610160810167ffffffffffffffff811182821017156149f3576149f36149a1565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614a6457614a646149a1565b604052919050565b803561ffff8116811461487557600080fd5b68ffffffffffffffffff8116811461075457600080fd5b803561487581614a7e565b600067ffffffffffffffff821115614aba57614aba6149a1565b5060051b60200190565b600082601f830112614ad557600080fd5b81356020614aea614ae583614aa0565b614a1d565b82815260059290921b84018101918181019086841115614b0957600080fd5b8286015b84811015614b2d578035614b208161489e565b8352918301918301614b0d565b509695505050505050565b600060208284031215614b4a57600080fd5b813567ffffffffffffffff80821115614b6257600080fd5b9083019060a08286031215614b7657600080fd5b614b7e6149d0565b614b8783614a6c565b81526020830135614b9781614a7e565b602082015260408301357fffffffff0000000000000000000000000000000000000000000000000000000081168114614bcf57600080fd5b6040820152614be060608401614a6c565b6060820152608083013582811115614bf757600080fd5b614c0387828601614ac4565b60808301525095945050505050565b600082601f830112614c2357600080fd5b813567ffffffffffffffff811115614c3d57614c3d6149a1565b614c6e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614a1d565b818152846020838601011115614c8357600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff8116811461075457600080fd5b803561487581614ca0565b73ffffffffffffffffffffffffffffffffffffffff8116811461075457600080fd5b803561487581614cc5565b64ffffffffff8116811461075457600080fd5b803561487581614cf2565b60006101608284031215614d2357600080fd5b614d2b6149f9565b905081358152614d3d60208301614ce7565b6020820152614d4e60408301614cba565b6040820152614d5f60608301614ce7565b6060820152614d706080830161486a565b6080820152614d8160a083016148b0565b60a0820152614d9260c08301614a95565b60c0820152614da360e08301614a95565b60e0820152610100614db6818401614d05565b90820152610120614dc8838201614d05565b90820152610140614dda8382016148b0565b9082015292915050565b6000806000806000806102008789031215614dfe57600080fd5b863567ffffffffffffffff80821115614e1657600080fd5b614e228a838b01614c12565b97506020890135915080821115614e3857600080fd5b50614e4589828a01614c12565b9550506040870135614e5681614ca0565b93506060870135614e6681614ca0565b92506080870135614e7681614cc5565b9150614e858860a08901614d10565b90509295509295509295565b60078110614ec8577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b60408101614eda8285614e91565b6bffffffffffffffffffffffff831660208301529392505050565b600082601f830112614f0657600080fd5b81356020614f16614ae583614aa0565b82815260059290921b84018101918181019086841115614f3557600080fd5b8286015b84811015614b2d578035614f4c81614cc5565b8352918301918301614f39565b60008060408385031215614f6c57600080fd5b823567ffffffffffffffff80821115614f8457600080fd5b818501915085601f830112614f9857600080fd5b81356020614fa8614ae583614aa0565b82815260059290921b84018101918181019089841115614fc757600080fd5b948201945b83861015614fe557853582529482019490820190614fcc565b96505086013592505080821115614ffb57600080fd5b5061500885828601614ef5565b9150509250929050565b60008083601f84011261502457600080fd5b50813567ffffffffffffffff81111561503c57600080fd5b60208301915083602082850101111561505457600080fd5b9250929050565b60008060008060008060a0878903121561507457600080fd5b863561507f81614854565b9550602087013567ffffffffffffffff81111561509b57600080fd5b6150a789828a01615012565b90965094506150ba905060408801614a6c565b925060608701356150ca8161489e565b80925050608087013590509295509295509295565b600080604083850312156150f257600080fd5b82356150fd81614854565b915060208301356148e981614cc5565b6000806040838503121561512057600080fd5b823561512b81614cc5565b915060208301356148e981614ca0565b6000806040838503121561514e57600080fd5b823561515981614cc5565b915060208301356148e981614854565b60006020828403121561517b57600080fd5b5035919050565b600081518084526020808501945080840160005b838110156151c857815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101615196565b509495945050505050565b6020815260006bffffffffffffffffffffffff808451166020840152602084015173ffffffffffffffffffffffffffffffffffffffff8082166040860152826040870151166060860152806060870151166080860152505050608083015160c060a084015261524560e0840182615182565b905060a084015160c08401528091505092915050565b6000806000806060858703121561527157600080fd5b843561527c81614cc5565b935060208501359250604085013567ffffffffffffffff81111561529f57600080fd5b6152ab87828801615012565b95989497509550505050565b604080825283519082018190526000906020906060840190828701845b828110156152f0578151845292840192908401906001016152d4565b505050838103828501526153048186615182565b9695505050505050565b6000602080835260c0830161ffff808651168386015268ffffffffffffffffff838701511660408601527fffffffff00000000000000000000000000000000000000000000000000000000604087015116606086015280606087015116608086015250608085015160a08086015281815180845260e0870191508483019350600092505b80831015614b2d57835163ffffffff168252928401926001929092019190840190615392565b6000602082840312156153ca57600080fd5b813561489781614cc5565b600080602083850312156153e857600080fd5b823567ffffffffffffffff8082111561540057600080fd5b818501915085601f83011261541457600080fd5b81358181111561542357600080fd5b8660206101608302850101111561543957600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff848116825283166020820152606081016144c56040830184614e91565b815181526020808301516101608301916154dd9084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516154fd60408401826bffffffffffffffffffffffff169052565b506060830151615525606084018273ffffffffffffffffffffffffffffffffffffffff169052565b506080830151615541608084018267ffffffffffffffff169052565b5060a083015161555960a084018263ffffffff169052565b5060c083015161557660c084018268ffffffffffffffffff169052565b5060e083015161559360e084018268ffffffffffffffffff169052565b506101008381015164ffffffffff81168483015250506101208381015164ffffffffff81168483015250506101408381015163ffffffff8116848301525b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b64ffffffffff818116838216019080821115615626576156266155d9565b5092915050565b6bffffffffffffffffffffffff8181168382160280821691908281146155d1576155d16155d9565b6bffffffffffffffffffffffff818116838216019080821115615626576156266155d9565b6bffffffffffffffffffffffff8716815273ffffffffffffffffffffffffffffffffffffffff861660208201526156b46040820186614e91565b60c0606082015260006156ca60c0830186614918565b82810360808401526156dc8186614918565b905082810360a08401526156f08185614918565b9998505050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361572e5761572e6155d9565b5060010190565b6bffffffffffffffffffffffff828116828216039080821115615626576156266155d9565b600060ff821660ff8103615770576157706155d9565b60010192915050565b818103818111156115d9576115d96155d9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600067ffffffffffffffff8083168181036157d8576157d86155d9565b6001019392505050565b808201808211156115d9576115d96155d9565b60006020828403121561580757600080fd5b5051919050565b6000610160828403121561582157600080fd5b6148978383614d10565b60006020828403121561583d57600080fd5b8151801515811461489757600080fd5b67ffffffffffffffff818116838216019080821115615626576156266155d9565b8381526060602082015260006158876060830185614918565b82810360408401526153048185614918565b60208152600082516101608060208501526158b8610180850183614918565b91506020850151604085015260408501516158eb606086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060608501516bffffffffffffffffffffffff8116608086015250608085015168ffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015167ffffffffffffffff811660e08601525060e08501516101006159628187018363ffffffff169052565b86015190506101206159798682018361ffff169052565b86015190506101406159968682018367ffffffffffffffff169052565b9095015173ffffffffffffffffffffffffffffffffffffffff1693019290925250919050565b805161487581614cc5565b805161487581614ca0565b805161487581614854565b80516148758161489e565b805161487581614a7e565b805161487581614cf2565b60006101608284031215615a1157600080fd5b615a196149f9565b82518152615a29602084016159bc565b6020820152615a3a604084016159c7565b6040820152615a4b606084016159bc565b6060820152615a5c608084016159d2565b6080820152615a6d60a084016159dd565b60a0820152615a7e60c084016159e8565b60c0820152615a8f60e084016159e8565b60e0820152610100615aa28185016159f3565b90820152610120615ab48482016159f3565b90820152610140615ac68482016159dd565b908201529392505050565b600073ffffffffffffffffffffffffffffffffffffffff808a168352808916602084015280881660408401525060e06060830152615b1260e0830187614918565b61ffff9590951660808301525063ffffffff9290921660a08301526bffffffffffffffffffffffff1660c090910152949350505050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006144c56040830184614918565b60008251615b8a8184602087016148f4565b919091019291505056fea164736f6c6343000813000a", } var FunctionsRouterABI = FunctionsRouterMetaData.ABI var FunctionsRouterBin = FunctionsRouterMetaData.Bin -func DeployFunctionsRouter(auth *bind.TransactOpts, backend bind.ContractBackend, timelockBlocks uint16, maximumTimelockBlocks uint16, linkToken common.Address, config []byte) (common.Address, *types.Transaction, *FunctionsRouter, error) { +func DeployFunctionsRouter(auth *bind.TransactOpts, backend bind.ContractBackend, linkToken common.Address, config FunctionsRouterConfig) (common.Address, *types.Transaction, *FunctionsRouter, error) { parsed, err := FunctionsRouterMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -48,7 +85,7 @@ func DeployFunctionsRouter(auth *bind.TransactOpts, backend bind.ContractBackend return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(FunctionsRouterBin), backend, timelockBlocks, maximumTimelockBlocks, linkToken, config) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(FunctionsRouterBin), backend, linkToken, config) if err != nil { return common.Address{}, nil, nil, err } @@ -171,6 +208,28 @@ func (_FunctionsRouter *FunctionsRouterTransactorRaw) Transact(opts *bind.Transa return _FunctionsRouter.Contract.contract.Transact(opts, method, params...) } +func (_FunctionsRouter *FunctionsRouterCaller) MAXCALLBACKRETURNBYTES(opts *bind.CallOpts) (uint16, error) { + var out []interface{} + err := _FunctionsRouter.contract.Call(opts, &out, "MAX_CALLBACK_RETURN_BYTES") + + if err != nil { + return *new(uint16), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + + return out0, err + +} + +func (_FunctionsRouter *FunctionsRouterSession) MAXCALLBACKRETURNBYTES() (uint16, error) { + return _FunctionsRouter.Contract.MAXCALLBACKRETURNBYTES(&_FunctionsRouter.CallOpts) +} + +func (_FunctionsRouter *FunctionsRouterCallerSession) MAXCALLBACKRETURNBYTES() (uint16, error) { + return _FunctionsRouter.Contract.MAXCALLBACKRETURNBYTES(&_FunctionsRouter.CallOpts) +} + func (_FunctionsRouter *FunctionsRouterCaller) GetAdminFee(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} err := _FunctionsRouter.contract.Call(opts, &out, "getAdminFee") @@ -215,62 +274,53 @@ func (_FunctionsRouter *FunctionsRouterCallerSession) GetAllowListId() ([32]byte return _FunctionsRouter.Contract.GetAllowListId(&_FunctionsRouter.CallOpts) } -func (_FunctionsRouter *FunctionsRouterCaller) GetConfigHash(opts *bind.CallOpts) ([32]byte, error) { +func (_FunctionsRouter *FunctionsRouterCaller) GetConfig(opts *bind.CallOpts) (FunctionsRouterConfig, error) { var out []interface{} - err := _FunctionsRouter.contract.Call(opts, &out, "getConfigHash") + err := _FunctionsRouter.contract.Call(opts, &out, "getConfig") if err != nil { - return *new([32]byte), err + return *new(FunctionsRouterConfig), err } - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out0 := *abi.ConvertType(out[0], new(FunctionsRouterConfig)).(*FunctionsRouterConfig) return out0, err } -func (_FunctionsRouter *FunctionsRouterSession) GetConfigHash() ([32]byte, error) { - return _FunctionsRouter.Contract.GetConfigHash(&_FunctionsRouter.CallOpts) +func (_FunctionsRouter *FunctionsRouterSession) GetConfig() (FunctionsRouterConfig, error) { + return _FunctionsRouter.Contract.GetConfig(&_FunctionsRouter.CallOpts) } -func (_FunctionsRouter *FunctionsRouterCallerSession) GetConfigHash() ([32]byte, error) { - return _FunctionsRouter.Contract.GetConfigHash(&_FunctionsRouter.CallOpts) +func (_FunctionsRouter *FunctionsRouterCallerSession) GetConfig() (FunctionsRouterConfig, error) { + return _FunctionsRouter.Contract.GetConfig(&_FunctionsRouter.CallOpts) } -func (_FunctionsRouter *FunctionsRouterCaller) GetConsumer(opts *bind.CallOpts, client common.Address, subscriptionId uint64) (GetConsumer, - - error) { +func (_FunctionsRouter *FunctionsRouterCaller) GetConsumer(opts *bind.CallOpts, client common.Address, subscriptionId uint64) (IFunctionsSubscriptionsConsumer, error) { var out []interface{} err := _FunctionsRouter.contract.Call(opts, &out, "getConsumer", client, subscriptionId) - outstruct := new(GetConsumer) if err != nil { - return *outstruct, err + return *new(IFunctionsSubscriptionsConsumer), err } - outstruct.Allowed = *abi.ConvertType(out[0], new(bool)).(*bool) - outstruct.InitiatedRequests = *abi.ConvertType(out[1], new(uint64)).(*uint64) - outstruct.CompletedRequests = *abi.ConvertType(out[2], new(uint64)).(*uint64) + out0 := *abi.ConvertType(out[0], new(IFunctionsSubscriptionsConsumer)).(*IFunctionsSubscriptionsConsumer) - return *outstruct, err + return out0, err } -func (_FunctionsRouter *FunctionsRouterSession) GetConsumer(client common.Address, subscriptionId uint64) (GetConsumer, - - error) { +func (_FunctionsRouter *FunctionsRouterSession) GetConsumer(client common.Address, subscriptionId uint64) (IFunctionsSubscriptionsConsumer, error) { return _FunctionsRouter.Contract.GetConsumer(&_FunctionsRouter.CallOpts, client, subscriptionId) } -func (_FunctionsRouter *FunctionsRouterCallerSession) GetConsumer(client common.Address, subscriptionId uint64) (GetConsumer, - - error) { +func (_FunctionsRouter *FunctionsRouterCallerSession) GetConsumer(client common.Address, subscriptionId uint64) (IFunctionsSubscriptionsConsumer, error) { return _FunctionsRouter.Contract.GetConsumer(&_FunctionsRouter.CallOpts, client, subscriptionId) } -func (_FunctionsRouter *FunctionsRouterCaller) GetContractById(opts *bind.CallOpts, id [32]byte, useProposed bool) (common.Address, error) { +func (_FunctionsRouter *FunctionsRouterCaller) GetContractById(opts *bind.CallOpts, id [32]byte) (common.Address, error) { var out []interface{} - err := _FunctionsRouter.contract.Call(opts, &out, "getContractById", id, useProposed) + err := _FunctionsRouter.contract.Call(opts, &out, "getContractById", id) if err != nil { return *new(common.Address), err @@ -282,112 +332,100 @@ func (_FunctionsRouter *FunctionsRouterCaller) GetContractById(opts *bind.CallOp } -func (_FunctionsRouter *FunctionsRouterSession) GetContractById(id [32]byte, useProposed bool) (common.Address, error) { - return _FunctionsRouter.Contract.GetContractById(&_FunctionsRouter.CallOpts, id, useProposed) +func (_FunctionsRouter *FunctionsRouterSession) GetContractById(id [32]byte) (common.Address, error) { + return _FunctionsRouter.Contract.GetContractById(&_FunctionsRouter.CallOpts, id) } -func (_FunctionsRouter *FunctionsRouterCallerSession) GetContractById(id [32]byte, useProposed bool) (common.Address, error) { - return _FunctionsRouter.Contract.GetContractById(&_FunctionsRouter.CallOpts, id, useProposed) +func (_FunctionsRouter *FunctionsRouterCallerSession) GetContractById(id [32]byte) (common.Address, error) { + return _FunctionsRouter.Contract.GetContractById(&_FunctionsRouter.CallOpts, id) } -func (_FunctionsRouter *FunctionsRouterCaller) GetContractById0(opts *bind.CallOpts, id [32]byte) (common.Address, error) { +func (_FunctionsRouter *FunctionsRouterCaller) GetFlags(opts *bind.CallOpts, subscriptionId uint64) ([32]byte, error) { var out []interface{} - err := _FunctionsRouter.contract.Call(opts, &out, "getContractById0", id) + err := _FunctionsRouter.contract.Call(opts, &out, "getFlags", subscriptionId) if err != nil { - return *new(common.Address), err + return *new([32]byte), err } - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) return out0, err } -func (_FunctionsRouter *FunctionsRouterSession) GetContractById0(id [32]byte) (common.Address, error) { - return _FunctionsRouter.Contract.GetContractById0(&_FunctionsRouter.CallOpts, id) +func (_FunctionsRouter *FunctionsRouterSession) GetFlags(subscriptionId uint64) ([32]byte, error) { + return _FunctionsRouter.Contract.GetFlags(&_FunctionsRouter.CallOpts, subscriptionId) } -func (_FunctionsRouter *FunctionsRouterCallerSession) GetContractById0(id [32]byte) (common.Address, error) { - return _FunctionsRouter.Contract.GetContractById0(&_FunctionsRouter.CallOpts, id) +func (_FunctionsRouter *FunctionsRouterCallerSession) GetFlags(subscriptionId uint64) ([32]byte, error) { + return _FunctionsRouter.Contract.GetFlags(&_FunctionsRouter.CallOpts, subscriptionId) } -func (_FunctionsRouter *FunctionsRouterCaller) GetMaxConsumers(opts *bind.CallOpts) (uint16, error) { +func (_FunctionsRouter *FunctionsRouterCaller) GetProposedContractById(opts *bind.CallOpts, id [32]byte) (common.Address, error) { var out []interface{} - err := _FunctionsRouter.contract.Call(opts, &out, "getMaxConsumers") + err := _FunctionsRouter.contract.Call(opts, &out, "getProposedContractById", id) if err != nil { - return *new(uint16), err + return *new(common.Address), err } - out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) return out0, err } -func (_FunctionsRouter *FunctionsRouterSession) GetMaxConsumers() (uint16, error) { - return _FunctionsRouter.Contract.GetMaxConsumers(&_FunctionsRouter.CallOpts) +func (_FunctionsRouter *FunctionsRouterSession) GetProposedContractById(id [32]byte) (common.Address, error) { + return _FunctionsRouter.Contract.GetProposedContractById(&_FunctionsRouter.CallOpts, id) } -func (_FunctionsRouter *FunctionsRouterCallerSession) GetMaxConsumers() (uint16, error) { - return _FunctionsRouter.Contract.GetMaxConsumers(&_FunctionsRouter.CallOpts) +func (_FunctionsRouter *FunctionsRouterCallerSession) GetProposedContractById(id [32]byte) (common.Address, error) { + return _FunctionsRouter.Contract.GetProposedContractById(&_FunctionsRouter.CallOpts, id) } -func (_FunctionsRouter *FunctionsRouterCaller) GetProposedContractSet(opts *bind.CallOpts) (*big.Int, [][32]byte, []common.Address, error) { +func (_FunctionsRouter *FunctionsRouterCaller) GetProposedContractSet(opts *bind.CallOpts) ([][32]byte, []common.Address, error) { var out []interface{} err := _FunctionsRouter.contract.Call(opts, &out, "getProposedContractSet") if err != nil { - return *new(*big.Int), *new([][32]byte), *new([]common.Address), err + return *new([][32]byte), *new([]common.Address), err } - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - out1 := *abi.ConvertType(out[1], new([][32]byte)).(*[][32]byte) - out2 := *abi.ConvertType(out[2], new([]common.Address)).(*[]common.Address) + out0 := *abi.ConvertType(out[0], new([][32]byte)).(*[][32]byte) + out1 := *abi.ConvertType(out[1], new([]common.Address)).(*[]common.Address) - return out0, out1, out2, err + return out0, out1, err } -func (_FunctionsRouter *FunctionsRouterSession) GetProposedContractSet() (*big.Int, [][32]byte, []common.Address, error) { +func (_FunctionsRouter *FunctionsRouterSession) GetProposedContractSet() ([][32]byte, []common.Address, error) { return _FunctionsRouter.Contract.GetProposedContractSet(&_FunctionsRouter.CallOpts) } -func (_FunctionsRouter *FunctionsRouterCallerSession) GetProposedContractSet() (*big.Int, [][32]byte, []common.Address, error) { +func (_FunctionsRouter *FunctionsRouterCallerSession) GetProposedContractSet() ([][32]byte, []common.Address, error) { return _FunctionsRouter.Contract.GetProposedContractSet(&_FunctionsRouter.CallOpts) } -func (_FunctionsRouter *FunctionsRouterCaller) GetSubscription(opts *bind.CallOpts, subscriptionId uint64) (GetSubscription, - - error) { +func (_FunctionsRouter *FunctionsRouterCaller) GetSubscription(opts *bind.CallOpts, subscriptionId uint64) (IFunctionsSubscriptionsSubscription, error) { var out []interface{} err := _FunctionsRouter.contract.Call(opts, &out, "getSubscription", subscriptionId) - outstruct := new(GetSubscription) if err != nil { - return *outstruct, err + return *new(IFunctionsSubscriptionsSubscription), err } - outstruct.Balance = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - outstruct.BlockedBalance = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - outstruct.Owner = *abi.ConvertType(out[2], new(common.Address)).(*common.Address) - outstruct.RequestedOwner = *abi.ConvertType(out[3], new(common.Address)).(*common.Address) - outstruct.Consumers = *abi.ConvertType(out[4], new([]common.Address)).(*[]common.Address) + out0 := *abi.ConvertType(out[0], new(IFunctionsSubscriptionsSubscription)).(*IFunctionsSubscriptionsSubscription) - return *outstruct, err + return out0, err } -func (_FunctionsRouter *FunctionsRouterSession) GetSubscription(subscriptionId uint64) (GetSubscription, - - error) { +func (_FunctionsRouter *FunctionsRouterSession) GetSubscription(subscriptionId uint64) (IFunctionsSubscriptionsSubscription, error) { return _FunctionsRouter.Contract.GetSubscription(&_FunctionsRouter.CallOpts, subscriptionId) } -func (_FunctionsRouter *FunctionsRouterCallerSession) GetSubscription(subscriptionId uint64) (GetSubscription, - - error) { +func (_FunctionsRouter *FunctionsRouterCallerSession) GetSubscription(subscriptionId uint64) (IFunctionsSubscriptionsSubscription, error) { return _FunctionsRouter.Contract.GetSubscription(&_FunctionsRouter.CallOpts, subscriptionId) } @@ -435,26 +473,24 @@ func (_FunctionsRouter *FunctionsRouterCallerSession) GetTotalBalance() (*big.In return _FunctionsRouter.Contract.GetTotalBalance(&_FunctionsRouter.CallOpts) } -func (_FunctionsRouter *FunctionsRouterCaller) IsPaused(opts *bind.CallOpts) (bool, error) { +func (_FunctionsRouter *FunctionsRouterCaller) IsValidCallbackGasLimit(opts *bind.CallOpts, subscriptionId uint64, callbackGasLimit uint32) error { var out []interface{} - err := _FunctionsRouter.contract.Call(opts, &out, "isPaused") + err := _FunctionsRouter.contract.Call(opts, &out, "isValidCallbackGasLimit", subscriptionId, callbackGasLimit) if err != nil { - return *new(bool), err + return err } - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err + return err } -func (_FunctionsRouter *FunctionsRouterSession) IsPaused() (bool, error) { - return _FunctionsRouter.Contract.IsPaused(&_FunctionsRouter.CallOpts) +func (_FunctionsRouter *FunctionsRouterSession) IsValidCallbackGasLimit(subscriptionId uint64, callbackGasLimit uint32) error { + return _FunctionsRouter.Contract.IsValidCallbackGasLimit(&_FunctionsRouter.CallOpts, subscriptionId, callbackGasLimit) } -func (_FunctionsRouter *FunctionsRouterCallerSession) IsPaused() (bool, error) { - return _FunctionsRouter.Contract.IsPaused(&_FunctionsRouter.CallOpts) +func (_FunctionsRouter *FunctionsRouterCallerSession) IsValidCallbackGasLimit(subscriptionId uint64, callbackGasLimit uint32) error { + return _FunctionsRouter.Contract.IsValidCallbackGasLimit(&_FunctionsRouter.CallOpts, subscriptionId, callbackGasLimit) } func (_FunctionsRouter *FunctionsRouterCaller) Owner(opts *bind.CallOpts) (common.Address, error) { @@ -545,30 +581,6 @@ func (_FunctionsRouter *FunctionsRouterCallerSession) TypeAndVersion() (string, return _FunctionsRouter.Contract.TypeAndVersion(&_FunctionsRouter.CallOpts) } -func (_FunctionsRouter *FunctionsRouterCaller) Version(opts *bind.CallOpts) (uint16, uint16, uint16, error) { - var out []interface{} - err := _FunctionsRouter.contract.Call(opts, &out, "version") - - if err != nil { - return *new(uint16), *new(uint16), *new(uint16), err - } - - out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) - out1 := *abi.ConvertType(out[1], new(uint16)).(*uint16) - out2 := *abi.ConvertType(out[2], new(uint16)).(*uint16) - - return out0, out1, out2, err - -} - -func (_FunctionsRouter *FunctionsRouterSession) Version() (uint16, uint16, uint16, error) { - return _FunctionsRouter.Contract.Version(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCallerSession) Version() (uint16, uint16, uint16, error) { - return _FunctionsRouter.Contract.Version(&_FunctionsRouter.CallOpts) -} - func (_FunctionsRouter *FunctionsRouterTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { return _FunctionsRouter.contract.Transact(opts, "acceptOwnership") } @@ -629,16 +641,28 @@ func (_FunctionsRouter *FunctionsRouterTransactorSession) CreateSubscription() ( return _FunctionsRouter.Contract.CreateSubscription(&_FunctionsRouter.TransactOpts) } -func (_FunctionsRouter *FunctionsRouterTransactor) Fulfill(opts *bind.TransactOpts, requestId [32]byte, response []byte, err []byte, juelsPerGas *big.Int, costWithoutFulfillment *big.Int, transmitter common.Address) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "fulfill", requestId, response, err, juelsPerGas, costWithoutFulfillment, transmitter) +func (_FunctionsRouter *FunctionsRouterTransactor) CreateSubscriptionWithConsumer(opts *bind.TransactOpts, consumer common.Address) (*types.Transaction, error) { + return _FunctionsRouter.contract.Transact(opts, "createSubscriptionWithConsumer", consumer) +} + +func (_FunctionsRouter *FunctionsRouterSession) CreateSubscriptionWithConsumer(consumer common.Address) (*types.Transaction, error) { + return _FunctionsRouter.Contract.CreateSubscriptionWithConsumer(&_FunctionsRouter.TransactOpts, consumer) +} + +func (_FunctionsRouter *FunctionsRouterTransactorSession) CreateSubscriptionWithConsumer(consumer common.Address) (*types.Transaction, error) { + return _FunctionsRouter.Contract.CreateSubscriptionWithConsumer(&_FunctionsRouter.TransactOpts, consumer) } -func (_FunctionsRouter *FunctionsRouterSession) Fulfill(requestId [32]byte, response []byte, err []byte, juelsPerGas *big.Int, costWithoutFulfillment *big.Int, transmitter common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.Fulfill(&_FunctionsRouter.TransactOpts, requestId, response, err, juelsPerGas, costWithoutFulfillment, transmitter) +func (_FunctionsRouter *FunctionsRouterTransactor) Fulfill(opts *bind.TransactOpts, response []byte, err []byte, juelsPerGas *big.Int, costWithoutCallback *big.Int, transmitter common.Address, commitment FunctionsResponseCommitment) (*types.Transaction, error) { + return _FunctionsRouter.contract.Transact(opts, "fulfill", response, err, juelsPerGas, costWithoutCallback, transmitter, commitment) } -func (_FunctionsRouter *FunctionsRouterTransactorSession) Fulfill(requestId [32]byte, response []byte, err []byte, juelsPerGas *big.Int, costWithoutFulfillment *big.Int, transmitter common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.Fulfill(&_FunctionsRouter.TransactOpts, requestId, response, err, juelsPerGas, costWithoutFulfillment, transmitter) +func (_FunctionsRouter *FunctionsRouterSession) Fulfill(response []byte, err []byte, juelsPerGas *big.Int, costWithoutCallback *big.Int, transmitter common.Address, commitment FunctionsResponseCommitment) (*types.Transaction, error) { + return _FunctionsRouter.Contract.Fulfill(&_FunctionsRouter.TransactOpts, response, err, juelsPerGas, costWithoutCallback, transmitter, commitment) +} + +func (_FunctionsRouter *FunctionsRouterTransactorSession) Fulfill(response []byte, err []byte, juelsPerGas *big.Int, costWithoutCallback *big.Int, transmitter common.Address, commitment FunctionsResponseCommitment) (*types.Transaction, error) { + return _FunctionsRouter.Contract.Fulfill(&_FunctionsRouter.TransactOpts, response, err, juelsPerGas, costWithoutCallback, transmitter, commitment) } func (_FunctionsRouter *FunctionsRouterTransactor) OnTokenTransfer(opts *bind.TransactOpts, arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { @@ -677,16 +701,28 @@ func (_FunctionsRouter *FunctionsRouterTransactorSession) OwnerCancelSubscriptio return _FunctionsRouter.Contract.OwnerCancelSubscription(&_FunctionsRouter.TransactOpts, subscriptionId) } -func (_FunctionsRouter *FunctionsRouterTransactor) ProposeConfigUpdate(opts *bind.TransactOpts, id [32]byte, config []byte) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "proposeConfigUpdate", id, config) +func (_FunctionsRouter *FunctionsRouterTransactor) OwnerWithdraw(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _FunctionsRouter.contract.Transact(opts, "ownerWithdraw", recipient, amount) +} + +func (_FunctionsRouter *FunctionsRouterSession) OwnerWithdraw(recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _FunctionsRouter.Contract.OwnerWithdraw(&_FunctionsRouter.TransactOpts, recipient, amount) +} + +func (_FunctionsRouter *FunctionsRouterTransactorSession) OwnerWithdraw(recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _FunctionsRouter.Contract.OwnerWithdraw(&_FunctionsRouter.TransactOpts, recipient, amount) +} + +func (_FunctionsRouter *FunctionsRouterTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _FunctionsRouter.contract.Transact(opts, "pause") } -func (_FunctionsRouter *FunctionsRouterSession) ProposeConfigUpdate(id [32]byte, config []byte) (*types.Transaction, error) { - return _FunctionsRouter.Contract.ProposeConfigUpdate(&_FunctionsRouter.TransactOpts, id, config) +func (_FunctionsRouter *FunctionsRouterSession) Pause() (*types.Transaction, error) { + return _FunctionsRouter.Contract.Pause(&_FunctionsRouter.TransactOpts) } -func (_FunctionsRouter *FunctionsRouterTransactorSession) ProposeConfigUpdate(id [32]byte, config []byte) (*types.Transaction, error) { - return _FunctionsRouter.Contract.ProposeConfigUpdate(&_FunctionsRouter.TransactOpts, id, config) +func (_FunctionsRouter *FunctionsRouterTransactorSession) Pause() (*types.Transaction, error) { + return _FunctionsRouter.Contract.Pause(&_FunctionsRouter.TransactOpts) } func (_FunctionsRouter *FunctionsRouterTransactor) ProposeContractsUpdate(opts *bind.TransactOpts, proposedContractSetIds [][32]byte, proposedContractSetAddresses []common.Address) (*types.Transaction, error) { @@ -701,16 +737,16 @@ func (_FunctionsRouter *FunctionsRouterTransactorSession) ProposeContractsUpdate return _FunctionsRouter.Contract.ProposeContractsUpdate(&_FunctionsRouter.TransactOpts, proposedContractSetIds, proposedContractSetAddresses) } -func (_FunctionsRouter *FunctionsRouterTransactor) ProposeTimelockBlocks(opts *bind.TransactOpts, blocks uint16) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "proposeTimelockBlocks", blocks) +func (_FunctionsRouter *FunctionsRouterTransactor) ProposeSubscriptionOwnerTransfer(opts *bind.TransactOpts, subscriptionId uint64, newOwner common.Address) (*types.Transaction, error) { + return _FunctionsRouter.contract.Transact(opts, "proposeSubscriptionOwnerTransfer", subscriptionId, newOwner) } -func (_FunctionsRouter *FunctionsRouterSession) ProposeTimelockBlocks(blocks uint16) (*types.Transaction, error) { - return _FunctionsRouter.Contract.ProposeTimelockBlocks(&_FunctionsRouter.TransactOpts, blocks) +func (_FunctionsRouter *FunctionsRouterSession) ProposeSubscriptionOwnerTransfer(subscriptionId uint64, newOwner common.Address) (*types.Transaction, error) { + return _FunctionsRouter.Contract.ProposeSubscriptionOwnerTransfer(&_FunctionsRouter.TransactOpts, subscriptionId, newOwner) } -func (_FunctionsRouter *FunctionsRouterTransactorSession) ProposeTimelockBlocks(blocks uint16) (*types.Transaction, error) { - return _FunctionsRouter.Contract.ProposeTimelockBlocks(&_FunctionsRouter.TransactOpts, blocks) +func (_FunctionsRouter *FunctionsRouterTransactorSession) ProposeSubscriptionOwnerTransfer(subscriptionId uint64, newOwner common.Address) (*types.Transaction, error) { + return _FunctionsRouter.Contract.ProposeSubscriptionOwnerTransfer(&_FunctionsRouter.TransactOpts, subscriptionId, newOwner) } func (_FunctionsRouter *FunctionsRouterTransactor) RecoverFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { @@ -737,18 +773,6 @@ func (_FunctionsRouter *FunctionsRouterTransactorSession) RemoveConsumer(subscri return _FunctionsRouter.Contract.RemoveConsumer(&_FunctionsRouter.TransactOpts, subscriptionId, consumer) } -func (_FunctionsRouter *FunctionsRouterTransactor) RequestSubscriptionOwnerTransfer(opts *bind.TransactOpts, subscriptionId uint64, newOwner common.Address) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "requestSubscriptionOwnerTransfer", subscriptionId, newOwner) -} - -func (_FunctionsRouter *FunctionsRouterSession) RequestSubscriptionOwnerTransfer(subscriptionId uint64, newOwner common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.RequestSubscriptionOwnerTransfer(&_FunctionsRouter.TransactOpts, subscriptionId, newOwner) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) RequestSubscriptionOwnerTransfer(subscriptionId uint64, newOwner common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.RequestSubscriptionOwnerTransfer(&_FunctionsRouter.TransactOpts, subscriptionId, newOwner) -} - func (_FunctionsRouter *FunctionsRouterTransactor) SendRequest(opts *bind.TransactOpts, subscriptionId uint64, data []byte, dataVersion uint16, callbackGasLimit uint32, donId [32]byte) (*types.Transaction, error) { return _FunctionsRouter.contract.Transact(opts, "sendRequest", subscriptionId, data, dataVersion, callbackGasLimit, donId) } @@ -761,92 +785,104 @@ func (_FunctionsRouter *FunctionsRouterTransactorSession) SendRequest(subscripti return _FunctionsRouter.Contract.SendRequest(&_FunctionsRouter.TransactOpts, subscriptionId, data, dataVersion, callbackGasLimit, donId) } -func (_FunctionsRouter *FunctionsRouterTransactor) TimeoutRequests(opts *bind.TransactOpts, requestIdsToTimeout [][32]byte) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "timeoutRequests", requestIdsToTimeout) +func (_FunctionsRouter *FunctionsRouterTransactor) SendRequestToProposed(opts *bind.TransactOpts, subscriptionId uint64, data []byte, dataVersion uint16, callbackGasLimit uint32, donId [32]byte) (*types.Transaction, error) { + return _FunctionsRouter.contract.Transact(opts, "sendRequestToProposed", subscriptionId, data, dataVersion, callbackGasLimit, donId) } -func (_FunctionsRouter *FunctionsRouterSession) TimeoutRequests(requestIdsToTimeout [][32]byte) (*types.Transaction, error) { - return _FunctionsRouter.Contract.TimeoutRequests(&_FunctionsRouter.TransactOpts, requestIdsToTimeout) +func (_FunctionsRouter *FunctionsRouterSession) SendRequestToProposed(subscriptionId uint64, data []byte, dataVersion uint16, callbackGasLimit uint32, donId [32]byte) (*types.Transaction, error) { + return _FunctionsRouter.Contract.SendRequestToProposed(&_FunctionsRouter.TransactOpts, subscriptionId, data, dataVersion, callbackGasLimit, donId) } -func (_FunctionsRouter *FunctionsRouterTransactorSession) TimeoutRequests(requestIdsToTimeout [][32]byte) (*types.Transaction, error) { - return _FunctionsRouter.Contract.TimeoutRequests(&_FunctionsRouter.TransactOpts, requestIdsToTimeout) +func (_FunctionsRouter *FunctionsRouterTransactorSession) SendRequestToProposed(subscriptionId uint64, data []byte, dataVersion uint16, callbackGasLimit uint32, donId [32]byte) (*types.Transaction, error) { + return _FunctionsRouter.Contract.SendRequestToProposed(&_FunctionsRouter.TransactOpts, subscriptionId, data, dataVersion, callbackGasLimit, donId) } -func (_FunctionsRouter *FunctionsRouterTransactor) TogglePaused(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "togglePaused") +func (_FunctionsRouter *FunctionsRouterTransactor) SetAllowListId(opts *bind.TransactOpts, allowListId [32]byte) (*types.Transaction, error) { + return _FunctionsRouter.contract.Transact(opts, "setAllowListId", allowListId) } -func (_FunctionsRouter *FunctionsRouterSession) TogglePaused() (*types.Transaction, error) { - return _FunctionsRouter.Contract.TogglePaused(&_FunctionsRouter.TransactOpts) +func (_FunctionsRouter *FunctionsRouterSession) SetAllowListId(allowListId [32]byte) (*types.Transaction, error) { + return _FunctionsRouter.Contract.SetAllowListId(&_FunctionsRouter.TransactOpts, allowListId) } -func (_FunctionsRouter *FunctionsRouterTransactorSession) TogglePaused() (*types.Transaction, error) { - return _FunctionsRouter.Contract.TogglePaused(&_FunctionsRouter.TransactOpts) +func (_FunctionsRouter *FunctionsRouterTransactorSession) SetAllowListId(allowListId [32]byte) (*types.Transaction, error) { + return _FunctionsRouter.Contract.SetAllowListId(&_FunctionsRouter.TransactOpts, allowListId) } -func (_FunctionsRouter *FunctionsRouterTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "transferOwnership", to) +func (_FunctionsRouter *FunctionsRouterTransactor) SetFlags(opts *bind.TransactOpts, subscriptionId uint64, flags [32]byte) (*types.Transaction, error) { + return _FunctionsRouter.contract.Transact(opts, "setFlags", subscriptionId, flags) } -func (_FunctionsRouter *FunctionsRouterSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.TransferOwnership(&_FunctionsRouter.TransactOpts, to) +func (_FunctionsRouter *FunctionsRouterSession) SetFlags(subscriptionId uint64, flags [32]byte) (*types.Transaction, error) { + return _FunctionsRouter.Contract.SetFlags(&_FunctionsRouter.TransactOpts, subscriptionId, flags) } -func (_FunctionsRouter *FunctionsRouterTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.TransferOwnership(&_FunctionsRouter.TransactOpts, to) +func (_FunctionsRouter *FunctionsRouterTransactorSession) SetFlags(subscriptionId uint64, flags [32]byte) (*types.Transaction, error) { + return _FunctionsRouter.Contract.SetFlags(&_FunctionsRouter.TransactOpts, subscriptionId, flags) } -func (_FunctionsRouter *FunctionsRouterTransactor) UpdateConfig(opts *bind.TransactOpts, id [32]byte) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "updateConfig", id) +func (_FunctionsRouter *FunctionsRouterTransactor) TimeoutRequests(opts *bind.TransactOpts, requestsToTimeoutByCommitment []FunctionsResponseCommitment) (*types.Transaction, error) { + return _FunctionsRouter.contract.Transact(opts, "timeoutRequests", requestsToTimeoutByCommitment) } -func (_FunctionsRouter *FunctionsRouterSession) UpdateConfig(id [32]byte) (*types.Transaction, error) { - return _FunctionsRouter.Contract.UpdateConfig(&_FunctionsRouter.TransactOpts, id) +func (_FunctionsRouter *FunctionsRouterSession) TimeoutRequests(requestsToTimeoutByCommitment []FunctionsResponseCommitment) (*types.Transaction, error) { + return _FunctionsRouter.Contract.TimeoutRequests(&_FunctionsRouter.TransactOpts, requestsToTimeoutByCommitment) } -func (_FunctionsRouter *FunctionsRouterTransactorSession) UpdateConfig(id [32]byte) (*types.Transaction, error) { - return _FunctionsRouter.Contract.UpdateConfig(&_FunctionsRouter.TransactOpts, id) +func (_FunctionsRouter *FunctionsRouterTransactorSession) TimeoutRequests(requestsToTimeoutByCommitment []FunctionsResponseCommitment) (*types.Transaction, error) { + return _FunctionsRouter.Contract.TimeoutRequests(&_FunctionsRouter.TransactOpts, requestsToTimeoutByCommitment) } -func (_FunctionsRouter *FunctionsRouterTransactor) UpdateContracts(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "updateContracts") +func (_FunctionsRouter *FunctionsRouterTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _FunctionsRouter.contract.Transact(opts, "transferOwnership", to) } -func (_FunctionsRouter *FunctionsRouterSession) UpdateContracts() (*types.Transaction, error) { - return _FunctionsRouter.Contract.UpdateContracts(&_FunctionsRouter.TransactOpts) +func (_FunctionsRouter *FunctionsRouterSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _FunctionsRouter.Contract.TransferOwnership(&_FunctionsRouter.TransactOpts, to) } -func (_FunctionsRouter *FunctionsRouterTransactorSession) UpdateContracts() (*types.Transaction, error) { - return _FunctionsRouter.Contract.UpdateContracts(&_FunctionsRouter.TransactOpts) +func (_FunctionsRouter *FunctionsRouterTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _FunctionsRouter.Contract.TransferOwnership(&_FunctionsRouter.TransactOpts, to) } -func (_FunctionsRouter *FunctionsRouterTransactor) UpdateTimelockBlocks(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "updateTimelockBlocks") +func (_FunctionsRouter *FunctionsRouterTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _FunctionsRouter.contract.Transact(opts, "unpause") } -func (_FunctionsRouter *FunctionsRouterSession) UpdateTimelockBlocks() (*types.Transaction, error) { - return _FunctionsRouter.Contract.UpdateTimelockBlocks(&_FunctionsRouter.TransactOpts) +func (_FunctionsRouter *FunctionsRouterSession) Unpause() (*types.Transaction, error) { + return _FunctionsRouter.Contract.Unpause(&_FunctionsRouter.TransactOpts) } -func (_FunctionsRouter *FunctionsRouterTransactorSession) UpdateTimelockBlocks() (*types.Transaction, error) { - return _FunctionsRouter.Contract.UpdateTimelockBlocks(&_FunctionsRouter.TransactOpts) +func (_FunctionsRouter *FunctionsRouterTransactorSession) Unpause() (*types.Transaction, error) { + return _FunctionsRouter.Contract.Unpause(&_FunctionsRouter.TransactOpts) } -func (_FunctionsRouter *FunctionsRouterTransactor) ValidateProposedContracts(opts *bind.TransactOpts, id [32]byte, data []byte) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "validateProposedContracts", id, data) +func (_FunctionsRouter *FunctionsRouterTransactor) UpdateConfig(opts *bind.TransactOpts, config FunctionsRouterConfig) (*types.Transaction, error) { + return _FunctionsRouter.contract.Transact(opts, "updateConfig", config) +} + +func (_FunctionsRouter *FunctionsRouterSession) UpdateConfig(config FunctionsRouterConfig) (*types.Transaction, error) { + return _FunctionsRouter.Contract.UpdateConfig(&_FunctionsRouter.TransactOpts, config) +} + +func (_FunctionsRouter *FunctionsRouterTransactorSession) UpdateConfig(config FunctionsRouterConfig) (*types.Transaction, error) { + return _FunctionsRouter.Contract.UpdateConfig(&_FunctionsRouter.TransactOpts, config) +} + +func (_FunctionsRouter *FunctionsRouterTransactor) UpdateContracts(opts *bind.TransactOpts) (*types.Transaction, error) { + return _FunctionsRouter.contract.Transact(opts, "updateContracts") } -func (_FunctionsRouter *FunctionsRouterSession) ValidateProposedContracts(id [32]byte, data []byte) (*types.Transaction, error) { - return _FunctionsRouter.Contract.ValidateProposedContracts(&_FunctionsRouter.TransactOpts, id, data) +func (_FunctionsRouter *FunctionsRouterSession) UpdateContracts() (*types.Transaction, error) { + return _FunctionsRouter.Contract.UpdateContracts(&_FunctionsRouter.TransactOpts) } -func (_FunctionsRouter *FunctionsRouterTransactorSession) ValidateProposedContracts(id [32]byte, data []byte) (*types.Transaction, error) { - return _FunctionsRouter.Contract.ValidateProposedContracts(&_FunctionsRouter.TransactOpts, id, data) +func (_FunctionsRouter *FunctionsRouterTransactorSession) UpdateContracts() (*types.Transaction, error) { + return _FunctionsRouter.Contract.UpdateContracts(&_FunctionsRouter.TransactOpts) } -type FunctionsRouterConfigProposedIterator struct { - Event *FunctionsRouterConfigProposed +type FunctionsRouterConfigUpdatedIterator struct { + Event *FunctionsRouterConfigUpdated contract *bind.BoundContract event string @@ -857,7 +893,7 @@ type FunctionsRouterConfigProposedIterator struct { fail error } -func (it *FunctionsRouterConfigProposedIterator) Next() bool { +func (it *FunctionsRouterConfigUpdatedIterator) Next() bool { if it.fail != nil { return false @@ -866,7 +902,7 @@ func (it *FunctionsRouterConfigProposedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(FunctionsRouterConfigProposed) + it.Event = new(FunctionsRouterConfigUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -881,7 +917,7 @@ func (it *FunctionsRouterConfigProposedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(FunctionsRouterConfigProposed) + it.Event = new(FunctionsRouterConfigUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -896,34 +932,32 @@ func (it *FunctionsRouterConfigProposedIterator) Next() bool { } } -func (it *FunctionsRouterConfigProposedIterator) Error() error { +func (it *FunctionsRouterConfigUpdatedIterator) Error() error { return it.fail } -func (it *FunctionsRouterConfigProposedIterator) Close() error { +func (it *FunctionsRouterConfigUpdatedIterator) Close() error { it.sub.Unsubscribe() return nil } -type FunctionsRouterConfigProposed struct { - Id [32]byte - FromHash [32]byte - ToBytes []byte - Raw types.Log +type FunctionsRouterConfigUpdated struct { + Arg0 FunctionsRouterConfig + Raw types.Log } -func (_FunctionsRouter *FunctionsRouterFilterer) FilterConfigProposed(opts *bind.FilterOpts) (*FunctionsRouterConfigProposedIterator, error) { +func (_FunctionsRouter *FunctionsRouterFilterer) FilterConfigUpdated(opts *bind.FilterOpts) (*FunctionsRouterConfigUpdatedIterator, error) { - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "ConfigProposed") + logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "ConfigUpdated") if err != nil { return nil, err } - return &FunctionsRouterConfigProposedIterator{contract: _FunctionsRouter.contract, event: "ConfigProposed", logs: logs, sub: sub}, nil + return &FunctionsRouterConfigUpdatedIterator{contract: _FunctionsRouter.contract, event: "ConfigUpdated", logs: logs, sub: sub}, nil } -func (_FunctionsRouter *FunctionsRouterFilterer) WatchConfigProposed(opts *bind.WatchOpts, sink chan<- *FunctionsRouterConfigProposed) (event.Subscription, error) { +func (_FunctionsRouter *FunctionsRouterFilterer) WatchConfigUpdated(opts *bind.WatchOpts, sink chan<- *FunctionsRouterConfigUpdated) (event.Subscription, error) { - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "ConfigProposed") + logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "ConfigUpdated") if err != nil { return nil, err } @@ -933,8 +967,8 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchConfigProposed(opts *bind. select { case log := <-logs: - event := new(FunctionsRouterConfigProposed) - if err := _FunctionsRouter.contract.UnpackLog(event, "ConfigProposed", log); err != nil { + event := new(FunctionsRouterConfigUpdated) + if err := _FunctionsRouter.contract.UnpackLog(event, "ConfigUpdated", log); err != nil { return err } event.Raw = log @@ -955,17 +989,17 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchConfigProposed(opts *bind. }), nil } -func (_FunctionsRouter *FunctionsRouterFilterer) ParseConfigProposed(log types.Log) (*FunctionsRouterConfigProposed, error) { - event := new(FunctionsRouterConfigProposed) - if err := _FunctionsRouter.contract.UnpackLog(event, "ConfigProposed", log); err != nil { +func (_FunctionsRouter *FunctionsRouterFilterer) ParseConfigUpdated(log types.Log) (*FunctionsRouterConfigUpdated, error) { + event := new(FunctionsRouterConfigUpdated) + if err := _FunctionsRouter.contract.UnpackLog(event, "ConfigUpdated", log); err != nil { return nil, err } event.Raw = log return event, nil } -type FunctionsRouterConfigSetIterator struct { - Event *FunctionsRouterConfigSet +type FunctionsRouterContractProposedIterator struct { + Event *FunctionsRouterContractProposed contract *bind.BoundContract event string @@ -976,7 +1010,7 @@ type FunctionsRouterConfigSetIterator struct { fail error } -func (it *FunctionsRouterConfigSetIterator) Next() bool { +func (it *FunctionsRouterContractProposedIterator) Next() bool { if it.fail != nil { return false @@ -985,7 +1019,7 @@ func (it *FunctionsRouterConfigSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(FunctionsRouterConfigSet) + it.Event = new(FunctionsRouterContractProposed) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1000,7 +1034,7 @@ func (it *FunctionsRouterConfigSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(FunctionsRouterConfigSet) + it.Event = new(FunctionsRouterContractProposed) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1015,33 +1049,34 @@ func (it *FunctionsRouterConfigSetIterator) Next() bool { } } -func (it *FunctionsRouterConfigSetIterator) Error() error { +func (it *FunctionsRouterContractProposedIterator) Error() error { return it.fail } -func (it *FunctionsRouterConfigSetIterator) Close() error { +func (it *FunctionsRouterContractProposedIterator) Close() error { it.sub.Unsubscribe() return nil } -type FunctionsRouterConfigSet struct { - AdminFee *big.Int - HandleOracleFulfillmentSelector [4]byte - Raw types.Log +type FunctionsRouterContractProposed struct { + ProposedContractSetId [32]byte + ProposedContractSetFromAddress common.Address + ProposedContractSetToAddress common.Address + Raw types.Log } -func (_FunctionsRouter *FunctionsRouterFilterer) FilterConfigSet(opts *bind.FilterOpts) (*FunctionsRouterConfigSetIterator, error) { +func (_FunctionsRouter *FunctionsRouterFilterer) FilterContractProposed(opts *bind.FilterOpts) (*FunctionsRouterContractProposedIterator, error) { - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "ConfigSet") + logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "ContractProposed") if err != nil { return nil, err } - return &FunctionsRouterConfigSetIterator{contract: _FunctionsRouter.contract, event: "ConfigSet", logs: logs, sub: sub}, nil + return &FunctionsRouterContractProposedIterator{contract: _FunctionsRouter.contract, event: "ContractProposed", logs: logs, sub: sub}, nil } -func (_FunctionsRouter *FunctionsRouterFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *FunctionsRouterConfigSet) (event.Subscription, error) { +func (_FunctionsRouter *FunctionsRouterFilterer) WatchContractProposed(opts *bind.WatchOpts, sink chan<- *FunctionsRouterContractProposed) (event.Subscription, error) { - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "ConfigSet") + logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "ContractProposed") if err != nil { return nil, err } @@ -1051,8 +1086,8 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchConfigSet(opts *bind.Watch select { case log := <-logs: - event := new(FunctionsRouterConfigSet) - if err := _FunctionsRouter.contract.UnpackLog(event, "ConfigSet", log); err != nil { + event := new(FunctionsRouterContractProposed) + if err := _FunctionsRouter.contract.UnpackLog(event, "ContractProposed", log); err != nil { return err } event.Raw = log @@ -1073,17 +1108,17 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchConfigSet(opts *bind.Watch }), nil } -func (_FunctionsRouter *FunctionsRouterFilterer) ParseConfigSet(log types.Log) (*FunctionsRouterConfigSet, error) { - event := new(FunctionsRouterConfigSet) - if err := _FunctionsRouter.contract.UnpackLog(event, "ConfigSet", log); err != nil { +func (_FunctionsRouter *FunctionsRouterFilterer) ParseContractProposed(log types.Log) (*FunctionsRouterContractProposed, error) { + event := new(FunctionsRouterContractProposed) + if err := _FunctionsRouter.contract.UnpackLog(event, "ContractProposed", log); err != nil { return nil, err } event.Raw = log return event, nil } -type FunctionsRouterConfigUpdatedIterator struct { - Event *FunctionsRouterConfigUpdated +type FunctionsRouterContractUpdatedIterator struct { + Event *FunctionsRouterContractUpdated contract *bind.BoundContract event string @@ -1094,7 +1129,7 @@ type FunctionsRouterConfigUpdatedIterator struct { fail error } -func (it *FunctionsRouterConfigUpdatedIterator) Next() bool { +func (it *FunctionsRouterContractUpdatedIterator) Next() bool { if it.fail != nil { return false @@ -1103,7 +1138,7 @@ func (it *FunctionsRouterConfigUpdatedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(FunctionsRouterConfigUpdated) + it.Event = new(FunctionsRouterContractUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1118,7 +1153,7 @@ func (it *FunctionsRouterConfigUpdatedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(FunctionsRouterConfigUpdated) + it.Event = new(FunctionsRouterContractUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1133,34 +1168,34 @@ func (it *FunctionsRouterConfigUpdatedIterator) Next() bool { } } -func (it *FunctionsRouterConfigUpdatedIterator) Error() error { +func (it *FunctionsRouterContractUpdatedIterator) Error() error { return it.fail } -func (it *FunctionsRouterConfigUpdatedIterator) Close() error { +func (it *FunctionsRouterContractUpdatedIterator) Close() error { it.sub.Unsubscribe() return nil } -type FunctionsRouterConfigUpdated struct { - Id [32]byte - FromHash [32]byte - ToBytes []byte - Raw types.Log +type FunctionsRouterContractUpdated struct { + Id [32]byte + From common.Address + To common.Address + Raw types.Log } -func (_FunctionsRouter *FunctionsRouterFilterer) FilterConfigUpdated(opts *bind.FilterOpts) (*FunctionsRouterConfigUpdatedIterator, error) { +func (_FunctionsRouter *FunctionsRouterFilterer) FilterContractUpdated(opts *bind.FilterOpts) (*FunctionsRouterContractUpdatedIterator, error) { - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "ConfigUpdated") + logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "ContractUpdated") if err != nil { return nil, err } - return &FunctionsRouterConfigUpdatedIterator{contract: _FunctionsRouter.contract, event: "ConfigUpdated", logs: logs, sub: sub}, nil + return &FunctionsRouterContractUpdatedIterator{contract: _FunctionsRouter.contract, event: "ContractUpdated", logs: logs, sub: sub}, nil } -func (_FunctionsRouter *FunctionsRouterFilterer) WatchConfigUpdated(opts *bind.WatchOpts, sink chan<- *FunctionsRouterConfigUpdated) (event.Subscription, error) { +func (_FunctionsRouter *FunctionsRouterFilterer) WatchContractUpdated(opts *bind.WatchOpts, sink chan<- *FunctionsRouterContractUpdated) (event.Subscription, error) { - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "ConfigUpdated") + logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "ContractUpdated") if err != nil { return nil, err } @@ -1170,8 +1205,8 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchConfigUpdated(opts *bind.W select { case log := <-logs: - event := new(FunctionsRouterConfigUpdated) - if err := _FunctionsRouter.contract.UnpackLog(event, "ConfigUpdated", log); err != nil { + event := new(FunctionsRouterContractUpdated) + if err := _FunctionsRouter.contract.UnpackLog(event, "ContractUpdated", log); err != nil { return err } event.Raw = log @@ -1192,17 +1227,17 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchConfigUpdated(opts *bind.W }), nil } -func (_FunctionsRouter *FunctionsRouterFilterer) ParseConfigUpdated(log types.Log) (*FunctionsRouterConfigUpdated, error) { - event := new(FunctionsRouterConfigUpdated) - if err := _FunctionsRouter.contract.UnpackLog(event, "ConfigUpdated", log); err != nil { +func (_FunctionsRouter *FunctionsRouterFilterer) ParseContractUpdated(log types.Log) (*FunctionsRouterContractUpdated, error) { + event := new(FunctionsRouterContractUpdated) + if err := _FunctionsRouter.contract.UnpackLog(event, "ContractUpdated", log); err != nil { return nil, err } event.Raw = log return event, nil } -type FunctionsRouterContractProposedIterator struct { - Event *FunctionsRouterContractProposed +type FunctionsRouterFundsRecoveredIterator struct { + Event *FunctionsRouterFundsRecovered contract *bind.BoundContract event string @@ -1213,7 +1248,7 @@ type FunctionsRouterContractProposedIterator struct { fail error } -func (it *FunctionsRouterContractProposedIterator) Next() bool { +func (it *FunctionsRouterFundsRecoveredIterator) Next() bool { if it.fail != nil { return false @@ -1222,7 +1257,7 @@ func (it *FunctionsRouterContractProposedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(FunctionsRouterContractProposed) + it.Event = new(FunctionsRouterFundsRecovered) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1237,7 +1272,7 @@ func (it *FunctionsRouterContractProposedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(FunctionsRouterContractProposed) + it.Event = new(FunctionsRouterFundsRecovered) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1252,35 +1287,33 @@ func (it *FunctionsRouterContractProposedIterator) Next() bool { } } -func (it *FunctionsRouterContractProposedIterator) Error() error { +func (it *FunctionsRouterFundsRecoveredIterator) Error() error { return it.fail } -func (it *FunctionsRouterContractProposedIterator) Close() error { +func (it *FunctionsRouterFundsRecoveredIterator) Close() error { it.sub.Unsubscribe() return nil } -type FunctionsRouterContractProposed struct { - ProposedContractSetId [32]byte - ProposedContractSetFromAddress common.Address - ProposedContractSetToAddress common.Address - TimelockEndBlock *big.Int - Raw types.Log +type FunctionsRouterFundsRecovered struct { + To common.Address + Amount *big.Int + Raw types.Log } -func (_FunctionsRouter *FunctionsRouterFilterer) FilterContractProposed(opts *bind.FilterOpts) (*FunctionsRouterContractProposedIterator, error) { +func (_FunctionsRouter *FunctionsRouterFilterer) FilterFundsRecovered(opts *bind.FilterOpts) (*FunctionsRouterFundsRecoveredIterator, error) { - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "ContractProposed") + logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "FundsRecovered") if err != nil { return nil, err } - return &FunctionsRouterContractProposedIterator{contract: _FunctionsRouter.contract, event: "ContractProposed", logs: logs, sub: sub}, nil + return &FunctionsRouterFundsRecoveredIterator{contract: _FunctionsRouter.contract, event: "FundsRecovered", logs: logs, sub: sub}, nil } -func (_FunctionsRouter *FunctionsRouterFilterer) WatchContractProposed(opts *bind.WatchOpts, sink chan<- *FunctionsRouterContractProposed) (event.Subscription, error) { +func (_FunctionsRouter *FunctionsRouterFilterer) WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *FunctionsRouterFundsRecovered) (event.Subscription, error) { - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "ContractProposed") + logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "FundsRecovered") if err != nil { return nil, err } @@ -1290,8 +1323,8 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchContractProposed(opts *bin select { case log := <-logs: - event := new(FunctionsRouterContractProposed) - if err := _FunctionsRouter.contract.UnpackLog(event, "ContractProposed", log); err != nil { + event := new(FunctionsRouterFundsRecovered) + if err := _FunctionsRouter.contract.UnpackLog(event, "FundsRecovered", log); err != nil { return err } event.Raw = log @@ -1312,17 +1345,17 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchContractProposed(opts *bin }), nil } -func (_FunctionsRouter *FunctionsRouterFilterer) ParseContractProposed(log types.Log) (*FunctionsRouterContractProposed, error) { - event := new(FunctionsRouterContractProposed) - if err := _FunctionsRouter.contract.UnpackLog(event, "ContractProposed", log); err != nil { +func (_FunctionsRouter *FunctionsRouterFilterer) ParseFundsRecovered(log types.Log) (*FunctionsRouterFundsRecovered, error) { + event := new(FunctionsRouterFundsRecovered) + if err := _FunctionsRouter.contract.UnpackLog(event, "FundsRecovered", log); err != nil { return nil, err } event.Raw = log return event, nil } -type FunctionsRouterContractUpdatedIterator struct { - Event *FunctionsRouterContractUpdated +type FunctionsRouterOwnershipTransferRequestedIterator struct { + Event *FunctionsRouterOwnershipTransferRequested contract *bind.BoundContract event string @@ -1333,7 +1366,7 @@ type FunctionsRouterContractUpdatedIterator struct { fail error } -func (it *FunctionsRouterContractUpdatedIterator) Next() bool { +func (it *FunctionsRouterOwnershipTransferRequestedIterator) Next() bool { if it.fail != nil { return false @@ -1342,7 +1375,7 @@ func (it *FunctionsRouterContractUpdatedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(FunctionsRouterContractUpdated) + it.Event = new(FunctionsRouterOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1357,7 +1390,7 @@ func (it *FunctionsRouterContractUpdatedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(FunctionsRouterContractUpdated) + it.Event = new(FunctionsRouterOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1372,37 +1405,51 @@ func (it *FunctionsRouterContractUpdatedIterator) Next() bool { } } -func (it *FunctionsRouterContractUpdatedIterator) Error() error { +func (it *FunctionsRouterOwnershipTransferRequestedIterator) Error() error { return it.fail } -func (it *FunctionsRouterContractUpdatedIterator) Close() error { +func (it *FunctionsRouterOwnershipTransferRequestedIterator) Close() error { it.sub.Unsubscribe() return nil } -type FunctionsRouterContractUpdated struct { - ProposedContractSetId [32]byte - ProposedContractSetFromAddress common.Address - ProposedContractSetToAddress common.Address - Major uint16 - Minor uint16 - Patch uint16 - Raw types.Log +type FunctionsRouterOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log } -func (_FunctionsRouter *FunctionsRouterFilterer) FilterContractUpdated(opts *bind.FilterOpts) (*FunctionsRouterContractUpdatedIterator, error) { +func (_FunctionsRouter *FunctionsRouterFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsRouterOwnershipTransferRequestedIterator, error) { - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "ContractUpdated") + 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 := _FunctionsRouter.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } - return &FunctionsRouterContractUpdatedIterator{contract: _FunctionsRouter.contract, event: "ContractUpdated", logs: logs, sub: sub}, nil + return &FunctionsRouterOwnershipTransferRequestedIterator{contract: _FunctionsRouter.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil } -func (_FunctionsRouter *FunctionsRouterFilterer) WatchContractUpdated(opts *bind.WatchOpts, sink chan<- *FunctionsRouterContractUpdated) (event.Subscription, error) { +func (_FunctionsRouter *FunctionsRouterFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsRouterOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "ContractUpdated") + 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 := _FunctionsRouter.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } @@ -1412,8 +1459,8 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchContractUpdated(opts *bind select { case log := <-logs: - event := new(FunctionsRouterContractUpdated) - if err := _FunctionsRouter.contract.UnpackLog(event, "ContractUpdated", log); err != nil { + event := new(FunctionsRouterOwnershipTransferRequested) + if err := _FunctionsRouter.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return err } event.Raw = log @@ -1434,17 +1481,17 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchContractUpdated(opts *bind }), nil } -func (_FunctionsRouter *FunctionsRouterFilterer) ParseContractUpdated(log types.Log) (*FunctionsRouterContractUpdated, error) { - event := new(FunctionsRouterContractUpdated) - if err := _FunctionsRouter.contract.UnpackLog(event, "ContractUpdated", log); err != nil { +func (_FunctionsRouter *FunctionsRouterFilterer) ParseOwnershipTransferRequested(log types.Log) (*FunctionsRouterOwnershipTransferRequested, error) { + event := new(FunctionsRouterOwnershipTransferRequested) + if err := _FunctionsRouter.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return nil, err } event.Raw = log return event, nil } -type FunctionsRouterFundsRecoveredIterator struct { - Event *FunctionsRouterFundsRecovered +type FunctionsRouterOwnershipTransferredIterator struct { + Event *FunctionsRouterOwnershipTransferred contract *bind.BoundContract event string @@ -1455,7 +1502,7 @@ type FunctionsRouterFundsRecoveredIterator struct { fail error } -func (it *FunctionsRouterFundsRecoveredIterator) Next() bool { +func (it *FunctionsRouterOwnershipTransferredIterator) Next() bool { if it.fail != nil { return false @@ -1464,7 +1511,7 @@ func (it *FunctionsRouterFundsRecoveredIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(FunctionsRouterFundsRecovered) + it.Event = new(FunctionsRouterOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1479,7 +1526,7 @@ func (it *FunctionsRouterFundsRecoveredIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(FunctionsRouterFundsRecovered) + it.Event = new(FunctionsRouterOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1494,33 +1541,51 @@ func (it *FunctionsRouterFundsRecoveredIterator) Next() bool { } } -func (it *FunctionsRouterFundsRecoveredIterator) Error() error { +func (it *FunctionsRouterOwnershipTransferredIterator) Error() error { return it.fail } -func (it *FunctionsRouterFundsRecoveredIterator) Close() error { +func (it *FunctionsRouterOwnershipTransferredIterator) Close() error { it.sub.Unsubscribe() return nil } -type FunctionsRouterFundsRecovered struct { - To common.Address - Amount *big.Int - Raw types.Log +type FunctionsRouterOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log } -func (_FunctionsRouter *FunctionsRouterFilterer) FilterFundsRecovered(opts *bind.FilterOpts) (*FunctionsRouterFundsRecoveredIterator, error) { +func (_FunctionsRouter *FunctionsRouterFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsRouterOwnershipTransferredIterator, error) { - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "FundsRecovered") + 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 := _FunctionsRouter.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) if err != nil { return nil, err } - return &FunctionsRouterFundsRecoveredIterator{contract: _FunctionsRouter.contract, event: "FundsRecovered", logs: logs, sub: sub}, nil + return &FunctionsRouterOwnershipTransferredIterator{contract: _FunctionsRouter.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -func (_FunctionsRouter *FunctionsRouterFilterer) WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *FunctionsRouterFundsRecovered) (event.Subscription, error) { +func (_FunctionsRouter *FunctionsRouterFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *FunctionsRouterOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "FundsRecovered") + 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 := _FunctionsRouter.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) if err != nil { return nil, err } @@ -1530,8 +1595,8 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchFundsRecovered(opts *bind. select { case log := <-logs: - event := new(FunctionsRouterFundsRecovered) - if err := _FunctionsRouter.contract.UnpackLog(event, "FundsRecovered", log); err != nil { + event := new(FunctionsRouterOwnershipTransferred) + if err := _FunctionsRouter.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return err } event.Raw = log @@ -1552,17 +1617,17 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchFundsRecovered(opts *bind. }), nil } -func (_FunctionsRouter *FunctionsRouterFilterer) ParseFundsRecovered(log types.Log) (*FunctionsRouterFundsRecovered, error) { - event := new(FunctionsRouterFundsRecovered) - if err := _FunctionsRouter.contract.UnpackLog(event, "FundsRecovered", log); err != nil { +func (_FunctionsRouter *FunctionsRouterFilterer) ParseOwnershipTransferred(log types.Log) (*FunctionsRouterOwnershipTransferred, error) { + event := new(FunctionsRouterOwnershipTransferred) + if err := _FunctionsRouter.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return nil, err } event.Raw = log return event, nil } -type FunctionsRouterOwnershipTransferRequestedIterator struct { - Event *FunctionsRouterOwnershipTransferRequested +type FunctionsRouterPausedIterator struct { + Event *FunctionsRouterPaused contract *bind.BoundContract event string @@ -1573,7 +1638,7 @@ type FunctionsRouterOwnershipTransferRequestedIterator struct { fail error } -func (it *FunctionsRouterOwnershipTransferRequestedIterator) Next() bool { +func (it *FunctionsRouterPausedIterator) Next() bool { if it.fail != nil { return false @@ -1582,7 +1647,7 @@ func (it *FunctionsRouterOwnershipTransferRequestedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(FunctionsRouterOwnershipTransferRequested) + it.Event = new(FunctionsRouterPaused) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1597,7 +1662,7 @@ func (it *FunctionsRouterOwnershipTransferRequestedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(FunctionsRouterOwnershipTransferRequested) + it.Event = new(FunctionsRouterPaused) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1612,51 +1677,32 @@ func (it *FunctionsRouterOwnershipTransferRequestedIterator) Next() bool { } } -func (it *FunctionsRouterOwnershipTransferRequestedIterator) Error() error { +func (it *FunctionsRouterPausedIterator) Error() error { return it.fail } -func (it *FunctionsRouterOwnershipTransferRequestedIterator) Close() error { +func (it *FunctionsRouterPausedIterator) Close() error { it.sub.Unsubscribe() return nil } -type FunctionsRouterOwnershipTransferRequested struct { - From common.Address - To common.Address - Raw types.Log +type FunctionsRouterPaused struct { + Account common.Address + Raw types.Log } -func (_FunctionsRouter *FunctionsRouterFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsRouterOwnershipTransferRequestedIterator, error) { - - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - var toRule []interface{} - for _, toItem := range to { - toRule = append(toRule, toItem) - } +func (_FunctionsRouter *FunctionsRouterFilterer) FilterPaused(opts *bind.FilterOpts) (*FunctionsRouterPausedIterator, error) { - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "Paused") if err != nil { return nil, err } - return &FunctionsRouterOwnershipTransferRequestedIterator{contract: _FunctionsRouter.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil + return &FunctionsRouterPausedIterator{contract: _FunctionsRouter.contract, event: "Paused", logs: logs, sub: sub}, nil } -func (_FunctionsRouter *FunctionsRouterFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsRouterOwnershipTransferRequested, 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) - } +func (_FunctionsRouter *FunctionsRouterFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *FunctionsRouterPaused) (event.Subscription, error) { - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "Paused") if err != nil { return nil, err } @@ -1666,8 +1712,8 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchOwnershipTransferRequested select { case log := <-logs: - event := new(FunctionsRouterOwnershipTransferRequested) - if err := _FunctionsRouter.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + event := new(FunctionsRouterPaused) + if err := _FunctionsRouter.contract.UnpackLog(event, "Paused", log); err != nil { return err } event.Raw = log @@ -1688,17 +1734,17 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchOwnershipTransferRequested }), nil } -func (_FunctionsRouter *FunctionsRouterFilterer) ParseOwnershipTransferRequested(log types.Log) (*FunctionsRouterOwnershipTransferRequested, error) { - event := new(FunctionsRouterOwnershipTransferRequested) - if err := _FunctionsRouter.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { +func (_FunctionsRouter *FunctionsRouterFilterer) ParsePaused(log types.Log) (*FunctionsRouterPaused, error) { + event := new(FunctionsRouterPaused) + if err := _FunctionsRouter.contract.UnpackLog(event, "Paused", log); err != nil { return nil, err } event.Raw = log return event, nil } -type FunctionsRouterOwnershipTransferredIterator struct { - Event *FunctionsRouterOwnershipTransferred +type FunctionsRouterRequestNotProcessedIterator struct { + Event *FunctionsRouterRequestNotProcessed contract *bind.BoundContract event string @@ -1709,7 +1755,7 @@ type FunctionsRouterOwnershipTransferredIterator struct { fail error } -func (it *FunctionsRouterOwnershipTransferredIterator) Next() bool { +func (it *FunctionsRouterRequestNotProcessedIterator) Next() bool { if it.fail != nil { return false @@ -1718,7 +1764,7 @@ func (it *FunctionsRouterOwnershipTransferredIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(FunctionsRouterOwnershipTransferred) + it.Event = new(FunctionsRouterRequestNotProcessed) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1733,7 +1779,7 @@ func (it *FunctionsRouterOwnershipTransferredIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(FunctionsRouterOwnershipTransferred) + it.Event = new(FunctionsRouterRequestNotProcessed) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1748,51 +1794,45 @@ func (it *FunctionsRouterOwnershipTransferredIterator) Next() bool { } } -func (it *FunctionsRouterOwnershipTransferredIterator) Error() error { +func (it *FunctionsRouterRequestNotProcessedIterator) Error() error { return it.fail } -func (it *FunctionsRouterOwnershipTransferredIterator) Close() error { +func (it *FunctionsRouterRequestNotProcessedIterator) Close() error { it.sub.Unsubscribe() return nil } -type FunctionsRouterOwnershipTransferred struct { - From common.Address - To common.Address - Raw types.Log +type FunctionsRouterRequestNotProcessed struct { + RequestId [32]byte + Coordinator common.Address + Transmitter common.Address + ResultCode uint8 + Raw types.Log } -func (_FunctionsRouter *FunctionsRouterFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsRouterOwnershipTransferredIterator, error) { +func (_FunctionsRouter *FunctionsRouterFilterer) FilterRequestNotProcessed(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsRouterRequestNotProcessedIterator, error) { - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - var toRule []interface{} - for _, toItem := range to { - toRule = append(toRule, toItem) + var requestIdRule []interface{} + for _, requestIdItem := range requestId { + requestIdRule = append(requestIdRule, requestIdItem) } - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "RequestNotProcessed", requestIdRule) if err != nil { return nil, err } - return &FunctionsRouterOwnershipTransferredIterator{contract: _FunctionsRouter.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + return &FunctionsRouterRequestNotProcessedIterator{contract: _FunctionsRouter.contract, event: "RequestNotProcessed", logs: logs, sub: sub}, nil } -func (_FunctionsRouter *FunctionsRouterFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *FunctionsRouterOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { +func (_FunctionsRouter *FunctionsRouterFilterer) WatchRequestNotProcessed(opts *bind.WatchOpts, sink chan<- *FunctionsRouterRequestNotProcessed, requestId [][32]byte) (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) + var requestIdRule []interface{} + for _, requestIdItem := range requestId { + requestIdRule = append(requestIdRule, requestIdItem) } - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "RequestNotProcessed", requestIdRule) if err != nil { return nil, err } @@ -1802,8 +1842,8 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchOwnershipTransferred(opts select { case log := <-logs: - event := new(FunctionsRouterOwnershipTransferred) - if err := _FunctionsRouter.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + event := new(FunctionsRouterRequestNotProcessed) + if err := _FunctionsRouter.contract.UnpackLog(event, "RequestNotProcessed", log); err != nil { return err } event.Raw = log @@ -1824,17 +1864,17 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchOwnershipTransferred(opts }), nil } -func (_FunctionsRouter *FunctionsRouterFilterer) ParseOwnershipTransferred(log types.Log) (*FunctionsRouterOwnershipTransferred, error) { - event := new(FunctionsRouterOwnershipTransferred) - if err := _FunctionsRouter.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { +func (_FunctionsRouter *FunctionsRouterFilterer) ParseRequestNotProcessed(log types.Log) (*FunctionsRouterRequestNotProcessed, error) { + event := new(FunctionsRouterRequestNotProcessed) + if err := _FunctionsRouter.contract.UnpackLog(event, "RequestNotProcessed", log); err != nil { return nil, err } event.Raw = log return event, nil } -type FunctionsRouterPausedIterator struct { - Event *FunctionsRouterPaused +type FunctionsRouterRequestProcessedIterator struct { + Event *FunctionsRouterRequestProcessed contract *bind.BoundContract event string @@ -1845,7 +1885,7 @@ type FunctionsRouterPausedIterator struct { fail error } -func (it *FunctionsRouterPausedIterator) Next() bool { +func (it *FunctionsRouterRequestProcessedIterator) Next() bool { if it.fail != nil { return false @@ -1854,7 +1894,7 @@ func (it *FunctionsRouterPausedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(FunctionsRouterPaused) + it.Event = new(FunctionsRouterRequestProcessed) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1869,7 +1909,7 @@ func (it *FunctionsRouterPausedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(FunctionsRouterPaused) + it.Event = new(FunctionsRouterRequestProcessed) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1884,32 +1924,57 @@ func (it *FunctionsRouterPausedIterator) Next() bool { } } -func (it *FunctionsRouterPausedIterator) Error() error { +func (it *FunctionsRouterRequestProcessedIterator) Error() error { return it.fail } -func (it *FunctionsRouterPausedIterator) Close() error { +func (it *FunctionsRouterRequestProcessedIterator) Close() error { it.sub.Unsubscribe() return nil } -type FunctionsRouterPaused struct { - Account common.Address - Raw types.Log +type FunctionsRouterRequestProcessed struct { + RequestId [32]byte + SubscriptionId uint64 + TotalCostJuels *big.Int + Transmitter common.Address + ResultCode uint8 + Response []byte + Err []byte + CallbackReturnData []byte + Raw types.Log } -func (_FunctionsRouter *FunctionsRouterFilterer) FilterPaused(opts *bind.FilterOpts) (*FunctionsRouterPausedIterator, error) { +func (_FunctionsRouter *FunctionsRouterFilterer) FilterRequestProcessed(opts *bind.FilterOpts, requestId [][32]byte, subscriptionId []uint64) (*FunctionsRouterRequestProcessedIterator, error) { - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "Paused") + var requestIdRule []interface{} + for _, requestIdItem := range requestId { + requestIdRule = append(requestIdRule, requestIdItem) + } + var subscriptionIdRule []interface{} + for _, subscriptionIdItem := range subscriptionId { + subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) + } + + logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "RequestProcessed", requestIdRule, subscriptionIdRule) if err != nil { return nil, err } - return &FunctionsRouterPausedIterator{contract: _FunctionsRouter.contract, event: "Paused", logs: logs, sub: sub}, nil + return &FunctionsRouterRequestProcessedIterator{contract: _FunctionsRouter.contract, event: "RequestProcessed", logs: logs, sub: sub}, nil } -func (_FunctionsRouter *FunctionsRouterFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *FunctionsRouterPaused) (event.Subscription, error) { +func (_FunctionsRouter *FunctionsRouterFilterer) WatchRequestProcessed(opts *bind.WatchOpts, sink chan<- *FunctionsRouterRequestProcessed, requestId [][32]byte, subscriptionId []uint64) (event.Subscription, error) { - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "Paused") + var requestIdRule []interface{} + for _, requestIdItem := range requestId { + requestIdRule = append(requestIdRule, requestIdItem) + } + var subscriptionIdRule []interface{} + for _, subscriptionIdItem := range subscriptionId { + subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) + } + + logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "RequestProcessed", requestIdRule, subscriptionIdRule) if err != nil { return nil, err } @@ -1919,8 +1984,8 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchPaused(opts *bind.WatchOpt select { case log := <-logs: - event := new(FunctionsRouterPaused) - if err := _FunctionsRouter.contract.UnpackLog(event, "Paused", log); err != nil { + event := new(FunctionsRouterRequestProcessed) + if err := _FunctionsRouter.contract.UnpackLog(event, "RequestProcessed", log); err != nil { return err } event.Raw = log @@ -1941,17 +2006,17 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchPaused(opts *bind.WatchOpt }), nil } -func (_FunctionsRouter *FunctionsRouterFilterer) ParsePaused(log types.Log) (*FunctionsRouterPaused, error) { - event := new(FunctionsRouterPaused) - if err := _FunctionsRouter.contract.UnpackLog(event, "Paused", log); err != nil { +func (_FunctionsRouter *FunctionsRouterFilterer) ParseRequestProcessed(log types.Log) (*FunctionsRouterRequestProcessed, error) { + event := new(FunctionsRouterRequestProcessed) + if err := _FunctionsRouter.contract.UnpackLog(event, "RequestProcessed", log); err != nil { return nil, err } event.Raw = log return event, nil } -type FunctionsRouterRequestEndIterator struct { - Event *FunctionsRouterRequestEnd +type FunctionsRouterRequestStartIterator struct { + Event *FunctionsRouterRequestStart contract *bind.BoundContract event string @@ -1962,7 +2027,7 @@ type FunctionsRouterRequestEndIterator struct { fail error } -func (it *FunctionsRouterRequestEndIterator) Next() bool { +func (it *FunctionsRouterRequestStartIterator) Next() bool { if it.fail != nil { return false @@ -1971,7 +2036,7 @@ func (it *FunctionsRouterRequestEndIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(FunctionsRouterRequestEnd) + it.Event = new(FunctionsRouterRequestStart) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1986,7 +2051,7 @@ func (it *FunctionsRouterRequestEndIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(FunctionsRouterRequestEnd) + it.Event = new(FunctionsRouterRequestStart) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2001,55 +2066,67 @@ func (it *FunctionsRouterRequestEndIterator) Next() bool { } } -func (it *FunctionsRouterRequestEndIterator) Error() error { +func (it *FunctionsRouterRequestStartIterator) Error() error { return it.fail } -func (it *FunctionsRouterRequestEndIterator) Close() error { +func (it *FunctionsRouterRequestStartIterator) Close() error { it.sub.Unsubscribe() return nil } -type FunctionsRouterRequestEnd struct { - RequestId [32]byte - SubscriptionId uint64 - TotalCostJuels *big.Int - Transmitter common.Address - ResultCode uint8 - Response []byte - Raw types.Log +type FunctionsRouterRequestStart struct { + RequestId [32]byte + DonId [32]byte + SubscriptionId uint64 + SubscriptionOwner common.Address + RequestingContract common.Address + RequestInitiator common.Address + Data []byte + DataVersion uint16 + CallbackGasLimit uint32 + EstimatedTotalCostJuels *big.Int + Raw types.Log } -func (_FunctionsRouter *FunctionsRouterFilterer) FilterRequestEnd(opts *bind.FilterOpts, requestId [][32]byte, subscriptionId []uint64) (*FunctionsRouterRequestEndIterator, error) { +func (_FunctionsRouter *FunctionsRouterFilterer) FilterRequestStart(opts *bind.FilterOpts, requestId [][32]byte, donId [][32]byte, subscriptionId []uint64) (*FunctionsRouterRequestStartIterator, error) { var requestIdRule []interface{} for _, requestIdItem := range requestId { requestIdRule = append(requestIdRule, requestIdItem) } + var donIdRule []interface{} + for _, donIdItem := range donId { + donIdRule = append(donIdRule, donIdItem) + } var subscriptionIdRule []interface{} for _, subscriptionIdItem := range subscriptionId { subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) } - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "RequestEnd", requestIdRule, subscriptionIdRule) + logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "RequestStart", requestIdRule, donIdRule, subscriptionIdRule) if err != nil { return nil, err } - return &FunctionsRouterRequestEndIterator{contract: _FunctionsRouter.contract, event: "RequestEnd", logs: logs, sub: sub}, nil + return &FunctionsRouterRequestStartIterator{contract: _FunctionsRouter.contract, event: "RequestStart", logs: logs, sub: sub}, nil } -func (_FunctionsRouter *FunctionsRouterFilterer) WatchRequestEnd(opts *bind.WatchOpts, sink chan<- *FunctionsRouterRequestEnd, requestId [][32]byte, subscriptionId []uint64) (event.Subscription, error) { +func (_FunctionsRouter *FunctionsRouterFilterer) WatchRequestStart(opts *bind.WatchOpts, sink chan<- *FunctionsRouterRequestStart, requestId [][32]byte, donId [][32]byte, subscriptionId []uint64) (event.Subscription, error) { var requestIdRule []interface{} for _, requestIdItem := range requestId { requestIdRule = append(requestIdRule, requestIdItem) } + var donIdRule []interface{} + for _, donIdItem := range donId { + donIdRule = append(donIdRule, donIdItem) + } var subscriptionIdRule []interface{} for _, subscriptionIdItem := range subscriptionId { subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) } - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "RequestEnd", requestIdRule, subscriptionIdRule) + logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "RequestStart", requestIdRule, donIdRule, subscriptionIdRule) if err != nil { return nil, err } @@ -2059,8 +2136,8 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchRequestEnd(opts *bind.Watc select { case log := <-logs: - event := new(FunctionsRouterRequestEnd) - if err := _FunctionsRouter.contract.UnpackLog(event, "RequestEnd", log); err != nil { + event := new(FunctionsRouterRequestStart) + if err := _FunctionsRouter.contract.UnpackLog(event, "RequestStart", log); err != nil { return err } event.Raw = log @@ -2081,17 +2158,17 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchRequestEnd(opts *bind.Watc }), nil } -func (_FunctionsRouter *FunctionsRouterFilterer) ParseRequestEnd(log types.Log) (*FunctionsRouterRequestEnd, error) { - event := new(FunctionsRouterRequestEnd) - if err := _FunctionsRouter.contract.UnpackLog(event, "RequestEnd", log); err != nil { +func (_FunctionsRouter *FunctionsRouterFilterer) ParseRequestStart(log types.Log) (*FunctionsRouterRequestStart, error) { + event := new(FunctionsRouterRequestStart) + if err := _FunctionsRouter.contract.UnpackLog(event, "RequestStart", log); err != nil { return nil, err } event.Raw = log return event, nil } -type FunctionsRouterRequestStartIterator struct { - Event *FunctionsRouterRequestStart +type FunctionsRouterRequestTimedOutIterator struct { + Event *FunctionsRouterRequestTimedOut contract *bind.BoundContract event string @@ -2102,7 +2179,7 @@ type FunctionsRouterRequestStartIterator struct { fail error } -func (it *FunctionsRouterRequestStartIterator) Next() bool { +func (it *FunctionsRouterRequestTimedOutIterator) Next() bool { if it.fail != nil { return false @@ -2111,7 +2188,7 @@ func (it *FunctionsRouterRequestStartIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(FunctionsRouterRequestStart) + it.Event = new(FunctionsRouterRequestTimedOut) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2126,7 +2203,7 @@ func (it *FunctionsRouterRequestStartIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(FunctionsRouterRequestStart) + it.Event = new(FunctionsRouterRequestTimedOut) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2141,66 +2218,42 @@ func (it *FunctionsRouterRequestStartIterator) Next() bool { } } -func (it *FunctionsRouterRequestStartIterator) Error() error { +func (it *FunctionsRouterRequestTimedOutIterator) Error() error { return it.fail } -func (it *FunctionsRouterRequestStartIterator) Close() error { +func (it *FunctionsRouterRequestTimedOutIterator) Close() error { it.sub.Unsubscribe() return nil } -type FunctionsRouterRequestStart struct { - RequestId [32]byte - DonId [32]byte - SubscriptionId uint64 - SubscriptionOwner common.Address - RequestingContract common.Address - RequestInitiator common.Address - Data []byte - DataVersion uint16 - CallbackGasLimit uint32 - Raw types.Log +type FunctionsRouterRequestTimedOut struct { + RequestId [32]byte + Raw types.Log } -func (_FunctionsRouter *FunctionsRouterFilterer) FilterRequestStart(opts *bind.FilterOpts, requestId [][32]byte, donId [][32]byte, subscriptionId []uint64) (*FunctionsRouterRequestStartIterator, error) { +func (_FunctionsRouter *FunctionsRouterFilterer) FilterRequestTimedOut(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsRouterRequestTimedOutIterator, error) { var requestIdRule []interface{} for _, requestIdItem := range requestId { requestIdRule = append(requestIdRule, requestIdItem) } - var donIdRule []interface{} - for _, donIdItem := range donId { - donIdRule = append(donIdRule, donIdItem) - } - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "RequestStart", requestIdRule, donIdRule, subscriptionIdRule) + logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "RequestTimedOut", requestIdRule) if err != nil { return nil, err } - return &FunctionsRouterRequestStartIterator{contract: _FunctionsRouter.contract, event: "RequestStart", logs: logs, sub: sub}, nil + return &FunctionsRouterRequestTimedOutIterator{contract: _FunctionsRouter.contract, event: "RequestTimedOut", logs: logs, sub: sub}, nil } -func (_FunctionsRouter *FunctionsRouterFilterer) WatchRequestStart(opts *bind.WatchOpts, sink chan<- *FunctionsRouterRequestStart, requestId [][32]byte, donId [][32]byte, subscriptionId []uint64) (event.Subscription, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - var donIdRule []interface{} - for _, donIdItem := range donId { - donIdRule = append(donIdRule, donIdItem) - } - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) +func (_FunctionsRouter *FunctionsRouterFilterer) WatchRequestTimedOut(opts *bind.WatchOpts, sink chan<- *FunctionsRouterRequestTimedOut, requestId [][32]byte) (event.Subscription, error) { + + var requestIdRule []interface{} + for _, requestIdItem := range requestId { + requestIdRule = append(requestIdRule, requestIdItem) } - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "RequestStart", requestIdRule, donIdRule, subscriptionIdRule) + logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "RequestTimedOut", requestIdRule) if err != nil { return nil, err } @@ -2210,8 +2263,8 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchRequestStart(opts *bind.Wa select { case log := <-logs: - event := new(FunctionsRouterRequestStart) - if err := _FunctionsRouter.contract.UnpackLog(event, "RequestStart", log); err != nil { + event := new(FunctionsRouterRequestTimedOut) + if err := _FunctionsRouter.contract.UnpackLog(event, "RequestTimedOut", log); err != nil { return err } event.Raw = log @@ -2232,9 +2285,9 @@ func (_FunctionsRouter *FunctionsRouterFilterer) WatchRequestStart(opts *bind.Wa }), nil } -func (_FunctionsRouter *FunctionsRouterFilterer) ParseRequestStart(log types.Log) (*FunctionsRouterRequestStart, error) { - event := new(FunctionsRouterRequestStart) - if err := _FunctionsRouter.contract.UnpackLog(event, "RequestStart", log); err != nil { +func (_FunctionsRouter *FunctionsRouterFilterer) ParseRequestTimedOut(log types.Log) (*FunctionsRouterRequestTimedOut, error) { + event := new(FunctionsRouterRequestTimedOut) + if err := _FunctionsRouter.contract.UnpackLog(event, "RequestTimedOut", log); err != nil { return nil, err } event.Raw = log @@ -3141,242 +3194,6 @@ func (_FunctionsRouter *FunctionsRouterFilterer) ParseSubscriptionOwnerTransferr return event, nil } -type FunctionsRouterTimeLockProposedIterator struct { - Event *FunctionsRouterTimeLockProposed - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterTimeLockProposedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterTimeLockProposed) - 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(FunctionsRouterTimeLockProposed) - 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 *FunctionsRouterTimeLockProposedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterTimeLockProposedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterTimeLockProposed struct { - From uint16 - To uint16 - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterTimeLockProposed(opts *bind.FilterOpts) (*FunctionsRouterTimeLockProposedIterator, error) { - - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "TimeLockProposed") - if err != nil { - return nil, err - } - return &FunctionsRouterTimeLockProposedIterator{contract: _FunctionsRouter.contract, event: "TimeLockProposed", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchTimeLockProposed(opts *bind.WatchOpts, sink chan<- *FunctionsRouterTimeLockProposed) (event.Subscription, error) { - - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "TimeLockProposed") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRouterTimeLockProposed) - if err := _FunctionsRouter.contract.UnpackLog(event, "TimeLockProposed", 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 (_FunctionsRouter *FunctionsRouterFilterer) ParseTimeLockProposed(log types.Log) (*FunctionsRouterTimeLockProposed, error) { - event := new(FunctionsRouterTimeLockProposed) - if err := _FunctionsRouter.contract.UnpackLog(event, "TimeLockProposed", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRouterTimeLockUpdatedIterator struct { - Event *FunctionsRouterTimeLockUpdated - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterTimeLockUpdatedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterTimeLockUpdated) - 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(FunctionsRouterTimeLockUpdated) - 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 *FunctionsRouterTimeLockUpdatedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterTimeLockUpdatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterTimeLockUpdated struct { - From uint16 - To uint16 - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterTimeLockUpdated(opts *bind.FilterOpts) (*FunctionsRouterTimeLockUpdatedIterator, error) { - - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "TimeLockUpdated") - if err != nil { - return nil, err - } - return &FunctionsRouterTimeLockUpdatedIterator{contract: _FunctionsRouter.contract, event: "TimeLockUpdated", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchTimeLockUpdated(opts *bind.WatchOpts, sink chan<- *FunctionsRouterTimeLockUpdated) (event.Subscription, error) { - - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "TimeLockUpdated") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRouterTimeLockUpdated) - if err := _FunctionsRouter.contract.UnpackLog(event, "TimeLockUpdated", 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 (_FunctionsRouter *FunctionsRouterFilterer) ParseTimeLockUpdated(log types.Log) (*FunctionsRouterTimeLockUpdated, error) { - event := new(FunctionsRouterTimeLockUpdated) - if err := _FunctionsRouter.contract.UnpackLog(event, "TimeLockUpdated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - type FunctionsRouterUnpausedIterator struct { Event *FunctionsRouterUnpaused @@ -3494,25 +3311,8 @@ func (_FunctionsRouter *FunctionsRouterFilterer) ParseUnpaused(log types.Log) (* return event, nil } -type GetConsumer struct { - Allowed bool - InitiatedRequests uint64 - CompletedRequests uint64 -} -type GetSubscription struct { - Balance *big.Int - BlockedBalance *big.Int - Owner common.Address - RequestedOwner common.Address - Consumers []common.Address -} - func (_FunctionsRouter *FunctionsRouter) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { - case _FunctionsRouter.abi.Events["ConfigProposed"].ID: - return _FunctionsRouter.ParseConfigProposed(log) - case _FunctionsRouter.abi.Events["ConfigSet"].ID: - return _FunctionsRouter.ParseConfigSet(log) case _FunctionsRouter.abi.Events["ConfigUpdated"].ID: return _FunctionsRouter.ParseConfigUpdated(log) case _FunctionsRouter.abi.Events["ContractProposed"].ID: @@ -3527,10 +3327,14 @@ func (_FunctionsRouter *FunctionsRouter) ParseLog(log types.Log) (generated.Abig return _FunctionsRouter.ParseOwnershipTransferred(log) case _FunctionsRouter.abi.Events["Paused"].ID: return _FunctionsRouter.ParsePaused(log) - case _FunctionsRouter.abi.Events["RequestEnd"].ID: - return _FunctionsRouter.ParseRequestEnd(log) + case _FunctionsRouter.abi.Events["RequestNotProcessed"].ID: + return _FunctionsRouter.ParseRequestNotProcessed(log) + case _FunctionsRouter.abi.Events["RequestProcessed"].ID: + return _FunctionsRouter.ParseRequestProcessed(log) case _FunctionsRouter.abi.Events["RequestStart"].ID: return _FunctionsRouter.ParseRequestStart(log) + case _FunctionsRouter.abi.Events["RequestTimedOut"].ID: + return _FunctionsRouter.ParseRequestTimedOut(log) case _FunctionsRouter.abi.Events["SubscriptionCanceled"].ID: return _FunctionsRouter.ParseSubscriptionCanceled(log) case _FunctionsRouter.abi.Events["SubscriptionConsumerAdded"].ID: @@ -3545,10 +3349,6 @@ func (_FunctionsRouter *FunctionsRouter) ParseLog(log types.Log) (generated.Abig return _FunctionsRouter.ParseSubscriptionOwnerTransferRequested(log) case _FunctionsRouter.abi.Events["SubscriptionOwnerTransferred"].ID: return _FunctionsRouter.ParseSubscriptionOwnerTransferred(log) - case _FunctionsRouter.abi.Events["TimeLockProposed"].ID: - return _FunctionsRouter.ParseTimeLockProposed(log) - case _FunctionsRouter.abi.Events["TimeLockUpdated"].ID: - return _FunctionsRouter.ParseTimeLockUpdated(log) case _FunctionsRouter.abi.Events["Unpaused"].ID: return _FunctionsRouter.ParseUnpaused(log) @@ -3557,24 +3357,16 @@ func (_FunctionsRouter *FunctionsRouter) ParseLog(log types.Log) (generated.Abig } } -func (FunctionsRouterConfigProposed) Topic() common.Hash { - return common.HexToHash("0x0fcfd32a68209b42944376bc5f4bf72c41ba0f378cf60434f84390b82c9844cf") -} - -func (FunctionsRouterConfigSet) Topic() common.Hash { - return common.HexToHash("0xb2b9bfb736b0bfef266985352cfca2a114226362209f5a6e5a2a2ed14383ba57") -} - func (FunctionsRouterConfigUpdated) Topic() common.Hash { - return common.HexToHash("0xc07626096b49b0462a576c9a7878cf0675e784bb4832584c1289c11664e55f47") + return common.HexToHash("0x049ce2e6e1420eb4b07b425e90129186833eb346bda40b37d5d921aad482f71c") } func (FunctionsRouterContractProposed) Topic() common.Hash { - return common.HexToHash("0x72a33d2f293a0a70fad221bb610d3d6b52aed2d840adae1fa721071fbd290cfd") + return common.HexToHash("0x8b052f0f4bf82fede7daffea71592b29d5ef86af1f3c7daaa0345dbb2f52f481") } func (FunctionsRouterContractUpdated) Topic() common.Hash { - return common.HexToHash("0xf17ce6b5bbeda6598ac50e505071ddbd27c188c5ecaf9126b42c951c9c4b61e9") + return common.HexToHash("0xf8a6175bca1ba37d682089187edc5e20a859989727f10ca6bd9a5bc0de8caf94") } func (FunctionsRouterFundsRecovered) Topic() common.Hash { @@ -3593,12 +3385,20 @@ func (FunctionsRouterPaused) Topic() common.Hash { return common.HexToHash("0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258") } -func (FunctionsRouterRequestEnd) Topic() common.Hash { - return common.HexToHash("0x526019d853b0b88e828dbdc124746afde5a47053256d2a0872a025ab145b0520") +func (FunctionsRouterRequestNotProcessed) Topic() common.Hash { + return common.HexToHash("0x1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee1") +} + +func (FunctionsRouterRequestProcessed) Topic() common.Hash { + return common.HexToHash("0x64778f26c70b60a8d7e29e2451b3844302d959448401c0535b768ed88c6b505e") } func (FunctionsRouterRequestStart) Topic() common.Hash { - return common.HexToHash("0x7c720ccd20069b8311a6be4ba1cf3294d09eb247aa5d73a8502054b6e68a2f54") + return common.HexToHash("0xf67aec45c9a7ede407974a3e0c3a743dffeab99ee3f2d4c9a8144c2ebf2c7ec9") +} + +func (FunctionsRouterRequestTimedOut) Topic() common.Hash { + return common.HexToHash("0xf1ca1e9147be737b04a2b018a79405f687a97de8dd8a2559bbe62357343af414") } func (FunctionsRouterSubscriptionCanceled) Topic() common.Hash { @@ -3629,14 +3429,6 @@ func (FunctionsRouterSubscriptionOwnerTransferred) Topic() common.Hash { return common.HexToHash("0x6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f0") } -func (FunctionsRouterTimeLockProposed) Topic() common.Hash { - return common.HexToHash("0x391ced87fc414ac6e67620b6432a8df0e27da63c8cc6782941fb535ac9e06c0a") -} - -func (FunctionsRouterTimeLockUpdated) Topic() common.Hash { - return common.HexToHash("0xbda3a518f5d5dbadc2e16a279c572f58eeddb114eb084747e012080e64c54d1d") -} - func (FunctionsRouterUnpaused) Topic() common.Hash { return common.HexToHash("0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa") } @@ -3646,33 +3438,31 @@ func (_FunctionsRouter *FunctionsRouter) Address() common.Address { } type FunctionsRouterInterface interface { + MAXCALLBACKRETURNBYTES(opts *bind.CallOpts) (uint16, error) + GetAdminFee(opts *bind.CallOpts) (*big.Int, error) GetAllowListId(opts *bind.CallOpts) ([32]byte, error) - GetConfigHash(opts *bind.CallOpts) ([32]byte, error) - - GetConsumer(opts *bind.CallOpts, client common.Address, subscriptionId uint64) (GetConsumer, + GetConfig(opts *bind.CallOpts) (FunctionsRouterConfig, error) - error) + GetConsumer(opts *bind.CallOpts, client common.Address, subscriptionId uint64) (IFunctionsSubscriptionsConsumer, error) - GetContractById(opts *bind.CallOpts, id [32]byte, useProposed bool) (common.Address, error) + GetContractById(opts *bind.CallOpts, id [32]byte) (common.Address, error) - GetContractById0(opts *bind.CallOpts, id [32]byte) (common.Address, error) + GetFlags(opts *bind.CallOpts, subscriptionId uint64) ([32]byte, error) - GetMaxConsumers(opts *bind.CallOpts) (uint16, error) + GetProposedContractById(opts *bind.CallOpts, id [32]byte) (common.Address, error) - GetProposedContractSet(opts *bind.CallOpts) (*big.Int, [][32]byte, []common.Address, error) + GetProposedContractSet(opts *bind.CallOpts) ([][32]byte, []common.Address, error) - GetSubscription(opts *bind.CallOpts, subscriptionId uint64) (GetSubscription, - - error) + GetSubscription(opts *bind.CallOpts, subscriptionId uint64) (IFunctionsSubscriptionsSubscription, error) GetSubscriptionCount(opts *bind.CallOpts) (uint64, error) GetTotalBalance(opts *bind.CallOpts) (*big.Int, error) - IsPaused(opts *bind.CallOpts) (bool, error) + IsValidCallbackGasLimit(opts *bind.CallOpts, subscriptionId uint64, callbackGasLimit uint32) error Owner(opts *bind.CallOpts) (common.Address, error) @@ -3682,8 +3472,6 @@ type FunctionsRouterInterface interface { TypeAndVersion(opts *bind.CallOpts) (string, error) - Version(opts *bind.CallOpts) (uint16, uint16, uint16, error) - AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) AcceptSubscriptionOwnerTransfer(opts *bind.TransactOpts, subscriptionId uint64) (*types.Transaction, error) @@ -3694,7 +3482,9 @@ type FunctionsRouterInterface interface { CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) - Fulfill(opts *bind.TransactOpts, requestId [32]byte, response []byte, err []byte, juelsPerGas *big.Int, costWithoutFulfillment *big.Int, transmitter common.Address) (*types.Transaction, error) + CreateSubscriptionWithConsumer(opts *bind.TransactOpts, consumer common.Address) (*types.Transaction, error) + + Fulfill(opts *bind.TransactOpts, response []byte, err []byte, juelsPerGas *big.Int, costWithoutCallback *big.Int, transmitter common.Address, commitment FunctionsResponseCommitment) (*types.Transaction, error) OnTokenTransfer(opts *bind.TransactOpts, arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) @@ -3702,45 +3492,35 @@ type FunctionsRouterInterface interface { OwnerCancelSubscription(opts *bind.TransactOpts, subscriptionId uint64) (*types.Transaction, error) - ProposeConfigUpdate(opts *bind.TransactOpts, id [32]byte, config []byte) (*types.Transaction, error) + OwnerWithdraw(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) + + Pause(opts *bind.TransactOpts) (*types.Transaction, error) ProposeContractsUpdate(opts *bind.TransactOpts, proposedContractSetIds [][32]byte, proposedContractSetAddresses []common.Address) (*types.Transaction, error) - ProposeTimelockBlocks(opts *bind.TransactOpts, blocks uint16) (*types.Transaction, error) + ProposeSubscriptionOwnerTransfer(opts *bind.TransactOpts, subscriptionId uint64, newOwner common.Address) (*types.Transaction, error) RecoverFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) RemoveConsumer(opts *bind.TransactOpts, subscriptionId uint64, consumer common.Address) (*types.Transaction, error) - RequestSubscriptionOwnerTransfer(opts *bind.TransactOpts, subscriptionId uint64, newOwner common.Address) (*types.Transaction, error) - SendRequest(opts *bind.TransactOpts, subscriptionId uint64, data []byte, dataVersion uint16, callbackGasLimit uint32, donId [32]byte) (*types.Transaction, error) - TimeoutRequests(opts *bind.TransactOpts, requestIdsToTimeout [][32]byte) (*types.Transaction, error) - - TogglePaused(opts *bind.TransactOpts) (*types.Transaction, error) - - TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) - - UpdateConfig(opts *bind.TransactOpts, id [32]byte) (*types.Transaction, error) - - UpdateContracts(opts *bind.TransactOpts) (*types.Transaction, error) - - UpdateTimelockBlocks(opts *bind.TransactOpts) (*types.Transaction, error) + SendRequestToProposed(opts *bind.TransactOpts, subscriptionId uint64, data []byte, dataVersion uint16, callbackGasLimit uint32, donId [32]byte) (*types.Transaction, error) - ValidateProposedContracts(opts *bind.TransactOpts, id [32]byte, data []byte) (*types.Transaction, error) + SetAllowListId(opts *bind.TransactOpts, allowListId [32]byte) (*types.Transaction, error) - FilterConfigProposed(opts *bind.FilterOpts) (*FunctionsRouterConfigProposedIterator, error) + SetFlags(opts *bind.TransactOpts, subscriptionId uint64, flags [32]byte) (*types.Transaction, error) - WatchConfigProposed(opts *bind.WatchOpts, sink chan<- *FunctionsRouterConfigProposed) (event.Subscription, error) + TimeoutRequests(opts *bind.TransactOpts, requestsToTimeoutByCommitment []FunctionsResponseCommitment) (*types.Transaction, error) - ParseConfigProposed(log types.Log) (*FunctionsRouterConfigProposed, error) + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) - FilterConfigSet(opts *bind.FilterOpts) (*FunctionsRouterConfigSetIterator, error) + Unpause(opts *bind.TransactOpts) (*types.Transaction, error) - WatchConfigSet(opts *bind.WatchOpts, sink chan<- *FunctionsRouterConfigSet) (event.Subscription, error) + UpdateConfig(opts *bind.TransactOpts, config FunctionsRouterConfig) (*types.Transaction, error) - ParseConfigSet(log types.Log) (*FunctionsRouterConfigSet, error) + UpdateContracts(opts *bind.TransactOpts) (*types.Transaction, error) FilterConfigUpdated(opts *bind.FilterOpts) (*FunctionsRouterConfigUpdatedIterator, error) @@ -3784,11 +3564,17 @@ type FunctionsRouterInterface interface { ParsePaused(log types.Log) (*FunctionsRouterPaused, error) - FilterRequestEnd(opts *bind.FilterOpts, requestId [][32]byte, subscriptionId []uint64) (*FunctionsRouterRequestEndIterator, error) + FilterRequestNotProcessed(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsRouterRequestNotProcessedIterator, error) - WatchRequestEnd(opts *bind.WatchOpts, sink chan<- *FunctionsRouterRequestEnd, requestId [][32]byte, subscriptionId []uint64) (event.Subscription, error) + WatchRequestNotProcessed(opts *bind.WatchOpts, sink chan<- *FunctionsRouterRequestNotProcessed, requestId [][32]byte) (event.Subscription, error) - ParseRequestEnd(log types.Log) (*FunctionsRouterRequestEnd, error) + ParseRequestNotProcessed(log types.Log) (*FunctionsRouterRequestNotProcessed, error) + + FilterRequestProcessed(opts *bind.FilterOpts, requestId [][32]byte, subscriptionId []uint64) (*FunctionsRouterRequestProcessedIterator, error) + + WatchRequestProcessed(opts *bind.WatchOpts, sink chan<- *FunctionsRouterRequestProcessed, requestId [][32]byte, subscriptionId []uint64) (event.Subscription, error) + + ParseRequestProcessed(log types.Log) (*FunctionsRouterRequestProcessed, error) FilterRequestStart(opts *bind.FilterOpts, requestId [][32]byte, donId [][32]byte, subscriptionId []uint64) (*FunctionsRouterRequestStartIterator, error) @@ -3796,6 +3582,12 @@ type FunctionsRouterInterface interface { ParseRequestStart(log types.Log) (*FunctionsRouterRequestStart, error) + FilterRequestTimedOut(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsRouterRequestTimedOutIterator, error) + + WatchRequestTimedOut(opts *bind.WatchOpts, sink chan<- *FunctionsRouterRequestTimedOut, requestId [][32]byte) (event.Subscription, error) + + ParseRequestTimedOut(log types.Log) (*FunctionsRouterRequestTimedOut, error) + FilterSubscriptionCanceled(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRouterSubscriptionCanceledIterator, error) WatchSubscriptionCanceled(opts *bind.WatchOpts, sink chan<- *FunctionsRouterSubscriptionCanceled, subscriptionId []uint64) (event.Subscription, error) @@ -3838,18 +3630,6 @@ type FunctionsRouterInterface interface { ParseSubscriptionOwnerTransferred(log types.Log) (*FunctionsRouterSubscriptionOwnerTransferred, error) - FilterTimeLockProposed(opts *bind.FilterOpts) (*FunctionsRouterTimeLockProposedIterator, error) - - WatchTimeLockProposed(opts *bind.WatchOpts, sink chan<- *FunctionsRouterTimeLockProposed) (event.Subscription, error) - - ParseTimeLockProposed(log types.Log) (*FunctionsRouterTimeLockProposed, error) - - FilterTimeLockUpdated(opts *bind.FilterOpts) (*FunctionsRouterTimeLockUpdatedIterator, error) - - WatchTimeLockUpdated(opts *bind.WatchOpts, sink chan<- *FunctionsRouterTimeLockUpdated) (event.Subscription, error) - - ParseTimeLockUpdated(log types.Log) (*FunctionsRouterTimeLockUpdated, error) - FilterUnpaused(opts *bind.FilterOpts) (*FunctionsRouterUnpausedIterator, error) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *FunctionsRouterUnpaused) (event.Subscription, error) diff --git a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt index f32c24902fb..0fb2b611b4d 100644 --- a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,10 +1,13 @@ GETH_VERSION: 1.12.0 -functions: ../../../contracts/solc/v0.8.19/functions/1_0_0/Functions.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/Functions.bin 3c972870b0afeb6d73a29ebb182f24956a2cebb127b21c4f867d1ecf19a762db -functions_allow_list: ../../../contracts/solc/v0.8.19/functions/1_0_0/TermsOfServiceAllowList.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/TermsOfServiceAllowList.bin a03725d15d3405d68bec96237a2155435a752c659c2b13b0746003f45e621ded -functions_client: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.bin fcfdcd4c0916533f648e5290768a34382465944b2ffe9465add1d5e81175a415 -functions_client_example: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.bin ea01c8210316c767b4925731a55ee03bfe5cf04f1c4663aa3115bbc36b94d01f -functions_coordinator: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.bin bb2992f4dccff3e9c763c7379991f9dbcfd158ac8f47c9987985f57a56cdd05f -functions_router: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.bin 158fb9e0f9caea329a037f17f0b73f291906c6d9e7e44a774fb17566232785e7 +functions: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRequest.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRequest.bin 3c972870b0afeb6d73a29ebb182f24956a2cebb127b21c4f867d1ecf19a762db +functions_allow_list: ../../../contracts/solc/v0.8.19/functions/1_0_0/TermsOfServiceAllowList.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/TermsOfServiceAllowList.bin b2697ad4dfece903a1d34028826a017fa445eb3cd984006f1734fa9d47836ca0 +functions_billing_registry_events_mock: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsBillingRegistryEventsMock.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsBillingRegistryEventsMock.bin 50deeb883bd9c3729702be335c0388f9d8553bab4be5e26ecacac496a89e2b77 +functions_client: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.bin 2368f537a04489c720a46733f8596c4fc88a31062ecfa966d05f25dd98608aca +functions_client_example: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.bin 25036bdb94a50a81df4222418bf9aa1e0c8540d5834b7e6e639aa63a2a2c8206 +functions_coordinator: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.bin 7b2fb23e2f49121dfe4b096de5e60fe57be0a196c2423a4693293c23c96f9af4 +functions_load_test_client: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.bin 28f2834dea12b3aefa7c696b64ca5272a1ab5cdf33365c9f7fafdc0b7d5669e8 +functions_oracle_events_mock: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracleEventsMock.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracleEventsMock.bin 3ca70f966f8fe751987f0ccb50bebb6aa5be77e4a9f835d1ae99e0e9bfb7d52c +functions_router: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.bin dd1d3527e19d65efe029c4a131ded44dc0ca961e5c4f459743992435431ec478 ocr2dr: ../../../contracts/solc/v0.8.6/functions/0_0_0/Functions.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/Functions.bin d9a794b33f47cc57563d216f7cf3a612309fc3062356a27e30005cf1d59e449d ocr2dr_client: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClient.bin 84aa63f9dbc5c7eac240db699b09e613ca4c6cd56dab10bdc25b02461b717e21 ocr2dr_client_example: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClientExample.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClientExample.bin a978d9b52a5a2da19eef0975979de256e62980a0cfb3084fe6d66a351b4ef534 diff --git a/core/gethwrappers/functions/go_generate.go b/core/gethwrappers/functions/go_generate.go index 54d5ea4fe66..bc0fcd2a0ce 100644 --- a/core/gethwrappers/functions/go_generate.go +++ b/core/gethwrappers/functions/go_generate.go @@ -12,9 +12,10 @@ package gethwrappers //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsBillingRegistryWithInit.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsBillingRegistryWithInit.bin OCR2DRRegistry ocr2dr_registry // Version 1 (Mainnet Preview) -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/1_0_0/Functions.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/Functions.bin Functions functions +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRequest.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRequest.bin Functions functions //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.bin FunctionsClient functions_client //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.bin FunctionsClientExample functions_client_example +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.bin FunctionsLoadTestClient functions_load_test_client //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.bin FunctionsCoordinator functions_coordinator //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.bin FunctionsRouter functions_router //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/1_0_0/TermsOfServiceAllowList.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/TermsOfServiceAllowList.bin TermsOfServiceAllowList functions_allow_list diff --git a/core/gethwrappers/generated/automation_forwarder_logic/automation_forwarder_logic.go b/core/gethwrappers/generated/automation_forwarder_logic/automation_forwarder_logic.go new file mode 100644 index 00000000000..b26f5e5692c --- /dev/null +++ b/core/gethwrappers/generated/automation_forwarder_logic/automation_forwarder_logic.go @@ -0,0 +1,240 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package automation_forwarder_logic + +import ( + "errors" + "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" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var AutomationForwarderLogicMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"getRegistry\",\"outputs\":[{\"internalType\":\"contractIAutomationRegistryConsumer\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRegistry\",\"type\":\"address\"}],\"name\":\"updateRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b506101f6806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063181f5a77146100465780631a5da6c8146100985780635ab1bd53146100ad575b600080fd5b6100826040518060400160405280601981526020017f4175746f6d6174696f6e466f7277617264657220312e302e300000000000000081525081565b60405161008f9190610140565b60405180910390f35b6100ab6100a63660046101ac565b6100d5565b005b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161008f565b60005473ffffffffffffffffffffffffffffffffffffffff1633146100f957600080fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600060208083528351808285015260005b8181101561016d57858101830151858201604001528201610151565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b6000602082840312156101be57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146101e257600080fd5b939250505056fea164736f6c6343000810000a", +} + +var AutomationForwarderLogicABI = AutomationForwarderLogicMetaData.ABI + +var AutomationForwarderLogicBin = AutomationForwarderLogicMetaData.Bin + +func DeployAutomationForwarderLogic(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *AutomationForwarderLogic, error) { + parsed, err := AutomationForwarderLogicMetaData.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(AutomationForwarderLogicBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &AutomationForwarderLogic{AutomationForwarderLogicCaller: AutomationForwarderLogicCaller{contract: contract}, AutomationForwarderLogicTransactor: AutomationForwarderLogicTransactor{contract: contract}, AutomationForwarderLogicFilterer: AutomationForwarderLogicFilterer{contract: contract}}, nil +} + +type AutomationForwarderLogic struct { + address common.Address + abi abi.ABI + AutomationForwarderLogicCaller + AutomationForwarderLogicTransactor + AutomationForwarderLogicFilterer +} + +type AutomationForwarderLogicCaller struct { + contract *bind.BoundContract +} + +type AutomationForwarderLogicTransactor struct { + contract *bind.BoundContract +} + +type AutomationForwarderLogicFilterer struct { + contract *bind.BoundContract +} + +type AutomationForwarderLogicSession struct { + Contract *AutomationForwarderLogic + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type AutomationForwarderLogicCallerSession struct { + Contract *AutomationForwarderLogicCaller + CallOpts bind.CallOpts +} + +type AutomationForwarderLogicTransactorSession struct { + Contract *AutomationForwarderLogicTransactor + TransactOpts bind.TransactOpts +} + +type AutomationForwarderLogicRaw struct { + Contract *AutomationForwarderLogic +} + +type AutomationForwarderLogicCallerRaw struct { + Contract *AutomationForwarderLogicCaller +} + +type AutomationForwarderLogicTransactorRaw struct { + Contract *AutomationForwarderLogicTransactor +} + +func NewAutomationForwarderLogic(address common.Address, backend bind.ContractBackend) (*AutomationForwarderLogic, error) { + abi, err := abi.JSON(strings.NewReader(AutomationForwarderLogicABI)) + if err != nil { + return nil, err + } + contract, err := bindAutomationForwarderLogic(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AutomationForwarderLogic{address: address, abi: abi, AutomationForwarderLogicCaller: AutomationForwarderLogicCaller{contract: contract}, AutomationForwarderLogicTransactor: AutomationForwarderLogicTransactor{contract: contract}, AutomationForwarderLogicFilterer: AutomationForwarderLogicFilterer{contract: contract}}, nil +} + +func NewAutomationForwarderLogicCaller(address common.Address, caller bind.ContractCaller) (*AutomationForwarderLogicCaller, error) { + contract, err := bindAutomationForwarderLogic(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AutomationForwarderLogicCaller{contract: contract}, nil +} + +func NewAutomationForwarderLogicTransactor(address common.Address, transactor bind.ContractTransactor) (*AutomationForwarderLogicTransactor, error) { + contract, err := bindAutomationForwarderLogic(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AutomationForwarderLogicTransactor{contract: contract}, nil +} + +func NewAutomationForwarderLogicFilterer(address common.Address, filterer bind.ContractFilterer) (*AutomationForwarderLogicFilterer, error) { + contract, err := bindAutomationForwarderLogic(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AutomationForwarderLogicFilterer{contract: contract}, nil +} + +func bindAutomationForwarderLogic(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := AutomationForwarderLogicMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_AutomationForwarderLogic *AutomationForwarderLogicRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AutomationForwarderLogic.Contract.AutomationForwarderLogicCaller.contract.Call(opts, result, method, params...) +} + +func (_AutomationForwarderLogic *AutomationForwarderLogicRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationForwarderLogic.Contract.AutomationForwarderLogicTransactor.contract.Transfer(opts) +} + +func (_AutomationForwarderLogic *AutomationForwarderLogicRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AutomationForwarderLogic.Contract.AutomationForwarderLogicTransactor.contract.Transact(opts, method, params...) +} + +func (_AutomationForwarderLogic *AutomationForwarderLogicCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AutomationForwarderLogic.Contract.contract.Call(opts, result, method, params...) +} + +func (_AutomationForwarderLogic *AutomationForwarderLogicTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationForwarderLogic.Contract.contract.Transfer(opts) +} + +func (_AutomationForwarderLogic *AutomationForwarderLogicTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AutomationForwarderLogic.Contract.contract.Transact(opts, method, params...) +} + +func (_AutomationForwarderLogic *AutomationForwarderLogicCaller) GetRegistry(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AutomationForwarderLogic.contract.Call(opts, &out, "getRegistry") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_AutomationForwarderLogic *AutomationForwarderLogicSession) GetRegistry() (common.Address, error) { + return _AutomationForwarderLogic.Contract.GetRegistry(&_AutomationForwarderLogic.CallOpts) +} + +func (_AutomationForwarderLogic *AutomationForwarderLogicCallerSession) GetRegistry() (common.Address, error) { + return _AutomationForwarderLogic.Contract.GetRegistry(&_AutomationForwarderLogic.CallOpts) +} + +func (_AutomationForwarderLogic *AutomationForwarderLogicCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _AutomationForwarderLogic.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_AutomationForwarderLogic *AutomationForwarderLogicSession) TypeAndVersion() (string, error) { + return _AutomationForwarderLogic.Contract.TypeAndVersion(&_AutomationForwarderLogic.CallOpts) +} + +func (_AutomationForwarderLogic *AutomationForwarderLogicCallerSession) TypeAndVersion() (string, error) { + return _AutomationForwarderLogic.Contract.TypeAndVersion(&_AutomationForwarderLogic.CallOpts) +} + +func (_AutomationForwarderLogic *AutomationForwarderLogicTransactor) UpdateRegistry(opts *bind.TransactOpts, newRegistry common.Address) (*types.Transaction, error) { + return _AutomationForwarderLogic.contract.Transact(opts, "updateRegistry", newRegistry) +} + +func (_AutomationForwarderLogic *AutomationForwarderLogicSession) UpdateRegistry(newRegistry common.Address) (*types.Transaction, error) { + return _AutomationForwarderLogic.Contract.UpdateRegistry(&_AutomationForwarderLogic.TransactOpts, newRegistry) +} + +func (_AutomationForwarderLogic *AutomationForwarderLogicTransactorSession) UpdateRegistry(newRegistry common.Address) (*types.Transaction, error) { + return _AutomationForwarderLogic.Contract.UpdateRegistry(&_AutomationForwarderLogic.TransactOpts, newRegistry) +} + +func (_AutomationForwarderLogic *AutomationForwarderLogic) Address() common.Address { + return _AutomationForwarderLogic.address +} + +type AutomationForwarderLogicInterface interface { + GetRegistry(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + UpdateRegistry(opts *bind.TransactOpts, newRegistry common.Address) (*types.Transaction, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/automation_registrar_wrapper2_1/automation_registrar_wrapper2_1.go b/core/gethwrappers/generated/automation_registrar_wrapper2_1/automation_registrar_wrapper2_1.go new file mode 100644 index 00000000000..d2b8054436a --- /dev/null +++ b/core/gethwrappers/generated/automation_registrar_wrapper2_1/automation_registrar_wrapper2_1.go @@ -0,0 +1,1685 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package automation_registrar_wrapper2_1 + +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 AutomationRegistrar21InitialTriggerConfig struct { + TriggerType uint8 + AutoApproveType uint8 + AutoApproveMaxAllowed uint32 +} + +type AutomationRegistrar21RegistrationParams struct { + Name string + EncryptedEmail []byte + UpkeepContract common.Address + GasLimit uint32 + AdminAddress common.Address + TriggerType uint8 + CheckData []byte + TriggerConfig []byte + OffchainConfig []byte + Amount *big.Int +} + +type AutomationRegistrar21TriggerRegistrationStorage struct { + AutoApproveType uint8 + AutoApproveMaxAllowed uint32 + ApprovedCount uint32 +} + +var AutomationRegistrarMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"LINKAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keeperRegistry\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"minLINKJuels\",\"type\":\"uint96\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"enumAutomationRegistrar2_1.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"}],\"internalType\":\"structAutomationRegistrar2_1.InitialTriggerConfig[]\",\"name\":\"triggerConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AmountMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FunctionNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HashMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientPayment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAdminAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"LinkTransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistrationRequestFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RequestNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SenderMismatch\",\"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\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"keeperRegistry\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"minLINKJuels\",\"type\":\"uint96\"}],\"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_1.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"}],\"name\":\"TriggerConfigSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"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\":[],\"name\":\"getConfig\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"keeperRegistry\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minLINKJuels\",\"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\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"}],\"name\":\"getTriggerRegistrationDetails\",\"outputs\":[{\"components\":[{\"internalType\":\"enumAutomationRegistrar2_1.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"approvedCount\",\"type\":\"uint32\"}],\"internalType\":\"structAutomationRegistrar2_1.TriggerRegistrationStorage\",\"name\":\"\",\"type\":\"tuple\"}],\"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\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedEmail\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedEmail\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"internalType\":\"structAutomationRegistrar2_1.RegistrationParams\",\"name\":\"requestParams\",\"type\":\"tuple\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"setAutoApproveAllowedSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"keeperRegistry\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"minLINKJuels\",\"type\":\"uint96\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"enumAutomationRegistrar2_1.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: "0x60a06040523480156200001157600080fd5b5060405162002d8238038062002d8283398101604081905262000034916200043b565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be816200017a565b5050506001600160a01b038416608052620000da838362000225565b60005b81518110156200016f576200015a82828151811062000100576200010062000598565b60200260200101516000015183838151811062000121576200012162000598565b60200260200101516020015184848151811062000142576200014262000598565b6020026020010151604001516200029e60201b60201c565b806200016681620005ae565b915050620000dd565b50505050506200062f565b336001600160a01b03821603620001d45760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200022f6200034c565b6040805180820182526001600160a01b0384168082526001600160601b0384166020928301819052600160a01b810282176004558351918252918101919091527f39ce5d867555f0b0183e358fce5b158e7ca4fecd7c01cb7e0e19f1e23285838a910160405180910390a15050565b620002a86200034c565b60ff83166000908152600360205260409020805483919060ff19166001836002811115620002da57620002da620005d6565b021790555060ff831660009081526003602052604090819020805464ffffffff00191661010063ffffffff851602179055517f830a6d06a4e2caac67eba04323de22bdb04f032dd8b3d6a0c52b503d9a7036a3906200033f90859085908590620005ec565b60405180910390a1505050565b6000546001600160a01b03163314620003a85760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b80516001600160a01b0381168114620003c257600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b0381118282101715620004025762000402620003c7565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620004335762000433620003c7565b604052919050565b600080600080608085870312156200045257600080fd5b6200045d85620003aa565b935060206200046e818701620003aa565b604087810151919550906001600160601b03811681146200048e57600080fd5b606088810151919550906001600160401b0380821115620004ae57600080fd5b818a0191508a601f830112620004c357600080fd5b815181811115620004d857620004d8620003c7565b620004e8868260051b0162000408565b818152868101925090840283018601908c8211156200050657600080fd5b928601925b81841015620005875784848e031215620005255760008081fd5b6200052f620003dd565b845160ff81168114620005425760008081fd5b81528488015160038110620005575760008081fd5b818901528487015163ffffffff81168114620005735760008081fd5b81880152835292840192918601916200050b565b999c989b5096995050505050505050565b634e487b7160e01b600052603260045260246000fd5b600060018201620005cf57634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052602160045260246000fd5b60ff8416815260608101600384106200061557634e487b7160e01b600052602160045260246000fd5b83602083015263ffffffff83166040830152949350505050565b6080516127146200066e60003960008181610177015281816105d601528181610887015281816109bd01528181610f0e015261171b01526127146000f3fe608060405234801561001057600080fd5b506004361061011b5760003560e01c8063856853e6116100b2578063b5ff5b4111610081578063c4d252f511610066578063c4d252f5146103e3578063e8d4070d146103f6578063f2fde38b1461040957600080fd5b8063b5ff5b4114610369578063c3f909d41461037c57600080fd5b8063856853e61461027857806388b12d551461028b5780638da5cb5b14610338578063a4c0ed361461035657600080fd5b80633f678e11116100ee5780633f678e11146101f35780636c4cdfc31461021457806379ba5097146102275780637e776f7f1461022f57600080fd5b8063181f5a77146101205780631b6b6d2314610172578063212d0884146101be578063367b9b4f146101de575b600080fd5b61015c6040518060400160405280601981526020017f4175746f6d6174696f6e52656769737472617220322e312e300000000000000081525081565b6040516101699190611a74565b60405180910390f35b6101997f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610169565b6101d16101cc366004611aa4565b61041c565b6040516101699190611b29565b6101f16101ec366004611b9d565b6104a9565b005b610206610201366004611bd6565b61053b565b604051908152602001610169565b6101f1610222366004611c2e565b6106d3565b6101f161076d565b61026861023d366004611c63565b73ffffffffffffffffffffffffffffffffffffffff1660009081526005602052604090205460ff1690565b6040519015158152602001610169565b6101f1610286366004611de1565b61086f565b6102ff610299366004611f40565b60009081526002602090815260409182902082518084019093525473ffffffffffffffffffffffffffffffffffffffff8116808452740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff169290910182905291565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526bffffffffffffffffffffffff909116602083015201610169565b60005473ffffffffffffffffffffffffffffffffffffffff16610199565b6101f1610364366004611f59565b6109a5565b6101f1610377366004611fb5565b610ce3565b60408051808201825260045473ffffffffffffffffffffffffffffffffffffffff8116808352740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16602092830181905283519182529181019190915201610169565b6101f16103f1366004611f40565b610dc2565b6101f1610404366004611ffe565b61104c565b6101f1610417366004611c63565b6112d9565b60408051606080820183526000808352602080840182905283850182905260ff86811683526003909152908490208451928301909452835492939192839116600281111561046c5761046c611abf565b600281111561047d5761047d611abf565b8152905463ffffffff610100820481166020840152650100000000009091041660409091015292915050565b6104b16112ed565b73ffffffffffffffffffffffffffffffffffffffff821660008181526005602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915591519182527f20c6237dac83526a849285a9f79d08a483291bdd3a056a0ef9ae94ecee1ad356910160405180910390a25050565b6004546000907401000000000000000000000000000000000000000090046bffffffffffffffffffffffff1661057961014084016101208501612109565b6bffffffffffffffffffffffff1610156105bf576040517fcd1c886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166323b872dd333061060f61014087016101208801612109565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815273ffffffffffffffffffffffffffffffffffffffff93841660048201529290911660248301526bffffffffffffffffffffffff1660448201526064016020604051808303816000875af1158015610696573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ba9190612124565b506106cd6106c783612141565b33611370565b92915050565b6106db6112ed565b60408051808201825273ffffffffffffffffffffffffffffffffffffffff84168082526bffffffffffffffffffffffff8416602092830181905274010000000000000000000000000000000000000000810282176004558351918252918101919091527f39ce5d867555f0b0183e358fce5b158e7ca4fecd7c01cb7e0e19f1e23285838a910160405180910390a15050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146107f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146108de576040517f018d10be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109966040518061014001604052808e81526020018d8d8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525073ffffffffffffffffffffffffffffffffffffffff808d16602083015263ffffffff8c1660408301528a16606082015260ff8916608082015260a0810188905260c0810187905260e081018690526bffffffffffffffffffffffff85166101009091015282611370565b50505050505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610a14576040517f018d10be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81818080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050505060208101517fffffffff0000000000000000000000000000000000000000000000000000000081167f856853e60000000000000000000000000000000000000000000000000000000014610aca576040517fe3d6792100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8484846000610adc8260048186612276565b810190610ae991906122a0565b509950505050505050505050806bffffffffffffffffffffffff168414610b3c576040517f55e97b0d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8988886000610b4e8260048186612276565b810190610b5b91906122a0565b9a50505050505050505050508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610bcc576040517ff8c5638e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004547401000000000000000000000000000000000000000090046bffffffffffffffffffffffff168d1015610c2e576040517fcd1c886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60003073ffffffffffffffffffffffffffffffffffffffff168d8d604051610c579291906123dd565b600060405180830381855af49150503d8060008114610c92576040519150601f19603f3d011682016040523d82523d6000602084013e610c97565b606091505b5050905080610cd2576040517f649bf81000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050505050565b610ceb6112ed565b60ff8316600090815260036020526040902080548391907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836002811115610d3857610d38611abf565b021790555060ff83166000908152600360205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010063ffffffff851602179055517f830a6d06a4e2caac67eba04323de22bdb04f032dd8b3d6a0c52b503d9a7036a390610db5908590859085906123ed565b60405180910390a1505050565b60008181526002602090815260409182902082518084019093525473ffffffffffffffffffffffffffffffffffffffff8116808452740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff1691830191909152331480610e49575060005473ffffffffffffffffffffffffffffffffffffffff1633145b610e7f576040517f61685c2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805173ffffffffffffffffffffffffffffffffffffffff16610ecd576040517f4b13b31e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260026020908152604080832083905583519184015190517fa9059cbb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169263a9059cbb92610f859260040173ffffffffffffffffffffffffffffffffffffffff9290921682526bffffffffffffffffffffffff16602082015260400190565b6020604051808303816000875af1158015610fa4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc89190612124565b90508061101c5781516040517fc2e4dce800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016107ea565b60405183907f3663fb28ebc87645eb972c9dad8521bf665c623f287e79f1c56f1eb374b82a2290600090a2505050565b6110546112ed565b60008181526002602090815260409182902082518084019093525473ffffffffffffffffffffffffffffffffffffffff8116808452740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16918301919091526110ed576040517f4b13b31e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008b8b8b8b8b8b8b8b8b60405160200161111099989796959493929190612461565b604051602081830303815290604052805190602001209050808314611161576040517f3f4d605300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026000848152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000820160146101000a8154906bffffffffffffffffffffffff021916905550506112c96040518061014001604052808f81526020016040518060200160405280600081525081526020018e73ffffffffffffffffffffffffffffffffffffffff1681526020018d63ffffffff1681526020018c73ffffffffffffffffffffffffffffffffffffffff1681526020018b60ff1681526020018a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060208082018a905260408051601f8a0183900483028101830182528981529201919089908990819084018382808284376000920191909152505050908252506020858101516bffffffffffffffffffffffff1691015282611647565b5050505050505050505050505050565b6112e16112ed565b6112ea81611876565b50565b60005473ffffffffffffffffffffffffffffffffffffffff16331461136e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107ea565b565b608082015160009073ffffffffffffffffffffffffffffffffffffffff166113c4576040517f05bb467c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008360400151846060015185608001518660a001518760c001518860e0015189610100015160405160200161140097969594939291906124e7565b604051602081830303815290604052805190602001209050836040015173ffffffffffffffffffffffffffffffffffffffff16817f7684390ebb103102f7f48c71439c2408713f8d437782a6fab2756acc0e42c1b786600001518760200151886060015189608001518a60a001518b60e001518c61010001518d60c001518e610120015160405161149999989796959493929190612569565b60405180910390a360a084015160ff9081166000908152600360205260408082208151606081019092528054929361151c9383911660028111156114df576114df611abf565b60028111156114f0576114f0611abf565b8152905463ffffffff61010082048116602084015265010000000000909104166040909101528561196b565b156115845760a085015160ff166000908152600360205260409020805465010000000000900463ffffffff1690600561155483612653565b91906101000a81548163ffffffff021916908363ffffffff1602179055505061157d8583611647565b905061163f565b61012085015160008381526002602052604081205490916115ca917401000000000000000000000000000000000000000090046bffffffffffffffffffffffff16612676565b604080518082018252608089015173ffffffffffffffffffffffffffffffffffffffff90811682526bffffffffffffffffffffffff9384166020808401918252600089815260029091529390932091519251909316740100000000000000000000000000000000000000000291909216179055505b949350505050565b600480546040808501516060860151608087015160a088015160c089015160e08a01516101008b015196517f28f32f3800000000000000000000000000000000000000000000000000000000815260009973ffffffffffffffffffffffffffffffffffffffff909916988a988a986328f32f38986116d29891979096919590949193909291016124e7565b6020604051808303816000875af11580156116f1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171591906126a2565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634000aea0848861012001518560405160200161176f91815260200190565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161179c939291906126bb565b6020604051808303816000875af11580156117bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117df9190612124565b905080611830576040517fc2e4dce800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024016107ea565b81857fb9a292fb7e3edd920cd2d2829a3615a640c43fd7de0a0820aa0668feb4c37d4b88600001516040516118659190611a74565b60405180910390a350949350505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036118f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107ea565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000808351600281111561198157611981611abf565b0361198e575060006106cd565b6001835160028111156119a3576119a3611abf565b1480156119d6575073ffffffffffffffffffffffffffffffffffffffff821660009081526005602052604090205460ff16155b156119e3575060006106cd565b826020015163ffffffff16836040015163ffffffff161015611a07575060016106cd565b50600092915050565b6000815180845260005b81811015611a3657602081850181015186830182015201611a1a565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611a876020830184611a10565b9392505050565b803560ff81168114611a9f57600080fd5b919050565b600060208284031215611ab657600080fd5b611a8782611a8e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110611b25577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b6000606082019050611b3c828451611aee565b602083015163ffffffff8082166020850152806040860151166040850152505092915050565b73ffffffffffffffffffffffffffffffffffffffff811681146112ea57600080fd5b8035611a9f81611b62565b80151581146112ea57600080fd5b60008060408385031215611bb057600080fd5b8235611bbb81611b62565b91506020830135611bcb81611b8f565b809150509250929050565b600060208284031215611be857600080fd5b813567ffffffffffffffff811115611bff57600080fd5b82016101408185031215611a8757600080fd5b80356bffffffffffffffffffffffff81168114611a9f57600080fd5b60008060408385031215611c4157600080fd5b8235611c4c81611b62565b9150611c5a60208401611c12565b90509250929050565b600060208284031215611c7557600080fd5b8135611a8781611b62565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611cd357611cd3611c80565b60405290565b600082601f830112611cea57600080fd5b813567ffffffffffffffff80821115611d0557611d05611c80565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715611d4b57611d4b611c80565b81604052838152866020858801011115611d6457600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008083601f840112611d9657600080fd5b50813567ffffffffffffffff811115611dae57600080fd5b602083019150836020828501011115611dc657600080fd5b9250929050565b803563ffffffff81168114611a9f57600080fd5b6000806000806000806000806000806000806101608d8f031215611e0457600080fd5b67ffffffffffffffff8d351115611e1a57600080fd5b611e278e8e358f01611cd9565b9b5067ffffffffffffffff60208e01351115611e4257600080fd5b611e528e60208f01358f01611d84565b909b509950611e6360408e01611b84565b9850611e7160608e01611dcd565b9750611e7f60808e01611b84565b9650611e8d60a08e01611a8e565b955067ffffffffffffffff60c08e01351115611ea857600080fd5b611eb88e60c08f01358f01611cd9565b945067ffffffffffffffff60e08e01351115611ed357600080fd5b611ee38e60e08f01358f01611cd9565b935067ffffffffffffffff6101008e01351115611eff57600080fd5b611f108e6101008f01358f01611cd9565b9250611f1f6101208e01611c12565b9150611f2e6101408e01611b84565b90509295989b509295989b509295989b565b600060208284031215611f5257600080fd5b5035919050565b60008060008060608587031215611f6f57600080fd5b8435611f7a81611b62565b935060208501359250604085013567ffffffffffffffff811115611f9d57600080fd5b611fa987828801611d84565b95989497509550505050565b600080600060608486031215611fca57600080fd5b611fd384611a8e565b9250602084013560038110611fe757600080fd5b9150611ff560408501611dcd565b90509250925092565b60008060008060008060008060008060006101208c8e03121561202057600080fd5b67ffffffffffffffff808d35111561203757600080fd5b6120448e8e358f01611cd9565b9b5061205260208e01611b84565b9a5061206060408e01611dcd565b995061206e60608e01611b84565b985061207c60808e01611a8e565b97508060a08e0135111561208f57600080fd5b61209f8e60a08f01358f01611d84565b909750955060c08d01358110156120b557600080fd5b6120c58e60c08f01358f01611cd9565b94508060e08e013511156120d857600080fd5b506120e98d60e08e01358e01611d84565b81945080935050506101008c013590509295989b509295989b9093969950565b60006020828403121561211b57600080fd5b611a8782611c12565b60006020828403121561213657600080fd5b8151611a8781611b8f565b6000610140823603121561215457600080fd5b61215c611caf565b823567ffffffffffffffff8082111561217457600080fd5b61218036838701611cd9565b8352602085013591508082111561219657600080fd5b6121a236838701611cd9565b60208401526121b360408601611b84565b60408401526121c460608601611dcd565b60608401526121d560808601611b84565b60808401526121e660a08601611a8e565b60a084015260c08501359150808211156121ff57600080fd5b61220b36838701611cd9565b60c084015260e085013591508082111561222457600080fd5b61223036838701611cd9565b60e08401526101009150818501358181111561224b57600080fd5b61225736828801611cd9565b8385015250505061012061226c818501611c12565b9082015292915050565b6000808585111561228657600080fd5b8386111561229357600080fd5b5050820193919092039150565b60008060008060008060008060008060006101608c8e0312156122c257600080fd5b67ffffffffffffffff808d3511156122d957600080fd5b6122e68e8e358f01611cd9565b9b508060208e013511156122f957600080fd5b6123098e60208f01358f01611cd9565b9a5061231760408e01611b84565b995061232560608e01611dcd565b985061233360808e01611b84565b975061234160a08e01611a8e565b96508060c08e0135111561235457600080fd5b6123648e60c08f01358f01611cd9565b95508060e08e0135111561237757600080fd5b6123878e60e08f01358f01611cd9565b9450806101008e0135111561239b57600080fd5b506123ad8d6101008e01358e01611cd9565b92506123bc6101208d01611c12565b91506123cb6101408d01611b84565b90509295989b509295989b9093969950565b8183823760009101908152919050565b60ff84168152606081016124046020830185611aee565b63ffffffff83166040830152949350505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b600073ffffffffffffffffffffffffffffffffffffffff808c16835263ffffffff8b166020840152808a1660408401525060ff8816606083015260e060808301526124b060e083018789612418565b82810360a08401526124c28187611a10565b905082810360c08401526124d7818587612418565b9c9b505050505050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835263ffffffff8916602084015280881660408401525060ff8616606083015260e0608083015261253560e0830186611a10565b82810360a08401526125478186611a10565b905082810360c084015261255b8185611a10565b9a9950505050505050505050565b600061012080835261257d8184018d611a10565b90508281036020840152612591818c611a10565b905063ffffffff8a16604084015273ffffffffffffffffffffffffffffffffffffffff8916606084015260ff8816608084015282810360a08401526125d68188611a10565b905082810360c08401526125ea8187611a10565b905082810360e08401526125fe8186611a10565b9150506bffffffffffffffffffffffff83166101008301529a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600063ffffffff80831681810361266c5761266c612624565b6001019392505050565b6bffffffffffffffffffffffff81811683821601908082111561269b5761269b612624565b5092915050565b6000602082840312156126b457600080fd5b5051919050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff831660208201526060604082015260006126fe6060830184611a10565b9594505050505056fea164736f6c6343000810000a", +} + +var AutomationRegistrarABI = AutomationRegistrarMetaData.ABI + +var AutomationRegistrarBin = AutomationRegistrarMetaData.Bin + +func DeployAutomationRegistrar(auth *bind.TransactOpts, backend bind.ContractBackend, LINKAddress common.Address, keeperRegistry common.Address, minLINKJuels *big.Int, triggerConfigs []AutomationRegistrar21InitialTriggerConfig) (common.Address, *types.Transaction, *AutomationRegistrar, error) { + parsed, err := AutomationRegistrarMetaData.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(AutomationRegistrarBin), backend, LINKAddress, keeperRegistry, minLINKJuels, triggerConfigs) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &AutomationRegistrar{AutomationRegistrarCaller: AutomationRegistrarCaller{contract: contract}, AutomationRegistrarTransactor: AutomationRegistrarTransactor{contract: contract}, AutomationRegistrarFilterer: AutomationRegistrarFilterer{contract: contract}}, nil +} + +type AutomationRegistrar struct { + address common.Address + abi abi.ABI + AutomationRegistrarCaller + AutomationRegistrarTransactor + AutomationRegistrarFilterer +} + +type AutomationRegistrarCaller struct { + contract *bind.BoundContract +} + +type AutomationRegistrarTransactor struct { + contract *bind.BoundContract +} + +type AutomationRegistrarFilterer struct { + contract *bind.BoundContract +} + +type AutomationRegistrarSession struct { + Contract *AutomationRegistrar + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type AutomationRegistrarCallerSession struct { + Contract *AutomationRegistrarCaller + CallOpts bind.CallOpts +} + +type AutomationRegistrarTransactorSession struct { + Contract *AutomationRegistrarTransactor + TransactOpts bind.TransactOpts +} + +type AutomationRegistrarRaw struct { + Contract *AutomationRegistrar +} + +type AutomationRegistrarCallerRaw struct { + Contract *AutomationRegistrarCaller +} + +type AutomationRegistrarTransactorRaw struct { + Contract *AutomationRegistrarTransactor +} + +func NewAutomationRegistrar(address common.Address, backend bind.ContractBackend) (*AutomationRegistrar, error) { + abi, err := abi.JSON(strings.NewReader(AutomationRegistrarABI)) + if err != nil { + return nil, err + } + contract, err := bindAutomationRegistrar(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AutomationRegistrar{address: address, abi: abi, AutomationRegistrarCaller: AutomationRegistrarCaller{contract: contract}, AutomationRegistrarTransactor: AutomationRegistrarTransactor{contract: contract}, AutomationRegistrarFilterer: AutomationRegistrarFilterer{contract: contract}}, nil +} + +func NewAutomationRegistrarCaller(address common.Address, caller bind.ContractCaller) (*AutomationRegistrarCaller, error) { + contract, err := bindAutomationRegistrar(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AutomationRegistrarCaller{contract: contract}, nil +} + +func NewAutomationRegistrarTransactor(address common.Address, transactor bind.ContractTransactor) (*AutomationRegistrarTransactor, error) { + contract, err := bindAutomationRegistrar(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AutomationRegistrarTransactor{contract: contract}, nil +} + +func NewAutomationRegistrarFilterer(address common.Address, filterer bind.ContractFilterer) (*AutomationRegistrarFilterer, error) { + contract, err := bindAutomationRegistrar(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AutomationRegistrarFilterer{contract: contract}, nil +} + +func bindAutomationRegistrar(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := AutomationRegistrarMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_AutomationRegistrar *AutomationRegistrarRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AutomationRegistrar.Contract.AutomationRegistrarCaller.contract.Call(opts, result, method, params...) +} + +func (_AutomationRegistrar *AutomationRegistrarRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.AutomationRegistrarTransactor.contract.Transfer(opts) +} + +func (_AutomationRegistrar *AutomationRegistrarRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.AutomationRegistrarTransactor.contract.Transact(opts, method, params...) +} + +func (_AutomationRegistrar *AutomationRegistrarCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AutomationRegistrar.Contract.contract.Call(opts, result, method, params...) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.contract.Transfer(opts) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.contract.Transact(opts, method, params...) +} + +func (_AutomationRegistrar *AutomationRegistrarCaller) LINK(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AutomationRegistrar.contract.Call(opts, &out, "LINK") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_AutomationRegistrar *AutomationRegistrarSession) LINK() (common.Address, error) { + return _AutomationRegistrar.Contract.LINK(&_AutomationRegistrar.CallOpts) +} + +func (_AutomationRegistrar *AutomationRegistrarCallerSession) LINK() (common.Address, error) { + return _AutomationRegistrar.Contract.LINK(&_AutomationRegistrar.CallOpts) +} + +func (_AutomationRegistrar *AutomationRegistrarCaller) GetAutoApproveAllowedSender(opts *bind.CallOpts, senderAddress common.Address) (bool, error) { + var out []interface{} + err := _AutomationRegistrar.contract.Call(opts, &out, "getAutoApproveAllowedSender", senderAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_AutomationRegistrar *AutomationRegistrarSession) GetAutoApproveAllowedSender(senderAddress common.Address) (bool, error) { + return _AutomationRegistrar.Contract.GetAutoApproveAllowedSender(&_AutomationRegistrar.CallOpts, senderAddress) +} + +func (_AutomationRegistrar *AutomationRegistrarCallerSession) GetAutoApproveAllowedSender(senderAddress common.Address) (bool, error) { + return _AutomationRegistrar.Contract.GetAutoApproveAllowedSender(&_AutomationRegistrar.CallOpts, senderAddress) +} + +func (_AutomationRegistrar *AutomationRegistrarCaller) GetConfig(opts *bind.CallOpts) (GetConfig, + + error) { + var out []interface{} + err := _AutomationRegistrar.contract.Call(opts, &out, "getConfig") + + outstruct := new(GetConfig) + if err != nil { + return *outstruct, err + } + + outstruct.KeeperRegistry = *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + outstruct.MinLINKJuels = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_AutomationRegistrar *AutomationRegistrarSession) GetConfig() (GetConfig, + + error) { + return _AutomationRegistrar.Contract.GetConfig(&_AutomationRegistrar.CallOpts) +} + +func (_AutomationRegistrar *AutomationRegistrarCallerSession) GetConfig() (GetConfig, + + error) { + return _AutomationRegistrar.Contract.GetConfig(&_AutomationRegistrar.CallOpts) +} + +func (_AutomationRegistrar *AutomationRegistrarCaller) GetPendingRequest(opts *bind.CallOpts, hash [32]byte) (common.Address, *big.Int, error) { + var out []interface{} + err := _AutomationRegistrar.contract.Call(opts, &out, "getPendingRequest", hash) + + if err != nil { + return *new(common.Address), *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return out0, out1, err + +} + +func (_AutomationRegistrar *AutomationRegistrarSession) GetPendingRequest(hash [32]byte) (common.Address, *big.Int, error) { + return _AutomationRegistrar.Contract.GetPendingRequest(&_AutomationRegistrar.CallOpts, hash) +} + +func (_AutomationRegistrar *AutomationRegistrarCallerSession) GetPendingRequest(hash [32]byte) (common.Address, *big.Int, error) { + return _AutomationRegistrar.Contract.GetPendingRequest(&_AutomationRegistrar.CallOpts, hash) +} + +func (_AutomationRegistrar *AutomationRegistrarCaller) GetTriggerRegistrationDetails(opts *bind.CallOpts, triggerType uint8) (AutomationRegistrar21TriggerRegistrationStorage, error) { + var out []interface{} + err := _AutomationRegistrar.contract.Call(opts, &out, "getTriggerRegistrationDetails", triggerType) + + if err != nil { + return *new(AutomationRegistrar21TriggerRegistrationStorage), err + } + + out0 := *abi.ConvertType(out[0], new(AutomationRegistrar21TriggerRegistrationStorage)).(*AutomationRegistrar21TriggerRegistrationStorage) + + return out0, err + +} + +func (_AutomationRegistrar *AutomationRegistrarSession) GetTriggerRegistrationDetails(triggerType uint8) (AutomationRegistrar21TriggerRegistrationStorage, error) { + return _AutomationRegistrar.Contract.GetTriggerRegistrationDetails(&_AutomationRegistrar.CallOpts, triggerType) +} + +func (_AutomationRegistrar *AutomationRegistrarCallerSession) GetTriggerRegistrationDetails(triggerType uint8) (AutomationRegistrar21TriggerRegistrationStorage, error) { + return _AutomationRegistrar.Contract.GetTriggerRegistrationDetails(&_AutomationRegistrar.CallOpts, triggerType) +} + +func (_AutomationRegistrar *AutomationRegistrarCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AutomationRegistrar.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 (_AutomationRegistrar *AutomationRegistrarSession) Owner() (common.Address, error) { + return _AutomationRegistrar.Contract.Owner(&_AutomationRegistrar.CallOpts) +} + +func (_AutomationRegistrar *AutomationRegistrarCallerSession) Owner() (common.Address, error) { + return _AutomationRegistrar.Contract.Owner(&_AutomationRegistrar.CallOpts) +} + +func (_AutomationRegistrar *AutomationRegistrarCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _AutomationRegistrar.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_AutomationRegistrar *AutomationRegistrarSession) TypeAndVersion() (string, error) { + return _AutomationRegistrar.Contract.TypeAndVersion(&_AutomationRegistrar.CallOpts) +} + +func (_AutomationRegistrar *AutomationRegistrarCallerSession) TypeAndVersion() (string, error) { + return _AutomationRegistrar.Contract.TypeAndVersion(&_AutomationRegistrar.CallOpts) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationRegistrar.contract.Transact(opts, "acceptOwnership") +} + +func (_AutomationRegistrar *AutomationRegistrarSession) AcceptOwnership() (*types.Transaction, error) { + return _AutomationRegistrar.Contract.AcceptOwnership(&_AutomationRegistrar.TransactOpts) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _AutomationRegistrar.Contract.AcceptOwnership(&_AutomationRegistrar.TransactOpts) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactor) Approve(opts *bind.TransactOpts, name string, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte, hash [32]byte) (*types.Transaction, error) { + return _AutomationRegistrar.contract.Transact(opts, "approve", name, upkeepContract, gasLimit, adminAddress, triggerType, checkData, triggerConfig, offchainConfig, hash) +} + +func (_AutomationRegistrar *AutomationRegistrarSession) Approve(name string, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte, hash [32]byte) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.Approve(&_AutomationRegistrar.TransactOpts, name, upkeepContract, gasLimit, adminAddress, triggerType, checkData, triggerConfig, offchainConfig, hash) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorSession) Approve(name string, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte, hash [32]byte) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.Approve(&_AutomationRegistrar.TransactOpts, name, upkeepContract, gasLimit, adminAddress, triggerType, checkData, triggerConfig, offchainConfig, hash) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactor) Cancel(opts *bind.TransactOpts, hash [32]byte) (*types.Transaction, error) { + return _AutomationRegistrar.contract.Transact(opts, "cancel", hash) +} + +func (_AutomationRegistrar *AutomationRegistrarSession) Cancel(hash [32]byte) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.Cancel(&_AutomationRegistrar.TransactOpts, hash) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorSession) Cancel(hash [32]byte) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.Cancel(&_AutomationRegistrar.TransactOpts, hash) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactor) OnTokenTransfer(opts *bind.TransactOpts, sender common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _AutomationRegistrar.contract.Transact(opts, "onTokenTransfer", sender, amount, data) +} + +func (_AutomationRegistrar *AutomationRegistrarSession) OnTokenTransfer(sender common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.OnTokenTransfer(&_AutomationRegistrar.TransactOpts, sender, amount, data) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorSession) OnTokenTransfer(sender common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.OnTokenTransfer(&_AutomationRegistrar.TransactOpts, sender, amount, data) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactor) Register(opts *bind.TransactOpts, name string, encryptedEmail []byte, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte, amount *big.Int, sender common.Address) (*types.Transaction, error) { + return _AutomationRegistrar.contract.Transact(opts, "register", name, encryptedEmail, upkeepContract, gasLimit, adminAddress, triggerType, checkData, triggerConfig, offchainConfig, amount, sender) +} + +func (_AutomationRegistrar *AutomationRegistrarSession) Register(name string, encryptedEmail []byte, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte, amount *big.Int, sender common.Address) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.Register(&_AutomationRegistrar.TransactOpts, name, encryptedEmail, upkeepContract, gasLimit, adminAddress, triggerType, checkData, triggerConfig, offchainConfig, amount, sender) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorSession) Register(name string, encryptedEmail []byte, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte, amount *big.Int, sender common.Address) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.Register(&_AutomationRegistrar.TransactOpts, name, encryptedEmail, upkeepContract, gasLimit, adminAddress, triggerType, checkData, triggerConfig, offchainConfig, amount, sender) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactor) RegisterUpkeep(opts *bind.TransactOpts, requestParams AutomationRegistrar21RegistrationParams) (*types.Transaction, error) { + return _AutomationRegistrar.contract.Transact(opts, "registerUpkeep", requestParams) +} + +func (_AutomationRegistrar *AutomationRegistrarSession) RegisterUpkeep(requestParams AutomationRegistrar21RegistrationParams) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.RegisterUpkeep(&_AutomationRegistrar.TransactOpts, requestParams) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorSession) RegisterUpkeep(requestParams AutomationRegistrar21RegistrationParams) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.RegisterUpkeep(&_AutomationRegistrar.TransactOpts, requestParams) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactor) SetAutoApproveAllowedSender(opts *bind.TransactOpts, senderAddress common.Address, allowed bool) (*types.Transaction, error) { + return _AutomationRegistrar.contract.Transact(opts, "setAutoApproveAllowedSender", senderAddress, allowed) +} + +func (_AutomationRegistrar *AutomationRegistrarSession) SetAutoApproveAllowedSender(senderAddress common.Address, allowed bool) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.SetAutoApproveAllowedSender(&_AutomationRegistrar.TransactOpts, senderAddress, allowed) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorSession) SetAutoApproveAllowedSender(senderAddress common.Address, allowed bool) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.SetAutoApproveAllowedSender(&_AutomationRegistrar.TransactOpts, senderAddress, allowed) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactor) SetConfig(opts *bind.TransactOpts, keeperRegistry common.Address, minLINKJuels *big.Int) (*types.Transaction, error) { + return _AutomationRegistrar.contract.Transact(opts, "setConfig", keeperRegistry, minLINKJuels) +} + +func (_AutomationRegistrar *AutomationRegistrarSession) SetConfig(keeperRegistry common.Address, minLINKJuels *big.Int) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.SetConfig(&_AutomationRegistrar.TransactOpts, keeperRegistry, minLINKJuels) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorSession) SetConfig(keeperRegistry common.Address, minLINKJuels *big.Int) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.SetConfig(&_AutomationRegistrar.TransactOpts, keeperRegistry, minLINKJuels) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactor) SetTriggerConfig(opts *bind.TransactOpts, triggerType uint8, autoApproveType uint8, autoApproveMaxAllowed uint32) (*types.Transaction, error) { + return _AutomationRegistrar.contract.Transact(opts, "setTriggerConfig", triggerType, autoApproveType, autoApproveMaxAllowed) +} + +func (_AutomationRegistrar *AutomationRegistrarSession) SetTriggerConfig(triggerType uint8, autoApproveType uint8, autoApproveMaxAllowed uint32) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.SetTriggerConfig(&_AutomationRegistrar.TransactOpts, triggerType, autoApproveType, autoApproveMaxAllowed) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorSession) SetTriggerConfig(triggerType uint8, autoApproveType uint8, autoApproveMaxAllowed uint32) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.SetTriggerConfig(&_AutomationRegistrar.TransactOpts, triggerType, autoApproveType, autoApproveMaxAllowed) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _AutomationRegistrar.contract.Transact(opts, "transferOwnership", to) +} + +func (_AutomationRegistrar *AutomationRegistrarSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.TransferOwnership(&_AutomationRegistrar.TransactOpts, to) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.TransferOwnership(&_AutomationRegistrar.TransactOpts, to) +} + +type AutomationRegistrarAutoApproveAllowedSenderSetIterator struct { + Event *AutomationRegistrarAutoApproveAllowedSenderSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistrarAutoApproveAllowedSenderSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarAutoApproveAllowedSenderSet) + 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(AutomationRegistrarAutoApproveAllowedSenderSet) + 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 *AutomationRegistrarAutoApproveAllowedSenderSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistrarAutoApproveAllowedSenderSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistrarAutoApproveAllowedSenderSet struct { + SenderAddress common.Address + Allowed bool + Raw types.Log +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) FilterAutoApproveAllowedSenderSet(opts *bind.FilterOpts, senderAddress []common.Address) (*AutomationRegistrarAutoApproveAllowedSenderSetIterator, error) { + + var senderAddressRule []interface{} + for _, senderAddressItem := range senderAddress { + senderAddressRule = append(senderAddressRule, senderAddressItem) + } + + logs, sub, err := _AutomationRegistrar.contract.FilterLogs(opts, "AutoApproveAllowedSenderSet", senderAddressRule) + if err != nil { + return nil, err + } + return &AutomationRegistrarAutoApproveAllowedSenderSetIterator{contract: _AutomationRegistrar.contract, event: "AutoApproveAllowedSenderSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) WatchAutoApproveAllowedSenderSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarAutoApproveAllowedSenderSet, senderAddress []common.Address) (event.Subscription, error) { + + var senderAddressRule []interface{} + for _, senderAddressItem := range senderAddress { + senderAddressRule = append(senderAddressRule, senderAddressItem) + } + + logs, sub, err := _AutomationRegistrar.contract.WatchLogs(opts, "AutoApproveAllowedSenderSet", senderAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistrarAutoApproveAllowedSenderSet) + if err := _AutomationRegistrar.contract.UnpackLog(event, "AutoApproveAllowedSenderSet", 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 (_AutomationRegistrar *AutomationRegistrarFilterer) ParseAutoApproveAllowedSenderSet(log types.Log) (*AutomationRegistrarAutoApproveAllowedSenderSet, error) { + event := new(AutomationRegistrarAutoApproveAllowedSenderSet) + if err := _AutomationRegistrar.contract.UnpackLog(event, "AutoApproveAllowedSenderSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistrarConfigChangedIterator struct { + Event *AutomationRegistrarConfigChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistrarConfigChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarConfigChanged) + 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(AutomationRegistrarConfigChanged) + 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 *AutomationRegistrarConfigChangedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistrarConfigChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistrarConfigChanged struct { + KeeperRegistry common.Address + MinLINKJuels *big.Int + Raw types.Log +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) FilterConfigChanged(opts *bind.FilterOpts) (*AutomationRegistrarConfigChangedIterator, error) { + + logs, sub, err := _AutomationRegistrar.contract.FilterLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return &AutomationRegistrarConfigChangedIterator{contract: _AutomationRegistrar.contract, event: "ConfigChanged", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarConfigChanged) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistrar.contract.WatchLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistrarConfigChanged) + if err := _AutomationRegistrar.contract.UnpackLog(event, "ConfigChanged", 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 (_AutomationRegistrar *AutomationRegistrarFilterer) ParseConfigChanged(log types.Log) (*AutomationRegistrarConfigChanged, error) { + event := new(AutomationRegistrarConfigChanged) + if err := _AutomationRegistrar.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistrarOwnershipTransferRequestedIterator struct { + Event *AutomationRegistrarOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistrarOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarOwnershipTransferRequested) + 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(AutomationRegistrarOwnershipTransferRequested) + 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 *AutomationRegistrarOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistrarOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistrarOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*AutomationRegistrarOwnershipTransferRequestedIterator, 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 := _AutomationRegistrar.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistrarOwnershipTransferRequestedIterator{contract: _AutomationRegistrar.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarOwnershipTransferRequested, 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 := _AutomationRegistrar.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(AutomationRegistrarOwnershipTransferRequested) + if err := _AutomationRegistrar.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 (_AutomationRegistrar *AutomationRegistrarFilterer) ParseOwnershipTransferRequested(log types.Log) (*AutomationRegistrarOwnershipTransferRequested, error) { + event := new(AutomationRegistrarOwnershipTransferRequested) + if err := _AutomationRegistrar.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistrarOwnershipTransferredIterator struct { + Event *AutomationRegistrarOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistrarOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarOwnershipTransferred) + 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(AutomationRegistrarOwnershipTransferred) + 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 *AutomationRegistrarOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistrarOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistrarOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*AutomationRegistrarOwnershipTransferredIterator, 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 := _AutomationRegistrar.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistrarOwnershipTransferredIterator{contract: _AutomationRegistrar.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarOwnershipTransferred, 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 := _AutomationRegistrar.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(AutomationRegistrarOwnershipTransferred) + if err := _AutomationRegistrar.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 (_AutomationRegistrar *AutomationRegistrarFilterer) ParseOwnershipTransferred(log types.Log) (*AutomationRegistrarOwnershipTransferred, error) { + event := new(AutomationRegistrarOwnershipTransferred) + if err := _AutomationRegistrar.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistrarRegistrationApprovedIterator struct { + Event *AutomationRegistrarRegistrationApproved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistrarRegistrationApprovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarRegistrationApproved) + 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(AutomationRegistrarRegistrationApproved) + 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 *AutomationRegistrarRegistrationApprovedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistrarRegistrationApprovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistrarRegistrationApproved struct { + Hash [32]byte + DisplayName string + UpkeepId *big.Int + Raw types.Log +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) FilterRegistrationApproved(opts *bind.FilterOpts, hash [][32]byte, upkeepId []*big.Int) (*AutomationRegistrarRegistrationApprovedIterator, error) { + + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + + var upkeepIdRule []interface{} + for _, upkeepIdItem := range upkeepId { + upkeepIdRule = append(upkeepIdRule, upkeepIdItem) + } + + logs, sub, err := _AutomationRegistrar.contract.FilterLogs(opts, "RegistrationApproved", hashRule, upkeepIdRule) + if err != nil { + return nil, err + } + return &AutomationRegistrarRegistrationApprovedIterator{contract: _AutomationRegistrar.contract, event: "RegistrationApproved", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) WatchRegistrationApproved(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarRegistrationApproved, hash [][32]byte, upkeepId []*big.Int) (event.Subscription, error) { + + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + + var upkeepIdRule []interface{} + for _, upkeepIdItem := range upkeepId { + upkeepIdRule = append(upkeepIdRule, upkeepIdItem) + } + + logs, sub, err := _AutomationRegistrar.contract.WatchLogs(opts, "RegistrationApproved", hashRule, upkeepIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistrarRegistrationApproved) + if err := _AutomationRegistrar.contract.UnpackLog(event, "RegistrationApproved", 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 (_AutomationRegistrar *AutomationRegistrarFilterer) ParseRegistrationApproved(log types.Log) (*AutomationRegistrarRegistrationApproved, error) { + event := new(AutomationRegistrarRegistrationApproved) + if err := _AutomationRegistrar.contract.UnpackLog(event, "RegistrationApproved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistrarRegistrationRejectedIterator struct { + Event *AutomationRegistrarRegistrationRejected + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistrarRegistrationRejectedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarRegistrationRejected) + 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(AutomationRegistrarRegistrationRejected) + 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 *AutomationRegistrarRegistrationRejectedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistrarRegistrationRejectedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistrarRegistrationRejected struct { + Hash [32]byte + Raw types.Log +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) FilterRegistrationRejected(opts *bind.FilterOpts, hash [][32]byte) (*AutomationRegistrarRegistrationRejectedIterator, error) { + + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + + logs, sub, err := _AutomationRegistrar.contract.FilterLogs(opts, "RegistrationRejected", hashRule) + if err != nil { + return nil, err + } + return &AutomationRegistrarRegistrationRejectedIterator{contract: _AutomationRegistrar.contract, event: "RegistrationRejected", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) WatchRegistrationRejected(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarRegistrationRejected, hash [][32]byte) (event.Subscription, error) { + + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + + logs, sub, err := _AutomationRegistrar.contract.WatchLogs(opts, "RegistrationRejected", hashRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistrarRegistrationRejected) + if err := _AutomationRegistrar.contract.UnpackLog(event, "RegistrationRejected", 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 (_AutomationRegistrar *AutomationRegistrarFilterer) ParseRegistrationRejected(log types.Log) (*AutomationRegistrarRegistrationRejected, error) { + event := new(AutomationRegistrarRegistrationRejected) + if err := _AutomationRegistrar.contract.UnpackLog(event, "RegistrationRejected", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistrarRegistrationRequestedIterator struct { + Event *AutomationRegistrarRegistrationRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistrarRegistrationRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarRegistrationRequested) + 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(AutomationRegistrarRegistrationRequested) + 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 *AutomationRegistrarRegistrationRequestedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistrarRegistrationRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistrarRegistrationRequested struct { + Hash [32]byte + Name string + EncryptedEmail []byte + UpkeepContract common.Address + GasLimit uint32 + AdminAddress common.Address + TriggerType uint8 + TriggerConfig []byte + OffchainConfig []byte + CheckData []byte + Amount *big.Int + Raw types.Log +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) FilterRegistrationRequested(opts *bind.FilterOpts, hash [][32]byte, upkeepContract []common.Address) (*AutomationRegistrarRegistrationRequestedIterator, error) { + + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + + var upkeepContractRule []interface{} + for _, upkeepContractItem := range upkeepContract { + upkeepContractRule = append(upkeepContractRule, upkeepContractItem) + } + + logs, sub, err := _AutomationRegistrar.contract.FilterLogs(opts, "RegistrationRequested", hashRule, upkeepContractRule) + if err != nil { + return nil, err + } + return &AutomationRegistrarRegistrationRequestedIterator{contract: _AutomationRegistrar.contract, event: "RegistrationRequested", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) WatchRegistrationRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarRegistrationRequested, hash [][32]byte, upkeepContract []common.Address) (event.Subscription, error) { + + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + + var upkeepContractRule []interface{} + for _, upkeepContractItem := range upkeepContract { + upkeepContractRule = append(upkeepContractRule, upkeepContractItem) + } + + logs, sub, err := _AutomationRegistrar.contract.WatchLogs(opts, "RegistrationRequested", hashRule, upkeepContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistrarRegistrationRequested) + if err := _AutomationRegistrar.contract.UnpackLog(event, "RegistrationRequested", 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 (_AutomationRegistrar *AutomationRegistrarFilterer) ParseRegistrationRequested(log types.Log) (*AutomationRegistrarRegistrationRequested, error) { + event := new(AutomationRegistrarRegistrationRequested) + if err := _AutomationRegistrar.contract.UnpackLog(event, "RegistrationRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistrarTriggerConfigSetIterator struct { + Event *AutomationRegistrarTriggerConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistrarTriggerConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarTriggerConfigSet) + 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(AutomationRegistrarTriggerConfigSet) + 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 *AutomationRegistrarTriggerConfigSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistrarTriggerConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistrarTriggerConfigSet struct { + TriggerType uint8 + AutoApproveType uint8 + AutoApproveMaxAllowed uint32 + Raw types.Log +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) FilterTriggerConfigSet(opts *bind.FilterOpts) (*AutomationRegistrarTriggerConfigSetIterator, error) { + + logs, sub, err := _AutomationRegistrar.contract.FilterLogs(opts, "TriggerConfigSet") + if err != nil { + return nil, err + } + return &AutomationRegistrarTriggerConfigSetIterator{contract: _AutomationRegistrar.contract, event: "TriggerConfigSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) WatchTriggerConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarTriggerConfigSet) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistrar.contract.WatchLogs(opts, "TriggerConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistrarTriggerConfigSet) + if err := _AutomationRegistrar.contract.UnpackLog(event, "TriggerConfigSet", 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 (_AutomationRegistrar *AutomationRegistrarFilterer) ParseTriggerConfigSet(log types.Log) (*AutomationRegistrarTriggerConfigSet, error) { + event := new(AutomationRegistrarTriggerConfigSet) + if err := _AutomationRegistrar.contract.UnpackLog(event, "TriggerConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetConfig struct { + KeeperRegistry common.Address + MinLINKJuels *big.Int +} + +func (_AutomationRegistrar *AutomationRegistrar) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _AutomationRegistrar.abi.Events["AutoApproveAllowedSenderSet"].ID: + return _AutomationRegistrar.ParseAutoApproveAllowedSenderSet(log) + case _AutomationRegistrar.abi.Events["ConfigChanged"].ID: + return _AutomationRegistrar.ParseConfigChanged(log) + case _AutomationRegistrar.abi.Events["OwnershipTransferRequested"].ID: + return _AutomationRegistrar.ParseOwnershipTransferRequested(log) + case _AutomationRegistrar.abi.Events["OwnershipTransferred"].ID: + return _AutomationRegistrar.ParseOwnershipTransferred(log) + case _AutomationRegistrar.abi.Events["RegistrationApproved"].ID: + return _AutomationRegistrar.ParseRegistrationApproved(log) + case _AutomationRegistrar.abi.Events["RegistrationRejected"].ID: + return _AutomationRegistrar.ParseRegistrationRejected(log) + case _AutomationRegistrar.abi.Events["RegistrationRequested"].ID: + return _AutomationRegistrar.ParseRegistrationRequested(log) + case _AutomationRegistrar.abi.Events["TriggerConfigSet"].ID: + return _AutomationRegistrar.ParseTriggerConfigSet(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (AutomationRegistrarAutoApproveAllowedSenderSet) Topic() common.Hash { + return common.HexToHash("0x20c6237dac83526a849285a9f79d08a483291bdd3a056a0ef9ae94ecee1ad356") +} + +func (AutomationRegistrarConfigChanged) Topic() common.Hash { + return common.HexToHash("0x39ce5d867555f0b0183e358fce5b158e7ca4fecd7c01cb7e0e19f1e23285838a") +} + +func (AutomationRegistrarOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (AutomationRegistrarOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (AutomationRegistrarRegistrationApproved) Topic() common.Hash { + return common.HexToHash("0xb9a292fb7e3edd920cd2d2829a3615a640c43fd7de0a0820aa0668feb4c37d4b") +} + +func (AutomationRegistrarRegistrationRejected) Topic() common.Hash { + return common.HexToHash("0x3663fb28ebc87645eb972c9dad8521bf665c623f287e79f1c56f1eb374b82a22") +} + +func (AutomationRegistrarRegistrationRequested) Topic() common.Hash { + return common.HexToHash("0x7684390ebb103102f7f48c71439c2408713f8d437782a6fab2756acc0e42c1b7") +} + +func (AutomationRegistrarTriggerConfigSet) Topic() common.Hash { + return common.HexToHash("0x830a6d06a4e2caac67eba04323de22bdb04f032dd8b3d6a0c52b503d9a7036a3") +} + +func (_AutomationRegistrar *AutomationRegistrar) Address() common.Address { + return _AutomationRegistrar.address +} + +type AutomationRegistrarInterface interface { + LINK(opts *bind.CallOpts) (common.Address, error) + + GetAutoApproveAllowedSender(opts *bind.CallOpts, senderAddress common.Address) (bool, error) + + GetConfig(opts *bind.CallOpts) (GetConfig, + + error) + + GetPendingRequest(opts *bind.CallOpts, hash [32]byte) (common.Address, *big.Int, error) + + GetTriggerRegistrationDetails(opts *bind.CallOpts, triggerType uint8) (AutomationRegistrar21TriggerRegistrationStorage, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + Approve(opts *bind.TransactOpts, name string, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte, hash [32]byte) (*types.Transaction, error) + + Cancel(opts *bind.TransactOpts, hash [32]byte) (*types.Transaction, error) + + OnTokenTransfer(opts *bind.TransactOpts, sender common.Address, amount *big.Int, data []byte) (*types.Transaction, error) + + Register(opts *bind.TransactOpts, name string, encryptedEmail []byte, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte, amount *big.Int, sender common.Address) (*types.Transaction, error) + + RegisterUpkeep(opts *bind.TransactOpts, requestParams AutomationRegistrar21RegistrationParams) (*types.Transaction, error) + + SetAutoApproveAllowedSender(opts *bind.TransactOpts, senderAddress common.Address, allowed bool) (*types.Transaction, error) + + SetConfig(opts *bind.TransactOpts, keeperRegistry common.Address, minLINKJuels *big.Int) (*types.Transaction, error) + + SetTriggerConfig(opts *bind.TransactOpts, triggerType uint8, autoApproveType uint8, autoApproveMaxAllowed uint32) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterAutoApproveAllowedSenderSet(opts *bind.FilterOpts, senderAddress []common.Address) (*AutomationRegistrarAutoApproveAllowedSenderSetIterator, error) + + WatchAutoApproveAllowedSenderSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarAutoApproveAllowedSenderSet, senderAddress []common.Address) (event.Subscription, error) + + ParseAutoApproveAllowedSenderSet(log types.Log) (*AutomationRegistrarAutoApproveAllowedSenderSet, error) + + FilterConfigChanged(opts *bind.FilterOpts) (*AutomationRegistrarConfigChangedIterator, error) + + WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarConfigChanged) (event.Subscription, error) + + ParseConfigChanged(log types.Log) (*AutomationRegistrarConfigChanged, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*AutomationRegistrarOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*AutomationRegistrarOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*AutomationRegistrarOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*AutomationRegistrarOwnershipTransferred, error) + + FilterRegistrationApproved(opts *bind.FilterOpts, hash [][32]byte, upkeepId []*big.Int) (*AutomationRegistrarRegistrationApprovedIterator, error) + + WatchRegistrationApproved(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarRegistrationApproved, hash [][32]byte, upkeepId []*big.Int) (event.Subscription, error) + + ParseRegistrationApproved(log types.Log) (*AutomationRegistrarRegistrationApproved, error) + + FilterRegistrationRejected(opts *bind.FilterOpts, hash [][32]byte) (*AutomationRegistrarRegistrationRejectedIterator, error) + + WatchRegistrationRejected(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarRegistrationRejected, hash [][32]byte) (event.Subscription, error) + + ParseRegistrationRejected(log types.Log) (*AutomationRegistrarRegistrationRejected, error) + + FilterRegistrationRequested(opts *bind.FilterOpts, hash [][32]byte, upkeepContract []common.Address) (*AutomationRegistrarRegistrationRequestedIterator, error) + + WatchRegistrationRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarRegistrationRequested, hash [][32]byte, upkeepContract []common.Address) (event.Subscription, error) + + ParseRegistrationRequested(log types.Log) (*AutomationRegistrarRegistrationRequested, error) + + FilterTriggerConfigSet(opts *bind.FilterOpts) (*AutomationRegistrarTriggerConfigSetIterator, error) + + WatchTriggerConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarTriggerConfigSet) (event.Subscription, error) + + ParseTriggerConfigSet(log types.Log) (*AutomationRegistrarTriggerConfigSet, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/dummy_protocol_wrapper/dummy_protocol_wrapper.go b/core/gethwrappers/generated/dummy_protocol_wrapper/dummy_protocol_wrapper.go new file mode 100644 index 00000000000..e7a88fdd06e --- /dev/null +++ b/core/gethwrappers/generated/dummy_protocol_wrapper/dummy_protocol_wrapper.go @@ -0,0 +1,751 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package dummy_protocol_wrapper + +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 DummyProtocolMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"orderId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"exchange\",\"type\":\"address\"}],\"name\":\"LimitOrderExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"LimitOrderSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"}],\"name\":\"LimitOrderWithdrawn\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"orderId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"exchange\",\"type\":\"address\"}],\"name\":\"executeLimitOrder\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"targetContract\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"selector\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"t0\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"t1\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"t2\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"t3\",\"type\":\"bytes32\"}],\"name\":\"getAdvancedLogTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"logTrigger\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"targetContract\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"t0\",\"type\":\"bytes32\"}],\"name\":\"getBasicLogTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"logTrigger\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"sendLimitedOrder\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"}],\"name\":\"withdrawLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b506103e2806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80636bb17e4c116100505780636bb17e4c1461013d5780639ab74b0e1461013d578063af38c9c21461015057600080fd5b80632065ff7e1461006c5780635f35f80b14610081575b600080fd5b61007f61007a3660046102ad565b6101f0565b005b61012761008f3660046102e2565b6040805160c0808201835273ffffffffffffffffffffffffffffffffffffffff9890981680825260ff97881660208084019182528385019889526060808501988952608080860198895260a095860197885286519283019490945291519099168985015296519688019690965293519486019490945290519184019190915251828401528051808303909301835260e0909101905290565b604051610134919061033f565b60405180910390f35b61007f61014b3660046102ad565b61023a565b61012761015e3660046103ab565b6040805160c0808201835273ffffffffffffffffffffffffffffffffffffffff94909416808252600060208084018281528486019687526060808601848152608080880186815260a0988901968752895195860197909752925160ff168489015297519083015295519581019590955290519184019190915251828401528051808303909301835260e0909101905290565b8073ffffffffffffffffffffffffffffffffffffffff1682847fd1ffe9e45581c11d7d9f2ed5f75217cd4be9f8b7eee6af0f6d03f46de53956cd60405160405180910390a4505050565b8073ffffffffffffffffffffffffffffffffffffffff1682847f3e9c37b3143f2eb7e9a2a0f8091b6de097b62efcfe48e1f68847a832e521750a60405160405180910390a4505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146102a857600080fd5b919050565b6000806000606084860312156102c257600080fd5b83359250602084013591506102d960408501610284565b90509250925092565b60008060008060008060c087890312156102fb57600080fd5b61030487610284565b9550602087013560ff8116811461031a57600080fd5b95989597505050506040840135936060810135936080820135935060a0909101359150565b600060208083528351808285015260005b8181101561036c57858101830151858201604001528201610350565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b600080604083850312156103be57600080fd5b6103c783610284565b94602093909301359350505056fea164736f6c6343000810000a", +} + +var DummyProtocolABI = DummyProtocolMetaData.ABI + +var DummyProtocolBin = DummyProtocolMetaData.Bin + +func DeployDummyProtocol(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *DummyProtocol, error) { + parsed, err := DummyProtocolMetaData.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(DummyProtocolBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &DummyProtocol{DummyProtocolCaller: DummyProtocolCaller{contract: contract}, DummyProtocolTransactor: DummyProtocolTransactor{contract: contract}, DummyProtocolFilterer: DummyProtocolFilterer{contract: contract}}, nil +} + +type DummyProtocol struct { + address common.Address + abi abi.ABI + DummyProtocolCaller + DummyProtocolTransactor + DummyProtocolFilterer +} + +type DummyProtocolCaller struct { + contract *bind.BoundContract +} + +type DummyProtocolTransactor struct { + contract *bind.BoundContract +} + +type DummyProtocolFilterer struct { + contract *bind.BoundContract +} + +type DummyProtocolSession struct { + Contract *DummyProtocol + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type DummyProtocolCallerSession struct { + Contract *DummyProtocolCaller + CallOpts bind.CallOpts +} + +type DummyProtocolTransactorSession struct { + Contract *DummyProtocolTransactor + TransactOpts bind.TransactOpts +} + +type DummyProtocolRaw struct { + Contract *DummyProtocol +} + +type DummyProtocolCallerRaw struct { + Contract *DummyProtocolCaller +} + +type DummyProtocolTransactorRaw struct { + Contract *DummyProtocolTransactor +} + +func NewDummyProtocol(address common.Address, backend bind.ContractBackend) (*DummyProtocol, error) { + abi, err := abi.JSON(strings.NewReader(DummyProtocolABI)) + if err != nil { + return nil, err + } + contract, err := bindDummyProtocol(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &DummyProtocol{address: address, abi: abi, DummyProtocolCaller: DummyProtocolCaller{contract: contract}, DummyProtocolTransactor: DummyProtocolTransactor{contract: contract}, DummyProtocolFilterer: DummyProtocolFilterer{contract: contract}}, nil +} + +func NewDummyProtocolCaller(address common.Address, caller bind.ContractCaller) (*DummyProtocolCaller, error) { + contract, err := bindDummyProtocol(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &DummyProtocolCaller{contract: contract}, nil +} + +func NewDummyProtocolTransactor(address common.Address, transactor bind.ContractTransactor) (*DummyProtocolTransactor, error) { + contract, err := bindDummyProtocol(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &DummyProtocolTransactor{contract: contract}, nil +} + +func NewDummyProtocolFilterer(address common.Address, filterer bind.ContractFilterer) (*DummyProtocolFilterer, error) { + contract, err := bindDummyProtocol(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &DummyProtocolFilterer{contract: contract}, nil +} + +func bindDummyProtocol(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := DummyProtocolMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_DummyProtocol *DummyProtocolRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DummyProtocol.Contract.DummyProtocolCaller.contract.Call(opts, result, method, params...) +} + +func (_DummyProtocol *DummyProtocolRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DummyProtocol.Contract.DummyProtocolTransactor.contract.Transfer(opts) +} + +func (_DummyProtocol *DummyProtocolRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DummyProtocol.Contract.DummyProtocolTransactor.contract.Transact(opts, method, params...) +} + +func (_DummyProtocol *DummyProtocolCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DummyProtocol.Contract.contract.Call(opts, result, method, params...) +} + +func (_DummyProtocol *DummyProtocolTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DummyProtocol.Contract.contract.Transfer(opts) +} + +func (_DummyProtocol *DummyProtocolTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DummyProtocol.Contract.contract.Transact(opts, method, params...) +} + +func (_DummyProtocol *DummyProtocolCaller) GetAdvancedLogTriggerConfig(opts *bind.CallOpts, targetContract common.Address, selector uint8, t0 [32]byte, t1 [32]byte, t2 [32]byte, t3 [32]byte) ([]byte, error) { + var out []interface{} + err := _DummyProtocol.contract.Call(opts, &out, "getAdvancedLogTriggerConfig", targetContract, selector, t0, t1, t2, t3) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_DummyProtocol *DummyProtocolSession) GetAdvancedLogTriggerConfig(targetContract common.Address, selector uint8, t0 [32]byte, t1 [32]byte, t2 [32]byte, t3 [32]byte) ([]byte, error) { + return _DummyProtocol.Contract.GetAdvancedLogTriggerConfig(&_DummyProtocol.CallOpts, targetContract, selector, t0, t1, t2, t3) +} + +func (_DummyProtocol *DummyProtocolCallerSession) GetAdvancedLogTriggerConfig(targetContract common.Address, selector uint8, t0 [32]byte, t1 [32]byte, t2 [32]byte, t3 [32]byte) ([]byte, error) { + return _DummyProtocol.Contract.GetAdvancedLogTriggerConfig(&_DummyProtocol.CallOpts, targetContract, selector, t0, t1, t2, t3) +} + +func (_DummyProtocol *DummyProtocolCaller) GetBasicLogTriggerConfig(opts *bind.CallOpts, targetContract common.Address, t0 [32]byte) ([]byte, error) { + var out []interface{} + err := _DummyProtocol.contract.Call(opts, &out, "getBasicLogTriggerConfig", targetContract, t0) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_DummyProtocol *DummyProtocolSession) GetBasicLogTriggerConfig(targetContract common.Address, t0 [32]byte) ([]byte, error) { + return _DummyProtocol.Contract.GetBasicLogTriggerConfig(&_DummyProtocol.CallOpts, targetContract, t0) +} + +func (_DummyProtocol *DummyProtocolCallerSession) GetBasicLogTriggerConfig(targetContract common.Address, t0 [32]byte) ([]byte, error) { + return _DummyProtocol.Contract.GetBasicLogTriggerConfig(&_DummyProtocol.CallOpts, targetContract, t0) +} + +func (_DummyProtocol *DummyProtocolTransactor) ExecuteLimitOrder(opts *bind.TransactOpts, orderId *big.Int, amount *big.Int, exchange common.Address) (*types.Transaction, error) { + return _DummyProtocol.contract.Transact(opts, "executeLimitOrder", orderId, amount, exchange) +} + +func (_DummyProtocol *DummyProtocolSession) ExecuteLimitOrder(orderId *big.Int, amount *big.Int, exchange common.Address) (*types.Transaction, error) { + return _DummyProtocol.Contract.ExecuteLimitOrder(&_DummyProtocol.TransactOpts, orderId, amount, exchange) +} + +func (_DummyProtocol *DummyProtocolTransactorSession) ExecuteLimitOrder(orderId *big.Int, amount *big.Int, exchange common.Address) (*types.Transaction, error) { + return _DummyProtocol.Contract.ExecuteLimitOrder(&_DummyProtocol.TransactOpts, orderId, amount, exchange) +} + +func (_DummyProtocol *DummyProtocolTransactor) SendLimitedOrder(opts *bind.TransactOpts, amount *big.Int, price *big.Int, to common.Address) (*types.Transaction, error) { + return _DummyProtocol.contract.Transact(opts, "sendLimitedOrder", amount, price, to) +} + +func (_DummyProtocol *DummyProtocolSession) SendLimitedOrder(amount *big.Int, price *big.Int, to common.Address) (*types.Transaction, error) { + return _DummyProtocol.Contract.SendLimitedOrder(&_DummyProtocol.TransactOpts, amount, price, to) +} + +func (_DummyProtocol *DummyProtocolTransactorSession) SendLimitedOrder(amount *big.Int, price *big.Int, to common.Address) (*types.Transaction, error) { + return _DummyProtocol.Contract.SendLimitedOrder(&_DummyProtocol.TransactOpts, amount, price, to) +} + +func (_DummyProtocol *DummyProtocolTransactor) WithdrawLimit(opts *bind.TransactOpts, amount *big.Int, price *big.Int, from common.Address) (*types.Transaction, error) { + return _DummyProtocol.contract.Transact(opts, "withdrawLimit", amount, price, from) +} + +func (_DummyProtocol *DummyProtocolSession) WithdrawLimit(amount *big.Int, price *big.Int, from common.Address) (*types.Transaction, error) { + return _DummyProtocol.Contract.WithdrawLimit(&_DummyProtocol.TransactOpts, amount, price, from) +} + +func (_DummyProtocol *DummyProtocolTransactorSession) WithdrawLimit(amount *big.Int, price *big.Int, from common.Address) (*types.Transaction, error) { + return _DummyProtocol.Contract.WithdrawLimit(&_DummyProtocol.TransactOpts, amount, price, from) +} + +type DummyProtocolLimitOrderExecutedIterator struct { + Event *DummyProtocolLimitOrderExecuted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DummyProtocolLimitOrderExecutedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DummyProtocolLimitOrderExecuted) + 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(DummyProtocolLimitOrderExecuted) + 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 *DummyProtocolLimitOrderExecutedIterator) Error() error { + return it.fail +} + +func (it *DummyProtocolLimitOrderExecutedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DummyProtocolLimitOrderExecuted struct { + OrderId *big.Int + Amount *big.Int + Exchange common.Address + Raw types.Log +} + +func (_DummyProtocol *DummyProtocolFilterer) FilterLimitOrderExecuted(opts *bind.FilterOpts, orderId []*big.Int, amount []*big.Int, exchange []common.Address) (*DummyProtocolLimitOrderExecutedIterator, error) { + + var orderIdRule []interface{} + for _, orderIdItem := range orderId { + orderIdRule = append(orderIdRule, orderIdItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + var exchangeRule []interface{} + for _, exchangeItem := range exchange { + exchangeRule = append(exchangeRule, exchangeItem) + } + + logs, sub, err := _DummyProtocol.contract.FilterLogs(opts, "LimitOrderExecuted", orderIdRule, amountRule, exchangeRule) + if err != nil { + return nil, err + } + return &DummyProtocolLimitOrderExecutedIterator{contract: _DummyProtocol.contract, event: "LimitOrderExecuted", logs: logs, sub: sub}, nil +} + +func (_DummyProtocol *DummyProtocolFilterer) WatchLimitOrderExecuted(opts *bind.WatchOpts, sink chan<- *DummyProtocolLimitOrderExecuted, orderId []*big.Int, amount []*big.Int, exchange []common.Address) (event.Subscription, error) { + + var orderIdRule []interface{} + for _, orderIdItem := range orderId { + orderIdRule = append(orderIdRule, orderIdItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + var exchangeRule []interface{} + for _, exchangeItem := range exchange { + exchangeRule = append(exchangeRule, exchangeItem) + } + + logs, sub, err := _DummyProtocol.contract.WatchLogs(opts, "LimitOrderExecuted", orderIdRule, amountRule, exchangeRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DummyProtocolLimitOrderExecuted) + if err := _DummyProtocol.contract.UnpackLog(event, "LimitOrderExecuted", 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 (_DummyProtocol *DummyProtocolFilterer) ParseLimitOrderExecuted(log types.Log) (*DummyProtocolLimitOrderExecuted, error) { + event := new(DummyProtocolLimitOrderExecuted) + if err := _DummyProtocol.contract.UnpackLog(event, "LimitOrderExecuted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DummyProtocolLimitOrderSentIterator struct { + Event *DummyProtocolLimitOrderSent + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DummyProtocolLimitOrderSentIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DummyProtocolLimitOrderSent) + 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(DummyProtocolLimitOrderSent) + 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 *DummyProtocolLimitOrderSentIterator) Error() error { + return it.fail +} + +func (it *DummyProtocolLimitOrderSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DummyProtocolLimitOrderSent struct { + Amount *big.Int + Price *big.Int + To common.Address + Raw types.Log +} + +func (_DummyProtocol *DummyProtocolFilterer) FilterLimitOrderSent(opts *bind.FilterOpts, amount []*big.Int, price []*big.Int, to []common.Address) (*DummyProtocolLimitOrderSentIterator, error) { + + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + var priceRule []interface{} + for _, priceItem := range price { + priceRule = append(priceRule, priceItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DummyProtocol.contract.FilterLogs(opts, "LimitOrderSent", amountRule, priceRule, toRule) + if err != nil { + return nil, err + } + return &DummyProtocolLimitOrderSentIterator{contract: _DummyProtocol.contract, event: "LimitOrderSent", logs: logs, sub: sub}, nil +} + +func (_DummyProtocol *DummyProtocolFilterer) WatchLimitOrderSent(opts *bind.WatchOpts, sink chan<- *DummyProtocolLimitOrderSent, amount []*big.Int, price []*big.Int, to []common.Address) (event.Subscription, error) { + + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + var priceRule []interface{} + for _, priceItem := range price { + priceRule = append(priceRule, priceItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DummyProtocol.contract.WatchLogs(opts, "LimitOrderSent", amountRule, priceRule, 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(DummyProtocolLimitOrderSent) + if err := _DummyProtocol.contract.UnpackLog(event, "LimitOrderSent", 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 (_DummyProtocol *DummyProtocolFilterer) ParseLimitOrderSent(log types.Log) (*DummyProtocolLimitOrderSent, error) { + event := new(DummyProtocolLimitOrderSent) + if err := _DummyProtocol.contract.UnpackLog(event, "LimitOrderSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DummyProtocolLimitOrderWithdrawnIterator struct { + Event *DummyProtocolLimitOrderWithdrawn + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DummyProtocolLimitOrderWithdrawnIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DummyProtocolLimitOrderWithdrawn) + 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(DummyProtocolLimitOrderWithdrawn) + 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 *DummyProtocolLimitOrderWithdrawnIterator) Error() error { + return it.fail +} + +func (it *DummyProtocolLimitOrderWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DummyProtocolLimitOrderWithdrawn struct { + Amount *big.Int + Price *big.Int + From common.Address + Raw types.Log +} + +func (_DummyProtocol *DummyProtocolFilterer) FilterLimitOrderWithdrawn(opts *bind.FilterOpts, amount []*big.Int, price []*big.Int, from []common.Address) (*DummyProtocolLimitOrderWithdrawnIterator, error) { + + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + var priceRule []interface{} + for _, priceItem := range price { + priceRule = append(priceRule, priceItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _DummyProtocol.contract.FilterLogs(opts, "LimitOrderWithdrawn", amountRule, priceRule, fromRule) + if err != nil { + return nil, err + } + return &DummyProtocolLimitOrderWithdrawnIterator{contract: _DummyProtocol.contract, event: "LimitOrderWithdrawn", logs: logs, sub: sub}, nil +} + +func (_DummyProtocol *DummyProtocolFilterer) WatchLimitOrderWithdrawn(opts *bind.WatchOpts, sink chan<- *DummyProtocolLimitOrderWithdrawn, amount []*big.Int, price []*big.Int, from []common.Address) (event.Subscription, error) { + + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + var priceRule []interface{} + for _, priceItem := range price { + priceRule = append(priceRule, priceItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _DummyProtocol.contract.WatchLogs(opts, "LimitOrderWithdrawn", amountRule, priceRule, fromRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DummyProtocolLimitOrderWithdrawn) + if err := _DummyProtocol.contract.UnpackLog(event, "LimitOrderWithdrawn", 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 (_DummyProtocol *DummyProtocolFilterer) ParseLimitOrderWithdrawn(log types.Log) (*DummyProtocolLimitOrderWithdrawn, error) { + event := new(DummyProtocolLimitOrderWithdrawn) + if err := _DummyProtocol.contract.UnpackLog(event, "LimitOrderWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_DummyProtocol *DummyProtocol) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _DummyProtocol.abi.Events["LimitOrderExecuted"].ID: + return _DummyProtocol.ParseLimitOrderExecuted(log) + case _DummyProtocol.abi.Events["LimitOrderSent"].ID: + return _DummyProtocol.ParseLimitOrderSent(log) + case _DummyProtocol.abi.Events["LimitOrderWithdrawn"].ID: + return _DummyProtocol.ParseLimitOrderWithdrawn(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (DummyProtocolLimitOrderExecuted) Topic() common.Hash { + return common.HexToHash("0xd1ffe9e45581c11d7d9f2ed5f75217cd4be9f8b7eee6af0f6d03f46de53956cd") +} + +func (DummyProtocolLimitOrderSent) Topic() common.Hash { + return common.HexToHash("0x3e9c37b3143f2eb7e9a2a0f8091b6de097b62efcfe48e1f68847a832e521750a") +} + +func (DummyProtocolLimitOrderWithdrawn) Topic() common.Hash { + return common.HexToHash("0x0a71b8ed921ff64d49e4d39449f8a21094f38a0aeae489c3051aedd63f2c229f") +} + +func (_DummyProtocol *DummyProtocol) Address() common.Address { + return _DummyProtocol.address +} + +type DummyProtocolInterface interface { + GetAdvancedLogTriggerConfig(opts *bind.CallOpts, targetContract common.Address, selector uint8, t0 [32]byte, t1 [32]byte, t2 [32]byte, t3 [32]byte) ([]byte, error) + + GetBasicLogTriggerConfig(opts *bind.CallOpts, targetContract common.Address, t0 [32]byte) ([]byte, error) + + ExecuteLimitOrder(opts *bind.TransactOpts, orderId *big.Int, amount *big.Int, exchange common.Address) (*types.Transaction, error) + + SendLimitedOrder(opts *bind.TransactOpts, amount *big.Int, price *big.Int, to common.Address) (*types.Transaction, error) + + WithdrawLimit(opts *bind.TransactOpts, amount *big.Int, price *big.Int, from common.Address) (*types.Transaction, error) + + FilterLimitOrderExecuted(opts *bind.FilterOpts, orderId []*big.Int, amount []*big.Int, exchange []common.Address) (*DummyProtocolLimitOrderExecutedIterator, error) + + WatchLimitOrderExecuted(opts *bind.WatchOpts, sink chan<- *DummyProtocolLimitOrderExecuted, orderId []*big.Int, amount []*big.Int, exchange []common.Address) (event.Subscription, error) + + ParseLimitOrderExecuted(log types.Log) (*DummyProtocolLimitOrderExecuted, error) + + FilterLimitOrderSent(opts *bind.FilterOpts, amount []*big.Int, price []*big.Int, to []common.Address) (*DummyProtocolLimitOrderSentIterator, error) + + WatchLimitOrderSent(opts *bind.WatchOpts, sink chan<- *DummyProtocolLimitOrderSent, amount []*big.Int, price []*big.Int, to []common.Address) (event.Subscription, error) + + ParseLimitOrderSent(log types.Log) (*DummyProtocolLimitOrderSent, error) + + FilterLimitOrderWithdrawn(opts *bind.FilterOpts, amount []*big.Int, price []*big.Int, from []common.Address) (*DummyProtocolLimitOrderWithdrawnIterator, error) + + WatchLimitOrderWithdrawn(opts *bind.WatchOpts, sink chan<- *DummyProtocolLimitOrderWithdrawn, amount []*big.Int, price []*big.Int, from []common.Address) (event.Subscription, error) + + ParseLimitOrderWithdrawn(log types.Log) (*DummyProtocolLimitOrderWithdrawn, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/functions/functions.go b/core/gethwrappers/generated/functions/functions.go deleted file mode 100644 index c82878691b5..00000000000 --- a/core/gethwrappers/generated/functions/functions.go +++ /dev/null @@ -1,202 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package functions - -import ( - "errors" - "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" -) - -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription - _ = abi.ConvertType -) - -var FunctionsMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"EmptyArgs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySource\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoInlineSecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"REQUEST_DATA_VERSION\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6063610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c80635d641dfc146038575b600080fd5b603f600181565b60405161ffff909116815260200160405180910390f3fea164736f6c6343000806000a", -} - -var FunctionsABI = FunctionsMetaData.ABI - -var FunctionsBin = FunctionsMetaData.Bin - -func DeployFunctions(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Functions, error) { - parsed, err := FunctionsMetaData.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(FunctionsBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &Functions{FunctionsCaller: FunctionsCaller{contract: contract}, FunctionsTransactor: FunctionsTransactor{contract: contract}, FunctionsFilterer: FunctionsFilterer{contract: contract}}, nil -} - -type Functions struct { - address common.Address - abi abi.ABI - FunctionsCaller - FunctionsTransactor - FunctionsFilterer -} - -type FunctionsCaller struct { - contract *bind.BoundContract -} - -type FunctionsTransactor struct { - contract *bind.BoundContract -} - -type FunctionsFilterer struct { - contract *bind.BoundContract -} - -type FunctionsSession struct { - Contract *Functions - CallOpts bind.CallOpts - TransactOpts bind.TransactOpts -} - -type FunctionsCallerSession struct { - Contract *FunctionsCaller - CallOpts bind.CallOpts -} - -type FunctionsTransactorSession struct { - Contract *FunctionsTransactor - TransactOpts bind.TransactOpts -} - -type FunctionsRaw struct { - Contract *Functions -} - -type FunctionsCallerRaw struct { - Contract *FunctionsCaller -} - -type FunctionsTransactorRaw struct { - Contract *FunctionsTransactor -} - -func NewFunctions(address common.Address, backend bind.ContractBackend) (*Functions, error) { - abi, err := abi.JSON(strings.NewReader(FunctionsABI)) - if err != nil { - return nil, err - } - contract, err := bindFunctions(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &Functions{address: address, abi: abi, FunctionsCaller: FunctionsCaller{contract: contract}, FunctionsTransactor: FunctionsTransactor{contract: contract}, FunctionsFilterer: FunctionsFilterer{contract: contract}}, nil -} - -func NewFunctionsCaller(address common.Address, caller bind.ContractCaller) (*FunctionsCaller, error) { - contract, err := bindFunctions(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &FunctionsCaller{contract: contract}, nil -} - -func NewFunctionsTransactor(address common.Address, transactor bind.ContractTransactor) (*FunctionsTransactor, error) { - contract, err := bindFunctions(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &FunctionsTransactor{contract: contract}, nil -} - -func NewFunctionsFilterer(address common.Address, filterer bind.ContractFilterer) (*FunctionsFilterer, error) { - contract, err := bindFunctions(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &FunctionsFilterer{contract: contract}, nil -} - -func bindFunctions(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := FunctionsMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -func (_Functions *FunctionsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Functions.Contract.FunctionsCaller.contract.Call(opts, result, method, params...) -} - -func (_Functions *FunctionsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Functions.Contract.FunctionsTransactor.contract.Transfer(opts) -} - -func (_Functions *FunctionsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Functions.Contract.FunctionsTransactor.contract.Transact(opts, method, params...) -} - -func (_Functions *FunctionsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Functions.Contract.contract.Call(opts, result, method, params...) -} - -func (_Functions *FunctionsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Functions.Contract.contract.Transfer(opts) -} - -func (_Functions *FunctionsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Functions.Contract.contract.Transact(opts, method, params...) -} - -func (_Functions *FunctionsCaller) REQUESTDATAVERSION(opts *bind.CallOpts) (uint16, error) { - var out []interface{} - err := _Functions.contract.Call(opts, &out, "REQUEST_DATA_VERSION") - - if err != nil { - return *new(uint16), err - } - - out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) - - return out0, err - -} - -func (_Functions *FunctionsSession) REQUESTDATAVERSION() (uint16, error) { - return _Functions.Contract.REQUESTDATAVERSION(&_Functions.CallOpts) -} - -func (_Functions *FunctionsCallerSession) REQUESTDATAVERSION() (uint16, error) { - return _Functions.Contract.REQUESTDATAVERSION(&_Functions.CallOpts) -} - -func (_Functions *Functions) Address() common.Address { - return _Functions.address -} - -type FunctionsInterface interface { - REQUESTDATAVERSION(opts *bind.CallOpts) (uint16, error) - - Address() common.Address -} diff --git a/core/gethwrappers/generated/functions_client/functions_client.go b/core/gethwrappers/generated/functions_client/functions_client.go deleted file mode 100644 index 2bfb9bb981c..00000000000 --- a/core/gethwrappers/generated/functions_client/functions_client.go +++ /dev/null @@ -1,463 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package functions_client - -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 FunctionsClientMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"OnlyRouterCanFufill\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestSent\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"handleOracleFulfillment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", -} - -var FunctionsClientABI = FunctionsClientMetaData.ABI - -type FunctionsClient struct { - address common.Address - abi abi.ABI - FunctionsClientCaller - FunctionsClientTransactor - FunctionsClientFilterer -} - -type FunctionsClientCaller struct { - contract *bind.BoundContract -} - -type FunctionsClientTransactor struct { - contract *bind.BoundContract -} - -type FunctionsClientFilterer struct { - contract *bind.BoundContract -} - -type FunctionsClientSession struct { - Contract *FunctionsClient - CallOpts bind.CallOpts - TransactOpts bind.TransactOpts -} - -type FunctionsClientCallerSession struct { - Contract *FunctionsClientCaller - CallOpts bind.CallOpts -} - -type FunctionsClientTransactorSession struct { - Contract *FunctionsClientTransactor - TransactOpts bind.TransactOpts -} - -type FunctionsClientRaw struct { - Contract *FunctionsClient -} - -type FunctionsClientCallerRaw struct { - Contract *FunctionsClientCaller -} - -type FunctionsClientTransactorRaw struct { - Contract *FunctionsClientTransactor -} - -func NewFunctionsClient(address common.Address, backend bind.ContractBackend) (*FunctionsClient, error) { - abi, err := abi.JSON(strings.NewReader(FunctionsClientABI)) - if err != nil { - return nil, err - } - contract, err := bindFunctionsClient(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &FunctionsClient{address: address, abi: abi, FunctionsClientCaller: FunctionsClientCaller{contract: contract}, FunctionsClientTransactor: FunctionsClientTransactor{contract: contract}, FunctionsClientFilterer: FunctionsClientFilterer{contract: contract}}, nil -} - -func NewFunctionsClientCaller(address common.Address, caller bind.ContractCaller) (*FunctionsClientCaller, error) { - contract, err := bindFunctionsClient(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &FunctionsClientCaller{contract: contract}, nil -} - -func NewFunctionsClientTransactor(address common.Address, transactor bind.ContractTransactor) (*FunctionsClientTransactor, error) { - contract, err := bindFunctionsClient(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &FunctionsClientTransactor{contract: contract}, nil -} - -func NewFunctionsClientFilterer(address common.Address, filterer bind.ContractFilterer) (*FunctionsClientFilterer, error) { - contract, err := bindFunctionsClient(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &FunctionsClientFilterer{contract: contract}, nil -} - -func bindFunctionsClient(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := FunctionsClientMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -func (_FunctionsClient *FunctionsClientRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _FunctionsClient.Contract.FunctionsClientCaller.contract.Call(opts, result, method, params...) -} - -func (_FunctionsClient *FunctionsClientRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsClient.Contract.FunctionsClientTransactor.contract.Transfer(opts) -} - -func (_FunctionsClient *FunctionsClientRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _FunctionsClient.Contract.FunctionsClientTransactor.contract.Transact(opts, method, params...) -} - -func (_FunctionsClient *FunctionsClientCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _FunctionsClient.Contract.contract.Call(opts, result, method, params...) -} - -func (_FunctionsClient *FunctionsClientTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsClient.Contract.contract.Transfer(opts) -} - -func (_FunctionsClient *FunctionsClientTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _FunctionsClient.Contract.contract.Transact(opts, method, params...) -} - -func (_FunctionsClient *FunctionsClientTransactor) HandleOracleFulfillment(opts *bind.TransactOpts, requestId [32]byte, response []byte, err []byte) (*types.Transaction, error) { - return _FunctionsClient.contract.Transact(opts, "handleOracleFulfillment", requestId, response, err) -} - -func (_FunctionsClient *FunctionsClientSession) HandleOracleFulfillment(requestId [32]byte, response []byte, err []byte) (*types.Transaction, error) { - return _FunctionsClient.Contract.HandleOracleFulfillment(&_FunctionsClient.TransactOpts, requestId, response, err) -} - -func (_FunctionsClient *FunctionsClientTransactorSession) HandleOracleFulfillment(requestId [32]byte, response []byte, err []byte) (*types.Transaction, error) { - return _FunctionsClient.Contract.HandleOracleFulfillment(&_FunctionsClient.TransactOpts, requestId, response, err) -} - -type FunctionsClientRequestFulfilledIterator struct { - Event *FunctionsClientRequestFulfilled - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsClientRequestFulfilledIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsClientRequestFulfilled) - 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(FunctionsClientRequestFulfilled) - 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 *FunctionsClientRequestFulfilledIterator) Error() error { - return it.fail -} - -func (it *FunctionsClientRequestFulfilledIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsClientRequestFulfilled struct { - Id [32]byte - Raw types.Log -} - -func (_FunctionsClient *FunctionsClientFilterer) FilterRequestFulfilled(opts *bind.FilterOpts, id [][32]byte) (*FunctionsClientRequestFulfilledIterator, error) { - - var idRule []interface{} - for _, idItem := range id { - idRule = append(idRule, idItem) - } - - logs, sub, err := _FunctionsClient.contract.FilterLogs(opts, "RequestFulfilled", idRule) - if err != nil { - return nil, err - } - return &FunctionsClientRequestFulfilledIterator{contract: _FunctionsClient.contract, event: "RequestFulfilled", logs: logs, sub: sub}, nil -} - -func (_FunctionsClient *FunctionsClientFilterer) WatchRequestFulfilled(opts *bind.WatchOpts, sink chan<- *FunctionsClientRequestFulfilled, id [][32]byte) (event.Subscription, error) { - - var idRule []interface{} - for _, idItem := range id { - idRule = append(idRule, idItem) - } - - logs, sub, err := _FunctionsClient.contract.WatchLogs(opts, "RequestFulfilled", idRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsClientRequestFulfilled) - if err := _FunctionsClient.contract.UnpackLog(event, "RequestFulfilled", 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 (_FunctionsClient *FunctionsClientFilterer) ParseRequestFulfilled(log types.Log) (*FunctionsClientRequestFulfilled, error) { - event := new(FunctionsClientRequestFulfilled) - if err := _FunctionsClient.contract.UnpackLog(event, "RequestFulfilled", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsClientRequestSentIterator struct { - Event *FunctionsClientRequestSent - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsClientRequestSentIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsClientRequestSent) - 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(FunctionsClientRequestSent) - 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 *FunctionsClientRequestSentIterator) Error() error { - return it.fail -} - -func (it *FunctionsClientRequestSentIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsClientRequestSent struct { - Id [32]byte - Raw types.Log -} - -func (_FunctionsClient *FunctionsClientFilterer) FilterRequestSent(opts *bind.FilterOpts, id [][32]byte) (*FunctionsClientRequestSentIterator, error) { - - var idRule []interface{} - for _, idItem := range id { - idRule = append(idRule, idItem) - } - - logs, sub, err := _FunctionsClient.contract.FilterLogs(opts, "RequestSent", idRule) - if err != nil { - return nil, err - } - return &FunctionsClientRequestSentIterator{contract: _FunctionsClient.contract, event: "RequestSent", logs: logs, sub: sub}, nil -} - -func (_FunctionsClient *FunctionsClientFilterer) WatchRequestSent(opts *bind.WatchOpts, sink chan<- *FunctionsClientRequestSent, id [][32]byte) (event.Subscription, error) { - - var idRule []interface{} - for _, idItem := range id { - idRule = append(idRule, idItem) - } - - logs, sub, err := _FunctionsClient.contract.WatchLogs(opts, "RequestSent", idRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsClientRequestSent) - if err := _FunctionsClient.contract.UnpackLog(event, "RequestSent", 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 (_FunctionsClient *FunctionsClientFilterer) ParseRequestSent(log types.Log) (*FunctionsClientRequestSent, error) { - event := new(FunctionsClientRequestSent) - if err := _FunctionsClient.contract.UnpackLog(event, "RequestSent", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -func (_FunctionsClient *FunctionsClient) ParseLog(log types.Log) (generated.AbigenLog, error) { - switch log.Topics[0] { - case _FunctionsClient.abi.Events["RequestFulfilled"].ID: - return _FunctionsClient.ParseRequestFulfilled(log) - case _FunctionsClient.abi.Events["RequestSent"].ID: - return _FunctionsClient.ParseRequestSent(log) - - default: - return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) - } -} - -func (FunctionsClientRequestFulfilled) Topic() common.Hash { - return common.HexToHash("0x85e1543bf2f84fe80c6badbce3648c8539ad1df4d2b3d822938ca0538be727e6") -} - -func (FunctionsClientRequestSent) Topic() common.Hash { - return common.HexToHash("0x1131472297a800fee664d1d89cfa8f7676ff07189ecc53f80bbb5f4969099db8") -} - -func (_FunctionsClient *FunctionsClient) Address() common.Address { - return _FunctionsClient.address -} - -type FunctionsClientInterface interface { - HandleOracleFulfillment(opts *bind.TransactOpts, requestId [32]byte, response []byte, err []byte) (*types.Transaction, error) - - FilterRequestFulfilled(opts *bind.FilterOpts, id [][32]byte) (*FunctionsClientRequestFulfilledIterator, error) - - WatchRequestFulfilled(opts *bind.WatchOpts, sink chan<- *FunctionsClientRequestFulfilled, id [][32]byte) (event.Subscription, error) - - ParseRequestFulfilled(log types.Log) (*FunctionsClientRequestFulfilled, error) - - FilterRequestSent(opts *bind.FilterOpts, id [][32]byte) (*FunctionsClientRequestSentIterator, error) - - WatchRequestSent(opts *bind.WatchOpts, sink chan<- *FunctionsClientRequestSent, id [][32]byte) (event.Subscription, error) - - ParseRequestSent(log types.Log) (*FunctionsClientRequestSent, error) - - ParseLog(log types.Log) (generated.AbigenLog, error) - - Address() common.Address -} diff --git a/core/gethwrappers/generated/functions_client_example/functions_client_example.go b/core/gethwrappers/generated/functions_client_example/functions_client_example.go deleted file mode 100644 index 90f7be78cbf..00000000000 --- a/core/gethwrappers/generated/functions_client_example/functions_client_example.go +++ /dev/null @@ -1,988 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package functions_client_example - -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 FunctionsClientExampleMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyArgs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySource\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoInlineSecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyRouterCanFufill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"UnexpectedRequestID\",\"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\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestSent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_GAS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"handleOracleFulfillment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastError\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastErrorLength\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastRequestId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastResponse\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastResponseLength\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"source\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedSecretsReferences\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"args\",\"type\":\"string[]\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"jobId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b5060405162001a3038038062001a30833981016040819052620000349162000199565b600080546001600160a01b0319166001600160a01b038316178155339081906001600160a01b038216620000af5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600180546001600160a01b0319166001600160a01b0384811691909117909155811615620000e257620000e281620000ec565b50505050620001cb565b6001600160a01b038116331415620001475760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000a6565b600280546001600160a01b0319166001600160a01b03838116918217909255600154604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b600060208284031215620001ac57600080fd5b81516001600160a01b0381168114620001c457600080fd5b9392505050565b61185580620001db6000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80636d9809a011610081578063b48cffea1161005b578063b48cffea14610182578063f2fde38b14610192578063fc2a88c3146101a557600080fd5b80636d9809a01461014857806379ba5097146101525780638da5cb5b1461015a57600080fd5b80632c29166b116100b25780632c29166b146100ff5780635fa353e71461012c57806362747e421461013f57600080fd5b80630ca76175146100ce57806329f0de3f146100e3575b600080fd5b6100e16100dc36600461129e565b6101ae565b005b6100ec60055481565b6040519081526020015b60405180910390f35b60065461011790640100000000900463ffffffff1681565b60405163ffffffff90911681526020016100f6565b6100e161013a36600461130b565b61020f565b6100ec60045481565b6101176201117081565b6100e1610319565b60015460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f6565b6006546101179063ffffffff1681565b6100e16101a036600461124f565b61041f565b6100ec60035481565b60005473ffffffffffffffffffffffffffffffffffffffff1633146101ff576040517f5099014100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61020a838383610433565b505050565b610217610501565b6102586040805160e0810190915280600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b61029a89898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506105849050565b85156102e2576102e287878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506105959050565b83156102fc576102fc6102f58587611679565b82906105dc565b61030b8184620111708561061c565b600355505050505050505050565b60025473ffffffffffffffffffffffffffffffffffffffff16331461039f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560028054909116905560405173ffffffffffffffffffffffffffffffffffffffff909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b610427610501565b61043081610640565b50565b8260035414610471576040517fd068bf5b00000000000000000000000000000000000000000000000000000000815260048101849052602401610396565b61047a82610737565b6004558151600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff9092169190911790556104bc81610737565b600555516006805463ffffffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff9092169190911790555050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610396565b565b61059182600080846107bf565b5050565b80516105cd576040517fe889636f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016020830152608090910152565b8051610614576040517ffe936cb700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a090910152565b60008061062886610853565b905061063681868686610bc5565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81163314156106c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610396565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600154604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b60008060006020905060208451101561074e575082515b60005b818110156107b657610764816008611625565b858281518110610776576107766117ea565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c9290921791806107ae81611718565b915050610751565b50909392505050565b80516107f7576040517f22ce3edd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8383600281111561080a5761080a6117bb565b9081600281111561081d5761081d6117bb565b90525060408401828015610833576108336117bb565b90818015610843576108436117bb565b9052506060909301929092525050565b606061085d61111e565b805161086b90610100610cad565b506108ab816040518060400160405280600c81526020017f636f64654c6f636174696f6e0000000000000000000000000000000000000000815250610d27565b6108ca81846000015160028111156108c5576108c56117bb565b610d40565b610909816040518060400160405280600881526020017f6c616e6775616765000000000000000000000000000000000000000000000000815250610d27565b61092381846040015160008111156108c5576108c56117bb565b610962816040518060400160405280600681526020017f736f757263650000000000000000000000000000000000000000000000000000815250610d27565b610970818460600151610d27565b60a08301515115610a16576109ba816040518060400160405280600481526020017f6172677300000000000000000000000000000000000000000000000000000000815250610d27565b6109c381610d79565b60005b8360a0015151811015610a0c576109fa828560a0015183815181106109ed576109ed6117ea565b6020026020010151610d27565b80610a0481611718565b9150506109c6565b50610a1681610d9d565b60808301515115610b1757600083602001516002811115610a3957610a396117bb565b1415610a71576040517fa80d31f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ab0816040518060400160405280600f81526020017f736563726574734c6f636174696f6e0000000000000000000000000000000000815250610d27565b610aca81846020015160028111156108c5576108c56117bb565b610b09816040518060400160405280600781526020017f7365637265747300000000000000000000000000000000000000000000000000815250610d27565b610b17818460800151610dbb565b60c08301515115610bbd57610b61816040518060400160405280600981526020017f6279746573417267730000000000000000000000000000000000000000000000815250610d27565b610b6a81610d79565b60005b8360c0015151811015610bb357610ba1828560c001518381518110610b9457610b946117ea565b6020026020010151610dbb565b80610bab81611718565b915050610b6d565b50610bbd81610d9d565b515192915050565b600080546040517f461d276200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063461d276290610c259087908990600190899089906004016113ef565b602060405180830381600087803b158015610c3f57600080fd5b505af1158015610c53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c779190611285565b60405190915081907f1131472297a800fee664d1d89cfa8f7676ff07189ecc53f80bbb5f4969099db890600090a2949350505050565b604080518082019091526060815260006020820152610ccd602083611751565b15610cf557610cdd602083611751565b610ce8906020611662565b610cf290836114e6565b91505b602080840183905260405180855260008152908184010181811015610d1957600080fd5b604052508290505b92915050565b610d348260038351610dc4565b815161020a9082610eeb565b8151610d4d9060c2610f13565b506105918282604051602001610d6591815260200190565b604051602081830303815290604052610dbb565b610d84816004610f7c565b600181602001818151610d9791906114e6565b90525050565b610da8816007610f7c565b600181602001818151610d979190611662565b610d3482600283515b60178167ffffffffffffffff1611610df1578251610deb9060e0600585901b168317610f13565b50505050565b60ff8167ffffffffffffffff1611610e33578251610e1a906018611fe0600586901b1617610f13565b508251610deb9067ffffffffffffffff83166001610f93565b61ffff8167ffffffffffffffff1611610e76578251610e5d906019611fe0600586901b1617610f13565b508251610deb9067ffffffffffffffff83166002610f93565b63ffffffff8167ffffffffffffffff1611610ebb578251610ea290601a611fe0600586901b1617610f13565b508251610deb9067ffffffffffffffff83166004610f93565b8251610ed290601b611fe0600586901b1617610f13565b508251610deb9067ffffffffffffffff83166008610f93565b604080518082019091526060815260006020820152610f0c83838451611018565b9392505050565b6040805180820190915260608152600060208201528251516000610f388260016114e6565b905084602001518210610f5957610f5985610f54836002611625565b611107565b8451602083820101858153508051821115610f72578181525b5093949350505050565b815161020a90601f611fe0600585901b1617610f13565b6040805180820190915260608152600060208201528351516000610fb782856114e6565b90508560200151811115610fd457610fd486610f54836002611625565b60006001610fe48661010061155f565b610fee9190611662565b9050865182810187831982511617815250805183111561100c578281525b50959695505050505050565b604080518082019091526060815260006020820152825182111561103b57600080fd5b835151600061104a84836114e6565b905085602001518111156110675761106786610f54836002611625565b855180518382016020019160009180851115611081578482525b505050602086015b602086106110c157805182526110a06020836114e6565b91506110ad6020826114e6565b90506110ba602087611662565b9550611089565b5181517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208890036101000a0190811690199190911617905250849150509392505050565b81516111138383610cad565b50610deb8382610eeb565b6040518060400160405280611146604051806040016040528060608152602001600081525090565b8152602001600081525090565b600067ffffffffffffffff83111561116d5761116d611819565b61119e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f86011601611497565b90508281528383830111156111b257600080fd5b828260208301376000602084830101529392505050565b60008083601f8401126111db57600080fd5b50813567ffffffffffffffff8111156111f357600080fd5b60208301915083602082850101111561120b57600080fd5b9250929050565b600082601f83011261122357600080fd5b610f0c83833560208501611153565b803567ffffffffffffffff8116811461124a57600080fd5b919050565b60006020828403121561126157600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610f0c57600080fd5b60006020828403121561129757600080fd5b5051919050565b6000806000606084860312156112b357600080fd5b83359250602084013567ffffffffffffffff808211156112d257600080fd5b6112de87838801611212565b935060408601359150808211156112f457600080fd5b5061130186828701611212565b9150509250925092565b60008060008060008060008060a0898b03121561132757600080fd5b883567ffffffffffffffff8082111561133f57600080fd5b61134b8c838d016111c9565b909a50985060208b013591508082111561136457600080fd5b6113708c838d016111c9565b909850965060408b013591508082111561138957600080fd5b818b0191508b601f83011261139d57600080fd5b8135818111156113ac57600080fd5b8c60208260051b85010111156113c157600080fd5b6020830196508095505050506113d960608a01611232565b9150608089013590509295985092959890939650565b67ffffffffffffffff861681526000602060a08184015286518060a085015260005b8181101561142d5788810183015185820160c001528201611411565b8181111561143f57600060c083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016830160c001915061147e9050604083018661ffff169052565b63ffffffff939093166060820152608001529392505050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156114de576114de611819565b604052919050565b600082198211156114f9576114f961178c565b500190565b600181815b8085111561155757817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561153d5761153d61178c565b8085161561154a57918102915b93841c9390800290611503565b509250929050565b6000610f0c838360008261157557506001610d21565b8161158257506000610d21565b816001811461159857600281146115a2576115be565b6001915050610d21565b60ff8411156115b3576115b361178c565b50506001821b610d21565b5060208310610133831016604e8410600b84101617156115e1575081810a610d21565b6115eb83836114fe565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561161d5761161d61178c565b029392505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561165d5761165d61178c565b500290565b6000828210156116745761167461178c565b500390565b600067ffffffffffffffff8084111561169457611694611819565b8360051b60206116a5818301611497565b86815281810190863685820111156116bc57600080fd5b600094505b8885101561170c578035868111156116d857600080fd5b880136601f8201126116e957600080fd5b6116f7368235878401611153565b845250600194909401939183019183016116c1565b50979650505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561174a5761174a61178c565b5060010190565b600082611787577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", -} - -var FunctionsClientExampleABI = FunctionsClientExampleMetaData.ABI - -var FunctionsClientExampleBin = FunctionsClientExampleMetaData.Bin - -func DeployFunctionsClientExample(auth *bind.TransactOpts, backend bind.ContractBackend, router common.Address) (common.Address, *types.Transaction, *FunctionsClientExample, error) { - parsed, err := FunctionsClientExampleMetaData.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(FunctionsClientExampleBin), backend, router) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &FunctionsClientExample{FunctionsClientExampleCaller: FunctionsClientExampleCaller{contract: contract}, FunctionsClientExampleTransactor: FunctionsClientExampleTransactor{contract: contract}, FunctionsClientExampleFilterer: FunctionsClientExampleFilterer{contract: contract}}, nil -} - -type FunctionsClientExample struct { - address common.Address - abi abi.ABI - FunctionsClientExampleCaller - FunctionsClientExampleTransactor - FunctionsClientExampleFilterer -} - -type FunctionsClientExampleCaller struct { - contract *bind.BoundContract -} - -type FunctionsClientExampleTransactor struct { - contract *bind.BoundContract -} - -type FunctionsClientExampleFilterer struct { - contract *bind.BoundContract -} - -type FunctionsClientExampleSession struct { - Contract *FunctionsClientExample - CallOpts bind.CallOpts - TransactOpts bind.TransactOpts -} - -type FunctionsClientExampleCallerSession struct { - Contract *FunctionsClientExampleCaller - CallOpts bind.CallOpts -} - -type FunctionsClientExampleTransactorSession struct { - Contract *FunctionsClientExampleTransactor - TransactOpts bind.TransactOpts -} - -type FunctionsClientExampleRaw struct { - Contract *FunctionsClientExample -} - -type FunctionsClientExampleCallerRaw struct { - Contract *FunctionsClientExampleCaller -} - -type FunctionsClientExampleTransactorRaw struct { - Contract *FunctionsClientExampleTransactor -} - -func NewFunctionsClientExample(address common.Address, backend bind.ContractBackend) (*FunctionsClientExample, error) { - abi, err := abi.JSON(strings.NewReader(FunctionsClientExampleABI)) - if err != nil { - return nil, err - } - contract, err := bindFunctionsClientExample(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &FunctionsClientExample{address: address, abi: abi, FunctionsClientExampleCaller: FunctionsClientExampleCaller{contract: contract}, FunctionsClientExampleTransactor: FunctionsClientExampleTransactor{contract: contract}, FunctionsClientExampleFilterer: FunctionsClientExampleFilterer{contract: contract}}, nil -} - -func NewFunctionsClientExampleCaller(address common.Address, caller bind.ContractCaller) (*FunctionsClientExampleCaller, error) { - contract, err := bindFunctionsClientExample(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &FunctionsClientExampleCaller{contract: contract}, nil -} - -func NewFunctionsClientExampleTransactor(address common.Address, transactor bind.ContractTransactor) (*FunctionsClientExampleTransactor, error) { - contract, err := bindFunctionsClientExample(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &FunctionsClientExampleTransactor{contract: contract}, nil -} - -func NewFunctionsClientExampleFilterer(address common.Address, filterer bind.ContractFilterer) (*FunctionsClientExampleFilterer, error) { - contract, err := bindFunctionsClientExample(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &FunctionsClientExampleFilterer{contract: contract}, nil -} - -func bindFunctionsClientExample(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := FunctionsClientExampleMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -func (_FunctionsClientExample *FunctionsClientExampleRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _FunctionsClientExample.Contract.FunctionsClientExampleCaller.contract.Call(opts, result, method, params...) -} - -func (_FunctionsClientExample *FunctionsClientExampleRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsClientExample.Contract.FunctionsClientExampleTransactor.contract.Transfer(opts) -} - -func (_FunctionsClientExample *FunctionsClientExampleRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _FunctionsClientExample.Contract.FunctionsClientExampleTransactor.contract.Transact(opts, method, params...) -} - -func (_FunctionsClientExample *FunctionsClientExampleCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _FunctionsClientExample.Contract.contract.Call(opts, result, method, params...) -} - -func (_FunctionsClientExample *FunctionsClientExampleTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsClientExample.Contract.contract.Transfer(opts) -} - -func (_FunctionsClientExample *FunctionsClientExampleTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _FunctionsClientExample.Contract.contract.Transact(opts, method, params...) -} - -func (_FunctionsClientExample *FunctionsClientExampleCaller) MAXCALLBACKGAS(opts *bind.CallOpts) (uint32, error) { - var out []interface{} - err := _FunctionsClientExample.contract.Call(opts, &out, "MAX_CALLBACK_GAS") - - if err != nil { - return *new(uint32), err - } - - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) - - return out0, err - -} - -func (_FunctionsClientExample *FunctionsClientExampleSession) MAXCALLBACKGAS() (uint32, error) { - return _FunctionsClientExample.Contract.MAXCALLBACKGAS(&_FunctionsClientExample.CallOpts) -} - -func (_FunctionsClientExample *FunctionsClientExampleCallerSession) MAXCALLBACKGAS() (uint32, error) { - return _FunctionsClientExample.Contract.MAXCALLBACKGAS(&_FunctionsClientExample.CallOpts) -} - -func (_FunctionsClientExample *FunctionsClientExampleCaller) LastError(opts *bind.CallOpts) ([32]byte, error) { - var out []interface{} - err := _FunctionsClientExample.contract.Call(opts, &out, "lastError") - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -func (_FunctionsClientExample *FunctionsClientExampleSession) LastError() ([32]byte, error) { - return _FunctionsClientExample.Contract.LastError(&_FunctionsClientExample.CallOpts) -} - -func (_FunctionsClientExample *FunctionsClientExampleCallerSession) LastError() ([32]byte, error) { - return _FunctionsClientExample.Contract.LastError(&_FunctionsClientExample.CallOpts) -} - -func (_FunctionsClientExample *FunctionsClientExampleCaller) LastErrorLength(opts *bind.CallOpts) (uint32, error) { - var out []interface{} - err := _FunctionsClientExample.contract.Call(opts, &out, "lastErrorLength") - - if err != nil { - return *new(uint32), err - } - - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) - - return out0, err - -} - -func (_FunctionsClientExample *FunctionsClientExampleSession) LastErrorLength() (uint32, error) { - return _FunctionsClientExample.Contract.LastErrorLength(&_FunctionsClientExample.CallOpts) -} - -func (_FunctionsClientExample *FunctionsClientExampleCallerSession) LastErrorLength() (uint32, error) { - return _FunctionsClientExample.Contract.LastErrorLength(&_FunctionsClientExample.CallOpts) -} - -func (_FunctionsClientExample *FunctionsClientExampleCaller) LastRequestId(opts *bind.CallOpts) ([32]byte, error) { - var out []interface{} - err := _FunctionsClientExample.contract.Call(opts, &out, "lastRequestId") - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -func (_FunctionsClientExample *FunctionsClientExampleSession) LastRequestId() ([32]byte, error) { - return _FunctionsClientExample.Contract.LastRequestId(&_FunctionsClientExample.CallOpts) -} - -func (_FunctionsClientExample *FunctionsClientExampleCallerSession) LastRequestId() ([32]byte, error) { - return _FunctionsClientExample.Contract.LastRequestId(&_FunctionsClientExample.CallOpts) -} - -func (_FunctionsClientExample *FunctionsClientExampleCaller) LastResponse(opts *bind.CallOpts) ([32]byte, error) { - var out []interface{} - err := _FunctionsClientExample.contract.Call(opts, &out, "lastResponse") - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -func (_FunctionsClientExample *FunctionsClientExampleSession) LastResponse() ([32]byte, error) { - return _FunctionsClientExample.Contract.LastResponse(&_FunctionsClientExample.CallOpts) -} - -func (_FunctionsClientExample *FunctionsClientExampleCallerSession) LastResponse() ([32]byte, error) { - return _FunctionsClientExample.Contract.LastResponse(&_FunctionsClientExample.CallOpts) -} - -func (_FunctionsClientExample *FunctionsClientExampleCaller) LastResponseLength(opts *bind.CallOpts) (uint32, error) { - var out []interface{} - err := _FunctionsClientExample.contract.Call(opts, &out, "lastResponseLength") - - if err != nil { - return *new(uint32), err - } - - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) - - return out0, err - -} - -func (_FunctionsClientExample *FunctionsClientExampleSession) LastResponseLength() (uint32, error) { - return _FunctionsClientExample.Contract.LastResponseLength(&_FunctionsClientExample.CallOpts) -} - -func (_FunctionsClientExample *FunctionsClientExampleCallerSession) LastResponseLength() (uint32, error) { - return _FunctionsClientExample.Contract.LastResponseLength(&_FunctionsClientExample.CallOpts) -} - -func (_FunctionsClientExample *FunctionsClientExampleCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _FunctionsClientExample.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 (_FunctionsClientExample *FunctionsClientExampleSession) Owner() (common.Address, error) { - return _FunctionsClientExample.Contract.Owner(&_FunctionsClientExample.CallOpts) -} - -func (_FunctionsClientExample *FunctionsClientExampleCallerSession) Owner() (common.Address, error) { - return _FunctionsClientExample.Contract.Owner(&_FunctionsClientExample.CallOpts) -} - -func (_FunctionsClientExample *FunctionsClientExampleTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsClientExample.contract.Transact(opts, "acceptOwnership") -} - -func (_FunctionsClientExample *FunctionsClientExampleSession) AcceptOwnership() (*types.Transaction, error) { - return _FunctionsClientExample.Contract.AcceptOwnership(&_FunctionsClientExample.TransactOpts) -} - -func (_FunctionsClientExample *FunctionsClientExampleTransactorSession) AcceptOwnership() (*types.Transaction, error) { - return _FunctionsClientExample.Contract.AcceptOwnership(&_FunctionsClientExample.TransactOpts) -} - -func (_FunctionsClientExample *FunctionsClientExampleTransactor) HandleOracleFulfillment(opts *bind.TransactOpts, requestId [32]byte, response []byte, err []byte) (*types.Transaction, error) { - return _FunctionsClientExample.contract.Transact(opts, "handleOracleFulfillment", requestId, response, err) -} - -func (_FunctionsClientExample *FunctionsClientExampleSession) HandleOracleFulfillment(requestId [32]byte, response []byte, err []byte) (*types.Transaction, error) { - return _FunctionsClientExample.Contract.HandleOracleFulfillment(&_FunctionsClientExample.TransactOpts, requestId, response, err) -} - -func (_FunctionsClientExample *FunctionsClientExampleTransactorSession) HandleOracleFulfillment(requestId [32]byte, response []byte, err []byte) (*types.Transaction, error) { - return _FunctionsClientExample.Contract.HandleOracleFulfillment(&_FunctionsClientExample.TransactOpts, requestId, response, err) -} - -func (_FunctionsClientExample *FunctionsClientExampleTransactor) SendRequest(opts *bind.TransactOpts, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) { - return _FunctionsClientExample.contract.Transact(opts, "sendRequest", source, encryptedSecretsReferences, args, subscriptionId, jobId) -} - -func (_FunctionsClientExample *FunctionsClientExampleSession) SendRequest(source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) { - return _FunctionsClientExample.Contract.SendRequest(&_FunctionsClientExample.TransactOpts, source, encryptedSecretsReferences, args, subscriptionId, jobId) -} - -func (_FunctionsClientExample *FunctionsClientExampleTransactorSession) SendRequest(source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) { - return _FunctionsClientExample.Contract.SendRequest(&_FunctionsClientExample.TransactOpts, source, encryptedSecretsReferences, args, subscriptionId, jobId) -} - -func (_FunctionsClientExample *FunctionsClientExampleTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _FunctionsClientExample.contract.Transact(opts, "transferOwnership", to) -} - -func (_FunctionsClientExample *FunctionsClientExampleSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _FunctionsClientExample.Contract.TransferOwnership(&_FunctionsClientExample.TransactOpts, to) -} - -func (_FunctionsClientExample *FunctionsClientExampleTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _FunctionsClientExample.Contract.TransferOwnership(&_FunctionsClientExample.TransactOpts, to) -} - -type FunctionsClientExampleOwnershipTransferRequestedIterator struct { - Event *FunctionsClientExampleOwnershipTransferRequested - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsClientExampleOwnershipTransferRequestedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsClientExampleOwnershipTransferRequested) - 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(FunctionsClientExampleOwnershipTransferRequested) - 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 *FunctionsClientExampleOwnershipTransferRequestedIterator) Error() error { - return it.fail -} - -func (it *FunctionsClientExampleOwnershipTransferRequestedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsClientExampleOwnershipTransferRequested struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_FunctionsClientExample *FunctionsClientExampleFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsClientExampleOwnershipTransferRequestedIterator, 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 := _FunctionsClientExample.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) - if err != nil { - return nil, err - } - return &FunctionsClientExampleOwnershipTransferRequestedIterator{contract: _FunctionsClientExample.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil -} - -func (_FunctionsClientExample *FunctionsClientExampleFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsClientExampleOwnershipTransferRequested, 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 := _FunctionsClientExample.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(FunctionsClientExampleOwnershipTransferRequested) - if err := _FunctionsClientExample.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 (_FunctionsClientExample *FunctionsClientExampleFilterer) ParseOwnershipTransferRequested(log types.Log) (*FunctionsClientExampleOwnershipTransferRequested, error) { - event := new(FunctionsClientExampleOwnershipTransferRequested) - if err := _FunctionsClientExample.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsClientExampleOwnershipTransferredIterator struct { - Event *FunctionsClientExampleOwnershipTransferred - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsClientExampleOwnershipTransferredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsClientExampleOwnershipTransferred) - 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(FunctionsClientExampleOwnershipTransferred) - 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 *FunctionsClientExampleOwnershipTransferredIterator) Error() error { - return it.fail -} - -func (it *FunctionsClientExampleOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsClientExampleOwnershipTransferred struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_FunctionsClientExample *FunctionsClientExampleFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsClientExampleOwnershipTransferredIterator, 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 := _FunctionsClientExample.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) - if err != nil { - return nil, err - } - return &FunctionsClientExampleOwnershipTransferredIterator{contract: _FunctionsClientExample.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil -} - -func (_FunctionsClientExample *FunctionsClientExampleFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *FunctionsClientExampleOwnershipTransferred, 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 := _FunctionsClientExample.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(FunctionsClientExampleOwnershipTransferred) - if err := _FunctionsClientExample.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 (_FunctionsClientExample *FunctionsClientExampleFilterer) ParseOwnershipTransferred(log types.Log) (*FunctionsClientExampleOwnershipTransferred, error) { - event := new(FunctionsClientExampleOwnershipTransferred) - if err := _FunctionsClientExample.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsClientExampleRequestFulfilledIterator struct { - Event *FunctionsClientExampleRequestFulfilled - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsClientExampleRequestFulfilledIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsClientExampleRequestFulfilled) - 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(FunctionsClientExampleRequestFulfilled) - 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 *FunctionsClientExampleRequestFulfilledIterator) Error() error { - return it.fail -} - -func (it *FunctionsClientExampleRequestFulfilledIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsClientExampleRequestFulfilled struct { - Id [32]byte - Raw types.Log -} - -func (_FunctionsClientExample *FunctionsClientExampleFilterer) FilterRequestFulfilled(opts *bind.FilterOpts, id [][32]byte) (*FunctionsClientExampleRequestFulfilledIterator, error) { - - var idRule []interface{} - for _, idItem := range id { - idRule = append(idRule, idItem) - } - - logs, sub, err := _FunctionsClientExample.contract.FilterLogs(opts, "RequestFulfilled", idRule) - if err != nil { - return nil, err - } - return &FunctionsClientExampleRequestFulfilledIterator{contract: _FunctionsClientExample.contract, event: "RequestFulfilled", logs: logs, sub: sub}, nil -} - -func (_FunctionsClientExample *FunctionsClientExampleFilterer) WatchRequestFulfilled(opts *bind.WatchOpts, sink chan<- *FunctionsClientExampleRequestFulfilled, id [][32]byte) (event.Subscription, error) { - - var idRule []interface{} - for _, idItem := range id { - idRule = append(idRule, idItem) - } - - logs, sub, err := _FunctionsClientExample.contract.WatchLogs(opts, "RequestFulfilled", idRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsClientExampleRequestFulfilled) - if err := _FunctionsClientExample.contract.UnpackLog(event, "RequestFulfilled", 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 (_FunctionsClientExample *FunctionsClientExampleFilterer) ParseRequestFulfilled(log types.Log) (*FunctionsClientExampleRequestFulfilled, error) { - event := new(FunctionsClientExampleRequestFulfilled) - if err := _FunctionsClientExample.contract.UnpackLog(event, "RequestFulfilled", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsClientExampleRequestSentIterator struct { - Event *FunctionsClientExampleRequestSent - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsClientExampleRequestSentIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsClientExampleRequestSent) - 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(FunctionsClientExampleRequestSent) - 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 *FunctionsClientExampleRequestSentIterator) Error() error { - return it.fail -} - -func (it *FunctionsClientExampleRequestSentIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsClientExampleRequestSent struct { - Id [32]byte - Raw types.Log -} - -func (_FunctionsClientExample *FunctionsClientExampleFilterer) FilterRequestSent(opts *bind.FilterOpts, id [][32]byte) (*FunctionsClientExampleRequestSentIterator, error) { - - var idRule []interface{} - for _, idItem := range id { - idRule = append(idRule, idItem) - } - - logs, sub, err := _FunctionsClientExample.contract.FilterLogs(opts, "RequestSent", idRule) - if err != nil { - return nil, err - } - return &FunctionsClientExampleRequestSentIterator{contract: _FunctionsClientExample.contract, event: "RequestSent", logs: logs, sub: sub}, nil -} - -func (_FunctionsClientExample *FunctionsClientExampleFilterer) WatchRequestSent(opts *bind.WatchOpts, sink chan<- *FunctionsClientExampleRequestSent, id [][32]byte) (event.Subscription, error) { - - var idRule []interface{} - for _, idItem := range id { - idRule = append(idRule, idItem) - } - - logs, sub, err := _FunctionsClientExample.contract.WatchLogs(opts, "RequestSent", idRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsClientExampleRequestSent) - if err := _FunctionsClientExample.contract.UnpackLog(event, "RequestSent", 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 (_FunctionsClientExample *FunctionsClientExampleFilterer) ParseRequestSent(log types.Log) (*FunctionsClientExampleRequestSent, error) { - event := new(FunctionsClientExampleRequestSent) - if err := _FunctionsClientExample.contract.UnpackLog(event, "RequestSent", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -func (_FunctionsClientExample *FunctionsClientExample) ParseLog(log types.Log) (generated.AbigenLog, error) { - switch log.Topics[0] { - case _FunctionsClientExample.abi.Events["OwnershipTransferRequested"].ID: - return _FunctionsClientExample.ParseOwnershipTransferRequested(log) - case _FunctionsClientExample.abi.Events["OwnershipTransferred"].ID: - return _FunctionsClientExample.ParseOwnershipTransferred(log) - case _FunctionsClientExample.abi.Events["RequestFulfilled"].ID: - return _FunctionsClientExample.ParseRequestFulfilled(log) - case _FunctionsClientExample.abi.Events["RequestSent"].ID: - return _FunctionsClientExample.ParseRequestSent(log) - - default: - return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) - } -} - -func (FunctionsClientExampleOwnershipTransferRequested) Topic() common.Hash { - return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") -} - -func (FunctionsClientExampleOwnershipTransferred) Topic() common.Hash { - return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") -} - -func (FunctionsClientExampleRequestFulfilled) Topic() common.Hash { - return common.HexToHash("0x85e1543bf2f84fe80c6badbce3648c8539ad1df4d2b3d822938ca0538be727e6") -} - -func (FunctionsClientExampleRequestSent) Topic() common.Hash { - return common.HexToHash("0x1131472297a800fee664d1d89cfa8f7676ff07189ecc53f80bbb5f4969099db8") -} - -func (_FunctionsClientExample *FunctionsClientExample) Address() common.Address { - return _FunctionsClientExample.address -} - -type FunctionsClientExampleInterface interface { - MAXCALLBACKGAS(opts *bind.CallOpts) (uint32, error) - - LastError(opts *bind.CallOpts) ([32]byte, error) - - LastErrorLength(opts *bind.CallOpts) (uint32, error) - - LastRequestId(opts *bind.CallOpts) ([32]byte, error) - - LastResponse(opts *bind.CallOpts) ([32]byte, error) - - LastResponseLength(opts *bind.CallOpts) (uint32, error) - - Owner(opts *bind.CallOpts) (common.Address, error) - - AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) - - HandleOracleFulfillment(opts *bind.TransactOpts, requestId [32]byte, response []byte, err []byte) (*types.Transaction, error) - - SendRequest(opts *bind.TransactOpts, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) - - TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) - - FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsClientExampleOwnershipTransferRequestedIterator, error) - - WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsClientExampleOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) - - ParseOwnershipTransferRequested(log types.Log) (*FunctionsClientExampleOwnershipTransferRequested, error) - - FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsClientExampleOwnershipTransferredIterator, error) - - WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *FunctionsClientExampleOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) - - ParseOwnershipTransferred(log types.Log) (*FunctionsClientExampleOwnershipTransferred, error) - - FilterRequestFulfilled(opts *bind.FilterOpts, id [][32]byte) (*FunctionsClientExampleRequestFulfilledIterator, error) - - WatchRequestFulfilled(opts *bind.WatchOpts, sink chan<- *FunctionsClientExampleRequestFulfilled, id [][32]byte) (event.Subscription, error) - - ParseRequestFulfilled(log types.Log) (*FunctionsClientExampleRequestFulfilled, error) - - FilterRequestSent(opts *bind.FilterOpts, id [][32]byte) (*FunctionsClientExampleRequestSentIterator, error) - - WatchRequestSent(opts *bind.WatchOpts, sink chan<- *FunctionsClientExampleRequestSent, id [][32]byte) (event.Subscription, error) - - ParseRequestSent(log types.Log) (*FunctionsClientExampleRequestSent, error) - - ParseLog(log types.Log) (generated.AbigenLog, error) - - Address() common.Address -} diff --git a/core/gethwrappers/generated/functions_coordinator/functions_coordinator.go b/core/gethwrappers/generated/functions_coordinator/functions_coordinator.go deleted file mode 100644 index b52268c6fb8..00000000000 --- a/core/gethwrappers/generated/functions_coordinator/functions_coordinator.go +++ /dev/null @@ -1,2612 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package functions_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 FunctionsBillingCommitment struct { - SubscriptionId uint64 - Client common.Address - CallbackGasLimit uint32 - ExpectedGasPrice *big.Int - Don common.Address - DonFee *big.Int - AdminFee *big.Int - EstimatedTotalCostJuels *big.Int - GasOverhead *big.Int - Timestamp *big.Int -} - -type IFunctionsBillingRequestBilling struct { - SubscriptionId uint64 - Client common.Address - CallbackGasLimit uint32 - ExpectedGasPrice *big.Int -} - -type IFunctionsCoordinatorRequest struct { - SubscriptionId uint64 - Data []byte - DataVersion uint16 - CallbackGasLimit uint32 - Caller common.Address - SubscriptionOwner common.Address -} - -var FunctionsCoordinatorMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"linkToNativeFeed\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyPublicKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyRequestData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentReportData\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouterOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReportInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustBeSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedPublicKeyChange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedRequestDataVersion\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"signerPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"transmitterPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalCost\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"enumFulfillResult\",\"name\":\"result\",\"type\":\"uint8\"}],\"name\":\"BillingEnd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"expectedGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"don\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"donFee\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"adminFee\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structFunctionsBilling.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"name\":\"BillingStart\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"fee\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"CostExceedsCommitment\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"InsufficientGasProvided\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"InvalidRequestID\",\"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\":\"OCRConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"}],\"name\":\"OracleRequest\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"OracleResponse\",\"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\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestTimedOut\",\"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\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"deleteCommitment\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"node\",\"type\":\"address\"}],\"name\":\"deleteNodePublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"}],\"name\":\"estimateCost\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"expectedGasPrice\",\"type\":\"uint256\"}],\"internalType\":\"structIFunctionsBilling.RequestBilling\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"getAdminFee\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllNodePublicKeys\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"linkPriceFeed\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfigHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"config\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"expectedGasPrice\",\"type\":\"uint256\"}],\"internalType\":\"structIFunctionsBilling.RequestBilling\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"getDONFee\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDONPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeedData\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getThresholdPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"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\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"}],\"internalType\":\"structIFunctionsCoordinator.Request\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"sendRequest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"uint96\",\"name\":\"estimatedCost\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"config\",\"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\"},{\"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\":\"bytes\",\"name\":\"donPublicKey\",\"type\":\"bytes\"}],\"name\":\"setDONPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"node\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"publicKey\",\"type\":\"bytes\"}],\"name\":\"setNodePublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"thresholdPublicKey\",\"type\":\"bytes\"}],\"name\":\"setThresholdPublicKey\",\"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\":\"transmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b50604051620059403803806200594083398101604081905262000034916200042d565b828282828260013380600081620000925760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c557620000c58162000156565b505050151560f81b6080526001600160a01b038216620000f857604051632530e88560e11b815260040160405180910390fd5b600980546001600160a01b0319166001600160a01b0384161790556200011e8162000202565b805160209091012060085550600a80546001600160a01b0319166001600160a01b039290921691909117905550620006009350505050565b6001600160a01b038116331415620001b15760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000089565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000806000806000806000808880602001905181019062000224919062000532565b97509750975097509750975097509750600084136200025a576040516321ea67b360e11b81526004810185905260240162000089565b604080516101008101825263ffffffff808b168083528a8216602084018190528983168486018190528b841660608601819052938916608086018190526001600160601b03891660a0870181905260c087018c905261ffff891660e0909701879052600c8054600160a01b9092026001600160a01b03600160801b909402939093166001600160801b036c0100000000000000000000000090980263ffffffff60601b196801000000000000000090960295909516600160401b600160801b03196401000000009097026001600160401b0319909416909717929092179490941694909417919091179390931691909117919091179055600d869055600e805461ffff19169091179055517fd09395baf4d99e44ce1b8e96a4396a3f896d0fd5e4517993f28ce0a6fb42e22790620003e8908a908a9089908b908a908990899063ffffffff97881681529587166020870152938616604086015291909416606084015260808301939093526001600160601b039290921660a082015261ffff9190911660c082015260e00190565b60405180910390a1505050505050505050565b80516001600160a01b03811681146200041357600080fd5b919050565b805163ffffffff811681146200041357600080fd5b6000806000606084860312156200044357600080fd5b6200044e84620003fb565b602085810151919450906001600160401b03808211156200046e57600080fd5b818701915087601f8301126200048357600080fd5b815181811115620004985762000498620005ea565b604051601f8201601f19908116603f01168101908382118183101715620004c357620004c3620005ea565b816040528281528a86848701011115620004dc57600080fd5b600093505b82841015620005005784840186015181850187015292850192620004e1565b82841115620005125760008684830101525b8097505050505050506200052960408501620003fb565b90509250925092565b600080600080600080600080610100898b0312156200055057600080fd5b6200055b8962000418565b97506200056b60208a0162000418565b96506200057b60408a0162000418565b95506200058b60608a0162000418565b945060808901519350620005a260a08a0162000418565b60c08a01519093506001600160601b0381168114620005c057600080fd5b60e08a015190925061ffff81168114620005d957600080fd5b809150509295985092959890939650565b634e487b7160e01b600052604160045260246000fd5b60805160f81c6153216200061f600039600061156f01526153216000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c806381ff7048116100ee578063b1dc65a411610097578063d328a91e11610071578063d328a91e146104aa578063de9dfa46146104b2578063e3d0e712146104c5578063f2fde38b146104d857600080fd5b8063b1dc65a4146103f7578063c3f909d41461040a578063d227d2451461049757600080fd5b80639883c10d116100c85780639883c10d146103bd578063af1296d3146103cf578063afcb95d7146103d757600080fd5b806381ff70481461034257806385b214cf146103725780638da5cb5b1461039557600080fd5b8063533989871161015b5780637f15e166116101355780637f15e166146102ff5780638075603114610312578063814118341461032557806381f1b9381461033a57600080fd5b806353398987146102ce57806366316d8d146102e457806379ba5097146102f757600080fd5b806326ceabac1161018c57806326ceabac1461024f578063354497aa14610262578063466557181461027557600080fd5b8063083a5466146101b35780630a33e0a5146101c8578063181f5a771461020d575b600080fd5b6101c66101c13660046144d4565b6104eb565b005b6101db6101d6366004614621565b61053b565b604080519485526bffffffffffffffffffffffff90931660208501529183015260608201526080015b60405180910390f35b60408051808201909152601881527f46756e6374696f6e7320436f6f7264696e61746f72207631000000000000000060208201525b6040516102049190614b81565b6101c661025d3660046140fc565b610760565b6101c6610270366004614516565b610893565b6102b161028336600461454b565b5050600c547401000000000000000000000000000000000000000090046bffffffffffffffffffffffff1690565b6040516bffffffffffffffffffffffff9091168152602001610204565b6102d66108fa565b604051610204929190614a80565b6101c66102f236600461418b565b610b1a565b6101c6610c95565b6101c661030d3660046144d4565b610d97565b6101c6610320366004614136565b610ee0565b61032d611028565b6040516102049190614a6d565b610242611097565b6004546002546040805163ffffffff80851682526401000000009094049093166020840152820152606001610204565b6103856103803660046144bb565b611120565b6040519015158152602001610204565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610204565b6008545b604051908152602001610204565b6103c161130a565b604080516001815260006020820181905291810191909152606001610204565b6101c66104053660046142ce565b6113fc565b600c54600d54600a54600e546040805163ffffffff80871682526401000000008704811660208301526c010000000000000000000000008704811692820192909252606081019490945268010000000000000000909404909316608083015273ffffffffffffffffffffffffffffffffffffffff1660a082015261ffff90911660c082015260e001610204565b6102b16104a5366004614759565b611b2d565b610242611c1c565b6102b16104c036600461454b565b611c2b565b6101c66104d3366004614201565b611cd5565b6101c66104e63660046140fc565b6126b9565b6104f36126ca565b8061052a576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61053660138383613d2a565b505050565b60095460009081908190819073ffffffffffffffffffffffffffffffffffffffff163314610595576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105a26020860186614e2d565b151590506105db576040517ec1cfc000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101909152600090806105f7602089018961473c565b67ffffffffffffffff16815260200161061660a0890160808a016140fc565b73ffffffffffffffffffffffffffffffffffffffff1681526020016106416080890160608a01614679565b63ffffffff1681523a6020918201529091506106ae9061066390880188614e2d565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506106a8925050506060890160408a0161465c565b8361274d565b929750909550935091506106c860a08701608088016140fc565b73ffffffffffffffffffffffffffffffffffffffff16857fb108b073fa485003d66284614f1c3b4feb3f47ffc88f7873bf3b2ec4bb8939bc3261070e60208b018b61473c565b61071e60c08c0160a08d016140fc565b61072b60208d018d614e2d565b8d604001602081019061073e919061465c565b604051610750969594939291906149d9565b60405180910390a3509193509193565b3073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156107a657600080fd5b505afa1580156107ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107de9190614119565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061082c57503373ffffffffffffffffffffffffffffffffffffffff8216145b610862576040517fed6dd19b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260126020526040812061089091613dcc565b50565b60095473ffffffffffffffffffffffffffffffffffffffff1633146108e4576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108ed81612dba565b8051602090910120600855565b60608060003073ffffffffffffffffffffffffffffffffffffffff1663814118346040518163ffffffff1660e01b815260040160006040518083038186803b15801561094557600080fd5b505afa158015610959573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261099f91908101906141c4565b90506000815167ffffffffffffffff8111156109bd576109bd615262565b6040519080825280602002602001820160405280156109f057816020015b60608152602001906001900390816109db5790505b50905060005b8251811015610b105760126000848381518110610a1557610a15615233565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054610a62906150ca565b80601f0160208091040260200160405190810160405280929190818152602001828054610a8e906150ca565b8015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b5050505050828281518110610af257610af2615233565b60200260200101819052508080610b089061511e565b9150506109f6565b5090939092509050565b610b22613067565b6bffffffffffffffffffffffff8116610b555750336000908152600f60205260409020546bffffffffffffffffffffffff165b336000908152600f60205260409020546bffffffffffffffffffffffff80831691161015610baf576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600f602052604081208054839290610bdc9084906bffffffffffffffffffffffff1661509d565b82546101009290920a6bffffffffffffffffffffffff8181021990931691831602179091556009546040517f66316d8d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015292851660248201529116915081906366316d8d90604401600060405180830381600087803b158015610c7857600080fd5b505af1158015610c8c573d6000803e3d6000fd5b50505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610e0157600080fd5b505af1158015610e15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e399190614119565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e9d576040517fa0f0a44600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80610ed4576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61053660118383613d2a565b3073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f2657600080fd5b505afa158015610f3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5e9190614119565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610fbc5750610f9b336131c7565b8015610fbc57503373ffffffffffffffffffffffffffffffffffffffff8416145b610ff2576040517fed6dd19b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000908152601260205260409020611022908383613d2a565b50505050565b6060600780548060200260200160405190810160405280929190818152602001828054801561108d57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611062575b5050505050905090565b6060601380546110a6906150ca565b80601f01602080910402602001604051908101604052809291908181526020018280546110d2906150ca565b801561108d5780601f106110f45761010080835404028352916020019161108d565b820191906000526020600020905b81548152906001019060200180831161110257509395945050505050565b60095460009073ffffffffffffffffffffffffffffffffffffffff163314611174576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600b6020908152604091829020825161014081018452815467ffffffffffffffff8116825268010000000000000000810473ffffffffffffffffffffffffffffffffffffffff908116948301949094527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169381019390935260018101546060840152600281015491821660808401819052740100000000000000000000000000000000000000009092046bffffffffffffffffffffffff90811660a0850152600382015480821660c08601526c0100000000000000000000000090041660e08401526004810154610100840152600501546101208301526112825750600092915050565b6000838152600b602052604080822082815560018101839055600281018390556003810180547fffffffffffffffff000000000000000000000000000000000000000000000000169055600481018390556005018290555184917ff1ca1e9147be737b04a2b018a79405f687a97de8dd8a2559bbe62357343af41491a260019150505b919050565b600c54600a54604080517ffeaf968c0000000000000000000000000000000000000000000000000000000081529051600093640100000000900463ffffffff1692831515928592839273ffffffffffffffffffffffffffffffffffffffff169163feaf968c9160048083019260a0929190829003018186803b15801561138f57600080fd5b505afa1580156113a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c791906147c9565b509350509250508280156113e957506113e08142615086565b8463ffffffff16105b156113f457600d5491505b509392505050565b60005a604080516020601f8b018190048102820181019092528981529192508a3591818c01359161145291849163ffffffff851691908e908e90819084018382808284376000920191909152506132eb92505050565b611488576040517f0be3632800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805183815262ffffff600884901c1660208201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925290831461155d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f636f6e666967446967657374206d69736d6174636800000000000000000000006044820152606401610d12565b61156b8b8b8b8b8b8b6132f4565b60007f0000000000000000000000000000000000000000000000000000000000000000156115c8576002826020015183604001516115a99190614f68565b6115b39190614fc8565b6115be906001614f68565b60ff1690506115de565b60208201516115d8906001614f68565b60ff1690505b888114611647576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e6174757265730000000000006044820152606401610d12565b8887146116b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f7369676e617475726573206f7574206f6620726567697374726174696f6e00006044820152606401610d12565b3360009081526005602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156116f3576116f36151d5565b6002811115611704576117046151d5565b9052509050600281602001516002811115611721576117216151d5565b14801561176857506007816000015160ff168154811061174357611743615233565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b6117ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f756e617574686f72697a6564207472616e736d697474657200000000000000006044820152606401610d12565b50505050506117db613e06565b6000808a8a6040516117ee9291906149c9565b604051908190038120611805918e906020016149ad565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120838301909252600080845290830152915060005b89811015611b0f57600060018489846020811061186e5761186e615233565b61187b91901a601b614f68565b8e8e8681811061188d5761188d615233565b905060200201358d8d878181106118a6576118a6615233565b90506020020135604051600081526020016040526040516118e3949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611905573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526005602090815290849020838501909452835460ff80821685529296509294508401916101009004166002811115611985576119856151d5565b6002811115611996576119966151d5565b90525092506001836020015160028111156119b3576119b36151d5565b14611a1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e00006044820152606401610d12565b8251600090879060ff16601f8110611a3457611a34615233565b602002015173ffffffffffffffffffffffffffffffffffffffff1614611ab6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6e6f6e2d756e69717565207369676e61747572650000000000000000000000006044820152606401610d12565b8086846000015160ff16601f8110611ad057611ad0615233565b73ffffffffffffffffffffffffffffffffffffffff9092166020929092020152611afb600186614f68565b94505080611b089061511e565b905061184f565b505050611b20833383858e8e6133a2565b5050505050505050505050565b60008060405180608001604052808867ffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018563ffffffff1681526020018481525090506000611bbc87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250869250610283915050565b90506000611c0188888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250611c2b915050565b9050611c0f8686848461364a565b9998505050505050505050565b6060601180546110a6906150ca565b600954604080517f2a905ccc000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691632a905ccc916004808301926020929190829003018186803b158015611c9657600080fd5b505afa158015611caa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cce9190614848565b9392505050565b855185518560ff16601f831115611d48576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e657273000000000000000000000000000000006044820152606401610d12565b60008111611db2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610d12565b818314611e40576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610d12565b611e4b816003615015565b8311611eb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610d12565b611ebb6126ca565b6040805160c0810182528a8152602081018a905260ff89169181018290526060810188905267ffffffffffffffff8716608082015260a0810186905290611f029088613780565b600654156120b757600654600090611f1c90600190615086565b9050600060068281548110611f3357611f33615233565b60009182526020822001546007805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110611f6d57611f6d615233565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526005909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090811690915592909116808452922080549091169055600680549192509080611fed57611fed615204565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055600780548061205657612056615204565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611f02915050565b60005b81515181101561251c57600060056000846000015184815181106120e0576120e0615233565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff16600281111561212a5761212a6151d5565b14612191576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610d12565b6040805180820190915260ff821681526001602082015282518051600591600091859081106121c2576121c2615233565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115612263576122636151d5565b0217905550600091506122739050565b600560008460200151848151811061228d5761228d615233565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff1660028111156122d7576122d76151d5565b1461233e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610d12565b6040805180820190915260ff82168152602081016002815250600560008460200151848151811061237157612371615233565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115612412576124126151d5565b02179055505082518051600692508390811061243057612430615233565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90931692909217909155820151805160079190839081106124ac576124ac615233565b60209081029190910181015182546001810184556000938452919092200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790556125158161511e565b90506120ba565b506040810151600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600480547fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff811664010000000063ffffffff4381168202928317855590830481169360019390926000926125ae928692908216911617614f1d565b92506101000a81548163ffffffff021916908363ffffffff16021790555061260d4630600460009054906101000a900463ffffffff1663ffffffff16856000015186602001518760400151886060015189608001518a60a0015161378c565b6002819055825180516003805460ff909216610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff90921691909117905560045460208501516040808701516060880151608089015160a08a015193517f324b4d5fd31c5865202bc49f712eb9fcdf22bcc3b89f8c721f3134ae6c081a09986126ac988b98919763ffffffff909216969095919491939192614d2b565b60405180910390a1611b20565b6126c16126ca565b61089081613837565b60005473ffffffffffffffffffffffffffffffffffffffff16331461274b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610d12565b565b600e5460009081908190819061ffff908116908716111561279a576040517fdada758700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c54604086015163ffffffff918216911611156127fc57604085810151600c5491517ff5d7e01e00000000000000000000000000000000000000000000000000000000815263ffffffff918216600482015291166024820152604401610d12565b600061282d600c547401000000000000000000000000000000000000000090046bffffffffffffffffffffffff1690565b9050600061283b8988611c2b565b9050600061285388604001518960600151858561364a565b60095489516040517fa47c769600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015291925073ffffffffffffffffffffffffffffffffffffffff16906000908190839063a47c76969060240160006040518083038186803b1580156128d157600080fd5b505afa1580156128e5573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261292b9190810190614865565b50505060208d01518d516040517f674603d000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316600482015267ffffffffffffffff90911660248201529294509092506000919085169063674603d09060440160606040518083038186803b1580156129b757600080fd5b505afa1580156129cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ef9190614469565b509150506bffffffffffffffffffffffff8516612a0c838561509d565b6bffffffffffffffffffffffff161015612a52576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612ad1308e602001518f60000151856001612a6f9190614f45565b6040805173ffffffffffffffffffffffffffffffffffffffff958616602080830191909152949095168582015267ffffffffffffffff928316606086015291166080808501919091528151808503909101815260a09093019052815191012090565b905060006040518061014001604052808f6000015167ffffffffffffffff1681526020018f6020015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6040015163ffffffff1681526020018f6060015181526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018a6bffffffffffffffffffffffff168152602001896bffffffffffffffffffffffff168152602001886bffffffffffffffffffffffff168152602001600c600001600c9054906101000a900463ffffffff16600c60000160089054906101000a900463ffffffff16612bbd9190614f1d565b63ffffffff9081168252426020928301526000858152600b835260409081902084518154948601518684015167ffffffffffffffff9092167fffffffff00000000000000000000000000000000000000000000000000000000909616959095176801000000000000000073ffffffffffffffffffffffffffffffffffffffff96871602177bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c0100000000000000000000000000000000000000000000000000000000919094160292909217825560608401516001830155608084015160a08501519316740100000000000000000000000000000000000000006bffffffffffffffffffffffff9485160217600283015560c084015160038301805460e08701519286167fffffffffffffffff000000000000000000000000000000000000000000000000909116176c0100000000000000000000000092909516919091029390931790925561010083015160048201556101208301516005909101555190915082907f9fadc54f9c9b79290fa97f2c9deb97ee080d1f8ae4f00deb1fb83cedd1ee542290612d6a908490614b94565b60405180910390a250600c54909f959e5063ffffffff6c01000000000000000000000000820481169e50700100000000000000000000000000000000909104169b50939950505050505050505050565b60008060008060008060008088806020019051810190612dda9190614696565b9750975097509750975097509750975060008413612e27576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101859052602401610d12565b604080516101008101825263ffffffff808b168083528a8216602084018190528983168486018190528b841660608601819052938916608086018190526bffffffffffffffffffffffff891660a0870181905260c087018c905261ffff891660e0909701879052600c80547401000000000000000000000000000000000000000090920273ffffffffffffffffffffffffffffffffffffffff700100000000000000000000000000000000909402939093166fffffffffffffffffffffffffffffffff6c010000000000000000000000009098027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff68010000000000000000909602959095167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff6401000000009097027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909416909717929092179490941694909417919091179390931691909117919091179055600d869055600e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169091179055517fd09395baf4d99e44ce1b8e96a4396a3f896d0fd5e4517993f28ce0a6fb42e22790613054908a908a9089908b908a908990899063ffffffff97881681529587166020870152938616604086015291909416606084015260808301939093526bffffffffffffffffffffffff9290921660a082015261ffff9190911660c082015260e00190565b60405180910390a1505050505050505050565b6000613071611028565b805160105491925060009161309491906bffffffffffffffffffffffff16614fea565b905060005b82518160ff1610156131685781600f6000858460ff16815181106130bf576130bf615233565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a90046bffffffffffffffffffffffff166131279190614f8d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550808061316090615157565b915050613099565b5081516131759082615052565b601080546000906131959084906bffffffffffffffffffffffff1661509d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505050565b6000803073ffffffffffffffffffffffffffffffffffffffff1663814118346040518163ffffffff1660e01b815260040160006040518083038186803b15801561321057600080fd5b505afa158015613224573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261326a91908101906141c4565b905060005b81518110156132e1578373ffffffffffffffffffffffffffffffffffffffff168282815181106132a1576132a1615233565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614156132cf575060019392505050565b806132d98161511e565b91505061326f565b5060009392505050565b60019392505050565b6000613301826020615015565b61330c856020615015565b61331888610144614f05565b6133229190614f05565b61332c9190614f05565b613337906000614f05565b9050368114610c8c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d6174636800000000000000006044820152606401610d12565b606080806133b284860186614385565b8251929550909350915015806133ca57508151835114155b806133d757508051835114155b1561340e576040517f0be3632800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b835181101561363e57600061347285838151811061343157613431615233565b602002602001015185848151811061344b5761344b615233565b602002602001015185858151811061346557613465615233565b602002602001015161392d565b90506000816006811115613488576134886151d5565b14806134a5575060018160068111156134a3576134a36151d5565b145b15613500578482815181106134bc576134bc615233565b60209081029190910181015160405133815290917fc708e0440951fd63499c0f7a73819b469ee5dd3ecc356c0ab4eb7f18389009d9910160405180910390a261362b565b6002816006811115613514576135146151d5565b14156135655784828151811061352c5761352c615233565b60200260200101517fa1c120e327c9ad8b075793878c88d59b8934b97ae37117faa3bb21616237f7be60405160405180910390a261362b565b6003816006811115613579576135796151d5565b14156135ca5784828151811061359157613591615233565b60200260200101517f357a60574f143e144d62ddc89636fee45ba5e2f8c9a30b9f91e28f8dfe5a56e060405160405180910390a261362b565b60058160068111156135de576135de6151d5565b141561362b578482815181106135f6576135f6615233565b60200260200101517f689f49eacf6db85082542f4b7873f4a519744a4e093fd002310545bfb4354cc860405160405180910390a25b50806136368161511e565b915050613411565b50505050505050505050565b60008061365561130a565b905060008113613694576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101829052602401610d12565b600c5460009087906136ca9063ffffffff6c01000000000000000000000000820481169168010000000000000000900416614f1d565b6136d49190614f1d565b63ffffffff169050600082826136f289670de0b6b3a7640000615015565b6136fc9190615015565b6137069190614fb4565b905060006137256bffffffffffffffffffffffff808816908916614f05565b905061373d816b033b2e3c9fd0803ce8000000615086565b821115613776576040517fe80fa38100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c0f8183614f05565b613788613067565b5050565b6000808a8a8a8a8a8a8a8a8a6040516020016137b099989796959493929190614c96565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff81163314156138b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610d12565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000838152600b60209081526040808320815161014081018352815467ffffffffffffffff8116825268010000000000000000810473ffffffffffffffffffffffffffffffffffffffff908116958301959095527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169281019290925260018101546060830152600281015492831660808301819052740100000000000000000000000000000000000000009093046bffffffffffffffffffffffff90811660a0840152600382015480821660c08501526c0100000000000000000000000090041660e083015260048101546101008301526005015461012082015290613a3c576002915050611cce565b6000858152600b6020526040812081815560018101829055600281018290556003810180547fffffffffffffffff00000000000000000000000000000000000000000000000016905560048101829055600501819055613a9a61130a565b905060008113613ad9576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101829052602401610d12565b600081613aee3a670de0b6b3a7640000615015565b613af89190614fb4565b9050600083610100015182613b0d9190615015565b905060008460a0015182613b219190614f8d565b6009546040517f3fd67e0500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff169060009081908390633fd67e0590613b89908f908f908f908c908b903390600401614b10565b6040805180830381600087803b158015613ba257600080fd5b505af1158015613bb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bda9190614819565b9092509050613be98186614f8d565b336000908152600f6020526040812080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff93841617905560a08a0151601080549193909291613c4991859116614f8d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508b7f30e1e299f390e4f3fa75e4489fed477e86183937a4a21a0ae7b137a4dff0353589600001518a60a001518489613caf9190614f8d565b60c08d015160a08e0151613cc3888d614f8d565b613ccd9190614f8d565b613cd79190614f8d565b8760ff166006811115613cec57613cec6151d5565b604051613cfd959493929190614db1565b60405180910390a28160ff166006811115613d1a57613d1a6151d5565b9c9b505050505050505050505050565b828054613d36906150ca565b90600052602060002090601f016020900481019282613d585760008555613dbc565b82601f10613d8f578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00823516178555613dbc565b82800160010185558215613dbc579182015b82811115613dbc578235825591602001919060010190613da1565b50613dc8929150613e25565b5090565b508054613dd8906150ca565b6000825580601f10613de8575050565b601f0160209004906000526020600020908101906108909190613e25565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613dc85760008155600101613e26565b600082601f830112613e4b57600080fd5b81356020613e60613e5b83614ee1565b614e92565b80838252828201915082860187848660051b8901011115613e8057600080fd5b60005b85811015613ea8578135613e9681615291565b84529284019290840190600101613e83565b5090979650505050505050565b600082601f830112613ec657600080fd5b81516020613ed6613e5b83614ee1565b80838252828201915082860187848660051b8901011115613ef657600080fd5b60005b85811015613ea8578151613f0c81615291565b84529284019290840190600101613ef9565b60008083601f840112613f3057600080fd5b50813567ffffffffffffffff811115613f4857600080fd5b6020830191508360208260051b8501011115613f6357600080fd5b9250929050565b600082601f830112613f7b57600080fd5b81356020613f8b613e5b83614ee1565b80838252828201915082860187848660051b8901011115613fab57600080fd5b6000805b86811015613fee57823567ffffffffffffffff811115613fcd578283fd5b613fdb8b88838d010161403e565b8652509385019391850191600101613faf565b509198975050505050505050565b60008083601f84011261400e57600080fd5b50813567ffffffffffffffff81111561402657600080fd5b602083019150836020828501011115613f6357600080fd5b600082601f83011261404f57600080fd5b813567ffffffffffffffff81111561406957614069615262565b61409a60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614e92565b8181528460208386010111156140af57600080fd5b816020850160208301376000918101602001919091529392505050565b8035611305816152d5565b8035611305816152eb565b805169ffffffffffffffffffff8116811461130557600080fd5b60006020828403121561410e57600080fd5b8135611cce81615291565b60006020828403121561412b57600080fd5b8151611cce81615291565b60008060006040848603121561414b57600080fd5b833561415681615291565b9250602084013567ffffffffffffffff81111561417257600080fd5b61417e86828701613ffc565b9497909650939450505050565b6000806040838503121561419e57600080fd5b82356141a981615291565b915060208301356141b9816152fa565b809150509250929050565b6000602082840312156141d657600080fd5b815167ffffffffffffffff8111156141ed57600080fd5b6141f984828501613eb5565b949350505050565b60008060008060008060c0878903121561421a57600080fd5b863567ffffffffffffffff8082111561423257600080fd5b61423e8a838b01613e3a565b9750602089013591508082111561425457600080fd5b6142608a838b01613e3a565b965061426e60408a016140d7565b9550606089013591508082111561428457600080fd5b6142908a838b0161403e565b945061429e60808a016140cc565b935060a08901359150808211156142b457600080fd5b506142c189828a0161403e565b9150509295509295509295565b60008060008060008060008060e0898b0312156142ea57600080fd5b606089018a8111156142fb57600080fd5b8998503567ffffffffffffffff8082111561431557600080fd5b6143218c838d01613ffc565b909950975060808b013591508082111561433a57600080fd5b6143468c838d01613f1e565b909750955060a08b013591508082111561435f57600080fd5b5061436c8b828c01613f1e565b999c989b50969995989497949560c00135949350505050565b60008060006060848603121561439a57600080fd5b833567ffffffffffffffff808211156143b257600080fd5b818601915086601f8301126143c657600080fd5b813560206143d6613e5b83614ee1565b8083825282820191508286018b848660051b89010111156143f657600080fd5b600096505b848710156144195780358352600196909601959183019183016143fb565b509750508701359250508082111561443057600080fd5b61443c87838801613f6a565b9350604086013591508082111561445257600080fd5b5061445f86828701613f6a565b9150509250925092565b60008060006060848603121561447e57600080fd5b8351801515811461448e57600080fd5b602085015190935061449f816152d5565b60408501519092506144b0816152d5565b809150509250925092565b6000602082840312156144cd57600080fd5b5035919050565b600080602083850312156144e757600080fd5b823567ffffffffffffffff8111156144fe57600080fd5b61450a85828601613ffc565b90969095509350505050565b60006020828403121561452857600080fd5b813567ffffffffffffffff81111561453f57600080fd5b6141f98482850161403e565b60008082840360a081121561455f57600080fd5b833567ffffffffffffffff8082111561457757600080fd5b6145838783880161403e565b945060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156145b557600080fd5b604051925060808301915082821081831117156145d4576145d4615262565b5060405260208401356145e6816152d5565b815260408401356145f681615291565b60208201526060840135614609816152c3565b60408201526080939093013560608401525092909150565b60006020828403121561463357600080fd5b813567ffffffffffffffff81111561464a57600080fd5b820160c08185031215611cce57600080fd5b60006020828403121561466e57600080fd5b8135611cce816152b3565b60006020828403121561468b57600080fd5b8135611cce816152c3565b600080600080600080600080610100898b0312156146b357600080fd5b88516146be816152c3565b60208a01519098506146cf816152c3565b60408a01519097506146e0816152c3565b60608a01519096506146f1816152c3565b60808a015160a08b01519196509450614709816152c3565b60c08a015190935061471a816152fa565b60e08a015190925061472b816152b3565b809150509295985092959890939650565b60006020828403121561474e57600080fd5b8135611cce816152d5565b60008060008060006080868803121561477157600080fd5b853561477c816152d5565b9450602086013567ffffffffffffffff81111561479857600080fd5b6147a488828901613ffc565b90955093505060408601356147b8816152c3565b949793965091946060013592915050565b600080600080600060a086880312156147e157600080fd5b6147ea866140e2565b945060208601519350604086015192506060860151915061480d608087016140e2565b90509295509295909350565b6000806040838503121561482c57600080fd5b8251614837816152eb565b60208401519092506141b9816152fa565b60006020828403121561485a57600080fd5b8151611cce816152fa565b600080600080600060a0868803121561487d57600080fd5b8551614888816152fa565b6020870151909550614899816152fa565b60408701519094506148aa81615291565b60608701519093506148bb81615291565b608087015190925067ffffffffffffffff8111156148d857600080fd5b6148e488828901613eb5565b9150509295509295909350565b600081518084526020808501945080840160005b8381101561493757815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101614905565b509495945050505050565b6000815180845260005b818110156149685760208185018101518683018201520161494c565b8181111561497a576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b8281526060826020830137600060809190910190815292915050565b8183823760009101908152919050565b600073ffffffffffffffffffffffffffffffffffffffff808916835267ffffffffffffffff8816602084015280871660408401525060a060608301528360a0830152838560c0840137600060c0858401015260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116830101905061ffff83166080830152979650505050505050565b602081526000611cce60208301846148f1565b604081526000614a9360408301856148f1565b6020838203818501528185518084528284019150828160051b85010183880160005b83811015614b01577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0878403018552614aef838351614942565b94860194925090850190600101614ab5565b50909998505050505050505050565b86815260c060208201526000614b2960c0830188614942565b8281036040840152614b3b8188614942565b6bffffffffffffffffffffffff96871660608501529490951660808301525073ffffffffffffffffffffffffffffffffffffffff9190911660a090910152949350505050565b602081526000611cce6020830184614942565b815167ffffffffffffffff16815261014081016020830151614bce602084018273ffffffffffffffffffffffffffffffffffffffff169052565b506040830151614be6604084018263ffffffff169052565b50606083015160608301526080830151614c18608084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a0830151614c3860a08401826bffffffffffffffffffffffff169052565b5060c0830151614c5860c08401826bffffffffffffffffffffffff169052565b5060e0830151614c7860e08401826bffffffffffffffffffffffff169052565b50610100838101519083015261012092830151929091019190915290565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614cdd8285018b6148f1565b91508382036080850152614cf1828a6148f1565b915060ff881660a085015283820360c0850152614d0e8288614942565b90861660e08501528381036101008501529050613d1a8185614942565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152614d5b8184018a6148f1565b90508281036080840152614d6f81896148f1565b905060ff871660a084015282810360c0840152614d8c8187614942565b905067ffffffffffffffff851660e0840152828103610100840152613d1a8185614942565b67ffffffffffffffff861681526bffffffffffffffffffffffff858116602083015284811660408301528316606082015260a0810160078310614e1d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8260808301529695505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614e6257600080fd5b83018035915067ffffffffffffffff821115614e7d57600080fd5b602001915036819003821315613f6357600080fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614ed957614ed9615262565b604052919050565b600067ffffffffffffffff821115614efb57614efb615262565b5060051b60200190565b60008219821115614f1857614f18615177565b500190565b600063ffffffff808316818516808303821115614f3c57614f3c615177565b01949350505050565b600067ffffffffffffffff808316818516808303821115614f3c57614f3c615177565b600060ff821660ff84168060ff03821115614f8557614f85615177565b019392505050565b60006bffffffffffffffffffffffff808316818516808303821115614f3c57614f3c615177565b600082614fc357614fc36151a6565b500490565b600060ff831680614fdb57614fdb6151a6565b8060ff84160491505092915050565b60006bffffffffffffffffffffffff80841680615009576150096151a6565b92169190910492915050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561504d5761504d615177565b500290565b60006bffffffffffffffffffffffff8083168185168183048111821515161561507d5761507d615177565b02949350505050565b60008282101561509857615098615177565b500390565b60006bffffffffffffffffffffffff838116908316818110156150c2576150c2615177565b039392505050565b600181811c908216806150de57607f821691505b60208210811415615118577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561515057615150615177565b5060010190565b600060ff821660ff81141561516e5761516e615177565b60010192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b61ffff8116811461089057600080fd5b63ffffffff8116811461089057600080fd5b67ffffffffffffffff8116811461089057600080fd5b60ff8116811461089057600080fd5b6bffffffffffffffffffffffff8116811461089057600080fdfea164736f6c6343000806000a", -} - -var FunctionsCoordinatorABI = FunctionsCoordinatorMetaData.ABI - -var FunctionsCoordinatorBin = FunctionsCoordinatorMetaData.Bin - -func DeployFunctionsCoordinator(auth *bind.TransactOpts, backend bind.ContractBackend, router common.Address, config []byte, linkToNativeFeed common.Address) (common.Address, *types.Transaction, *FunctionsCoordinator, error) { - parsed, err := FunctionsCoordinatorMetaData.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(FunctionsCoordinatorBin), backend, router, config, linkToNativeFeed) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &FunctionsCoordinator{FunctionsCoordinatorCaller: FunctionsCoordinatorCaller{contract: contract}, FunctionsCoordinatorTransactor: FunctionsCoordinatorTransactor{contract: contract}, FunctionsCoordinatorFilterer: FunctionsCoordinatorFilterer{contract: contract}}, nil -} - -type FunctionsCoordinator struct { - address common.Address - abi abi.ABI - FunctionsCoordinatorCaller - FunctionsCoordinatorTransactor - FunctionsCoordinatorFilterer -} - -type FunctionsCoordinatorCaller struct { - contract *bind.BoundContract -} - -type FunctionsCoordinatorTransactor struct { - contract *bind.BoundContract -} - -type FunctionsCoordinatorFilterer struct { - contract *bind.BoundContract -} - -type FunctionsCoordinatorSession struct { - Contract *FunctionsCoordinator - CallOpts bind.CallOpts - TransactOpts bind.TransactOpts -} - -type FunctionsCoordinatorCallerSession struct { - Contract *FunctionsCoordinatorCaller - CallOpts bind.CallOpts -} - -type FunctionsCoordinatorTransactorSession struct { - Contract *FunctionsCoordinatorTransactor - TransactOpts bind.TransactOpts -} - -type FunctionsCoordinatorRaw struct { - Contract *FunctionsCoordinator -} - -type FunctionsCoordinatorCallerRaw struct { - Contract *FunctionsCoordinatorCaller -} - -type FunctionsCoordinatorTransactorRaw struct { - Contract *FunctionsCoordinatorTransactor -} - -func NewFunctionsCoordinator(address common.Address, backend bind.ContractBackend) (*FunctionsCoordinator, error) { - abi, err := abi.JSON(strings.NewReader(FunctionsCoordinatorABI)) - if err != nil { - return nil, err - } - contract, err := bindFunctionsCoordinator(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &FunctionsCoordinator{address: address, abi: abi, FunctionsCoordinatorCaller: FunctionsCoordinatorCaller{contract: contract}, FunctionsCoordinatorTransactor: FunctionsCoordinatorTransactor{contract: contract}, FunctionsCoordinatorFilterer: FunctionsCoordinatorFilterer{contract: contract}}, nil -} - -func NewFunctionsCoordinatorCaller(address common.Address, caller bind.ContractCaller) (*FunctionsCoordinatorCaller, error) { - contract, err := bindFunctionsCoordinator(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &FunctionsCoordinatorCaller{contract: contract}, nil -} - -func NewFunctionsCoordinatorTransactor(address common.Address, transactor bind.ContractTransactor) (*FunctionsCoordinatorTransactor, error) { - contract, err := bindFunctionsCoordinator(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &FunctionsCoordinatorTransactor{contract: contract}, nil -} - -func NewFunctionsCoordinatorFilterer(address common.Address, filterer bind.ContractFilterer) (*FunctionsCoordinatorFilterer, error) { - contract, err := bindFunctionsCoordinator(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &FunctionsCoordinatorFilterer{contract: contract}, nil -} - -func bindFunctionsCoordinator(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := FunctionsCoordinatorMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -func (_FunctionsCoordinator *FunctionsCoordinatorRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _FunctionsCoordinator.Contract.FunctionsCoordinatorCaller.contract.Call(opts, result, method, params...) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.FunctionsCoordinatorTransactor.contract.Transfer(opts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.FunctionsCoordinatorTransactor.contract.Transact(opts, method, params...) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _FunctionsCoordinator.Contract.contract.Call(opts, result, method, params...) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.contract.Transfer(opts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.contract.Transact(opts, method, params...) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) EstimateCost(opts *bind.CallOpts, subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPrice *big.Int) (*big.Int, error) { - var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "estimateCost", subscriptionId, data, callbackGasLimit, gasPrice) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) EstimateCost(subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPrice *big.Int) (*big.Int, error) { - return _FunctionsCoordinator.Contract.EstimateCost(&_FunctionsCoordinator.CallOpts, subscriptionId, data, callbackGasLimit, gasPrice) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) EstimateCost(subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPrice *big.Int) (*big.Int, error) { - return _FunctionsCoordinator.Contract.EstimateCost(&_FunctionsCoordinator.CallOpts, subscriptionId, data, callbackGasLimit, gasPrice) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetAdminFee(opts *bind.CallOpts, arg0 []byte, arg1 IFunctionsBillingRequestBilling) (*big.Int, error) { - var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "getAdminFee", arg0, arg1) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetAdminFee(arg0 []byte, arg1 IFunctionsBillingRequestBilling) (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetAdminFee(&_FunctionsCoordinator.CallOpts, arg0, arg1) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetAdminFee(arg0 []byte, arg1 IFunctionsBillingRequestBilling) (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetAdminFee(&_FunctionsCoordinator.CallOpts, arg0, arg1) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetAllNodePublicKeys(opts *bind.CallOpts) ([]common.Address, [][]byte, error) { - var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "getAllNodePublicKeys") - - if err != nil { - return *new([]common.Address), *new([][]byte), err - } - - out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) - out1 := *abi.ConvertType(out[1], new([][]byte)).(*[][]byte) - - return out0, out1, err - -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetAllNodePublicKeys() ([]common.Address, [][]byte, error) { - return _FunctionsCoordinator.Contract.GetAllNodePublicKeys(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetAllNodePublicKeys() ([]common.Address, [][]byte, error) { - return _FunctionsCoordinator.Contract.GetAllNodePublicKeys(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetConfig(opts *bind.CallOpts) (GetConfig, - - error) { - var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "getConfig") - - outstruct := new(GetConfig) - if err != nil { - return *outstruct, err - } - - outstruct.MaxCallbackGasLimit = *abi.ConvertType(out[0], new(uint32)).(*uint32) - outstruct.FeedStalenessSeconds = *abi.ConvertType(out[1], new(uint32)).(*uint32) - outstruct.GasOverheadAfterCallback = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) - outstruct.FallbackNativePerUnitLink = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) - outstruct.GasOverheadBeforeCallback = *abi.ConvertType(out[4], new(uint32)).(*uint32) - outstruct.LinkPriceFeed = *abi.ConvertType(out[5], new(common.Address)).(*common.Address) - outstruct.MaxSupportedRequestDataVersion = *abi.ConvertType(out[6], new(uint16)).(*uint16) - - return *outstruct, err - -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetConfig() (GetConfig, - - error) { - return _FunctionsCoordinator.Contract.GetConfig(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetConfig() (GetConfig, - - error) { - return _FunctionsCoordinator.Contract.GetConfig(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetConfigHash(opts *bind.CallOpts) ([32]byte, error) { - var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "getConfigHash") - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetConfigHash() ([32]byte, error) { - return _FunctionsCoordinator.Contract.GetConfigHash(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetConfigHash() ([32]byte, error) { - return _FunctionsCoordinator.Contract.GetConfigHash(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetDONFee(opts *bind.CallOpts, arg0 []byte, arg1 IFunctionsBillingRequestBilling) (*big.Int, error) { - var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "getDONFee", arg0, arg1) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetDONFee(arg0 []byte, arg1 IFunctionsBillingRequestBilling) (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetDONFee(&_FunctionsCoordinator.CallOpts, arg0, arg1) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetDONFee(arg0 []byte, arg1 IFunctionsBillingRequestBilling) (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetDONFee(&_FunctionsCoordinator.CallOpts, arg0, arg1) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetDONPublicKey(opts *bind.CallOpts) ([]byte, error) { - var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "getDONPublicKey") - - if err != nil { - return *new([]byte), err - } - - out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) - - return out0, err - -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetDONPublicKey() ([]byte, error) { - return _FunctionsCoordinator.Contract.GetDONPublicKey(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetDONPublicKey() ([]byte, error) { - return _FunctionsCoordinator.Contract.GetDONPublicKey(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetFeedData(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "getFeedData") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetFeedData() (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetFeedData(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetFeedData() (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetFeedData(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetThresholdPublicKey(opts *bind.CallOpts) ([]byte, error) { - var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "getThresholdPublicKey") - - if err != nil { - return *new([]byte), err - } - - out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) - - return out0, err - -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetThresholdPublicKey() ([]byte, error) { - return _FunctionsCoordinator.Contract.GetThresholdPublicKey(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetThresholdPublicKey() ([]byte, error) { - return _FunctionsCoordinator.Contract.GetThresholdPublicKey(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, - - error) { - var out []interface{} - err := _FunctionsCoordinator.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 (_FunctionsCoordinator *FunctionsCoordinatorSession) LatestConfigDetails() (LatestConfigDetails, - - error) { - return _FunctionsCoordinator.Contract.LatestConfigDetails(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) LatestConfigDetails() (LatestConfigDetails, - - error) { - return _FunctionsCoordinator.Contract.LatestConfigDetails(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, - - error) { - var out []interface{} - err := _FunctionsCoordinator.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 (_FunctionsCoordinator *FunctionsCoordinatorSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, - - error) { - return _FunctionsCoordinator.Contract.LatestConfigDigestAndEpoch(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, - - error) { - return _FunctionsCoordinator.Contract.LatestConfigDigestAndEpoch(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _FunctionsCoordinator.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 (_FunctionsCoordinator *FunctionsCoordinatorSession) Owner() (common.Address, error) { - return _FunctionsCoordinator.Contract.Owner(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) Owner() (common.Address, error) { - return _FunctionsCoordinator.Contract.Owner(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) Transmitters(opts *bind.CallOpts) ([]common.Address, error) { - var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "transmitters") - - if err != nil { - return *new([]common.Address), err - } - - out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) - - return out0, err - -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) Transmitters() ([]common.Address, error) { - return _FunctionsCoordinator.Contract.Transmitters(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) Transmitters() ([]common.Address, error) { - return _FunctionsCoordinator.Contract.Transmitters(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { - var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "typeAndVersion") - - if err != nil { - return *new(string), err - } - - out0 := *abi.ConvertType(out[0], new(string)).(*string) - - return out0, err - -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) TypeAndVersion() (string, error) { - return _FunctionsCoordinator.Contract.TypeAndVersion(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) TypeAndVersion() (string, error) { - return _FunctionsCoordinator.Contract.TypeAndVersion(&_FunctionsCoordinator.CallOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsCoordinator.contract.Transact(opts, "acceptOwnership") -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) AcceptOwnership() (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.AcceptOwnership(&_FunctionsCoordinator.TransactOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) AcceptOwnership() (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.AcceptOwnership(&_FunctionsCoordinator.TransactOpts) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) DeleteCommitment(opts *bind.TransactOpts, requestId [32]byte) (*types.Transaction, error) { - return _FunctionsCoordinator.contract.Transact(opts, "deleteCommitment", requestId) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) DeleteCommitment(requestId [32]byte) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.DeleteCommitment(&_FunctionsCoordinator.TransactOpts, requestId) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) DeleteCommitment(requestId [32]byte) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.DeleteCommitment(&_FunctionsCoordinator.TransactOpts, requestId) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) DeleteNodePublicKey(opts *bind.TransactOpts, node common.Address) (*types.Transaction, error) { - return _FunctionsCoordinator.contract.Transact(opts, "deleteNodePublicKey", node) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) DeleteNodePublicKey(node common.Address) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.DeleteNodePublicKey(&_FunctionsCoordinator.TransactOpts, node) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) DeleteNodePublicKey(node common.Address) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.DeleteNodePublicKey(&_FunctionsCoordinator.TransactOpts, node) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) OracleWithdraw(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _FunctionsCoordinator.contract.Transact(opts, "oracleWithdraw", recipient, amount) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) OracleWithdraw(recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.OracleWithdraw(&_FunctionsCoordinator.TransactOpts, recipient, amount) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) OracleWithdraw(recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.OracleWithdraw(&_FunctionsCoordinator.TransactOpts, recipient, amount) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) SendRequest(opts *bind.TransactOpts, request IFunctionsCoordinatorRequest) (*types.Transaction, error) { - return _FunctionsCoordinator.contract.Transact(opts, "sendRequest", request) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) SendRequest(request IFunctionsCoordinatorRequest) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.SendRequest(&_FunctionsCoordinator.TransactOpts, request) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) SendRequest(request IFunctionsCoordinatorRequest) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.SendRequest(&_FunctionsCoordinator.TransactOpts, request) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) SetConfig(opts *bind.TransactOpts, config []byte) (*types.Transaction, error) { - return _FunctionsCoordinator.contract.Transact(opts, "setConfig", config) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) SetConfig(config []byte) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.SetConfig(&_FunctionsCoordinator.TransactOpts, config) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) SetConfig(config []byte) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.SetConfig(&_FunctionsCoordinator.TransactOpts, config) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) SetConfig0(opts *bind.TransactOpts, _signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) { - return _FunctionsCoordinator.contract.Transact(opts, "setConfig0", _signers, _transmitters, _f, _onchainConfig, _offchainConfigVersion, _offchainConfig) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) SetConfig0(_signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.SetConfig0(&_FunctionsCoordinator.TransactOpts, _signers, _transmitters, _f, _onchainConfig, _offchainConfigVersion, _offchainConfig) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) SetConfig0(_signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.SetConfig0(&_FunctionsCoordinator.TransactOpts, _signers, _transmitters, _f, _onchainConfig, _offchainConfigVersion, _offchainConfig) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) SetDONPublicKey(opts *bind.TransactOpts, donPublicKey []byte) (*types.Transaction, error) { - return _FunctionsCoordinator.contract.Transact(opts, "setDONPublicKey", donPublicKey) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) SetDONPublicKey(donPublicKey []byte) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.SetDONPublicKey(&_FunctionsCoordinator.TransactOpts, donPublicKey) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) SetDONPublicKey(donPublicKey []byte) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.SetDONPublicKey(&_FunctionsCoordinator.TransactOpts, donPublicKey) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) SetNodePublicKey(opts *bind.TransactOpts, node common.Address, publicKey []byte) (*types.Transaction, error) { - return _FunctionsCoordinator.contract.Transact(opts, "setNodePublicKey", node, publicKey) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) SetNodePublicKey(node common.Address, publicKey []byte) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.SetNodePublicKey(&_FunctionsCoordinator.TransactOpts, node, publicKey) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) SetNodePublicKey(node common.Address, publicKey []byte) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.SetNodePublicKey(&_FunctionsCoordinator.TransactOpts, node, publicKey) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) SetThresholdPublicKey(opts *bind.TransactOpts, thresholdPublicKey []byte) (*types.Transaction, error) { - return _FunctionsCoordinator.contract.Transact(opts, "setThresholdPublicKey", thresholdPublicKey) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) SetThresholdPublicKey(thresholdPublicKey []byte) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.SetThresholdPublicKey(&_FunctionsCoordinator.TransactOpts, thresholdPublicKey) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) SetThresholdPublicKey(thresholdPublicKey []byte) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.SetThresholdPublicKey(&_FunctionsCoordinator.TransactOpts, thresholdPublicKey) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _FunctionsCoordinator.contract.Transact(opts, "transferOwnership", to) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.TransferOwnership(&_FunctionsCoordinator.TransactOpts, to) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.TransferOwnership(&_FunctionsCoordinator.TransactOpts, to) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { - return _FunctionsCoordinator.contract.Transact(opts, "transmit", reportContext, report, rs, ss, rawVs) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.Transmit(&_FunctionsCoordinator.TransactOpts, reportContext, report, rs, ss, rawVs) -} - -func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { - return _FunctionsCoordinator.Contract.Transmit(&_FunctionsCoordinator.TransactOpts, reportContext, report, rs, ss, rawVs) -} - -type FunctionsCoordinatorBillingEndIterator struct { - Event *FunctionsCoordinatorBillingEnd - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsCoordinatorBillingEndIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsCoordinatorBillingEnd) - 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(FunctionsCoordinatorBillingEnd) - 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 *FunctionsCoordinatorBillingEndIterator) Error() error { - return it.fail -} - -func (it *FunctionsCoordinatorBillingEndIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsCoordinatorBillingEnd struct { - RequestId [32]byte - SubscriptionId uint64 - SignerPayment *big.Int - TransmitterPayment *big.Int - TotalCost *big.Int - Result uint8 - Raw types.Log -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterBillingEnd(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorBillingEndIterator, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "BillingEnd", requestIdRule) - if err != nil { - return nil, err - } - return &FunctionsCoordinatorBillingEndIterator{contract: _FunctionsCoordinator.contract, event: "BillingEnd", logs: logs, sub: sub}, nil -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchBillingEnd(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorBillingEnd, requestId [][32]byte) (event.Subscription, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "BillingEnd", 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(FunctionsCoordinatorBillingEnd) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "BillingEnd", 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 (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseBillingEnd(log types.Log) (*FunctionsCoordinatorBillingEnd, error) { - event := new(FunctionsCoordinatorBillingEnd) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "BillingEnd", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsCoordinatorBillingStartIterator struct { - Event *FunctionsCoordinatorBillingStart - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsCoordinatorBillingStartIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsCoordinatorBillingStart) - 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(FunctionsCoordinatorBillingStart) - 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 *FunctionsCoordinatorBillingStartIterator) Error() error { - return it.fail -} - -func (it *FunctionsCoordinatorBillingStartIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsCoordinatorBillingStart struct { - RequestId [32]byte - Commitment FunctionsBillingCommitment - Raw types.Log -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterBillingStart(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorBillingStartIterator, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "BillingStart", requestIdRule) - if err != nil { - return nil, err - } - return &FunctionsCoordinatorBillingStartIterator{contract: _FunctionsCoordinator.contract, event: "BillingStart", logs: logs, sub: sub}, nil -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchBillingStart(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorBillingStart, requestId [][32]byte) (event.Subscription, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "BillingStart", 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(FunctionsCoordinatorBillingStart) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "BillingStart", 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 (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseBillingStart(log types.Log) (*FunctionsCoordinatorBillingStart, error) { - event := new(FunctionsCoordinatorBillingStart) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "BillingStart", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsCoordinatorConfigSetIterator struct { - Event *FunctionsCoordinatorConfigSet - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsCoordinatorConfigSetIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsCoordinatorConfigSet) - 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(FunctionsCoordinatorConfigSet) - 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 *FunctionsCoordinatorConfigSetIterator) Error() error { - return it.fail -} - -func (it *FunctionsCoordinatorConfigSetIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsCoordinatorConfigSet struct { - MaxCallbackGasLimit uint32 - FeedStalenessSeconds uint32 - GasOverheadBeforeCallback uint32 - GasOverheadAfterCallback uint32 - FallbackNativePerUnitLink *big.Int - Fee *big.Int - MaxSupportedRequestDataVersion uint16 - Raw types.Log -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterConfigSet(opts *bind.FilterOpts) (*FunctionsCoordinatorConfigSetIterator, error) { - - logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "ConfigSet") - if err != nil { - return nil, err - } - return &FunctionsCoordinatorConfigSetIterator{contract: _FunctionsCoordinator.contract, event: "ConfigSet", logs: logs, sub: sub}, nil -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorConfigSet) (event.Subscription, error) { - - logs, sub, err := _FunctionsCoordinator.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(FunctionsCoordinatorConfigSet) - if err := _FunctionsCoordinator.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 (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseConfigSet(log types.Log) (*FunctionsCoordinatorConfigSet, error) { - event := new(FunctionsCoordinatorConfigSet) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "ConfigSet", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsCoordinatorCostExceedsCommitmentIterator struct { - Event *FunctionsCoordinatorCostExceedsCommitment - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsCoordinatorCostExceedsCommitmentIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsCoordinatorCostExceedsCommitment) - 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(FunctionsCoordinatorCostExceedsCommitment) - 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 *FunctionsCoordinatorCostExceedsCommitmentIterator) Error() error { - return it.fail -} - -func (it *FunctionsCoordinatorCostExceedsCommitmentIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsCoordinatorCostExceedsCommitment struct { - RequestId [32]byte - Raw types.Log -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterCostExceedsCommitment(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorCostExceedsCommitmentIterator, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "CostExceedsCommitment", requestIdRule) - if err != nil { - return nil, err - } - return &FunctionsCoordinatorCostExceedsCommitmentIterator{contract: _FunctionsCoordinator.contract, event: "CostExceedsCommitment", logs: logs, sub: sub}, nil -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchCostExceedsCommitment(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorCostExceedsCommitment, requestId [][32]byte) (event.Subscription, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "CostExceedsCommitment", 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(FunctionsCoordinatorCostExceedsCommitment) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "CostExceedsCommitment", 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 (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseCostExceedsCommitment(log types.Log) (*FunctionsCoordinatorCostExceedsCommitment, error) { - event := new(FunctionsCoordinatorCostExceedsCommitment) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "CostExceedsCommitment", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsCoordinatorInsufficientGasProvidedIterator struct { - Event *FunctionsCoordinatorInsufficientGasProvided - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsCoordinatorInsufficientGasProvidedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsCoordinatorInsufficientGasProvided) - 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(FunctionsCoordinatorInsufficientGasProvided) - 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 *FunctionsCoordinatorInsufficientGasProvidedIterator) Error() error { - return it.fail -} - -func (it *FunctionsCoordinatorInsufficientGasProvidedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsCoordinatorInsufficientGasProvided struct { - RequestId [32]byte - Raw types.Log -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterInsufficientGasProvided(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorInsufficientGasProvidedIterator, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "InsufficientGasProvided", requestIdRule) - if err != nil { - return nil, err - } - return &FunctionsCoordinatorInsufficientGasProvidedIterator{contract: _FunctionsCoordinator.contract, event: "InsufficientGasProvided", logs: logs, sub: sub}, nil -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchInsufficientGasProvided(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorInsufficientGasProvided, requestId [][32]byte) (event.Subscription, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "InsufficientGasProvided", 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(FunctionsCoordinatorInsufficientGasProvided) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "InsufficientGasProvided", 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 (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseInsufficientGasProvided(log types.Log) (*FunctionsCoordinatorInsufficientGasProvided, error) { - event := new(FunctionsCoordinatorInsufficientGasProvided) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "InsufficientGasProvided", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsCoordinatorInvalidRequestIDIterator struct { - Event *FunctionsCoordinatorInvalidRequestID - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsCoordinatorInvalidRequestIDIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsCoordinatorInvalidRequestID) - 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(FunctionsCoordinatorInvalidRequestID) - 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 *FunctionsCoordinatorInvalidRequestIDIterator) Error() error { - return it.fail -} - -func (it *FunctionsCoordinatorInvalidRequestIDIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsCoordinatorInvalidRequestID struct { - RequestId [32]byte - Raw types.Log -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterInvalidRequestID(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorInvalidRequestIDIterator, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "InvalidRequestID", requestIdRule) - if err != nil { - return nil, err - } - return &FunctionsCoordinatorInvalidRequestIDIterator{contract: _FunctionsCoordinator.contract, event: "InvalidRequestID", logs: logs, sub: sub}, nil -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchInvalidRequestID(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorInvalidRequestID, requestId [][32]byte) (event.Subscription, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "InvalidRequestID", 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(FunctionsCoordinatorInvalidRequestID) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "InvalidRequestID", 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 (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseInvalidRequestID(log types.Log) (*FunctionsCoordinatorInvalidRequestID, error) { - event := new(FunctionsCoordinatorInvalidRequestID) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "InvalidRequestID", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsCoordinatorOCRConfigSetIterator struct { - Event *FunctionsCoordinatorOCRConfigSet - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsCoordinatorOCRConfigSetIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsCoordinatorOCRConfigSet) - 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(FunctionsCoordinatorOCRConfigSet) - 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 *FunctionsCoordinatorOCRConfigSetIterator) Error() error { - return it.fail -} - -func (it *FunctionsCoordinatorOCRConfigSetIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsCoordinatorOCRConfigSet 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 (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterOCRConfigSet(opts *bind.FilterOpts) (*FunctionsCoordinatorOCRConfigSetIterator, error) { - - logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "OCRConfigSet") - if err != nil { - return nil, err - } - return &FunctionsCoordinatorOCRConfigSetIterator{contract: _FunctionsCoordinator.contract, event: "OCRConfigSet", logs: logs, sub: sub}, nil -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchOCRConfigSet(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorOCRConfigSet) (event.Subscription, error) { - - logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "OCRConfigSet") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsCoordinatorOCRConfigSet) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "OCRConfigSet", 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 (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseOCRConfigSet(log types.Log) (*FunctionsCoordinatorOCRConfigSet, error) { - event := new(FunctionsCoordinatorOCRConfigSet) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "OCRConfigSet", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsCoordinatorOracleRequestIterator struct { - Event *FunctionsCoordinatorOracleRequest - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsCoordinatorOracleRequestIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsCoordinatorOracleRequest) - 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(FunctionsCoordinatorOracleRequest) - 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 *FunctionsCoordinatorOracleRequestIterator) Error() error { - return it.fail -} - -func (it *FunctionsCoordinatorOracleRequestIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsCoordinatorOracleRequest struct { - RequestId [32]byte - RequestingContract common.Address - RequestInitiator common.Address - SubscriptionId uint64 - SubscriptionOwner common.Address - Data []byte - DataVersion uint16 - Raw types.Log -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterOracleRequest(opts *bind.FilterOpts, requestId [][32]byte, requestingContract []common.Address) (*FunctionsCoordinatorOracleRequestIterator, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - var requestingContractRule []interface{} - for _, requestingContractItem := range requestingContract { - requestingContractRule = append(requestingContractRule, requestingContractItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "OracleRequest", requestIdRule, requestingContractRule) - if err != nil { - return nil, err - } - return &FunctionsCoordinatorOracleRequestIterator{contract: _FunctionsCoordinator.contract, event: "OracleRequest", logs: logs, sub: sub}, nil -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchOracleRequest(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorOracleRequest, requestId [][32]byte, requestingContract []common.Address) (event.Subscription, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - var requestingContractRule []interface{} - for _, requestingContractItem := range requestingContract { - requestingContractRule = append(requestingContractRule, requestingContractItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "OracleRequest", requestIdRule, requestingContractRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsCoordinatorOracleRequest) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "OracleRequest", 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 (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseOracleRequest(log types.Log) (*FunctionsCoordinatorOracleRequest, error) { - event := new(FunctionsCoordinatorOracleRequest) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "OracleRequest", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsCoordinatorOracleResponseIterator struct { - Event *FunctionsCoordinatorOracleResponse - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsCoordinatorOracleResponseIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsCoordinatorOracleResponse) - 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(FunctionsCoordinatorOracleResponse) - 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 *FunctionsCoordinatorOracleResponseIterator) Error() error { - return it.fail -} - -func (it *FunctionsCoordinatorOracleResponseIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsCoordinatorOracleResponse struct { - RequestId [32]byte - Transmitter common.Address - Raw types.Log -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterOracleResponse(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorOracleResponseIterator, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "OracleResponse", requestIdRule) - if err != nil { - return nil, err - } - return &FunctionsCoordinatorOracleResponseIterator{contract: _FunctionsCoordinator.contract, event: "OracleResponse", logs: logs, sub: sub}, nil -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchOracleResponse(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorOracleResponse, requestId [][32]byte) (event.Subscription, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "OracleResponse", 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(FunctionsCoordinatorOracleResponse) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "OracleResponse", 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 (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseOracleResponse(log types.Log) (*FunctionsCoordinatorOracleResponse, error) { - event := new(FunctionsCoordinatorOracleResponse) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "OracleResponse", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsCoordinatorOwnershipTransferRequestedIterator struct { - Event *FunctionsCoordinatorOwnershipTransferRequested - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsCoordinatorOwnershipTransferRequestedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsCoordinatorOwnershipTransferRequested) - 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(FunctionsCoordinatorOwnershipTransferRequested) - 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 *FunctionsCoordinatorOwnershipTransferRequestedIterator) Error() error { - return it.fail -} - -func (it *FunctionsCoordinatorOwnershipTransferRequestedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsCoordinatorOwnershipTransferRequested struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsCoordinatorOwnershipTransferRequestedIterator, 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 := _FunctionsCoordinator.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) - if err != nil { - return nil, err - } - return &FunctionsCoordinatorOwnershipTransferRequestedIterator{contract: _FunctionsCoordinator.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorOwnershipTransferRequested, 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 := _FunctionsCoordinator.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(FunctionsCoordinatorOwnershipTransferRequested) - if err := _FunctionsCoordinator.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 (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseOwnershipTransferRequested(log types.Log) (*FunctionsCoordinatorOwnershipTransferRequested, error) { - event := new(FunctionsCoordinatorOwnershipTransferRequested) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsCoordinatorOwnershipTransferredIterator struct { - Event *FunctionsCoordinatorOwnershipTransferred - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsCoordinatorOwnershipTransferredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsCoordinatorOwnershipTransferred) - 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(FunctionsCoordinatorOwnershipTransferred) - 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 *FunctionsCoordinatorOwnershipTransferredIterator) Error() error { - return it.fail -} - -func (it *FunctionsCoordinatorOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsCoordinatorOwnershipTransferred struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsCoordinatorOwnershipTransferredIterator, 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 := _FunctionsCoordinator.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) - if err != nil { - return nil, err - } - return &FunctionsCoordinatorOwnershipTransferredIterator{contract: _FunctionsCoordinator.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorOwnershipTransferred, 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 := _FunctionsCoordinator.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(FunctionsCoordinatorOwnershipTransferred) - if err := _FunctionsCoordinator.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 (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseOwnershipTransferred(log types.Log) (*FunctionsCoordinatorOwnershipTransferred, error) { - event := new(FunctionsCoordinatorOwnershipTransferred) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsCoordinatorRequestTimedOutIterator struct { - Event *FunctionsCoordinatorRequestTimedOut - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsCoordinatorRequestTimedOutIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsCoordinatorRequestTimedOut) - 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(FunctionsCoordinatorRequestTimedOut) - 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 *FunctionsCoordinatorRequestTimedOutIterator) Error() error { - return it.fail -} - -func (it *FunctionsCoordinatorRequestTimedOutIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsCoordinatorRequestTimedOut struct { - RequestId [32]byte - Raw types.Log -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterRequestTimedOut(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorRequestTimedOutIterator, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "RequestTimedOut", requestIdRule) - if err != nil { - return nil, err - } - return &FunctionsCoordinatorRequestTimedOutIterator{contract: _FunctionsCoordinator.contract, event: "RequestTimedOut", logs: logs, sub: sub}, nil -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchRequestTimedOut(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorRequestTimedOut, requestId [][32]byte) (event.Subscription, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsCoordinator.contract.WatchLogs(opts, "RequestTimedOut", 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(FunctionsCoordinatorRequestTimedOut) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "RequestTimedOut", 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 (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseRequestTimedOut(log types.Log) (*FunctionsCoordinatorRequestTimedOut, error) { - event := new(FunctionsCoordinatorRequestTimedOut) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "RequestTimedOut", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsCoordinatorTransmittedIterator struct { - Event *FunctionsCoordinatorTransmitted - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsCoordinatorTransmittedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsCoordinatorTransmitted) - 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(FunctionsCoordinatorTransmitted) - 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 *FunctionsCoordinatorTransmittedIterator) Error() error { - return it.fail -} - -func (it *FunctionsCoordinatorTransmittedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsCoordinatorTransmitted struct { - ConfigDigest [32]byte - Epoch uint32 - Raw types.Log -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterTransmitted(opts *bind.FilterOpts) (*FunctionsCoordinatorTransmittedIterator, error) { - - logs, sub, err := _FunctionsCoordinator.contract.FilterLogs(opts, "Transmitted") - if err != nil { - return nil, err - } - return &FunctionsCoordinatorTransmittedIterator{contract: _FunctionsCoordinator.contract, event: "Transmitted", logs: logs, sub: sub}, nil -} - -func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorTransmitted) (event.Subscription, error) { - - logs, sub, err := _FunctionsCoordinator.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(FunctionsCoordinatorTransmitted) - if err := _FunctionsCoordinator.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 (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseTransmitted(log types.Log) (*FunctionsCoordinatorTransmitted, error) { - event := new(FunctionsCoordinatorTransmitted) - if err := _FunctionsCoordinator.contract.UnpackLog(event, "Transmitted", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type GetConfig struct { - MaxCallbackGasLimit uint32 - FeedStalenessSeconds uint32 - GasOverheadAfterCallback *big.Int - FallbackNativePerUnitLink *big.Int - GasOverheadBeforeCallback uint32 - LinkPriceFeed common.Address - MaxSupportedRequestDataVersion uint16 -} -type LatestConfigDetails struct { - ConfigCount uint32 - BlockNumber uint32 - ConfigDigest [32]byte -} -type LatestConfigDigestAndEpoch struct { - ScanLogs bool - ConfigDigest [32]byte - Epoch uint32 -} - -func (_FunctionsCoordinator *FunctionsCoordinator) ParseLog(log types.Log) (generated.AbigenLog, error) { - switch log.Topics[0] { - case _FunctionsCoordinator.abi.Events["BillingEnd"].ID: - return _FunctionsCoordinator.ParseBillingEnd(log) - case _FunctionsCoordinator.abi.Events["BillingStart"].ID: - return _FunctionsCoordinator.ParseBillingStart(log) - case _FunctionsCoordinator.abi.Events["ConfigSet"].ID: - return _FunctionsCoordinator.ParseConfigSet(log) - case _FunctionsCoordinator.abi.Events["CostExceedsCommitment"].ID: - return _FunctionsCoordinator.ParseCostExceedsCommitment(log) - case _FunctionsCoordinator.abi.Events["InsufficientGasProvided"].ID: - return _FunctionsCoordinator.ParseInsufficientGasProvided(log) - case _FunctionsCoordinator.abi.Events["InvalidRequestID"].ID: - return _FunctionsCoordinator.ParseInvalidRequestID(log) - case _FunctionsCoordinator.abi.Events["OCRConfigSet"].ID: - return _FunctionsCoordinator.ParseOCRConfigSet(log) - case _FunctionsCoordinator.abi.Events["OracleRequest"].ID: - return _FunctionsCoordinator.ParseOracleRequest(log) - case _FunctionsCoordinator.abi.Events["OracleResponse"].ID: - return _FunctionsCoordinator.ParseOracleResponse(log) - case _FunctionsCoordinator.abi.Events["OwnershipTransferRequested"].ID: - return _FunctionsCoordinator.ParseOwnershipTransferRequested(log) - case _FunctionsCoordinator.abi.Events["OwnershipTransferred"].ID: - return _FunctionsCoordinator.ParseOwnershipTransferred(log) - case _FunctionsCoordinator.abi.Events["RequestTimedOut"].ID: - return _FunctionsCoordinator.ParseRequestTimedOut(log) - case _FunctionsCoordinator.abi.Events["Transmitted"].ID: - return _FunctionsCoordinator.ParseTransmitted(log) - - default: - return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) - } -} - -func (FunctionsCoordinatorBillingEnd) Topic() common.Hash { - return common.HexToHash("0x30e1e299f390e4f3fa75e4489fed477e86183937a4a21a0ae7b137a4dff03535") -} - -func (FunctionsCoordinatorBillingStart) Topic() common.Hash { - return common.HexToHash("0x9fadc54f9c9b79290fa97f2c9deb97ee080d1f8ae4f00deb1fb83cedd1ee5422") -} - -func (FunctionsCoordinatorConfigSet) Topic() common.Hash { - return common.HexToHash("0xd09395baf4d99e44ce1b8e96a4396a3f896d0fd5e4517993f28ce0a6fb42e227") -} - -func (FunctionsCoordinatorCostExceedsCommitment) Topic() common.Hash { - return common.HexToHash("0x689f49eacf6db85082542f4b7873f4a519744a4e093fd002310545bfb4354cc8") -} - -func (FunctionsCoordinatorInsufficientGasProvided) Topic() common.Hash { - return common.HexToHash("0x357a60574f143e144d62ddc89636fee45ba5e2f8c9a30b9f91e28f8dfe5a56e0") -} - -func (FunctionsCoordinatorInvalidRequestID) Topic() common.Hash { - return common.HexToHash("0xa1c120e327c9ad8b075793878c88d59b8934b97ae37117faa3bb21616237f7be") -} - -func (FunctionsCoordinatorOCRConfigSet) Topic() common.Hash { - return common.HexToHash("0x324b4d5fd31c5865202bc49f712eb9fcdf22bcc3b89f8c721f3134ae6c081a09") -} - -func (FunctionsCoordinatorOracleRequest) Topic() common.Hash { - return common.HexToHash("0xb108b073fa485003d66284614f1c3b4feb3f47ffc88f7873bf3b2ec4bb8939bc") -} - -func (FunctionsCoordinatorOracleResponse) Topic() common.Hash { - return common.HexToHash("0xc708e0440951fd63499c0f7a73819b469ee5dd3ecc356c0ab4eb7f18389009d9") -} - -func (FunctionsCoordinatorOwnershipTransferRequested) Topic() common.Hash { - return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") -} - -func (FunctionsCoordinatorOwnershipTransferred) Topic() common.Hash { - return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") -} - -func (FunctionsCoordinatorRequestTimedOut) Topic() common.Hash { - return common.HexToHash("0xf1ca1e9147be737b04a2b018a79405f687a97de8dd8a2559bbe62357343af414") -} - -func (FunctionsCoordinatorTransmitted) Topic() common.Hash { - return common.HexToHash("0xb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62") -} - -func (_FunctionsCoordinator *FunctionsCoordinator) Address() common.Address { - return _FunctionsCoordinator.address -} - -type FunctionsCoordinatorInterface interface { - EstimateCost(opts *bind.CallOpts, subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPrice *big.Int) (*big.Int, error) - - GetAdminFee(opts *bind.CallOpts, arg0 []byte, arg1 IFunctionsBillingRequestBilling) (*big.Int, error) - - GetAllNodePublicKeys(opts *bind.CallOpts) ([]common.Address, [][]byte, error) - - GetConfig(opts *bind.CallOpts) (GetConfig, - - error) - - GetConfigHash(opts *bind.CallOpts) ([32]byte, error) - - GetDONFee(opts *bind.CallOpts, arg0 []byte, arg1 IFunctionsBillingRequestBilling) (*big.Int, error) - - GetDONPublicKey(opts *bind.CallOpts) ([]byte, error) - - GetFeedData(opts *bind.CallOpts) (*big.Int, error) - - GetThresholdPublicKey(opts *bind.CallOpts) ([]byte, error) - - LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, - - error) - - LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, - - error) - - Owner(opts *bind.CallOpts) (common.Address, error) - - Transmitters(opts *bind.CallOpts) ([]common.Address, error) - - TypeAndVersion(opts *bind.CallOpts) (string, error) - - AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) - - DeleteCommitment(opts *bind.TransactOpts, requestId [32]byte) (*types.Transaction, error) - - DeleteNodePublicKey(opts *bind.TransactOpts, node common.Address) (*types.Transaction, error) - - OracleWithdraw(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) - - SendRequest(opts *bind.TransactOpts, request IFunctionsCoordinatorRequest) (*types.Transaction, error) - - SetConfig(opts *bind.TransactOpts, config []byte) (*types.Transaction, error) - - SetConfig0(opts *bind.TransactOpts, _signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) - - SetDONPublicKey(opts *bind.TransactOpts, donPublicKey []byte) (*types.Transaction, error) - - SetNodePublicKey(opts *bind.TransactOpts, node common.Address, publicKey []byte) (*types.Transaction, error) - - SetThresholdPublicKey(opts *bind.TransactOpts, thresholdPublicKey []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) - - FilterBillingEnd(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorBillingEndIterator, error) - - WatchBillingEnd(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorBillingEnd, requestId [][32]byte) (event.Subscription, error) - - ParseBillingEnd(log types.Log) (*FunctionsCoordinatorBillingEnd, error) - - FilterBillingStart(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorBillingStartIterator, error) - - WatchBillingStart(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorBillingStart, requestId [][32]byte) (event.Subscription, error) - - ParseBillingStart(log types.Log) (*FunctionsCoordinatorBillingStart, error) - - FilterConfigSet(opts *bind.FilterOpts) (*FunctionsCoordinatorConfigSetIterator, error) - - WatchConfigSet(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorConfigSet) (event.Subscription, error) - - ParseConfigSet(log types.Log) (*FunctionsCoordinatorConfigSet, error) - - FilterCostExceedsCommitment(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorCostExceedsCommitmentIterator, error) - - WatchCostExceedsCommitment(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorCostExceedsCommitment, requestId [][32]byte) (event.Subscription, error) - - ParseCostExceedsCommitment(log types.Log) (*FunctionsCoordinatorCostExceedsCommitment, error) - - FilterInsufficientGasProvided(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorInsufficientGasProvidedIterator, error) - - WatchInsufficientGasProvided(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorInsufficientGasProvided, requestId [][32]byte) (event.Subscription, error) - - ParseInsufficientGasProvided(log types.Log) (*FunctionsCoordinatorInsufficientGasProvided, error) - - FilterInvalidRequestID(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorInvalidRequestIDIterator, error) - - WatchInvalidRequestID(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorInvalidRequestID, requestId [][32]byte) (event.Subscription, error) - - ParseInvalidRequestID(log types.Log) (*FunctionsCoordinatorInvalidRequestID, error) - - FilterOCRConfigSet(opts *bind.FilterOpts) (*FunctionsCoordinatorOCRConfigSetIterator, error) - - WatchOCRConfigSet(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorOCRConfigSet) (event.Subscription, error) - - ParseOCRConfigSet(log types.Log) (*FunctionsCoordinatorOCRConfigSet, error) - - FilterOracleRequest(opts *bind.FilterOpts, requestId [][32]byte, requestingContract []common.Address) (*FunctionsCoordinatorOracleRequestIterator, error) - - WatchOracleRequest(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorOracleRequest, requestId [][32]byte, requestingContract []common.Address) (event.Subscription, error) - - ParseOracleRequest(log types.Log) (*FunctionsCoordinatorOracleRequest, error) - - FilterOracleResponse(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorOracleResponseIterator, error) - - WatchOracleResponse(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorOracleResponse, requestId [][32]byte) (event.Subscription, error) - - ParseOracleResponse(log types.Log) (*FunctionsCoordinatorOracleResponse, error) - - FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsCoordinatorOwnershipTransferRequestedIterator, error) - - WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) - - ParseOwnershipTransferRequested(log types.Log) (*FunctionsCoordinatorOwnershipTransferRequested, error) - - FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsCoordinatorOwnershipTransferredIterator, error) - - WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) - - ParseOwnershipTransferred(log types.Log) (*FunctionsCoordinatorOwnershipTransferred, error) - - FilterRequestTimedOut(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsCoordinatorRequestTimedOutIterator, error) - - WatchRequestTimedOut(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorRequestTimedOut, requestId [][32]byte) (event.Subscription, error) - - ParseRequestTimedOut(log types.Log) (*FunctionsCoordinatorRequestTimedOut, error) - - FilterTransmitted(opts *bind.FilterOpts) (*FunctionsCoordinatorTransmittedIterator, error) - - WatchTransmitted(opts *bind.WatchOpts, sink chan<- *FunctionsCoordinatorTransmitted) (event.Subscription, error) - - ParseTransmitted(log types.Log) (*FunctionsCoordinatorTransmitted, error) - - ParseLog(log types.Log) (generated.AbigenLog, error) - - Address() common.Address -} diff --git a/core/gethwrappers/generated/functions_registry/functions_registry.go b/core/gethwrappers/generated/functions_registry/functions_registry.go deleted file mode 100644 index cb8c5ce2ca5..00000000000 --- a/core/gethwrappers/generated/functions_registry/functions_registry.go +++ /dev/null @@ -1,3350 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package functions_registry - -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 FunctionsBillingRegistryCommitment struct { - SubscriptionId uint64 - Client common.Address - GasLimit uint32 - GasPrice *big.Int - Don common.Address - DonFee *big.Int - RegistryFee *big.Int - EstimatedCost *big.Int - Timestamp *big.Int -} - -type IFunctionsBillingRegistryRequestBilling struct { - SubscriptionId uint64 - Client common.Address - GasLimit uint32 - GasPrice *big.Int -} - -var FunctionsRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkEthFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"oracle\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"internalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"externalBalance\",\"type\":\"uint256\"}],\"name\":\"BalanceInvariantViolated\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotSelfTransfer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySendersList\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"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\":\"NotAllowedToSetSenders\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerMustBeSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSender\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"senders\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"changedBy\",\"type\":\"address\"}],\"name\":\"AuthorizedSendersChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"signerPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"transmitterPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalCost\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"BillingEnd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"don\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"donFee\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"registryFee\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"estimatedCost\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structFunctionsBillingRegistry.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"name\":\"BillingStart\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasOverhead\",\"type\":\"uint32\"}],\"name\":\"ConfigSet\",\"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\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"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\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestTimedOut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"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\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"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\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"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\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CONSUMERS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"donFee\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"registryFee\",\"type\":\"uint96\"}],\"name\":\"estimateCost\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address[31]\",\"name\":\"signers\",\"type\":\"address[31]\"},{\"internalType\":\"uint8\",\"name\":\"signerCount\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"reportValidationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"initialGas\",\"type\":\"uint256\"}],\"name\":\"fulfillAndBill\",\"outputs\":[{\"internalType\":\"enumIFunctionsBillingRegistry.FulfillResult\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAuthorizedSenders\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"gasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"linkAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkPriceFeed\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentsubscriptionId\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRequestConfig\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"}],\"internalType\":\"structIFunctionsBillingRegistry.RequestBilling\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"getRequiredFee\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getSubscriptionOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTotalBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkEthFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"oracle\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"isAuthorizedSender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"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\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"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\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"requestSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"senders\",\"type\":\"address[]\"}],\"name\":\"setAuthorizedSenders\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"gasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"}],\"internalType\":\"structIFunctionsBillingRegistry.RequestBilling\",\"name\":\"billing\",\"type\":\"tuple\"}],\"name\":\"startBilling\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"requestIdsToTimeout\",\"type\":\"bytes32[]\"}],\"name\":\"timeoutRequests\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b5060405162005d3838038062005d3883398101604081905262000034916200040c565b620000418383836200004a565b50505062000456565b600054610100900460ff16158080156200006b5750600054600160ff909116105b806200009b57506200008830620001c960201b62003bd41760201c565b1580156200009b575060005460ff166001145b620001045760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000128576000805461ff0019166101001790555b62000132620001d8565b6200013f33600062000240565b606980546001600160a01b038087166001600160a01b031992831617909255606a8054868416908316179055606b8054928516929091169190911790558015620001c3576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6001600160a01b03163b151590565b600054610100900460ff16620002345760405162461bcd60e51b815260206004820152602b602482015260008051602062005d1883398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000fb565b6200023e62000304565b565b600054610100900460ff166200029c5760405162461bcd60e51b815260206004820152602b602482015260008051602062005d1883398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000fb565b6001600160a01b038216620002c457604051635b5a8afd60e11b815260040160405180910390fd5b600080546001600160a01b03808516620100000262010000600160b01b031990921691909117909155811615620003005762000300816200036c565b5050565b600054610100900460ff16620003605760405162461bcd60e51b815260206004820152602b602482015260008051602062005d1883398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000fb565b6034805460ff19169055565b6001600160a01b038116331415620003975760405163282010c360e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038381169182179092556000805460405192936201000090910416917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146200040757600080fd5b919050565b6000806000606084860312156200042257600080fd5b6200042d84620003ef565b92506200043d60208501620003ef565b91506200044d60408501620003ef565b90509250925092565b6158b280620004666000396000f3fe608060405234801561001057600080fd5b50600436106102255760003560e01c80638da5cb5b1161012a578063c0c53b8b116100bd578063e82ad7d41161008c578063f1e14a2111610071578063f1e14a2114610561578063f2fde38b14610578578063fa00763a1461058b57600080fd5b8063e82ad7d41461053b578063ee56997b1461054e57600080fd5b8063c0c53b8b1461048d578063c3f909d4146104a0578063d7ae1d3014610515578063e72f6e301461052857600080fd5b8063a47c7696116100f9578063a47c769614610432578063a4c0ed3614610454578063a9d03c0514610467578063b2a489ff1461047a57600080fd5b80638da5cb5b146103a25780639f87fad7146103e7578063a1a6d041146103fa578063a21a23e41461042a57600080fd5b80633f4ba83a116101bd578063665871ec1161018c57806379ba50971161017157806379ba50971461037f57806382359740146103875780638456cb591461039a57600080fd5b8063665871ec146103595780637341c10c1461036c57600080fd5b80633f4ba83a1461030c5780635c975abb1461031457806364d51a2a1461032b57806366316d8d1461034657600080fd5b806312b58349116101f957806312b58349146102915780632408afaa146102bd57806327923e41146102d257806333652e3e146102e557600080fd5b80620122911461022a57806302bcc5b61461024957806304c357cb1461025e5780630739e4f114610271575b600080fd5b61023261059e565b6040516102409291906155a1565b60405180910390f35b61025c6102573660046151d9565b6105bd565b005b61025c61026c3660046151f4565b61063a565b61028461027f366004614edf565b610835565b6040516102409190615470565b606f546801000000000000000090046bffffffffffffffffffffffff165b604051908152602001610240565b6102c5610ef7565b60405161024091906153a6565b61025c6102e0366004615173565b610f66565b606f5467ffffffffffffffff165b60405167ffffffffffffffff9091168152602001610240565b61025c6110b9565b60345460ff165b6040519015158152602001610240565b610333606481565b60405161ffff9091168152602001610240565b61025c610354366004614e44565b6110cb565b61025c610367366004614e7b565b611331565b61025c61037a3660046151f4565b6115fd565b61025c611890565b61025c6103953660046151d9565b611983565b61025c611d04565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610240565b61025c6103f53660046151f4565b611d14565b61040d610408366004615122565b61219b565b6040516bffffffffffffffffffffffff9091168152602001610240565b6102f36122bf565b6104456104403660046151d9565b612657565b604051610240939291906155c8565b61025c610462366004614dea565b612788565b6102af610475366004615009565b6129e1565b6103c26104883660046151d9565b6131dc565b61025c61049b366004614da7565b613275565b607354607454607254607554606954606a546040805163ffffffff808916825265010000000000909804881660208201529081019590955260608501939093529316608083015273ffffffffffffffffffffffffffffffffffffffff92831660a08301529190911660c082015260e001610240565b61025c6105233660046151f4565b613477565b61025c610536366004614d8c565b6135de565b61031b6105493660046151d9565b6137fb565b61025c61055c366004614e7b565b613a3a565b61040d61056f366004615086565b60009392505050565b61025c610586366004614d8c565b613bad565b61031b610599366004614d8c565b613bc1565b60735460009060609063ffffffff166105b5610ef7565b915091509091565b6105c5613bf0565b67ffffffffffffffff81166000908152606d602052604090205473ffffffffffffffffffffffffffffffffffffffff168061062c576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106368282613c47565b5050565b67ffffffffffffffff82166000908152606d6020526040902054829073ffffffffffffffffffffffffffffffffffffffff16806106a3576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff82161461070f576040517fd8a3fb5200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024015b60405180910390fd5b607354640100000000900460ff1615610754576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61075c61404e565b67ffffffffffffffff84166000908152606d602052604090206001015473ffffffffffffffffffffffffffffffffffffffff84811691161461082f5767ffffffffffffffff84166000818152606d602090815260409182902060010180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff88169081179091558251338152918201527f69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be91015b60405180910390a25b50505050565b600061083f6140bb565b607354640100000000900460ff1615610884576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61088c61404e565b60008b815260716020908152604091829020825161012081018452815467ffffffffffffffff8116825268010000000000000000810473ffffffffffffffffffffffffffffffffffffffff908116948301949094527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169381019390935260018101546060840152600281015491821660808401819052740100000000000000000000000000000000000000009092046bffffffffffffffffffffffff90811660a0850152600382015480821660c08601526c0100000000000000000000000090041660e084015260040154610100830152610990576002915050610ee9565b60008c81526071602052604080822082815560018101839055600281018390556003810180547fffffffffffffffff000000000000000000000000000000000000000000000000169055600401829055517f0ca761750000000000000000000000000000000000000000000000000000000090610a19908f908f908f908f908f906024016153b9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090951694909417909352607380547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff1664010000000017905584015191840151909250600091610ae69163ffffffff90911690846140fa565b607380547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff16905560745460a085015160c0860151929350600092610b3292899290918c908c3a614146565b604080820151865167ffffffffffffffff166000908152606e60205291909120549192506bffffffffffffffffffffffff90811691161015610ba0576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080820151855167ffffffffffffffff166000908152606e602052918220805491929091610bde9084906bffffffffffffffffffffffff16615712565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555060005b8860ff16811015610cd8578151607060008c84601f8110610c3257610c3261582d565b602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a90046bffffffffffffffffffffffff16610c979190615658565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508080610cd09061573f565b915050610c0f565b508360c0015160706000610d0860005473ffffffffffffffffffffffffffffffffffffffff620100009091041690565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160009081208054909190610d4e9084906bffffffffffffffffffffffff16615658565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560208381015173ffffffffffffffffffffffffffffffffffffffff8e166000908152607090925260408220805491945092610db091859116615658565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560e0860151865167ffffffffffffffff166000908152606e60205260409020805491935091600c91610e199185916c01000000000000000000000000900416615712565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508e7fc8dc973332de19a5f71b6026983110e9c2e04b0c98b87eb771ccb78607fd114f856000015183600001518460200151856040015187604051610ecb95949392919067ffffffffffffffff9590951685526bffffffffffffffffffffffff9384166020860152918316604085015290911660608301521515608082015260a00190565b60405180910390a281610edf576001610ee2565b60005b9450505050505b9a9950505050505050505050565b60606068805480602002602001604051908101604052809291908181526020018280548015610f5c57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610f31575b5050505050905090565b610f6e613bf0565b60008313610fab576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101849052602401610706565b6040805160c08101825263ffffffff888116808352600060208085019190915289831684860181905260608086018b9052888516608080880182905295891660a0978801819052607380547fffffffffffffffffffffffffffffffffffffffffffffff00000000000000000016871765010000000000860217905560748d9055607580547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016831764010000000090920291909117905560728b9055875194855292840191909152948201899052938101879052908101929092527f24d3d934adfef9b9029d6ffa463c07d0139ed47d26ee23506f85ece2879d2bd4910160405180910390a1505050505050565b6110c1613bf0565b6110c96142c6565b565b607354640100000000900460ff1615611110576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61111861404e565b6bffffffffffffffffffffffff811661114b5750336000908152607060205260409020546bffffffffffffffffffffffff165b336000908152607060205260409020546bffffffffffffffffffffffff808316911610156111a5576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600090815260706020526040812080548392906111d29084906bffffffffffffffffffffffff16615712565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080606f60088282829054906101000a90046bffffffffffffffffffffffff166112299190615712565b82546101009290920a6bffffffffffffffffffffffff8181021990931691831602179091556069546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015292851660248201529116915063a9059cbb90604401602060405180830381600087803b1580156112c357600080fd5b505af11580156112d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112fb9190614ebd565b610636576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61133961404e565b60005b818110156115f85760008383838181106113585761135861582d565b602090810292909201356000818152607184526040808220815161012081018352815467ffffffffffffffff811680835268010000000000000000820473ffffffffffffffffffffffffffffffffffffffff908116848b01527c010000000000000000000000000000000000000000000000000000000090920463ffffffff168386015260018401546060840152600284015480831660808501527401000000000000000000000000000000000000000090046bffffffffffffffffffffffff90811660a0850152600385015480821660c08601526c0100000000000000000000000090041660e0840152600490930154610100830152918452606d90965291205491945016331490506114cd57805167ffffffffffffffff166000908152606d6020526040908190205490517fd8a3fb5200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610706565b60755461010082015142916114f19164010000000090910463ffffffff1690615614565b11156115e35760e0810151815167ffffffffffffffff166000908152606e602052604090208054600c906115449084906c0100000000000000000000000090046bffffffffffffffffffffffff16615712565b82546bffffffffffffffffffffffff9182166101009390930a92830291909202199091161790555060008281526071602052604080822082815560018101839055600281018390556003810180547fffffffffffffffff0000000000000000000000000000000000000000000000001690556004018290555183917ff1ca1e9147be737b04a2b018a79405f687a97de8dd8a2559bbe62357343af41491a25b505080806115f09061573f565b91505061133c565b505050565b67ffffffffffffffff82166000908152606d6020526040902054829073ffffffffffffffffffffffffffffffffffffffff1680611666576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff8216146116cd576040517fd8a3fb5200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610706565b607354640100000000900460ff1615611712576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61171a61404e565b67ffffffffffffffff84166000908152606d602052604090206002015460641415611771576040517f05a48e0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000908152606c6020908152604080832067ffffffffffffffff808916855292529091205416156117b85761082f565b73ffffffffffffffffffffffffffffffffffffffff83166000818152606c6020908152604080832067ffffffffffffffff891680855290835281842080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001908117909155606d84528285206002018054918201815585529383902090930180547fffffffffffffffffffffffff000000000000000000000000000000000000000016851790555192835290917f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e09101610826565b60015473ffffffffffffffffffffffffffffffffffffffff1633146118e1576040517f0f22ca5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805433620100008181027fffffffffffffffffffff0000000000000000000000000000000000000000ffff8416178455600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905560405173ffffffffffffffffffffffffffffffffffffffff919093041692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b607354640100000000900460ff16156119c8576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119d061404e565b606b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634b4fa0c16040518163ffffffff1660e01b815260040160206040518083038186803b158015611a3857600080fd5b505afa158015611a4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a709190614ebd565b8015611b1a5750606b546040517ffa00763a00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063fa00763a9060240160206040518083038186803b158015611ae057600080fd5b505afa158015611af4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b189190614ebd565b155b15611b51576040517f0809490800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152606d602052604090205473ffffffffffffffffffffffffffffffffffffffff16611bb7576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152606d602052604090206001015473ffffffffffffffffffffffffffffffffffffffff163314611c595767ffffffffffffffff81166000908152606d6020526040908190206001015490517fd084e97500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610706565b67ffffffffffffffff81166000818152606d60209081526040918290208054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560019093018054909316909255835173ffffffffffffffffffffffffffffffffffffffff909116808252928101919091529092917f6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f0910160405180910390a25050565b611d0c613bf0565b6110c9614343565b67ffffffffffffffff82166000908152606d6020526040902054829073ffffffffffffffffffffffffffffffffffffffff1680611d7d576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821614611de4576040517fd8a3fb5200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610706565b607354640100000000900460ff1615611e29576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e3161404e565b73ffffffffffffffffffffffffffffffffffffffff83166000908152606c6020908152604080832067ffffffffffffffff808916855292529091205416611ecc576040517ff0019fe600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8516600482015273ffffffffffffffffffffffffffffffffffffffff84166024820152604401610706565b67ffffffffffffffff84166000908152606d6020908152604080832060020180548251818502810185019093528083529192909190830182828015611f4757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611f1c575b50505050509050600060018251611f5e91906156fb565b905060005b82518110156120fd578573ffffffffffffffffffffffffffffffffffffffff16838281518110611f9557611f9561582d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614156120eb576000838381518110611fcd57611fcd61582d565b6020026020010151905080606d60008a67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060020183815481106120135761201361582d565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff949094169390931790925567ffffffffffffffff8a168152606d9091526040902060020180548061208d5761208d6157fe565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055506120fd565b806120f58161573f565b915050611f63565b5073ffffffffffffffffffffffffffffffffffffffff85166000818152606c6020908152604080832067ffffffffffffffff8b168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001690555192835290917f182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b91015b60405180910390a2505050505050565b6000806121a661439e565b9050600081136121e5576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101829052602401610706565b60745460755460009163ffffffff808a1692612202929116615614565b61220c9190615614565b90506000828261222489670de0b6b3a76400006156be565b61222e91906156be565b612238919061567f565b905060006122576bffffffffffffffffffffffff808816908916615614565b905061226f816b033b2e3c9fd0803ce80000006156fb565b8211156122a8576040517fe80fa38100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122b28183615614565b9998505050505050505050565b607354600090640100000000900460ff1615612307576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61230f61404e565b606b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634b4fa0c16040518163ffffffff1660e01b815260040160206040518083038186803b15801561237757600080fd5b505afa15801561238b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123af9190614ebd565b80156124595750606b546040517ffa00763a00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063fa00763a9060240160206040518083038186803b15801561241f57600080fd5b505afa158015612433573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124579190614ebd565b155b15612490576040517f0809490800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606f805467ffffffffffffffff169060006124aa83615778565b82546101009290920a67ffffffffffffffff818102199093169183160217909155606f541690506000806040519080825280602002602001820160405280156124fd578160200160208202803683370190505b506040805180820182526000808252602080830182815267ffffffffffffffff8816808452606e83528584209451855492516bffffffffffffffffffffffff9081166c01000000000000000000000000027fffffffffffffffff000000000000000000000000000000000000000000000000909416911617919091179093558351606081018552338152808201838152818601878152948452606d8352949092208251815473ffffffffffffffffffffffffffffffffffffffff9182167fffffffffffffffffffffffff000000000000000000000000000000000000000091821617835595516001830180549190921696169590951790945591518051949550909361260f9260028501920190614ad8565b505060405133815267ffffffffffffffff841691507f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf9060200160405180910390a250905090565b67ffffffffffffffff81166000908152606d6020526040812054819060609073ffffffffffffffffffffffffffffffffffffffff166126c2576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff84166000908152606e6020908152604080832054606d8352928190208054600290910180548351818602810186019094528084526bffffffffffffffffffffffff9095169473ffffffffffffffffffffffffffffffffffffffff90921693909291839183018282801561277457602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612749575b505050505090509250925092509193909250565b607354640100000000900460ff16156127cd576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6127d561404e565b60695473ffffffffffffffffffffffffffffffffffffffff163314612826576040517f44b0e3c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114612860576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061286e828401846151d9565b67ffffffffffffffff81166000908152606d602052604090205490915073ffffffffffffffffffffffffffffffffffffffff166128d7576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152606e6020526040812080546bffffffffffffffffffffffff169186919061290e8385615658565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555084606f60088282829054906101000a90046bffffffffffffffffffffffff166129659190615658565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508167ffffffffffffffff167fd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f88287846129cc9190615614565b6040805192835260208301919091520161218b565b60006129eb6140bb565b607354640100000000900460ff1615612a30576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612a3861404e565b6000606d81612a4a60208601866151d9565b67ffffffffffffffff16815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff161415612ab3576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000606c81612ac86040860160208701614d8c565b73ffffffffffffffffffffffffffffffffffffffff168152602080820192909252604001600090812091612afe908601866151d9565b67ffffffffffffffff908116825260208201929092526040016000205416905080612b9a57612b3060208401846151d9565b612b406040850160208601614d8c565b6040517ff0019fe600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909216600483015273ffffffffffffffffffffffffffffffffffffffff166024820152604401610706565b60735463ffffffff16612bb36060850160408601615107565b63ffffffff161115612c1457612bcf6060840160408501615107565b6073546040517ff5d7e01e00000000000000000000000000000000000000000000000000000000815263ffffffff928316600482015291166024820152604401610706565b6040517ff1e14a21000000000000000000000000000000000000000000000000000000008152600090339063f1e14a2190612c57908990899089906004016153f2565b60206040518083038186803b158015612c6f57600080fd5b505afa158015612c83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ca79190615277565b90506000612cbf878761056f368990038901896150d2565b90506000612ce2612cd66060880160408901615107565b8760600135858561219b565b90506000606e81612cf660208a018a6151d9565b67ffffffffffffffff1681526020808201929092526040016000908120546c0100000000000000000000000090046bffffffffffffffffffffffff1691606e9190612d43908b018b6151d9565b67ffffffffffffffff168152602081019190915260400160002054612d7691906bffffffffffffffffffffffff16615712565b9050816bffffffffffffffffffffffff16816bffffffffffffffffffffffff161015612dce576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612ddb86600161562c565b90506000612e6333612df360408c0160208d01614d8c565b612e0060208d018d6151d9565b856040805173ffffffffffffffffffffffffffffffffffffffff958616602080830191909152949095168582015267ffffffffffffffff928316606086015291166080808501919091528151808503909101815260a09093019052815191012090565b60408051610120810190915290915060009080612e8360208d018d6151d9565b67ffffffffffffffff1681526020018b6020016020810190612ea59190614d8c565b73ffffffffffffffffffffffffffffffffffffffff168152602001612ed060608d0160408e01615107565b63ffffffff90811682526060808e0135602080850191909152336040808601919091526bffffffffffffffffffffffff808e16848701528c81166080808801919091528c821660a0808901919091524260c09889015260008b8152607186528481208a5181548c890151978d0151909a167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff98891668010000000000000000027fffffffff00000000000000000000000000000000000000000000000000000000909c1667ffffffffffffffff909316929092179a909a171698909817885595890151600188015590880151908801518216740100000000000000000000000000000000000000000292169190911760028501559385015160038401805460e088015187166c01000000000000000000000000027fffffffffffffffff0000000000000000000000000000000000000000000000009091169290961691909117949094179093556101008401516004909201919091559192508691606e9161308a908e018e6151d9565b67ffffffffffffffff16815260208101919091526040016000208054600c906130d29084906c0100000000000000000000000090046bffffffffffffffffffffffff16615658565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550817f99f7f4e65b4b9fbabd4e357c47ed3099b36e57ecd3a43e84662f34c207d0ebe48260405161313091906154b1565b60405180910390a282606c600061314d60408e0160208f01614d8c565b73ffffffffffffffffffffffffffffffffffffffff168152602080820192909252604001600090812091613183908e018e6151d9565b67ffffffffffffffff9081168252602082019290925260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001692909116919091179055509a9950505050505050505050565b67ffffffffffffffff81166000908152606d602052604081205473ffffffffffffffffffffffffffffffffffffffff16613242576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5067ffffffffffffffff166000908152606d602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b600054610100900460ff16158080156132955750600054600160ff909116105b806132af5750303b1580156132af575060005460ff166001145b61333b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610706565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561339957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6133a1614491565b6133ac336000614530565b6069805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255606a8054868416908316179055606b805492851692909116919091179055801561082f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a150505050565b67ffffffffffffffff82166000908152606d6020526040902054829073ffffffffffffffffffffffffffffffffffffffff16806134e0576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821614613547576040517fd8a3fb5200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610706565b607354640100000000900460ff161561358c576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61359461404e565b61359d846137fb565b156135d4576040517fb42f66e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61082f8484613c47565b6135e6613bf0565b6069546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a082319060240160206040518083038186803b15801561365057600080fd5b505afa158015613664573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061368891906150ee565b606f549091506801000000000000000090046bffffffffffffffffffffffff16818111156136ec576040517fa99da3020000000000000000000000000000000000000000000000000000000081526004810182905260248101839052604401610706565b818110156115f857600061370082846156fb565b6069546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301526024820184905292935091169063a9059cbb90604401602060405180830381600087803b15801561377657600080fd5b505af115801561378a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137ae9190614ebd565b506040805173ffffffffffffffffffffffffffffffffffffffff86168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b4366009101613469565b67ffffffffffffffff81166000908152606d602090815260408083206002018054825181850281018501909352808352849383018282801561387357602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311613848575b505050505090506000613884610ef7565b905060005b8251811015613a2f5760005b8251811015613a1c5760006139cc8483815181106138b5576138b561582d565b60200260200101518685815181106138cf576138cf61582d565b602002602001015189606c60008a89815181106138ee576138ee61582d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060009054906101000a900467ffffffffffffffff166040805173ffffffffffffffffffffffffffffffffffffffff958616602080830191909152949095168582015267ffffffffffffffff928316606086015291166080808501919091528151808503909101815260a09093019052815191012090565b60008181526071602052604090206002015490915073ffffffffffffffffffffffffffffffffffffffff1615613a09575060019695505050505050565b5080613a148161573f565b915050613895565b5080613a278161573f565b915050613889565b506000949350505050565b613a42614670565b613a78576040517fad77f06100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80613aaf576040517f75158c3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b606854811015613b0f57613afc60688281548110613ad257613ad261582d565b60009182526020909120015460669073ffffffffffffffffffffffffffffffffffffffff16614680565b5080613b078161573f565b915050613ab2565b5060005b81811015613b6057613b4d838383818110613b3057613b3061582d565b9050602002016020810190613b459190614d8c565b6066906146a9565b5080613b588161573f565b915050613b13565b50613b6d60688383614b5e565b507ff263cfb3e4298332e776194610cf9fdc09ccb3ada8b9aa39764d882e11fbf0a0828233604051613ba19392919061532e565b60405180910390a15050565b613bb5613bf0565b613bbe816146cb565b50565b6000613bce606683614798565b92915050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff1633146110c9576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b607354640100000000900460ff1615613c8c576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff82166000908152606d602090815260408083208151606081018352815473ffffffffffffffffffffffffffffffffffffffff908116825260018301541681850152600282018054845181870281018701865281815292959394860193830182828015613d3757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311613d0c575b5050509190925250505067ffffffffffffffff84166000908152606e60205260408120549192506bffffffffffffffffffffffff909116905b826040015151811015613e1657606c600084604001518381518110613d9757613d9761582d565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff89168252909252902080547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016905580613e0e8161573f565b915050613d70565b5067ffffffffffffffff84166000908152606d6020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081168255600182018054909116905590613e716002830182614bd6565b505067ffffffffffffffff84166000908152606e6020526040902080547fffffffffffffffff000000000000000000000000000000000000000000000000169055606f8054829190600890613ee19084906801000000000000000090046bffffffffffffffffffffffff16615712565b82546101009290920a6bffffffffffffffffffffffff8181021990931691831602179091556069546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015292851660248201529116915063a9059cbb90604401602060405180830381600087803b158015613f7b57600080fd5b505af1158015613f8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fb39190614ebd565b613fe9576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff851681526bffffffffffffffffffffffff8316602082015267ffffffffffffffff8616917fe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd498159101610826565b60345460ff16156110c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610706565b6140c433613bc1565b6110c9576040517f0809490800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005a61138881101561410c57600080fd5b61138881039050846040820482031161412457600080fd5b50823b61413057600080fd5b60008083516020850160008789f1949350505050565b604080516060810182526000808252602082018190529181018290529061416b61439e565b9050600081136141aa576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101829052602401610706565b6000815a8b6141b98c89615614565b6141c39190615614565b6141cd91906156fb565b6141df86670de0b6b3a76400006156be565b6141e991906156be565b6141f3919061567f565b905060006142126bffffffffffffffffffffffff808916908b16615614565b905061422a816b033b2e3c9fd0803ce80000006156fb565b821115614263576040517fe80fa38100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061427260ff8a168b615693565b90508260006142896142848584615614565b6147c7565b604080516060810182526bffffffffffffffffffffffff958616815293851660208501529316928201929092529c9b505050505050505050505050565b6142ce614869565b603480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b61434b61404e565b603480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586143193390565b607354606a54604080517ffeaf968c000000000000000000000000000000000000000000000000000000008152905160009365010000000000900463ffffffff1692831515928592839273ffffffffffffffffffffffffffffffffffffffff169163feaf968c9160048083019260a0929190829003018186803b15801561442457600080fd5b505afa158015614438573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061445c9190615227565b5093505092505082801561447e575061447581426156fb565b8463ffffffff16105b156144895760725491505b509392505050565b600054610100900460ff16614528576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610706565b6110c96148d5565b600054610100900460ff166145c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610706565b73ffffffffffffffffffffffffffffffffffffffff8216614614576040517fb6b515fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff80851662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff9092169190911790915581161561063657610636816146cb565b600061467a613bf0565b50600190565b60006146a28373ffffffffffffffffffffffffffffffffffffffff8416614996565b9392505050565b60006146a28373ffffffffffffffffffffffffffffffffffffffff8416614a89565b73ffffffffffffffffffffffffffffffffffffffff811633141561471b576040517f282010c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8381169182179092556000805460405192936201000090910416917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415156146a2565b60006bffffffffffffffffffffffff821115614865576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610706565b5090565b60345460ff166110c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610706565b600054610100900460ff1661496c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610706565b603480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60008181526001830160205260408120548015614a7f5760006149ba6001836156fb565b85549091506000906149ce906001906156fb565b9050818114614a335760008660000182815481106149ee576149ee61582d565b9060005260206000200154905080876000018481548110614a1157614a1161582d565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080614a4457614a446157fe565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050613bce565b6000915050613bce565b6000818152600183016020526040812054614ad057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155613bce565b506000613bce565b828054828255906000526020600020908101928215614b52579160200282015b82811115614b5257825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190614af8565b50614865929150614bf0565b828054828255906000526020600020908101928215614b52579160200282015b82811115614b525781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff843516178255602090920191600190910190614b7e565b5080546000825590600052602060002090810190613bbe91905b5b808211156148655760008155600101614bf1565b803573ffffffffffffffffffffffffffffffffffffffff81168114614c2957600080fd5b919050565b60008083601f840112614c4057600080fd5b50813567ffffffffffffffff811115614c5857600080fd5b6020830191508360208260051b8501011115614c7357600080fd5b9250929050565b60008083601f840112614c8c57600080fd5b50813567ffffffffffffffff811115614ca457600080fd5b602083019150836020828501011115614c7357600080fd5b600060808284031215614cce57600080fd5b6040516080810181811067ffffffffffffffff82111715614cf157614cf161585c565b604052905080614d0083614d49565b8152614d0e60208401614c05565b6020820152614d1f60408401614d35565b6040820152606083013560608201525092915050565b803563ffffffff81168114614c2957600080fd5b803567ffffffffffffffff81168114614c2957600080fd5b803560ff81168114614c2957600080fd5b805169ffffffffffffffffffff81168114614c2957600080fd5b600060208284031215614d9e57600080fd5b6146a282614c05565b600080600060608486031215614dbc57600080fd5b614dc584614c05565b9250614dd360208501614c05565b9150614de160408501614c05565b90509250925092565b60008060008060608587031215614e0057600080fd5b614e0985614c05565b935060208501359250604085013567ffffffffffffffff811115614e2c57600080fd5b614e3887828801614c7a565b95989497509550505050565b60008060408385031215614e5757600080fd5b614e6083614c05565b91506020830135614e708161588b565b809150509250929050565b60008060208385031215614e8e57600080fd5b823567ffffffffffffffff811115614ea557600080fd5b614eb185828601614c2e565b90969095509350505050565b600060208284031215614ecf57600080fd5b815180151581146146a257600080fd5b6000806000806000806000806000806104c08b8d031215614eff57600080fd5b8a35995060208b013567ffffffffffffffff80821115614f1e57600080fd5b614f2a8e838f01614c7a565b909b50995060408d0135915080821115614f4357600080fd5b614f4f8e838f01614c7a565b9099509750879150614f6360608e01614c05565b96508d609f8e0112614f7457600080fd5b60405191506103e082018281108282111715614f9257614f9261585c565b604052508060808d016104608e018f811115614fad57600080fd5b60005b601f811015614fd757614fc283614c05565b84526020938401939290920191600101614fb0565b50839750614fe481614d61565b9650505050506104808b013591506104a08b013590509295989b9194979a5092959850565b600080600083850360a081121561501f57600080fd5b843567ffffffffffffffff81111561503657600080fd5b61504287828801614c7a565b90955093505060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201121561507857600080fd5b506020840190509250925092565b600080600060a0848603121561509b57600080fd5b833567ffffffffffffffff8111156150b257600080fd5b6150be86828701614c7a565b9094509250614de190508560208601614cbc565b6000608082840312156150e457600080fd5b6146a28383614cbc565b60006020828403121561510057600080fd5b5051919050565b60006020828403121561511957600080fd5b6146a282614d35565b6000806000806080858703121561513857600080fd5b61514185614d35565b93506020850135925060408501356151588161588b565b915060608501356151688161588b565b939692955090935050565b60008060008060008060c0878903121561518c57600080fd5b61519587614d35565b95506151a360208801614d35565b945060408701359350606087013592506151bf60808801614d35565b91506151cd60a08801614d35565b90509295509295509295565b6000602082840312156151eb57600080fd5b6146a282614d49565b6000806040838503121561520757600080fd5b61521083614d49565b915061521e60208401614c05565b90509250929050565b600080600080600060a0868803121561523f57600080fd5b61524886614d72565b945060208601519350604086015192506060860151915061526b60808701614d72565b90509295509295909350565b60006020828403121561528957600080fd5b81516146a28161588b565b600081518084526020808501945080840160005b838110156152da57815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016152a8565b509495945050505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6040808252810183905260008460608301825b8681101561537c5773ffffffffffffffffffffffffffffffffffffffff61536784614c05565b16825260209283019290910190600101615341565b50809250505073ffffffffffffffffffffffffffffffffffffffff83166020830152949350505050565b6020815260006146a26020830184615294565b8581526060602082015260006153d36060830186886152e5565b82810360408401526153e68185876152e5565b98975050505050505050565b60a08152600061540660a0830185876152e5565b905067ffffffffffffffff61541a84614d49565b16602083015273ffffffffffffffffffffffffffffffffffffffff61544160208501614c05565b16604083015263ffffffff61545860408501614d35565b16606083015260608301356080830152949350505050565b60208101600383106154ab577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60006101208201905067ffffffffffffffff835116825273ffffffffffffffffffffffffffffffffffffffff602084015116602083015260408301516154ff604084018263ffffffff169052565b50606083015160608301526080830151615531608084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a083015161555160a08401826bffffffffffffffffffffffff169052565b5060c083015161557160c08401826bffffffffffffffffffffffff169052565b5060e083015161559160e08401826bffffffffffffffffffffffff169052565b5061010092830151919092015290565b63ffffffff831681526040602082015260006155c06040830184615294565b949350505050565b6bffffffffffffffffffffffff8416815273ffffffffffffffffffffffffffffffffffffffff8316602082015260606040820152600061560b6060830184615294565b95945050505050565b60008219821115615627576156276157a0565b500190565b600067ffffffffffffffff80831681851680830382111561564f5761564f6157a0565b01949350505050565b60006bffffffffffffffffffffffff80831681851680830382111561564f5761564f6157a0565b60008261568e5761568e6157cf565b500490565b60006bffffffffffffffffffffffff808416806156b2576156b26157cf565b92169190910492915050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156156f6576156f66157a0565b500290565b60008282101561570d5761570d6157a0565b500390565b60006bffffffffffffffffffffffff83811690831681811015615737576157376157a0565b039392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415615771576157716157a0565b5060010190565b600067ffffffffffffffff80831681811415615796576157966157a0565b6001019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6bffffffffffffffffffffffff81168114613bbe57600080fdfea164736f6c6343000806000a496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", -} - -var FunctionsRegistryABI = FunctionsRegistryMetaData.ABI - -var FunctionsRegistryBin = FunctionsRegistryMetaData.Bin - -func DeployFunctionsRegistry(auth *bind.TransactOpts, backend bind.ContractBackend, link common.Address, linkEthFeed common.Address, oracle common.Address) (common.Address, *types.Transaction, *FunctionsRegistry, error) { - parsed, err := FunctionsRegistryMetaData.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(FunctionsRegistryBin), backend, link, linkEthFeed, oracle) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &FunctionsRegistry{FunctionsRegistryCaller: FunctionsRegistryCaller{contract: contract}, FunctionsRegistryTransactor: FunctionsRegistryTransactor{contract: contract}, FunctionsRegistryFilterer: FunctionsRegistryFilterer{contract: contract}}, nil -} - -type FunctionsRegistry struct { - address common.Address - abi abi.ABI - FunctionsRegistryCaller - FunctionsRegistryTransactor - FunctionsRegistryFilterer -} - -type FunctionsRegistryCaller struct { - contract *bind.BoundContract -} - -type FunctionsRegistryTransactor struct { - contract *bind.BoundContract -} - -type FunctionsRegistryFilterer struct { - contract *bind.BoundContract -} - -type FunctionsRegistrySession struct { - Contract *FunctionsRegistry - CallOpts bind.CallOpts - TransactOpts bind.TransactOpts -} - -type FunctionsRegistryCallerSession struct { - Contract *FunctionsRegistryCaller - CallOpts bind.CallOpts -} - -type FunctionsRegistryTransactorSession struct { - Contract *FunctionsRegistryTransactor - TransactOpts bind.TransactOpts -} - -type FunctionsRegistryRaw struct { - Contract *FunctionsRegistry -} - -type FunctionsRegistryCallerRaw struct { - Contract *FunctionsRegistryCaller -} - -type FunctionsRegistryTransactorRaw struct { - Contract *FunctionsRegistryTransactor -} - -func NewFunctionsRegistry(address common.Address, backend bind.ContractBackend) (*FunctionsRegistry, error) { - abi, err := abi.JSON(strings.NewReader(FunctionsRegistryABI)) - if err != nil { - return nil, err - } - contract, err := bindFunctionsRegistry(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &FunctionsRegistry{address: address, abi: abi, FunctionsRegistryCaller: FunctionsRegistryCaller{contract: contract}, FunctionsRegistryTransactor: FunctionsRegistryTransactor{contract: contract}, FunctionsRegistryFilterer: FunctionsRegistryFilterer{contract: contract}}, nil -} - -func NewFunctionsRegistryCaller(address common.Address, caller bind.ContractCaller) (*FunctionsRegistryCaller, error) { - contract, err := bindFunctionsRegistry(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &FunctionsRegistryCaller{contract: contract}, nil -} - -func NewFunctionsRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*FunctionsRegistryTransactor, error) { - contract, err := bindFunctionsRegistry(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &FunctionsRegistryTransactor{contract: contract}, nil -} - -func NewFunctionsRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*FunctionsRegistryFilterer, error) { - contract, err := bindFunctionsRegistry(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &FunctionsRegistryFilterer{contract: contract}, nil -} - -func bindFunctionsRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := FunctionsRegistryMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -func (_FunctionsRegistry *FunctionsRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _FunctionsRegistry.Contract.FunctionsRegistryCaller.contract.Call(opts, result, method, params...) -} - -func (_FunctionsRegistry *FunctionsRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.FunctionsRegistryTransactor.contract.Transfer(opts) -} - -func (_FunctionsRegistry *FunctionsRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.FunctionsRegistryTransactor.contract.Transact(opts, method, params...) -} - -func (_FunctionsRegistry *FunctionsRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _FunctionsRegistry.Contract.contract.Call(opts, result, method, params...) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.contract.Transfer(opts) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.contract.Transact(opts, method, params...) -} - -func (_FunctionsRegistry *FunctionsRegistryCaller) MAXCONSUMERS(opts *bind.CallOpts) (uint16, error) { - var out []interface{} - err := _FunctionsRegistry.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 (_FunctionsRegistry *FunctionsRegistrySession) MAXCONSUMERS() (uint16, error) { - return _FunctionsRegistry.Contract.MAXCONSUMERS(&_FunctionsRegistry.CallOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryCallerSession) MAXCONSUMERS() (uint16, error) { - return _FunctionsRegistry.Contract.MAXCONSUMERS(&_FunctionsRegistry.CallOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryCaller) EstimateCost(opts *bind.CallOpts, gasLimit uint32, gasPrice *big.Int, donFee *big.Int, registryFee *big.Int) (*big.Int, error) { - var out []interface{} - err := _FunctionsRegistry.contract.Call(opts, &out, "estimateCost", gasLimit, gasPrice, donFee, registryFee) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_FunctionsRegistry *FunctionsRegistrySession) EstimateCost(gasLimit uint32, gasPrice *big.Int, donFee *big.Int, registryFee *big.Int) (*big.Int, error) { - return _FunctionsRegistry.Contract.EstimateCost(&_FunctionsRegistry.CallOpts, gasLimit, gasPrice, donFee, registryFee) -} - -func (_FunctionsRegistry *FunctionsRegistryCallerSession) EstimateCost(gasLimit uint32, gasPrice *big.Int, donFee *big.Int, registryFee *big.Int) (*big.Int, error) { - return _FunctionsRegistry.Contract.EstimateCost(&_FunctionsRegistry.CallOpts, gasLimit, gasPrice, donFee, registryFee) -} - -func (_FunctionsRegistry *FunctionsRegistryCaller) GetAuthorizedSenders(opts *bind.CallOpts) ([]common.Address, error) { - var out []interface{} - err := _FunctionsRegistry.contract.Call(opts, &out, "getAuthorizedSenders") - - if err != nil { - return *new([]common.Address), err - } - - out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) - - return out0, err - -} - -func (_FunctionsRegistry *FunctionsRegistrySession) GetAuthorizedSenders() ([]common.Address, error) { - return _FunctionsRegistry.Contract.GetAuthorizedSenders(&_FunctionsRegistry.CallOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryCallerSession) GetAuthorizedSenders() ([]common.Address, error) { - return _FunctionsRegistry.Contract.GetAuthorizedSenders(&_FunctionsRegistry.CallOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryCaller) GetConfig(opts *bind.CallOpts) (GetConfig, - - error) { - var out []interface{} - err := _FunctionsRegistry.contract.Call(opts, &out, "getConfig") - - outstruct := new(GetConfig) - if err != nil { - return *outstruct, err - } - - outstruct.MaxGasLimit = *abi.ConvertType(out[0], new(uint32)).(*uint32) - outstruct.StalenessSeconds = *abi.ConvertType(out[1], new(uint32)).(*uint32) - outstruct.GasAfterPaymentCalculation = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) - outstruct.FallbackWeiPerUnitLink = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) - outstruct.GasOverhead = *abi.ConvertType(out[4], new(uint32)).(*uint32) - outstruct.LinkAddress = *abi.ConvertType(out[5], new(common.Address)).(*common.Address) - outstruct.LinkPriceFeed = *abi.ConvertType(out[6], new(common.Address)).(*common.Address) - - return *outstruct, err - -} - -func (_FunctionsRegistry *FunctionsRegistrySession) GetConfig() (GetConfig, - - error) { - return _FunctionsRegistry.Contract.GetConfig(&_FunctionsRegistry.CallOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryCallerSession) GetConfig() (GetConfig, - - error) { - return _FunctionsRegistry.Contract.GetConfig(&_FunctionsRegistry.CallOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryCaller) GetCurrentsubscriptionId(opts *bind.CallOpts) (uint64, error) { - var out []interface{} - err := _FunctionsRegistry.contract.Call(opts, &out, "getCurrentsubscriptionId") - - if err != nil { - return *new(uint64), err - } - - out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) - - return out0, err - -} - -func (_FunctionsRegistry *FunctionsRegistrySession) GetCurrentsubscriptionId() (uint64, error) { - return _FunctionsRegistry.Contract.GetCurrentsubscriptionId(&_FunctionsRegistry.CallOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryCallerSession) GetCurrentsubscriptionId() (uint64, error) { - return _FunctionsRegistry.Contract.GetCurrentsubscriptionId(&_FunctionsRegistry.CallOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryCaller) GetRequestConfig(opts *bind.CallOpts) (uint32, []common.Address, error) { - var out []interface{} - err := _FunctionsRegistry.contract.Call(opts, &out, "getRequestConfig") - - if err != nil { - return *new(uint32), *new([]common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) - out1 := *abi.ConvertType(out[1], new([]common.Address)).(*[]common.Address) - - return out0, out1, err - -} - -func (_FunctionsRegistry *FunctionsRegistrySession) GetRequestConfig() (uint32, []common.Address, error) { - return _FunctionsRegistry.Contract.GetRequestConfig(&_FunctionsRegistry.CallOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryCallerSession) GetRequestConfig() (uint32, []common.Address, error) { - return _FunctionsRegistry.Contract.GetRequestConfig(&_FunctionsRegistry.CallOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryCaller) GetRequiredFee(opts *bind.CallOpts, arg0 []byte, arg1 IFunctionsBillingRegistryRequestBilling) (*big.Int, error) { - var out []interface{} - err := _FunctionsRegistry.contract.Call(opts, &out, "getRequiredFee", arg0, arg1) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_FunctionsRegistry *FunctionsRegistrySession) GetRequiredFee(arg0 []byte, arg1 IFunctionsBillingRegistryRequestBilling) (*big.Int, error) { - return _FunctionsRegistry.Contract.GetRequiredFee(&_FunctionsRegistry.CallOpts, arg0, arg1) -} - -func (_FunctionsRegistry *FunctionsRegistryCallerSession) GetRequiredFee(arg0 []byte, arg1 IFunctionsBillingRegistryRequestBilling) (*big.Int, error) { - return _FunctionsRegistry.Contract.GetRequiredFee(&_FunctionsRegistry.CallOpts, arg0, arg1) -} - -func (_FunctionsRegistry *FunctionsRegistryCaller) GetSubscription(opts *bind.CallOpts, subscriptionId uint64) (GetSubscription, - - error) { - var out []interface{} - err := _FunctionsRegistry.contract.Call(opts, &out, "getSubscription", subscriptionId) - - outstruct := new(GetSubscription) - if err != nil { - return *outstruct, err - } - - outstruct.Balance = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - outstruct.Owner = *abi.ConvertType(out[1], new(common.Address)).(*common.Address) - outstruct.Consumers = *abi.ConvertType(out[2], new([]common.Address)).(*[]common.Address) - - return *outstruct, err - -} - -func (_FunctionsRegistry *FunctionsRegistrySession) GetSubscription(subscriptionId uint64) (GetSubscription, - - error) { - return _FunctionsRegistry.Contract.GetSubscription(&_FunctionsRegistry.CallOpts, subscriptionId) -} - -func (_FunctionsRegistry *FunctionsRegistryCallerSession) GetSubscription(subscriptionId uint64) (GetSubscription, - - error) { - return _FunctionsRegistry.Contract.GetSubscription(&_FunctionsRegistry.CallOpts, subscriptionId) -} - -func (_FunctionsRegistry *FunctionsRegistryCaller) GetSubscriptionOwner(opts *bind.CallOpts, subscriptionId uint64) (common.Address, error) { - var out []interface{} - err := _FunctionsRegistry.contract.Call(opts, &out, "getSubscriptionOwner", subscriptionId) - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -func (_FunctionsRegistry *FunctionsRegistrySession) GetSubscriptionOwner(subscriptionId uint64) (common.Address, error) { - return _FunctionsRegistry.Contract.GetSubscriptionOwner(&_FunctionsRegistry.CallOpts, subscriptionId) -} - -func (_FunctionsRegistry *FunctionsRegistryCallerSession) GetSubscriptionOwner(subscriptionId uint64) (common.Address, error) { - return _FunctionsRegistry.Contract.GetSubscriptionOwner(&_FunctionsRegistry.CallOpts, subscriptionId) -} - -func (_FunctionsRegistry *FunctionsRegistryCaller) GetTotalBalance(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _FunctionsRegistry.contract.Call(opts, &out, "getTotalBalance") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_FunctionsRegistry *FunctionsRegistrySession) GetTotalBalance() (*big.Int, error) { - return _FunctionsRegistry.Contract.GetTotalBalance(&_FunctionsRegistry.CallOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryCallerSession) GetTotalBalance() (*big.Int, error) { - return _FunctionsRegistry.Contract.GetTotalBalance(&_FunctionsRegistry.CallOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryCaller) IsAuthorizedSender(opts *bind.CallOpts, sender common.Address) (bool, error) { - var out []interface{} - err := _FunctionsRegistry.contract.Call(opts, &out, "isAuthorizedSender", sender) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -func (_FunctionsRegistry *FunctionsRegistrySession) IsAuthorizedSender(sender common.Address) (bool, error) { - return _FunctionsRegistry.Contract.IsAuthorizedSender(&_FunctionsRegistry.CallOpts, sender) -} - -func (_FunctionsRegistry *FunctionsRegistryCallerSession) IsAuthorizedSender(sender common.Address) (bool, error) { - return _FunctionsRegistry.Contract.IsAuthorizedSender(&_FunctionsRegistry.CallOpts, sender) -} - -func (_FunctionsRegistry *FunctionsRegistryCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _FunctionsRegistry.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 (_FunctionsRegistry *FunctionsRegistrySession) Owner() (common.Address, error) { - return _FunctionsRegistry.Contract.Owner(&_FunctionsRegistry.CallOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryCallerSession) Owner() (common.Address, error) { - return _FunctionsRegistry.Contract.Owner(&_FunctionsRegistry.CallOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryCaller) Paused(opts *bind.CallOpts) (bool, error) { - var out []interface{} - err := _FunctionsRegistry.contract.Call(opts, &out, "paused") - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -func (_FunctionsRegistry *FunctionsRegistrySession) Paused() (bool, error) { - return _FunctionsRegistry.Contract.Paused(&_FunctionsRegistry.CallOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryCallerSession) Paused() (bool, error) { - return _FunctionsRegistry.Contract.Paused(&_FunctionsRegistry.CallOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryCaller) PendingRequestExists(opts *bind.CallOpts, subscriptionId uint64) (bool, error) { - var out []interface{} - err := _FunctionsRegistry.contract.Call(opts, &out, "pendingRequestExists", subscriptionId) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -func (_FunctionsRegistry *FunctionsRegistrySession) PendingRequestExists(subscriptionId uint64) (bool, error) { - return _FunctionsRegistry.Contract.PendingRequestExists(&_FunctionsRegistry.CallOpts, subscriptionId) -} - -func (_FunctionsRegistry *FunctionsRegistryCallerSession) PendingRequestExists(subscriptionId uint64) (bool, error) { - return _FunctionsRegistry.Contract.PendingRequestExists(&_FunctionsRegistry.CallOpts, subscriptionId) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsRegistry.contract.Transact(opts, "acceptOwnership") -} - -func (_FunctionsRegistry *FunctionsRegistrySession) AcceptOwnership() (*types.Transaction, error) { - return _FunctionsRegistry.Contract.AcceptOwnership(&_FunctionsRegistry.TransactOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorSession) AcceptOwnership() (*types.Transaction, error) { - return _FunctionsRegistry.Contract.AcceptOwnership(&_FunctionsRegistry.TransactOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactor) AcceptSubscriptionOwnerTransfer(opts *bind.TransactOpts, subscriptionId uint64) (*types.Transaction, error) { - return _FunctionsRegistry.contract.Transact(opts, "acceptSubscriptionOwnerTransfer", subscriptionId) -} - -func (_FunctionsRegistry *FunctionsRegistrySession) AcceptSubscriptionOwnerTransfer(subscriptionId uint64) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.AcceptSubscriptionOwnerTransfer(&_FunctionsRegistry.TransactOpts, subscriptionId) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorSession) AcceptSubscriptionOwnerTransfer(subscriptionId uint64) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.AcceptSubscriptionOwnerTransfer(&_FunctionsRegistry.TransactOpts, subscriptionId) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactor) AddConsumer(opts *bind.TransactOpts, subscriptionId uint64, consumer common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.contract.Transact(opts, "addConsumer", subscriptionId, consumer) -} - -func (_FunctionsRegistry *FunctionsRegistrySession) AddConsumer(subscriptionId uint64, consumer common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.AddConsumer(&_FunctionsRegistry.TransactOpts, subscriptionId, consumer) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorSession) AddConsumer(subscriptionId uint64, consumer common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.AddConsumer(&_FunctionsRegistry.TransactOpts, subscriptionId, consumer) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactor) CancelSubscription(opts *bind.TransactOpts, subscriptionId uint64, to common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.contract.Transact(opts, "cancelSubscription", subscriptionId, to) -} - -func (_FunctionsRegistry *FunctionsRegistrySession) CancelSubscription(subscriptionId uint64, to common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.CancelSubscription(&_FunctionsRegistry.TransactOpts, subscriptionId, to) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorSession) CancelSubscription(subscriptionId uint64, to common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.CancelSubscription(&_FunctionsRegistry.TransactOpts, subscriptionId, to) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactor) CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsRegistry.contract.Transact(opts, "createSubscription") -} - -func (_FunctionsRegistry *FunctionsRegistrySession) CreateSubscription() (*types.Transaction, error) { - return _FunctionsRegistry.Contract.CreateSubscription(&_FunctionsRegistry.TransactOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorSession) CreateSubscription() (*types.Transaction, error) { - return _FunctionsRegistry.Contract.CreateSubscription(&_FunctionsRegistry.TransactOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactor) FulfillAndBill(opts *bind.TransactOpts, requestId [32]byte, response []byte, err []byte, transmitter common.Address, signers [31]common.Address, signerCount uint8, reportValidationGas *big.Int, initialGas *big.Int) (*types.Transaction, error) { - return _FunctionsRegistry.contract.Transact(opts, "fulfillAndBill", requestId, response, err, transmitter, signers, signerCount, reportValidationGas, initialGas) -} - -func (_FunctionsRegistry *FunctionsRegistrySession) FulfillAndBill(requestId [32]byte, response []byte, err []byte, transmitter common.Address, signers [31]common.Address, signerCount uint8, reportValidationGas *big.Int, initialGas *big.Int) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.FulfillAndBill(&_FunctionsRegistry.TransactOpts, requestId, response, err, transmitter, signers, signerCount, reportValidationGas, initialGas) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorSession) FulfillAndBill(requestId [32]byte, response []byte, err []byte, transmitter common.Address, signers [31]common.Address, signerCount uint8, reportValidationGas *big.Int, initialGas *big.Int) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.FulfillAndBill(&_FunctionsRegistry.TransactOpts, requestId, response, err, transmitter, signers, signerCount, reportValidationGas, initialGas) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactor) Initialize(opts *bind.TransactOpts, link common.Address, linkEthFeed common.Address, oracle common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.contract.Transact(opts, "initialize", link, linkEthFeed, oracle) -} - -func (_FunctionsRegistry *FunctionsRegistrySession) Initialize(link common.Address, linkEthFeed common.Address, oracle common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.Initialize(&_FunctionsRegistry.TransactOpts, link, linkEthFeed, oracle) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorSession) Initialize(link common.Address, linkEthFeed common.Address, oracle common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.Initialize(&_FunctionsRegistry.TransactOpts, link, linkEthFeed, oracle) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactor) OnTokenTransfer(opts *bind.TransactOpts, arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { - return _FunctionsRegistry.contract.Transact(opts, "onTokenTransfer", arg0, amount, data) -} - -func (_FunctionsRegistry *FunctionsRegistrySession) OnTokenTransfer(arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.OnTokenTransfer(&_FunctionsRegistry.TransactOpts, arg0, amount, data) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorSession) OnTokenTransfer(arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.OnTokenTransfer(&_FunctionsRegistry.TransactOpts, arg0, amount, data) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactor) OracleWithdraw(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _FunctionsRegistry.contract.Transact(opts, "oracleWithdraw", recipient, amount) -} - -func (_FunctionsRegistry *FunctionsRegistrySession) OracleWithdraw(recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.OracleWithdraw(&_FunctionsRegistry.TransactOpts, recipient, amount) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorSession) OracleWithdraw(recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.OracleWithdraw(&_FunctionsRegistry.TransactOpts, recipient, amount) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactor) OwnerCancelSubscription(opts *bind.TransactOpts, subscriptionId uint64) (*types.Transaction, error) { - return _FunctionsRegistry.contract.Transact(opts, "ownerCancelSubscription", subscriptionId) -} - -func (_FunctionsRegistry *FunctionsRegistrySession) OwnerCancelSubscription(subscriptionId uint64) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.OwnerCancelSubscription(&_FunctionsRegistry.TransactOpts, subscriptionId) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorSession) OwnerCancelSubscription(subscriptionId uint64) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.OwnerCancelSubscription(&_FunctionsRegistry.TransactOpts, subscriptionId) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsRegistry.contract.Transact(opts, "pause") -} - -func (_FunctionsRegistry *FunctionsRegistrySession) Pause() (*types.Transaction, error) { - return _FunctionsRegistry.Contract.Pause(&_FunctionsRegistry.TransactOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorSession) Pause() (*types.Transaction, error) { - return _FunctionsRegistry.Contract.Pause(&_FunctionsRegistry.TransactOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactor) RecoverFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.contract.Transact(opts, "recoverFunds", to) -} - -func (_FunctionsRegistry *FunctionsRegistrySession) RecoverFunds(to common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.RecoverFunds(&_FunctionsRegistry.TransactOpts, to) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorSession) RecoverFunds(to common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.RecoverFunds(&_FunctionsRegistry.TransactOpts, to) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactor) RemoveConsumer(opts *bind.TransactOpts, subscriptionId uint64, consumer common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.contract.Transact(opts, "removeConsumer", subscriptionId, consumer) -} - -func (_FunctionsRegistry *FunctionsRegistrySession) RemoveConsumer(subscriptionId uint64, consumer common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.RemoveConsumer(&_FunctionsRegistry.TransactOpts, subscriptionId, consumer) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorSession) RemoveConsumer(subscriptionId uint64, consumer common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.RemoveConsumer(&_FunctionsRegistry.TransactOpts, subscriptionId, consumer) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactor) RequestSubscriptionOwnerTransfer(opts *bind.TransactOpts, subscriptionId uint64, newOwner common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.contract.Transact(opts, "requestSubscriptionOwnerTransfer", subscriptionId, newOwner) -} - -func (_FunctionsRegistry *FunctionsRegistrySession) RequestSubscriptionOwnerTransfer(subscriptionId uint64, newOwner common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.RequestSubscriptionOwnerTransfer(&_FunctionsRegistry.TransactOpts, subscriptionId, newOwner) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorSession) RequestSubscriptionOwnerTransfer(subscriptionId uint64, newOwner common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.RequestSubscriptionOwnerTransfer(&_FunctionsRegistry.TransactOpts, subscriptionId, newOwner) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactor) SetAuthorizedSenders(opts *bind.TransactOpts, senders []common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.contract.Transact(opts, "setAuthorizedSenders", senders) -} - -func (_FunctionsRegistry *FunctionsRegistrySession) SetAuthorizedSenders(senders []common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.SetAuthorizedSenders(&_FunctionsRegistry.TransactOpts, senders) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorSession) SetAuthorizedSenders(senders []common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.SetAuthorizedSenders(&_FunctionsRegistry.TransactOpts, senders) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactor) SetConfig(opts *bind.TransactOpts, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation *big.Int, fallbackWeiPerUnitLink *big.Int, gasOverhead uint32, requestTimeoutSeconds uint32) (*types.Transaction, error) { - return _FunctionsRegistry.contract.Transact(opts, "setConfig", maxGasLimit, stalenessSeconds, gasAfterPaymentCalculation, fallbackWeiPerUnitLink, gasOverhead, requestTimeoutSeconds) -} - -func (_FunctionsRegistry *FunctionsRegistrySession) SetConfig(maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation *big.Int, fallbackWeiPerUnitLink *big.Int, gasOverhead uint32, requestTimeoutSeconds uint32) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.SetConfig(&_FunctionsRegistry.TransactOpts, maxGasLimit, stalenessSeconds, gasAfterPaymentCalculation, fallbackWeiPerUnitLink, gasOverhead, requestTimeoutSeconds) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorSession) SetConfig(maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation *big.Int, fallbackWeiPerUnitLink *big.Int, gasOverhead uint32, requestTimeoutSeconds uint32) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.SetConfig(&_FunctionsRegistry.TransactOpts, maxGasLimit, stalenessSeconds, gasAfterPaymentCalculation, fallbackWeiPerUnitLink, gasOverhead, requestTimeoutSeconds) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactor) StartBilling(opts *bind.TransactOpts, data []byte, billing IFunctionsBillingRegistryRequestBilling) (*types.Transaction, error) { - return _FunctionsRegistry.contract.Transact(opts, "startBilling", data, billing) -} - -func (_FunctionsRegistry *FunctionsRegistrySession) StartBilling(data []byte, billing IFunctionsBillingRegistryRequestBilling) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.StartBilling(&_FunctionsRegistry.TransactOpts, data, billing) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorSession) StartBilling(data []byte, billing IFunctionsBillingRegistryRequestBilling) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.StartBilling(&_FunctionsRegistry.TransactOpts, data, billing) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactor) TimeoutRequests(opts *bind.TransactOpts, requestIdsToTimeout [][32]byte) (*types.Transaction, error) { - return _FunctionsRegistry.contract.Transact(opts, "timeoutRequests", requestIdsToTimeout) -} - -func (_FunctionsRegistry *FunctionsRegistrySession) TimeoutRequests(requestIdsToTimeout [][32]byte) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.TimeoutRequests(&_FunctionsRegistry.TransactOpts, requestIdsToTimeout) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorSession) TimeoutRequests(requestIdsToTimeout [][32]byte) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.TimeoutRequests(&_FunctionsRegistry.TransactOpts, requestIdsToTimeout) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.contract.Transact(opts, "transferOwnership", to) -} - -func (_FunctionsRegistry *FunctionsRegistrySession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.TransferOwnership(&_FunctionsRegistry.TransactOpts, to) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _FunctionsRegistry.Contract.TransferOwnership(&_FunctionsRegistry.TransactOpts, to) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsRegistry.contract.Transact(opts, "unpause") -} - -func (_FunctionsRegistry *FunctionsRegistrySession) Unpause() (*types.Transaction, error) { - return _FunctionsRegistry.Contract.Unpause(&_FunctionsRegistry.TransactOpts) -} - -func (_FunctionsRegistry *FunctionsRegistryTransactorSession) Unpause() (*types.Transaction, error) { - return _FunctionsRegistry.Contract.Unpause(&_FunctionsRegistry.TransactOpts) -} - -type FunctionsRegistryAuthorizedSendersChangedIterator struct { - Event *FunctionsRegistryAuthorizedSendersChanged - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRegistryAuthorizedSendersChangedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRegistryAuthorizedSendersChanged) - 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(FunctionsRegistryAuthorizedSendersChanged) - 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 *FunctionsRegistryAuthorizedSendersChangedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRegistryAuthorizedSendersChangedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRegistryAuthorizedSendersChanged struct { - Senders []common.Address - ChangedBy common.Address - Raw types.Log -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) FilterAuthorizedSendersChanged(opts *bind.FilterOpts) (*FunctionsRegistryAuthorizedSendersChangedIterator, error) { - - logs, sub, err := _FunctionsRegistry.contract.FilterLogs(opts, "AuthorizedSendersChanged") - if err != nil { - return nil, err - } - return &FunctionsRegistryAuthorizedSendersChangedIterator{contract: _FunctionsRegistry.contract, event: "AuthorizedSendersChanged", logs: logs, sub: sub}, nil -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) WatchAuthorizedSendersChanged(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryAuthorizedSendersChanged) (event.Subscription, error) { - - logs, sub, err := _FunctionsRegistry.contract.WatchLogs(opts, "AuthorizedSendersChanged") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRegistryAuthorizedSendersChanged) - if err := _FunctionsRegistry.contract.UnpackLog(event, "AuthorizedSendersChanged", 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 (_FunctionsRegistry *FunctionsRegistryFilterer) ParseAuthorizedSendersChanged(log types.Log) (*FunctionsRegistryAuthorizedSendersChanged, error) { - event := new(FunctionsRegistryAuthorizedSendersChanged) - if err := _FunctionsRegistry.contract.UnpackLog(event, "AuthorizedSendersChanged", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRegistryBillingEndIterator struct { - Event *FunctionsRegistryBillingEnd - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRegistryBillingEndIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRegistryBillingEnd) - 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(FunctionsRegistryBillingEnd) - 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 *FunctionsRegistryBillingEndIterator) Error() error { - return it.fail -} - -func (it *FunctionsRegistryBillingEndIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRegistryBillingEnd struct { - RequestId [32]byte - SubscriptionId uint64 - SignerPayment *big.Int - TransmitterPayment *big.Int - TotalCost *big.Int - Success bool - Raw types.Log -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) FilterBillingEnd(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsRegistryBillingEndIterator, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsRegistry.contract.FilterLogs(opts, "BillingEnd", requestIdRule) - if err != nil { - return nil, err - } - return &FunctionsRegistryBillingEndIterator{contract: _FunctionsRegistry.contract, event: "BillingEnd", logs: logs, sub: sub}, nil -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) WatchBillingEnd(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryBillingEnd, requestId [][32]byte) (event.Subscription, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsRegistry.contract.WatchLogs(opts, "BillingEnd", 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(FunctionsRegistryBillingEnd) - if err := _FunctionsRegistry.contract.UnpackLog(event, "BillingEnd", 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 (_FunctionsRegistry *FunctionsRegistryFilterer) ParseBillingEnd(log types.Log) (*FunctionsRegistryBillingEnd, error) { - event := new(FunctionsRegistryBillingEnd) - if err := _FunctionsRegistry.contract.UnpackLog(event, "BillingEnd", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRegistryBillingStartIterator struct { - Event *FunctionsRegistryBillingStart - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRegistryBillingStartIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRegistryBillingStart) - 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(FunctionsRegistryBillingStart) - 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 *FunctionsRegistryBillingStartIterator) Error() error { - return it.fail -} - -func (it *FunctionsRegistryBillingStartIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRegistryBillingStart struct { - RequestId [32]byte - Commitment FunctionsBillingRegistryCommitment - Raw types.Log -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) FilterBillingStart(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsRegistryBillingStartIterator, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsRegistry.contract.FilterLogs(opts, "BillingStart", requestIdRule) - if err != nil { - return nil, err - } - return &FunctionsRegistryBillingStartIterator{contract: _FunctionsRegistry.contract, event: "BillingStart", logs: logs, sub: sub}, nil -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) WatchBillingStart(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryBillingStart, requestId [][32]byte) (event.Subscription, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsRegistry.contract.WatchLogs(opts, "BillingStart", 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(FunctionsRegistryBillingStart) - if err := _FunctionsRegistry.contract.UnpackLog(event, "BillingStart", 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 (_FunctionsRegistry *FunctionsRegistryFilterer) ParseBillingStart(log types.Log) (*FunctionsRegistryBillingStart, error) { - event := new(FunctionsRegistryBillingStart) - if err := _FunctionsRegistry.contract.UnpackLog(event, "BillingStart", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRegistryConfigSetIterator struct { - Event *FunctionsRegistryConfigSet - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRegistryConfigSetIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRegistryConfigSet) - 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(FunctionsRegistryConfigSet) - 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 *FunctionsRegistryConfigSetIterator) Error() error { - return it.fail -} - -func (it *FunctionsRegistryConfigSetIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRegistryConfigSet struct { - MaxGasLimit uint32 - StalenessSeconds uint32 - GasAfterPaymentCalculation *big.Int - FallbackWeiPerUnitLink *big.Int - GasOverhead uint32 - Raw types.Log -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) FilterConfigSet(opts *bind.FilterOpts) (*FunctionsRegistryConfigSetIterator, error) { - - logs, sub, err := _FunctionsRegistry.contract.FilterLogs(opts, "ConfigSet") - if err != nil { - return nil, err - } - return &FunctionsRegistryConfigSetIterator{contract: _FunctionsRegistry.contract, event: "ConfigSet", logs: logs, sub: sub}, nil -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryConfigSet) (event.Subscription, error) { - - logs, sub, err := _FunctionsRegistry.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(FunctionsRegistryConfigSet) - if err := _FunctionsRegistry.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 (_FunctionsRegistry *FunctionsRegistryFilterer) ParseConfigSet(log types.Log) (*FunctionsRegistryConfigSet, error) { - event := new(FunctionsRegistryConfigSet) - if err := _FunctionsRegistry.contract.UnpackLog(event, "ConfigSet", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRegistryFundsRecoveredIterator struct { - Event *FunctionsRegistryFundsRecovered - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRegistryFundsRecoveredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRegistryFundsRecovered) - 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(FunctionsRegistryFundsRecovered) - 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 *FunctionsRegistryFundsRecoveredIterator) Error() error { - return it.fail -} - -func (it *FunctionsRegistryFundsRecoveredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRegistryFundsRecovered struct { - To common.Address - Amount *big.Int - Raw types.Log -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) FilterFundsRecovered(opts *bind.FilterOpts) (*FunctionsRegistryFundsRecoveredIterator, error) { - - logs, sub, err := _FunctionsRegistry.contract.FilterLogs(opts, "FundsRecovered") - if err != nil { - return nil, err - } - return &FunctionsRegistryFundsRecoveredIterator{contract: _FunctionsRegistry.contract, event: "FundsRecovered", logs: logs, sub: sub}, nil -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryFundsRecovered) (event.Subscription, error) { - - logs, sub, err := _FunctionsRegistry.contract.WatchLogs(opts, "FundsRecovered") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRegistryFundsRecovered) - if err := _FunctionsRegistry.contract.UnpackLog(event, "FundsRecovered", 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 (_FunctionsRegistry *FunctionsRegistryFilterer) ParseFundsRecovered(log types.Log) (*FunctionsRegistryFundsRecovered, error) { - event := new(FunctionsRegistryFundsRecovered) - if err := _FunctionsRegistry.contract.UnpackLog(event, "FundsRecovered", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRegistryInitializedIterator struct { - Event *FunctionsRegistryInitialized - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRegistryInitializedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRegistryInitialized) - 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(FunctionsRegistryInitialized) - 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 *FunctionsRegistryInitializedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRegistryInitializedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRegistryInitialized struct { - Version uint8 - Raw types.Log -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) FilterInitialized(opts *bind.FilterOpts) (*FunctionsRegistryInitializedIterator, error) { - - logs, sub, err := _FunctionsRegistry.contract.FilterLogs(opts, "Initialized") - if err != nil { - return nil, err - } - return &FunctionsRegistryInitializedIterator{contract: _FunctionsRegistry.contract, event: "Initialized", logs: logs, sub: sub}, nil -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryInitialized) (event.Subscription, error) { - - logs, sub, err := _FunctionsRegistry.contract.WatchLogs(opts, "Initialized") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRegistryInitialized) - if err := _FunctionsRegistry.contract.UnpackLog(event, "Initialized", 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 (_FunctionsRegistry *FunctionsRegistryFilterer) ParseInitialized(log types.Log) (*FunctionsRegistryInitialized, error) { - event := new(FunctionsRegistryInitialized) - if err := _FunctionsRegistry.contract.UnpackLog(event, "Initialized", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRegistryOwnershipTransferRequestedIterator struct { - Event *FunctionsRegistryOwnershipTransferRequested - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRegistryOwnershipTransferRequestedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRegistryOwnershipTransferRequested) - 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(FunctionsRegistryOwnershipTransferRequested) - 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 *FunctionsRegistryOwnershipTransferRequestedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRegistryOwnershipTransferRequestedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRegistryOwnershipTransferRequested struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsRegistryOwnershipTransferRequestedIterator, 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 := _FunctionsRegistry.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) - if err != nil { - return nil, err - } - return &FunctionsRegistryOwnershipTransferRequestedIterator{contract: _FunctionsRegistry.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryOwnershipTransferRequested, 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 := _FunctionsRegistry.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(FunctionsRegistryOwnershipTransferRequested) - if err := _FunctionsRegistry.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 (_FunctionsRegistry *FunctionsRegistryFilterer) ParseOwnershipTransferRequested(log types.Log) (*FunctionsRegistryOwnershipTransferRequested, error) { - event := new(FunctionsRegistryOwnershipTransferRequested) - if err := _FunctionsRegistry.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRegistryOwnershipTransferredIterator struct { - Event *FunctionsRegistryOwnershipTransferred - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRegistryOwnershipTransferredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRegistryOwnershipTransferred) - 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(FunctionsRegistryOwnershipTransferred) - 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 *FunctionsRegistryOwnershipTransferredIterator) Error() error { - return it.fail -} - -func (it *FunctionsRegistryOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRegistryOwnershipTransferred struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsRegistryOwnershipTransferredIterator, 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 := _FunctionsRegistry.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) - if err != nil { - return nil, err - } - return &FunctionsRegistryOwnershipTransferredIterator{contract: _FunctionsRegistry.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryOwnershipTransferred, 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 := _FunctionsRegistry.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(FunctionsRegistryOwnershipTransferred) - if err := _FunctionsRegistry.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 (_FunctionsRegistry *FunctionsRegistryFilterer) ParseOwnershipTransferred(log types.Log) (*FunctionsRegistryOwnershipTransferred, error) { - event := new(FunctionsRegistryOwnershipTransferred) - if err := _FunctionsRegistry.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRegistryPausedIterator struct { - Event *FunctionsRegistryPaused - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRegistryPausedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRegistryPaused) - 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(FunctionsRegistryPaused) - 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 *FunctionsRegistryPausedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRegistryPausedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRegistryPaused struct { - Account common.Address - Raw types.Log -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) FilterPaused(opts *bind.FilterOpts) (*FunctionsRegistryPausedIterator, error) { - - logs, sub, err := _FunctionsRegistry.contract.FilterLogs(opts, "Paused") - if err != nil { - return nil, err - } - return &FunctionsRegistryPausedIterator{contract: _FunctionsRegistry.contract, event: "Paused", logs: logs, sub: sub}, nil -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryPaused) (event.Subscription, error) { - - logs, sub, err := _FunctionsRegistry.contract.WatchLogs(opts, "Paused") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRegistryPaused) - if err := _FunctionsRegistry.contract.UnpackLog(event, "Paused", 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 (_FunctionsRegistry *FunctionsRegistryFilterer) ParsePaused(log types.Log) (*FunctionsRegistryPaused, error) { - event := new(FunctionsRegistryPaused) - if err := _FunctionsRegistry.contract.UnpackLog(event, "Paused", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRegistryRequestTimedOutIterator struct { - Event *FunctionsRegistryRequestTimedOut - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRegistryRequestTimedOutIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRegistryRequestTimedOut) - 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(FunctionsRegistryRequestTimedOut) - 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 *FunctionsRegistryRequestTimedOutIterator) Error() error { - return it.fail -} - -func (it *FunctionsRegistryRequestTimedOutIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRegistryRequestTimedOut struct { - RequestId [32]byte - Raw types.Log -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) FilterRequestTimedOut(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsRegistryRequestTimedOutIterator, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsRegistry.contract.FilterLogs(opts, "RequestTimedOut", requestIdRule) - if err != nil { - return nil, err - } - return &FunctionsRegistryRequestTimedOutIterator{contract: _FunctionsRegistry.contract, event: "RequestTimedOut", logs: logs, sub: sub}, nil -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) WatchRequestTimedOut(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryRequestTimedOut, requestId [][32]byte) (event.Subscription, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - logs, sub, err := _FunctionsRegistry.contract.WatchLogs(opts, "RequestTimedOut", 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(FunctionsRegistryRequestTimedOut) - if err := _FunctionsRegistry.contract.UnpackLog(event, "RequestTimedOut", 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 (_FunctionsRegistry *FunctionsRegistryFilterer) ParseRequestTimedOut(log types.Log) (*FunctionsRegistryRequestTimedOut, error) { - event := new(FunctionsRegistryRequestTimedOut) - if err := _FunctionsRegistry.contract.UnpackLog(event, "RequestTimedOut", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRegistrySubscriptionCanceledIterator struct { - Event *FunctionsRegistrySubscriptionCanceled - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRegistrySubscriptionCanceledIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRegistrySubscriptionCanceled) - 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(FunctionsRegistrySubscriptionCanceled) - 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 *FunctionsRegistrySubscriptionCanceledIterator) Error() error { - return it.fail -} - -func (it *FunctionsRegistrySubscriptionCanceledIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRegistrySubscriptionCanceled struct { - SubscriptionId uint64 - To common.Address - Amount *big.Int - Raw types.Log -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) FilterSubscriptionCanceled(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRegistrySubscriptionCanceledIterator, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRegistry.contract.FilterLogs(opts, "SubscriptionCanceled", subscriptionIdRule) - if err != nil { - return nil, err - } - return &FunctionsRegistrySubscriptionCanceledIterator{contract: _FunctionsRegistry.contract, event: "SubscriptionCanceled", logs: logs, sub: sub}, nil -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) WatchSubscriptionCanceled(opts *bind.WatchOpts, sink chan<- *FunctionsRegistrySubscriptionCanceled, subscriptionId []uint64) (event.Subscription, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRegistry.contract.WatchLogs(opts, "SubscriptionCanceled", subscriptionIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRegistrySubscriptionCanceled) - if err := _FunctionsRegistry.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 (_FunctionsRegistry *FunctionsRegistryFilterer) ParseSubscriptionCanceled(log types.Log) (*FunctionsRegistrySubscriptionCanceled, error) { - event := new(FunctionsRegistrySubscriptionCanceled) - if err := _FunctionsRegistry.contract.UnpackLog(event, "SubscriptionCanceled", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRegistrySubscriptionConsumerAddedIterator struct { - Event *FunctionsRegistrySubscriptionConsumerAdded - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRegistrySubscriptionConsumerAddedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRegistrySubscriptionConsumerAdded) - 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(FunctionsRegistrySubscriptionConsumerAdded) - 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 *FunctionsRegistrySubscriptionConsumerAddedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRegistrySubscriptionConsumerAddedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRegistrySubscriptionConsumerAdded struct { - SubscriptionId uint64 - Consumer common.Address - Raw types.Log -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) FilterSubscriptionConsumerAdded(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRegistrySubscriptionConsumerAddedIterator, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRegistry.contract.FilterLogs(opts, "SubscriptionConsumerAdded", subscriptionIdRule) - if err != nil { - return nil, err - } - return &FunctionsRegistrySubscriptionConsumerAddedIterator{contract: _FunctionsRegistry.contract, event: "SubscriptionConsumerAdded", logs: logs, sub: sub}, nil -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) WatchSubscriptionConsumerAdded(opts *bind.WatchOpts, sink chan<- *FunctionsRegistrySubscriptionConsumerAdded, subscriptionId []uint64) (event.Subscription, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRegistry.contract.WatchLogs(opts, "SubscriptionConsumerAdded", subscriptionIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRegistrySubscriptionConsumerAdded) - if err := _FunctionsRegistry.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 (_FunctionsRegistry *FunctionsRegistryFilterer) ParseSubscriptionConsumerAdded(log types.Log) (*FunctionsRegistrySubscriptionConsumerAdded, error) { - event := new(FunctionsRegistrySubscriptionConsumerAdded) - if err := _FunctionsRegistry.contract.UnpackLog(event, "SubscriptionConsumerAdded", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRegistrySubscriptionConsumerRemovedIterator struct { - Event *FunctionsRegistrySubscriptionConsumerRemoved - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRegistrySubscriptionConsumerRemovedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRegistrySubscriptionConsumerRemoved) - 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(FunctionsRegistrySubscriptionConsumerRemoved) - 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 *FunctionsRegistrySubscriptionConsumerRemovedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRegistrySubscriptionConsumerRemovedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRegistrySubscriptionConsumerRemoved struct { - SubscriptionId uint64 - Consumer common.Address - Raw types.Log -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) FilterSubscriptionConsumerRemoved(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRegistrySubscriptionConsumerRemovedIterator, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRegistry.contract.FilterLogs(opts, "SubscriptionConsumerRemoved", subscriptionIdRule) - if err != nil { - return nil, err - } - return &FunctionsRegistrySubscriptionConsumerRemovedIterator{contract: _FunctionsRegistry.contract, event: "SubscriptionConsumerRemoved", logs: logs, sub: sub}, nil -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) WatchSubscriptionConsumerRemoved(opts *bind.WatchOpts, sink chan<- *FunctionsRegistrySubscriptionConsumerRemoved, subscriptionId []uint64) (event.Subscription, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRegistry.contract.WatchLogs(opts, "SubscriptionConsumerRemoved", subscriptionIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRegistrySubscriptionConsumerRemoved) - if err := _FunctionsRegistry.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 (_FunctionsRegistry *FunctionsRegistryFilterer) ParseSubscriptionConsumerRemoved(log types.Log) (*FunctionsRegistrySubscriptionConsumerRemoved, error) { - event := new(FunctionsRegistrySubscriptionConsumerRemoved) - if err := _FunctionsRegistry.contract.UnpackLog(event, "SubscriptionConsumerRemoved", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRegistrySubscriptionCreatedIterator struct { - Event *FunctionsRegistrySubscriptionCreated - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRegistrySubscriptionCreatedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRegistrySubscriptionCreated) - 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(FunctionsRegistrySubscriptionCreated) - 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 *FunctionsRegistrySubscriptionCreatedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRegistrySubscriptionCreatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRegistrySubscriptionCreated struct { - SubscriptionId uint64 - Owner common.Address - Raw types.Log -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) FilterSubscriptionCreated(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRegistrySubscriptionCreatedIterator, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRegistry.contract.FilterLogs(opts, "SubscriptionCreated", subscriptionIdRule) - if err != nil { - return nil, err - } - return &FunctionsRegistrySubscriptionCreatedIterator{contract: _FunctionsRegistry.contract, event: "SubscriptionCreated", logs: logs, sub: sub}, nil -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) WatchSubscriptionCreated(opts *bind.WatchOpts, sink chan<- *FunctionsRegistrySubscriptionCreated, subscriptionId []uint64) (event.Subscription, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRegistry.contract.WatchLogs(opts, "SubscriptionCreated", subscriptionIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRegistrySubscriptionCreated) - if err := _FunctionsRegistry.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 (_FunctionsRegistry *FunctionsRegistryFilterer) ParseSubscriptionCreated(log types.Log) (*FunctionsRegistrySubscriptionCreated, error) { - event := new(FunctionsRegistrySubscriptionCreated) - if err := _FunctionsRegistry.contract.UnpackLog(event, "SubscriptionCreated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRegistrySubscriptionFundedIterator struct { - Event *FunctionsRegistrySubscriptionFunded - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRegistrySubscriptionFundedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRegistrySubscriptionFunded) - 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(FunctionsRegistrySubscriptionFunded) - 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 *FunctionsRegistrySubscriptionFundedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRegistrySubscriptionFundedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRegistrySubscriptionFunded struct { - SubscriptionId uint64 - OldBalance *big.Int - NewBalance *big.Int - Raw types.Log -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) FilterSubscriptionFunded(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRegistrySubscriptionFundedIterator, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRegistry.contract.FilterLogs(opts, "SubscriptionFunded", subscriptionIdRule) - if err != nil { - return nil, err - } - return &FunctionsRegistrySubscriptionFundedIterator{contract: _FunctionsRegistry.contract, event: "SubscriptionFunded", logs: logs, sub: sub}, nil -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) WatchSubscriptionFunded(opts *bind.WatchOpts, sink chan<- *FunctionsRegistrySubscriptionFunded, subscriptionId []uint64) (event.Subscription, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRegistry.contract.WatchLogs(opts, "SubscriptionFunded", subscriptionIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRegistrySubscriptionFunded) - if err := _FunctionsRegistry.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 (_FunctionsRegistry *FunctionsRegistryFilterer) ParseSubscriptionFunded(log types.Log) (*FunctionsRegistrySubscriptionFunded, error) { - event := new(FunctionsRegistrySubscriptionFunded) - if err := _FunctionsRegistry.contract.UnpackLog(event, "SubscriptionFunded", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRegistrySubscriptionOwnerTransferRequestedIterator struct { - Event *FunctionsRegistrySubscriptionOwnerTransferRequested - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRegistrySubscriptionOwnerTransferRequestedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRegistrySubscriptionOwnerTransferRequested) - 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(FunctionsRegistrySubscriptionOwnerTransferRequested) - 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 *FunctionsRegistrySubscriptionOwnerTransferRequestedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRegistrySubscriptionOwnerTransferRequestedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRegistrySubscriptionOwnerTransferRequested struct { - SubscriptionId uint64 - From common.Address - To common.Address - Raw types.Log -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) FilterSubscriptionOwnerTransferRequested(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRegistrySubscriptionOwnerTransferRequestedIterator, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRegistry.contract.FilterLogs(opts, "SubscriptionOwnerTransferRequested", subscriptionIdRule) - if err != nil { - return nil, err - } - return &FunctionsRegistrySubscriptionOwnerTransferRequestedIterator{contract: _FunctionsRegistry.contract, event: "SubscriptionOwnerTransferRequested", logs: logs, sub: sub}, nil -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) WatchSubscriptionOwnerTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsRegistrySubscriptionOwnerTransferRequested, subscriptionId []uint64) (event.Subscription, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRegistry.contract.WatchLogs(opts, "SubscriptionOwnerTransferRequested", subscriptionIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRegistrySubscriptionOwnerTransferRequested) - if err := _FunctionsRegistry.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 (_FunctionsRegistry *FunctionsRegistryFilterer) ParseSubscriptionOwnerTransferRequested(log types.Log) (*FunctionsRegistrySubscriptionOwnerTransferRequested, error) { - event := new(FunctionsRegistrySubscriptionOwnerTransferRequested) - if err := _FunctionsRegistry.contract.UnpackLog(event, "SubscriptionOwnerTransferRequested", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRegistrySubscriptionOwnerTransferredIterator struct { - Event *FunctionsRegistrySubscriptionOwnerTransferred - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRegistrySubscriptionOwnerTransferredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRegistrySubscriptionOwnerTransferred) - 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(FunctionsRegistrySubscriptionOwnerTransferred) - 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 *FunctionsRegistrySubscriptionOwnerTransferredIterator) Error() error { - return it.fail -} - -func (it *FunctionsRegistrySubscriptionOwnerTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRegistrySubscriptionOwnerTransferred struct { - SubscriptionId uint64 - From common.Address - To common.Address - Raw types.Log -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) FilterSubscriptionOwnerTransferred(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRegistrySubscriptionOwnerTransferredIterator, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRegistry.contract.FilterLogs(opts, "SubscriptionOwnerTransferred", subscriptionIdRule) - if err != nil { - return nil, err - } - return &FunctionsRegistrySubscriptionOwnerTransferredIterator{contract: _FunctionsRegistry.contract, event: "SubscriptionOwnerTransferred", logs: logs, sub: sub}, nil -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) WatchSubscriptionOwnerTransferred(opts *bind.WatchOpts, sink chan<- *FunctionsRegistrySubscriptionOwnerTransferred, subscriptionId []uint64) (event.Subscription, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRegistry.contract.WatchLogs(opts, "SubscriptionOwnerTransferred", subscriptionIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRegistrySubscriptionOwnerTransferred) - if err := _FunctionsRegistry.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 (_FunctionsRegistry *FunctionsRegistryFilterer) ParseSubscriptionOwnerTransferred(log types.Log) (*FunctionsRegistrySubscriptionOwnerTransferred, error) { - event := new(FunctionsRegistrySubscriptionOwnerTransferred) - if err := _FunctionsRegistry.contract.UnpackLog(event, "SubscriptionOwnerTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRegistryUnpausedIterator struct { - Event *FunctionsRegistryUnpaused - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRegistryUnpausedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRegistryUnpaused) - 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(FunctionsRegistryUnpaused) - 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 *FunctionsRegistryUnpausedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRegistryUnpausedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRegistryUnpaused struct { - Account common.Address - Raw types.Log -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) FilterUnpaused(opts *bind.FilterOpts) (*FunctionsRegistryUnpausedIterator, error) { - - logs, sub, err := _FunctionsRegistry.contract.FilterLogs(opts, "Unpaused") - if err != nil { - return nil, err - } - return &FunctionsRegistryUnpausedIterator{contract: _FunctionsRegistry.contract, event: "Unpaused", logs: logs, sub: sub}, nil -} - -func (_FunctionsRegistry *FunctionsRegistryFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryUnpaused) (event.Subscription, error) { - - logs, sub, err := _FunctionsRegistry.contract.WatchLogs(opts, "Unpaused") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRegistryUnpaused) - if err := _FunctionsRegistry.contract.UnpackLog(event, "Unpaused", 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 (_FunctionsRegistry *FunctionsRegistryFilterer) ParseUnpaused(log types.Log) (*FunctionsRegistryUnpaused, error) { - event := new(FunctionsRegistryUnpaused) - if err := _FunctionsRegistry.contract.UnpackLog(event, "Unpaused", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type GetConfig struct { - MaxGasLimit uint32 - StalenessSeconds uint32 - GasAfterPaymentCalculation *big.Int - FallbackWeiPerUnitLink *big.Int - GasOverhead uint32 - LinkAddress common.Address - LinkPriceFeed common.Address -} -type GetSubscription struct { - Balance *big.Int - Owner common.Address - Consumers []common.Address -} - -func (_FunctionsRegistry *FunctionsRegistry) ParseLog(log types.Log) (generated.AbigenLog, error) { - switch log.Topics[0] { - case _FunctionsRegistry.abi.Events["AuthorizedSendersChanged"].ID: - return _FunctionsRegistry.ParseAuthorizedSendersChanged(log) - case _FunctionsRegistry.abi.Events["BillingEnd"].ID: - return _FunctionsRegistry.ParseBillingEnd(log) - case _FunctionsRegistry.abi.Events["BillingStart"].ID: - return _FunctionsRegistry.ParseBillingStart(log) - case _FunctionsRegistry.abi.Events["ConfigSet"].ID: - return _FunctionsRegistry.ParseConfigSet(log) - case _FunctionsRegistry.abi.Events["FundsRecovered"].ID: - return _FunctionsRegistry.ParseFundsRecovered(log) - case _FunctionsRegistry.abi.Events["Initialized"].ID: - return _FunctionsRegistry.ParseInitialized(log) - case _FunctionsRegistry.abi.Events["OwnershipTransferRequested"].ID: - return _FunctionsRegistry.ParseOwnershipTransferRequested(log) - case _FunctionsRegistry.abi.Events["OwnershipTransferred"].ID: - return _FunctionsRegistry.ParseOwnershipTransferred(log) - case _FunctionsRegistry.abi.Events["Paused"].ID: - return _FunctionsRegistry.ParsePaused(log) - case _FunctionsRegistry.abi.Events["RequestTimedOut"].ID: - return _FunctionsRegistry.ParseRequestTimedOut(log) - case _FunctionsRegistry.abi.Events["SubscriptionCanceled"].ID: - return _FunctionsRegistry.ParseSubscriptionCanceled(log) - case _FunctionsRegistry.abi.Events["SubscriptionConsumerAdded"].ID: - return _FunctionsRegistry.ParseSubscriptionConsumerAdded(log) - case _FunctionsRegistry.abi.Events["SubscriptionConsumerRemoved"].ID: - return _FunctionsRegistry.ParseSubscriptionConsumerRemoved(log) - case _FunctionsRegistry.abi.Events["SubscriptionCreated"].ID: - return _FunctionsRegistry.ParseSubscriptionCreated(log) - case _FunctionsRegistry.abi.Events["SubscriptionFunded"].ID: - return _FunctionsRegistry.ParseSubscriptionFunded(log) - case _FunctionsRegistry.abi.Events["SubscriptionOwnerTransferRequested"].ID: - return _FunctionsRegistry.ParseSubscriptionOwnerTransferRequested(log) - case _FunctionsRegistry.abi.Events["SubscriptionOwnerTransferred"].ID: - return _FunctionsRegistry.ParseSubscriptionOwnerTransferred(log) - case _FunctionsRegistry.abi.Events["Unpaused"].ID: - return _FunctionsRegistry.ParseUnpaused(log) - - default: - return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) - } -} - -func (FunctionsRegistryAuthorizedSendersChanged) Topic() common.Hash { - return common.HexToHash("0xf263cfb3e4298332e776194610cf9fdc09ccb3ada8b9aa39764d882e11fbf0a0") -} - -func (FunctionsRegistryBillingEnd) Topic() common.Hash { - return common.HexToHash("0xc8dc973332de19a5f71b6026983110e9c2e04b0c98b87eb771ccb78607fd114f") -} - -func (FunctionsRegistryBillingStart) Topic() common.Hash { - return common.HexToHash("0x99f7f4e65b4b9fbabd4e357c47ed3099b36e57ecd3a43e84662f34c207d0ebe4") -} - -func (FunctionsRegistryConfigSet) Topic() common.Hash { - return common.HexToHash("0x24d3d934adfef9b9029d6ffa463c07d0139ed47d26ee23506f85ece2879d2bd4") -} - -func (FunctionsRegistryFundsRecovered) Topic() common.Hash { - return common.HexToHash("0x59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600") -} - -func (FunctionsRegistryInitialized) Topic() common.Hash { - return common.HexToHash("0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498") -} - -func (FunctionsRegistryOwnershipTransferRequested) Topic() common.Hash { - return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") -} - -func (FunctionsRegistryOwnershipTransferred) Topic() common.Hash { - return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") -} - -func (FunctionsRegistryPaused) Topic() common.Hash { - return common.HexToHash("0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258") -} - -func (FunctionsRegistryRequestTimedOut) Topic() common.Hash { - return common.HexToHash("0xf1ca1e9147be737b04a2b018a79405f687a97de8dd8a2559bbe62357343af414") -} - -func (FunctionsRegistrySubscriptionCanceled) Topic() common.Hash { - return common.HexToHash("0xe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd49815") -} - -func (FunctionsRegistrySubscriptionConsumerAdded) Topic() common.Hash { - return common.HexToHash("0x43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e0") -} - -func (FunctionsRegistrySubscriptionConsumerRemoved) Topic() common.Hash { - return common.HexToHash("0x182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b") -} - -func (FunctionsRegistrySubscriptionCreated) Topic() common.Hash { - return common.HexToHash("0x464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf") -} - -func (FunctionsRegistrySubscriptionFunded) Topic() common.Hash { - return common.HexToHash("0xd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f8") -} - -func (FunctionsRegistrySubscriptionOwnerTransferRequested) Topic() common.Hash { - return common.HexToHash("0x69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be") -} - -func (FunctionsRegistrySubscriptionOwnerTransferred) Topic() common.Hash { - return common.HexToHash("0x6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f0") -} - -func (FunctionsRegistryUnpaused) Topic() common.Hash { - return common.HexToHash("0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa") -} - -func (_FunctionsRegistry *FunctionsRegistry) Address() common.Address { - return _FunctionsRegistry.address -} - -type FunctionsRegistryInterface interface { - MAXCONSUMERS(opts *bind.CallOpts) (uint16, error) - - EstimateCost(opts *bind.CallOpts, gasLimit uint32, gasPrice *big.Int, donFee *big.Int, registryFee *big.Int) (*big.Int, error) - - GetAuthorizedSenders(opts *bind.CallOpts) ([]common.Address, error) - - GetConfig(opts *bind.CallOpts) (GetConfig, - - error) - - GetCurrentsubscriptionId(opts *bind.CallOpts) (uint64, error) - - GetRequestConfig(opts *bind.CallOpts) (uint32, []common.Address, error) - - GetRequiredFee(opts *bind.CallOpts, arg0 []byte, arg1 IFunctionsBillingRegistryRequestBilling) (*big.Int, error) - - GetSubscription(opts *bind.CallOpts, subscriptionId uint64) (GetSubscription, - - error) - - GetSubscriptionOwner(opts *bind.CallOpts, subscriptionId uint64) (common.Address, error) - - GetTotalBalance(opts *bind.CallOpts) (*big.Int, error) - - IsAuthorizedSender(opts *bind.CallOpts, sender common.Address) (bool, error) - - Owner(opts *bind.CallOpts) (common.Address, error) - - Paused(opts *bind.CallOpts) (bool, error) - - PendingRequestExists(opts *bind.CallOpts, subscriptionId uint64) (bool, error) - - AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) - - AcceptSubscriptionOwnerTransfer(opts *bind.TransactOpts, subscriptionId uint64) (*types.Transaction, error) - - AddConsumer(opts *bind.TransactOpts, subscriptionId uint64, consumer common.Address) (*types.Transaction, error) - - CancelSubscription(opts *bind.TransactOpts, subscriptionId uint64, to common.Address) (*types.Transaction, error) - - CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) - - FulfillAndBill(opts *bind.TransactOpts, requestId [32]byte, response []byte, err []byte, transmitter common.Address, signers [31]common.Address, signerCount uint8, reportValidationGas *big.Int, initialGas *big.Int) (*types.Transaction, error) - - Initialize(opts *bind.TransactOpts, link common.Address, linkEthFeed common.Address, oracle common.Address) (*types.Transaction, error) - - OnTokenTransfer(opts *bind.TransactOpts, arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) - - OracleWithdraw(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) - - OwnerCancelSubscription(opts *bind.TransactOpts, subscriptionId uint64) (*types.Transaction, error) - - Pause(opts *bind.TransactOpts) (*types.Transaction, error) - - RecoverFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) - - RemoveConsumer(opts *bind.TransactOpts, subscriptionId uint64, consumer common.Address) (*types.Transaction, error) - - RequestSubscriptionOwnerTransfer(opts *bind.TransactOpts, subscriptionId uint64, newOwner common.Address) (*types.Transaction, error) - - SetAuthorizedSenders(opts *bind.TransactOpts, senders []common.Address) (*types.Transaction, error) - - SetConfig(opts *bind.TransactOpts, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation *big.Int, fallbackWeiPerUnitLink *big.Int, gasOverhead uint32, requestTimeoutSeconds uint32) (*types.Transaction, error) - - StartBilling(opts *bind.TransactOpts, data []byte, billing IFunctionsBillingRegistryRequestBilling) (*types.Transaction, error) - - TimeoutRequests(opts *bind.TransactOpts, requestIdsToTimeout [][32]byte) (*types.Transaction, error) - - TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) - - Unpause(opts *bind.TransactOpts) (*types.Transaction, error) - - FilterAuthorizedSendersChanged(opts *bind.FilterOpts) (*FunctionsRegistryAuthorizedSendersChangedIterator, error) - - WatchAuthorizedSendersChanged(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryAuthorizedSendersChanged) (event.Subscription, error) - - ParseAuthorizedSendersChanged(log types.Log) (*FunctionsRegistryAuthorizedSendersChanged, error) - - FilterBillingEnd(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsRegistryBillingEndIterator, error) - - WatchBillingEnd(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryBillingEnd, requestId [][32]byte) (event.Subscription, error) - - ParseBillingEnd(log types.Log) (*FunctionsRegistryBillingEnd, error) - - FilterBillingStart(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsRegistryBillingStartIterator, error) - - WatchBillingStart(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryBillingStart, requestId [][32]byte) (event.Subscription, error) - - ParseBillingStart(log types.Log) (*FunctionsRegistryBillingStart, error) - - FilterConfigSet(opts *bind.FilterOpts) (*FunctionsRegistryConfigSetIterator, error) - - WatchConfigSet(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryConfigSet) (event.Subscription, error) - - ParseConfigSet(log types.Log) (*FunctionsRegistryConfigSet, error) - - FilterFundsRecovered(opts *bind.FilterOpts) (*FunctionsRegistryFundsRecoveredIterator, error) - - WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryFundsRecovered) (event.Subscription, error) - - ParseFundsRecovered(log types.Log) (*FunctionsRegistryFundsRecovered, error) - - FilterInitialized(opts *bind.FilterOpts) (*FunctionsRegistryInitializedIterator, error) - - WatchInitialized(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryInitialized) (event.Subscription, error) - - ParseInitialized(log types.Log) (*FunctionsRegistryInitialized, error) - - FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsRegistryOwnershipTransferRequestedIterator, error) - - WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) - - ParseOwnershipTransferRequested(log types.Log) (*FunctionsRegistryOwnershipTransferRequested, error) - - FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsRegistryOwnershipTransferredIterator, error) - - WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) - - ParseOwnershipTransferred(log types.Log) (*FunctionsRegistryOwnershipTransferred, error) - - FilterPaused(opts *bind.FilterOpts) (*FunctionsRegistryPausedIterator, error) - - WatchPaused(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryPaused) (event.Subscription, error) - - ParsePaused(log types.Log) (*FunctionsRegistryPaused, error) - - FilterRequestTimedOut(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsRegistryRequestTimedOutIterator, error) - - WatchRequestTimedOut(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryRequestTimedOut, requestId [][32]byte) (event.Subscription, error) - - ParseRequestTimedOut(log types.Log) (*FunctionsRegistryRequestTimedOut, error) - - FilterSubscriptionCanceled(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRegistrySubscriptionCanceledIterator, error) - - WatchSubscriptionCanceled(opts *bind.WatchOpts, sink chan<- *FunctionsRegistrySubscriptionCanceled, subscriptionId []uint64) (event.Subscription, error) - - ParseSubscriptionCanceled(log types.Log) (*FunctionsRegistrySubscriptionCanceled, error) - - FilterSubscriptionConsumerAdded(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRegistrySubscriptionConsumerAddedIterator, error) - - WatchSubscriptionConsumerAdded(opts *bind.WatchOpts, sink chan<- *FunctionsRegistrySubscriptionConsumerAdded, subscriptionId []uint64) (event.Subscription, error) - - ParseSubscriptionConsumerAdded(log types.Log) (*FunctionsRegistrySubscriptionConsumerAdded, error) - - FilterSubscriptionConsumerRemoved(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRegistrySubscriptionConsumerRemovedIterator, error) - - WatchSubscriptionConsumerRemoved(opts *bind.WatchOpts, sink chan<- *FunctionsRegistrySubscriptionConsumerRemoved, subscriptionId []uint64) (event.Subscription, error) - - ParseSubscriptionConsumerRemoved(log types.Log) (*FunctionsRegistrySubscriptionConsumerRemoved, error) - - FilterSubscriptionCreated(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRegistrySubscriptionCreatedIterator, error) - - WatchSubscriptionCreated(opts *bind.WatchOpts, sink chan<- *FunctionsRegistrySubscriptionCreated, subscriptionId []uint64) (event.Subscription, error) - - ParseSubscriptionCreated(log types.Log) (*FunctionsRegistrySubscriptionCreated, error) - - FilterSubscriptionFunded(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRegistrySubscriptionFundedIterator, error) - - WatchSubscriptionFunded(opts *bind.WatchOpts, sink chan<- *FunctionsRegistrySubscriptionFunded, subscriptionId []uint64) (event.Subscription, error) - - ParseSubscriptionFunded(log types.Log) (*FunctionsRegistrySubscriptionFunded, error) - - FilterSubscriptionOwnerTransferRequested(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRegistrySubscriptionOwnerTransferRequestedIterator, error) - - WatchSubscriptionOwnerTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsRegistrySubscriptionOwnerTransferRequested, subscriptionId []uint64) (event.Subscription, error) - - ParseSubscriptionOwnerTransferRequested(log types.Log) (*FunctionsRegistrySubscriptionOwnerTransferRequested, error) - - FilterSubscriptionOwnerTransferred(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRegistrySubscriptionOwnerTransferredIterator, error) - - WatchSubscriptionOwnerTransferred(opts *bind.WatchOpts, sink chan<- *FunctionsRegistrySubscriptionOwnerTransferred, subscriptionId []uint64) (event.Subscription, error) - - ParseSubscriptionOwnerTransferred(log types.Log) (*FunctionsRegistrySubscriptionOwnerTransferred, error) - - FilterUnpaused(opts *bind.FilterOpts) (*FunctionsRegistryUnpausedIterator, error) - - WatchUnpaused(opts *bind.WatchOpts, sink chan<- *FunctionsRegistryUnpaused) (event.Subscription, error) - - ParseUnpaused(log types.Log) (*FunctionsRegistryUnpaused, error) - - ParseLog(log types.Log) (generated.AbigenLog, error) - - Address() common.Address -} diff --git a/core/gethwrappers/generated/functions_router/functions_router.go b/core/gethwrappers/generated/functions_router/functions_router.go deleted file mode 100644 index c90c1071106..00000000000 --- a/core/gethwrappers/generated/functions_router/functions_router.go +++ /dev/null @@ -1,3839 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package functions_router - -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 FunctionsRouterMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"timelockBlocks\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"maximumTimelockBlocks\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"internalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"externalBalance\",\"type\":\"uint256\"}],\"name\":\"BalanceInvariantViolated\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConsumerRequestsInFlight\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfigData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProposal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"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\":\"OnlyCallableByRoute\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ProposedTimelockAboveMaximum\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"ReservedLabel\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RouteNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TimelockInEffect\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"fromHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"toBytes\",\"type\":\"bytes\"}],\"name\":\"ConfigProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"adminFee\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"fromHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"toBytes\",\"type\":\"bytes\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"proposedContractSetId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetFromAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetToAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timelockEndBlock\",\"type\":\"uint256\"}],\"name\":\"ContractProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"proposedContractSetId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetFromAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetToAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"major\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minor\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"patch\",\"type\":\"uint16\"}],\"name\":\"ContractUpdated\",\"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\":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\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalCostJuels\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"}],\"name\":\"RequestEnd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"RequestStart\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"fundsRecipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fundsAmount\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"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\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"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\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"from\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"to\",\"type\":\"uint16\"}],\"name\":\"TimeLockProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"from\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"to\",\"type\":\"uint16\"}],\"name\":\"TimeLockUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CONSUMERS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"juelsPerGas\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"costWithoutFulfillment\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"fulfill\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"callbackGasCostJuels\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminFee\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfigHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"config\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getConsumer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"initiatedRequests\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"completedRequests\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"useProposed\",\"type\":\"bool\"}],\"name\":\"getContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"routeDestination\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"routeDestination\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getProposedContractSet\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"blockedBalance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"requestedOwner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSubscriptionCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTotalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"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\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"proposeConfigUpdate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"proposedContractSetIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"proposedContractSetFromAddresses\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"proposedContractSetToAddresses\",\"type\":\"address[]\"}],\"name\":\"proposeContractsUpdate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"blocks\",\"type\":\"uint16\"}],\"name\":\"proposeTimelockBlocks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"requestSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"requestIdsToTimeout\",\"type\":\"bytes32[]\"}],\"name\":\"timeoutRequests\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"togglePaused\",\"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\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updateContracts\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updateTimelockBlocks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"validateProposedContracts\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60806040526001805463ffffffff60a01b191690553480156200002157600080fd5b50604051620063f0380380620063f083398101604081905262000044916200030d565b6000805460ff1916815582903390869086908590849081620000ad5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0380851661010002610100600160a81b031990921691909117909155811615620000e757620000e78162000198565b50506008805461ffff84811661ffff1991871662010000029190911663ffffffff19909216919091171790556000805260026020527fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b80546001600160a01b0319163017905562000158816200024a565b8051602090910120600b555050600c80546001600160a01b0390931661010002610100600160a81b031990931692909217909155506200049c9350505050565b6001600160a01b038116331415620001f35760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000a4565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929361010090910416917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000808280602001905181019062000263919062000430565b6040805180820182526001600160601b0384168082526001600160e01b031984166020928301819052601280546001600160801b03191683176c0100000000000000000000000060e088901c021790558351918252918101919091529294509092507fb2b9bfb736b0bfef266985352cfca2a114226362209f5a6e5a2a2ed14383ba57910160405180910390a1505050565b805161ffff811681146200030857600080fd5b919050565b600080600080608085870312156200032457600080fd5b6200032f85620002f5565b9350602062000340818701620002f5565b60408701519094506001600160a01b03811681146200035e57600080fd5b60608701519093506001600160401b03808211156200037c57600080fd5b818801915088601f8301126200039157600080fd5b815181811115620003a657620003a662000486565b604051601f8201601f19908116603f01168101908382118183101715620003d157620003d162000486565b816040528281528b86848701011115620003ea57600080fd5b600093505b828410156200040e5784840186015181850187015292850192620003ef565b82841115620004205760008684830101525b989b979a50959850505050505050565b600080604083850312156200044457600080fd5b82516001600160601b03811681146200045c57600080fd5b60208401519092506001600160e01b0319811681146200047b57600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b615f4480620004ac6000396000f3fe608060405234801561001057600080fd5b50600436106102ad5760003560e01c806379ba50971161017b578063b187bd26116100d8578063d7ae1d301161008c578063e82ad7d411610071578063e82ad7d4146106e7578063eb523d6c146106fa578063f2fde38b1461070d57600080fd5b8063d7ae1d30146106c1578063e72f6e30146106d457600080fd5b8063b734c0f4116100bd578063b734c0f41461068e578063badc3eb614610696578063c4614d61146106ae57600080fd5b8063b187bd2614610670578063b56438581461067b57600080fd5b80639f87fad71161012f578063a47c769611610114578063a47c769614610626578063a4c0ed361461064a578063a9c9a9181461065d57600080fd5b80639f87fad71461060b578063a21a23e41461061e57600080fd5b80638da5cb5b116101605780638da5cb5b146105d85780638fde5317146105fb5780639883c10d1461060357600080fd5b806379ba5097146105bd57806382359740146105c557600080fd5b8063461d27621161022957806366419970116101dd578063674603d0116101c2578063674603d0146104dd5780636a6df79b146105725780637341c10c146105aa57600080fd5b8063664199701461048a578063665871ec146104ca57600080fd5b80635c975abb1161020e5780635c975abb1461044557806364d51a2a1461045c57806366316d8d1461047757600080fd5b8063461d2762146103cd57806354fd4d50146103ee57600080fd5b80631e9fb8cd1161028057806336566f061161026557806336566f0614610379578063385de9ae146103815780633fd67e051461039457600080fd5b80631e9fb8cd146103505780632a905ccc1461036357600080fd5b806302bcc5b6146102b257806304c357cb146102c757806312b58349146102da578063181f5a771461030e575b600080fd5b6102c56102c03660046155dc565b610720565b005b6102c56102d53660046155f7565b6107a0565b600d546bffffffffffffffffffffffff165b6040516bffffffffffffffffffffffff90911681526020015b60405180910390f35b60408051808201909152601381527f46756e6374696f6e7320526f757465722076310000000000000000000000000060208201525b6040516103059190615a35565b6102c561035e366004615339565b61098e565b6012546bffffffffffffffffffffffff166102ec565b6102c5610b1d565b6102c561038f366004615491565b610b42565b6103a76103a23660046154dd565b610d8e565b6040805160ff90931683526bffffffffffffffffffffffff909116602083015201610305565b6103e06103db366004615623565b61106f565b604051908152602001610305565b600180546040805192835261ffff7401000000000000000000000000000000000000000083048116602085015276010000000000000000000000000000000000000000000090920490911690820152606001610305565b60005460ff165b6040519015158152602001610305565b610464606481565b60405161ffff9091168152602001610305565b6102c561048536600461528b565b61110b565b600c547501000000000000000000000000000000000000000000900467ffffffffffffffff165b60405167ffffffffffffffff9091168152602001610305565b6102c56104d83660046152c4565b611378565b61054a6104eb366004615256565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152600f6020908152604080832067ffffffffffffffff948516845290915290205460ff8116926101008204831692690100000000000000000090920490911690565b60408051931515845267ffffffffffffffff9283166020850152911690820152606001610305565b61058561058036600461546c565b611861565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610305565b6102c56105b83660046155f7565b611874565b6102c5611b00565b6102c56105d33660046155dc565b611c22565b600054610100900473ffffffffffffffffffffffffffffffffffffffff16610585565b6102c5611e18565b600b546103e0565b6102c56106193660046155f7565b611e9c565b6104b16123a0565b6106396106343660046155dc565b6125d3565b604051610305959493929190615b94565b6102c56106583660046151fa565b6126c1565b61058561066b36600461543a565b61291d565b60005460ff1661044c565b6102c56106893660046155c1565b612930565b6102c5612a4a565b61069e612d3f565b6040516103059493929190615ad2565b6103436106bc366004615491565b612e8c565b6102c56106cf3660046155f7565b612ea1565b6102c56106e23660046151dd565b613083565b61044c6106f53660046155dc565b6132a9565b6102c561070836600461543a565b6133fa565b6102c561071b3660046151dd565b6136ae565b6107286136bf565b67ffffffffffffffff81166000908152600e602052604090206001015473ffffffffffffffffffffffffffffffffffffffff1680610792576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61079c8282613745565b5050565b67ffffffffffffffff82166000908152600e6020526040902060010154829073ffffffffffffffffffffffffffffffffffffffff168061080c576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821614610878576040517fd8a3fb5200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024015b60405180910390fd5b600c5460ff16156108b5576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff84166000908152600e602052604090206002015473ffffffffffffffffffffffffffffffffffffffff8481169116146109885767ffffffffffffffff84166000818152600e602090815260409182902060020180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff88169081179091558251338152918201527f69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be91015b60405180910390a25b50505050565b6109966136bf565b6109a1838383613b60565b6008546000906109bb9062010000900461ffff1643615c82565b604080516080810182528681526020808201879052918101859052606081018390528651929350916003916109f4918391890190614ee5565b506020828101518051610a0d9260018501920190614f2c565b5060408201518051610a29916002840191602090910190614f2c565b506060820151816003015590505060005b84518160ff161015610b16577f72a33d2f293a0a70fad221bb610d3d6b52aed2d840adae1fa721071fbd290cfd858260ff1681518110610a7c57610a7c615e8f565b6020026020010151858360ff1681518110610a9957610a99615e8f565b6020026020010151858460ff1681518110610ab657610ab6615e8f565b602002602001015185604051610afc949392919093845273ffffffffffffffffffffffffffffffffffffffff928316602085015291166040830152606082015260800190565b60405180910390a180610b0e81615e11565b915050610a3a565b5050505050565b610b256136bf565b60005460ff1615610b3a57610b38613e4f565b565b610b38613ecc565b610b4a6136bf565b60008381526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1680610ba9576040517f80833e330000000000000000000000000000000000000000000000000000000081526004810185905260240161086f565b600073ffffffffffffffffffffffffffffffffffffffff8216301415610bd25750600b54610c55565b8173ffffffffffffffffffffffffffffffffffffffff16639883c10d6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610c1a57600080fd5b505af1158015610c2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c529190615453565b90505b8383604051610c65929190615913565b6040518091039020811415610ca6576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604051806060016040528082815260200185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250600854602090910190610d0d9062010000900461ffff1643615c82565b90526000868152600760209081526040909120825181558282015180519192610d3e92600185019290910190614fa6565b50604091820151600290910155517f0fcfd32a68209b42944376bc5f4bf72c41ba0f378cf60434f84390b82c9844cf90610d7f908790849088908890615987565b60405180910390a15050505050565b600c54600090819060ff1615610dd0576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088815260116020908152604091829020825161010081018452815473ffffffffffffffffffffffffffffffffffffffff9081168252600183015490811693820184905274010000000000000000000000000000000000000000810467ffffffffffffffff16948201949094527c010000000000000000000000000000000000000000000000000000000090930463ffffffff16606084015260028101546bffffffffffffffffffffffff9081166080850152600382015460a0850152600482015460c08501526005909101541660e0830152610eb2576002925050611064565b805173ffffffffffffffffffffffffffffffffffffffff163314610f02576040517f8bec23e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f2081608001518260c001518360e0015184606001518a8a613f27565b60008a8152601160209081526040822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018390556002810180547fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090811690915560038201849055600482018490556005909101805490911690556060840151908401519295509091610fc1918c918c918c91613fad565b8051909150610fd1576001610fd4565b60005b93506000610ffb8360400151846080015185602001518660e001518c87602001518d61412b565b9050826040015167ffffffffffffffff168b7f526019d853b0b88e828dbdc124746afde5a47053256d2a0872a025ab145b0520836020015189898760000151611044578e611046565b8f5b6040516110569493929190615b48565b60405180910390a351925050505b965096945050505050565b600c5460009060ff16156110af576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110b761439a565b6110fe8260008989898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92508a91506144079050565b90505b9695505050505050565b600c5460ff1615611148576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6bffffffffffffffffffffffff811661118d576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152601060205260409020546bffffffffffffffffffffffff808316911610156111e7576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600090815260106020526040812080548392906112149084906bffffffffffffffffffffffff16615d2f565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080600d60008282829054906101000a90046bffffffffffffffffffffffff1661126b9190615d2f565b82546bffffffffffffffffffffffff91821661010093840a9081029083021990911617909255600c546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301529386166024820152919004909116915063a9059cbb90604401602060405180830381600087803b15801561130a57600080fd5b505af115801561131e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611342919061541d565b61079c576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c5460ff16156113b5576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8181101561185c5760008383838181106113d4576113d4615e8f565b602090810292909201356000818152601184526040808220815161010081018352815473ffffffffffffffffffffffffffffffffffffffff908116825260018301549081169782019790975274010000000000000000000000000000000000000000870467ffffffffffffffff168184018190527c010000000000000000000000000000000000000000000000000000000090970463ffffffff16606082015260028201546bffffffffffffffffffffffff9081166080830152600383015460a083015260048084015460c08401526005909301541660e082015291517fa47c7696000000000000000000000000000000000000000000000000000000008152908101959095529194509092909150309063a47c76969060240160006040518083038186803b15801561150657600080fd5b505afa15801561151a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526115609190810190615764565b5050925050508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146115e3576040517fd8a3fb5200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161086f565b8160a00151421015611621576040517fbcc4005500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81516040517f85b214cf0000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff8216906385b214cf90602401602060405180830381600087803b15801561168b57600080fd5b505af115801561169f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c3919061541d565b1561184557608083015160408085015167ffffffffffffffff166000908152600e602052208054600c906117169084906c0100000000000000000000000090046bffffffffffffffffffffffff16615d2f565b82546bffffffffffffffffffffffff9182166101009390930a92830291909202199091161790555060208084015173ffffffffffffffffffffffffffffffffffffffff166000908152600f825260408082208187015167ffffffffffffffff908116845293529020805460019260099161179f9185916901000000000000000000900416615c9a565b825467ffffffffffffffff9182166101009390930a928302919092021990911617905550600084815260116020526040812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018290556002810180547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000908116909155600382018390556004820192909255600501805490911690555b50505050808061185490615db0565b9150506113b8565b505050565b600061186d8383614816565b9392505050565b67ffffffffffffffff82166000908152600e6020526040902060010154829073ffffffffffffffffffffffffffffffffffffffff16806118e0576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821614611947576040517fd8a3fb5200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161086f565b600c5460ff1615611984576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff84166000908152600e6020526040902060030154606414156119db576040517f05a48e0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000908152600f6020908152604080832067ffffffffffffffff8816845290915290205460ff16151560011415611a2857610988565b73ffffffffffffffffffffffffffffffffffffffff83166000818152600f6020908152604080832067ffffffffffffffff891680855290835281842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155600e84528285206003018054918201815585529383902090930180547fffffffffffffffffffffffff000000000000000000000000000000000000000016851790555192835290917f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e0910161097f565b60015473ffffffffffffffffffffffffffffffffffffffff163314611b81576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161086f565b60008054336101008181027fffffffffffffffffffffff0000000000000000000000000000000000000000ff8416178455600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905560405173ffffffffffffffffffffffffffffffffffffffff919093041692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600c5460ff1615611c5f576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600e602052604090206001015473ffffffffffffffffffffffffffffffffffffffff16611cc8576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600e602052604090206002015473ffffffffffffffffffffffffffffffffffffffff163314611d6a5767ffffffffffffffff81166000908152600e6020526040908190206002015490517fd084e97500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161086f565b67ffffffffffffffff81166000818152600e60209081526040918290206001810180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560029093018054909316909255835173ffffffffffffffffffffffffffffffffffffffff909216808352928201529092917f6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f0910160405180910390a25050565b611e206136bf565b600a54431015611e5c576040517fa93d035c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600954600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffff16620100009283900461ffff16909202919091179055565b67ffffffffffffffff82166000908152600e6020526040902060010154829073ffffffffffffffffffffffffffffffffffffffff1680611f08576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821614611f6f576040517fd8a3fb5200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161086f565b600c5460ff1615611fac576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000908152600f6020908152604080832067ffffffffffffffff8089168552908352928190208151606081018352905460ff811615158083526101008204861694830194909452690100000000000000000090049093169083015261207c576040517ff0019fe600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015273ffffffffffffffffffffffffffffffffffffffff8516602482015260440161086f565b806040015167ffffffffffffffff16816020015167ffffffffffffffff16146120d1576040517fbcc4005500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff85166000908152600e602090815260408083206003018054825181850281018501909352808352919290919083018282801561214c57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612121575b505050505090506000600182516121639190615d18565b905060005b8251811015612302578673ffffffffffffffffffffffffffffffffffffffff1683828151811061219a5761219a615e8f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614156122f05760008383815181106121d2576121d2615e8f565b6020026020010151905080600e60008b67ffffffffffffffff1667ffffffffffffffff168152602001908152602001600020600301838154811061221857612218615e8f565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff949094169390931790925567ffffffffffffffff8b168152600e9091526040902060030180548061229257612292615e60565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550612302565b806122fa81615db0565b915050612168565b5073ffffffffffffffffffffffffffffffffffffffff86166000818152600f6020908152604080832067ffffffffffffffff8c168085529083529281902080547fffffffffffffffffffffffffffffff00000000000000000000000000000000001690555192835290917f182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b910160405180910390a250505050505050565b600c5460009060ff16156123e0576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c80547501000000000000000000000000000000000000000000900467ffffffffffffffff1690601561241383615de9565b82546101009290920a67ffffffffffffffff818102199093169183160217909155600c547501000000000000000000000000000000000000000000900416905060008060405190808252806020026020018201604052801561247f578160200160208202803683370190505b506040805160a0810182526000808252602080830182815233848601908152606085018481526080860188815267ffffffffffffffff8b168652600e8552969094208551815493516bffffffffffffffffffffffff9081166c01000000000000000000000000027fffffffffffffffff0000000000000000000000000000000000000000000000009095169116179290921782555160018201805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff000000000000000000000000000000000000000091821617909155935160028301805491909216941693909317909255925180519495509193909261258b926003850192910190614f2c565b505060405133815267ffffffffffffffff841691507f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf9060200160405180910390a250905090565b60008060008060606125e486614946565b67ffffffffffffffff86166000908152600e6020908152604091829020805460018201546002830154600390930180548651818702810187019097528087526bffffffffffffffffffffffff8085169c506c01000000000000000000000000909404909316995073ffffffffffffffffffffffffffffffffffffffff91821698509216955090918301828280156126b157602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612686575b5050505050905091939590929450565b600c5460ff16156126fe576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c54610100900473ffffffffffffffffffffffffffffffffffffffff163314612754576040517f44b0e3c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020811461278e576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061279c828401846155dc565b67ffffffffffffffff81166000908152600e602052604090206001015490915073ffffffffffffffffffffffffffffffffffffffff16612808576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600e6020526040812080546bffffffffffffffffffffffff169186919061283f8385615cbd565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555084600d60008282829054906101000a90046bffffffffffffffffffffffff166128969190615cbd565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508167ffffffffffffffff167fd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f88287846128fd9190615c82565b6040805192835260208301919091520160405180910390a2505050505050565b600061292a826000614816565b92915050565b6129386136bf565b60085461ffff82811662010000909204161415612981576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60085461ffff90811690821611156129c5576040517fe9a3062200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160608101825260085461ffff620100009091048116808352908416602083015290918201906129f89043615c82565b9052805160098054602084015161ffff90811662010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000090921693169290921791909117905560400151600a5550565b612a526136bf565b600654431015612a8e576040517fa93d035c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160149054906101000a900461ffff166001612aab9190615c5c565b600180547fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000061ffff93841602179081905576010000000000000000000000000000000000000000000090041615612b3c57600180547fffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff1690555b60005b60035460ff82161015612d3c576005805460ff8316908110612b6357612b63615e8f565b60009182526020822001546003805473ffffffffffffffffffffffffffffffffffffffff9092169260029290919060ff8616908110612ba457612ba4615e8f565b9060005260206000200154815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff17ce6b5bbeda6598ac50e505071ddbd27c188c5ecaf9126b42c951c9c4b61e960036000018260ff1681548110612c3557612c35615e8f565b906000526020600020015460036001018360ff1681548110612c5957612c59615e8f565b6000918252602090912001546005805473ffffffffffffffffffffffffffffffffffffffff9092169160ff8616908110612c9557612c95615e8f565b60009182526020918290200154600180546040805196875273ffffffffffffffffffffffffffffffffffffffff958616948701949094529390911691840191909152606083015261ffff740100000000000000000000000000000000000000008204811660808401527601000000000000000000000000000000000000000000009091041660a082015260c00160405180910390a180612d3481615e11565b915050612b3f565b50565b60006060806060600380015460036000016003600101600360020182805480602002602001604051908101604052809291908181526020018280548015612da557602002820191906000526020600020905b815481526020019060010190808311612d91575b5050505050925081805480602002602001604051908101604052809291908181526020018280548015612e0e57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612de3575b5050505050915080805480602002602001604051908101604052809291908181526020018280548015612e7757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612e4c575b50505050509050935093509350935090919293565b6060612e998484846149af565b949350505050565b67ffffffffffffffff82166000908152600e6020526040902060010154829073ffffffffffffffffffffffffffffffffffffffff1680612f0d576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821614612f74576040517fd8a3fb5200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161086f565b600c5460ff1615612fb1576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fe82ad7d400000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152309063e82ad7d49060240160206040518083038186803b15801561300a57600080fd5b505afa15801561301e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613042919061541d565b15613079576040517fb42f66e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109888484613745565b61308b6136bf565b600c546040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152600091610100900473ffffffffffffffffffffffffffffffffffffffff16906370a082319060240160206040518083038186803b1580156130fa57600080fd5b505afa15801561310e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131329190615453565b600d549091506bffffffffffffffffffffffff168181111561318a576040517fa99da302000000000000000000000000000000000000000000000000000000008152600481018290526024810183905260440161086f565b8181101561185c57600061319e8284615d18565b600c546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152602482018490529293506101009091049091169063a9059cbb90604401602060405180830381600087803b15801561321b57600080fd5b505af115801561322f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613253919061541d565b506040805173ffffffffffffffffffffffffffffffffffffffff86168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a150505050565b67ffffffffffffffff81166000908152600e602090815260408083206003018054825181850281018501909352808352849383018282801561332157602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116132f6575b5050505050905060005b81518110156133f0576000600f600084848151811061334c5761334c615e8f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff808a168352908452908290208251606081018452905460ff81161515825261010081048316948201859052690100000000000000000090049091169181018290529250146133dd57506001949350505050565b50806133e881615db0565b91505061332b565b5060009392505050565b6134026136bf565b600081815260026020908152604080832054600783528184208251606081019093528054835260018101805473ffffffffffffffffffffffffffffffffffffffff909316959491929184019161345790615d5c565b80601f016020809104026020016040519081016040528092919081815260200182805461348390615d5c565b80156134d05780601f106134a5576101008083540402835291602001916134d0565b820191906000526020600020905b8154815290600101906020018083116134b357829003601f168201915b5050505050815260200160028201548152505090508060400151431015613523576040517fa93d035c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82613548576135358160200151614a7e565b6020808201518051910120600b556135ff565b60208101516040517f354497aa00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84169163354497aa9161359e9190600401615a35565b600060405180830381600087803b1580156135b857600080fd5b505af19250505080156135c9575060015b6135ff576040517ffe680b2600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160169054906101000a900461ffff16600161361c9190615c5c565b6001805461ffff92909216760100000000000000000000000000000000000000000000027fffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff909216919091179055805160208201516040517fc07626096b49b0462a576c9a7878cf0675e784bb4832584c1289c11664e55f47926136a19287926159e2565b60405180910390a1505050565b6136b66136bf565b612d3c81614b54565b600054610100900473ffffffffffffffffffffffffffffffffffffffff163314610b38576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161086f565b600c5460ff1615613782576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff82166000908152600e60209081526040808320815160a08101835281546bffffffffffffffffffffffff80821683526c010000000000000000000000009091041681850152600182015473ffffffffffffffffffffffffffffffffffffffff90811682850152600283015416606082015260038201805484518187028101870190955280855291949293608086019390929083018282801561386357602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311613838575b5050509190925250505067ffffffffffffffff84166000908152600e60205260408120549192506bffffffffffffffffffffffff909116905b82608001515181101561394257600f6000846080015183815181106138c3576138c3615e8f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff89168252909252902080547fffffffffffffffffffffffffffffff00000000000000000000000000000000001690558061393a81615db0565b91505061389c565b5067ffffffffffffffff84166000908152600e6020526040812080547fffffffffffffffff0000000000000000000000000000000000000000000000001681556001810180547fffffffffffffffffffffffff00000000000000000000000000000000000000009081169091556002820180549091169055906139c86003830182615019565b5050600d80548291906000906139ed9084906bffffffffffffffffffffffff16615d2f565b82546bffffffffffffffffffffffff91821661010093840a9081029083021990911617909255600c546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152938616602482015291900491909116915063a9059cbb90604401602060405180830381600087803b158015613a8d57600080fd5b505af1158015613aa1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ac5919061541d565b613afb576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff851681526bffffffffffffffffffffffff8316602082015267ffffffffffffffff8616917fe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd49815910161097f565b81518351141580613b7357508051835114155b15613baa576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b825160081015613be6576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b83518160ff16101561098857600073ffffffffffffffffffffffffffffffffffffffff16828260ff1681518110613c2257613c22615e8f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161415613c78576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818160ff1681518110613c8d57613c8d615e8f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1660026000868460ff1681518110613cc457613cc4615e8f565b60209081029190910181015182528101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff161415613d2d576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b828160ff1681518110613d4257613d42615e8f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1660026000868460ff1681518110613d7957613d79615e8f565b60209081029190910181015182528101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1614613de1576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000801b848260ff1681518110613dfa57613dfa615e8f565b60200260200101511415613e3d576040517f7ee392220000000000000000000000000000000000000000000000000000000081526000600482015260240161086f565b80613e4781615e11565b915050613be9565b613e57614c50565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b613ed461439a565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258613ea23390565b6000613f398663ffffffff8616615c82565b5a1015613f4857506003611101565b866bffffffffffffffffffffffff16613f668563ffffffff16614cbc565b613f709085615ce4565b613f7a8488615cbd565b613f849190615cbd565b6bffffffffffffffffffffffff161115613fa057506004611101565b5060009695505050505050565b60408051808201909152600080825260208201526012546040516000916c01000000000000000000000000900460e01b90613ff090899089908990602401615a0a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152600c80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590506000805a6113888110156140ad57600080fd5b6113888103905086604082048203116140c557600080fd5b853b6140d057600080fd5b60008085516020870160008a8cf192505a600c80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040805180820190915293151584529003602083015250979650505050505050565b6040805180820190915260008082526020820152600061414a84614cbc565b6141549086615ce4565b905060006141628482615cbd565b905061416e8782615cbd565b905061417a8282615cbd565b6040805180820182526bffffffffffffffffffffffff808616825280841660208084019190915267ffffffffffffffff8f166000908152600e9091529283208054929750939450849392916141d191859116615d2f565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550818461420b9190615cbd565b33600090815260106020526040812080549091906142389084906bffffffffffffffffffffffff16615cbd565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915530600090815260106020526040812080548b9450909261427f91859116615cbd565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915567ffffffffffffffff8c166000908152600e6020526040902080548c93509091600c916142e39185916c01000000000000000000000000900416615d2f565b82546bffffffffffffffffffffffff9182166101009390930a92830291909202199091161790555073ffffffffffffffffffffffffffffffffffffffff88166000908152600f6020908152604080832067ffffffffffffffff808f168552925290912080546001926009916143679185916901000000000000000000900416615c9a565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505050979650505050505050565b60005460ff1615610b38576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015260640161086f565b600061441285614946565b61441c3386614d5e565b60006144288888614816565b6040805160c08101825267ffffffffffffffff891680825260208083018a905261ffff89168385015263ffffffff881660608401523360808401526000918252600e90528281206001015473ffffffffffffffffffffffffffffffffffffffff90811660a084015292517f0a33e0a5000000000000000000000000000000000000000000000000000000008152939450928392839290861691630a33e0a5916144d391600401615a48565b608060405180830381600087803b1580156144ed57600080fd5b505af1158015614501573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145259190615583565b9297509094509250905061453a338a85614dfa565b6040518061010001604052808573ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018a67ffffffffffffffff1681526020018763ffffffff168152602001846bffffffffffffffffffffffff16815260200182426145ba9190615c82565b8152602001838152602001601260000160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152506011600087815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550606082015181600101601c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160020160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555060a0820151816003015560c0820151816004015560e08201518160050160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055509050508867ffffffffffffffff168b867f7c720ccd20069b8311a6be4ba1cf3294d09eb247aa5d73a8502054b6e68a2f54600e60008e67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633328e8e8e60405161480096959493929190615923565b60405180910390a4505050509695505050505050565b6000816148835760008381526002602052604090205473ffffffffffffffffffffffffffffffffffffffff168061487c576040517f80833e330000000000000000000000000000000000000000000000000000000081526004810185905260240161086f565b905061292a565b60005b60035460ff82161015614910576003805460ff83169081106148aa576148aa615e8f565b90600052602060002001548414156148fe576005805460ff83169081106148d3576148d3615e8f565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16915061292a9050565b8061490881615e11565b915050614886565b506040517f80833e330000000000000000000000000000000000000000000000000000000081526004810184905260240161086f565b67ffffffffffffffff81166000908152600e602052604090206001015473ffffffffffffffffffffffffffffffffffffffff16612d3c576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606060008080806149c2868801886156a1565b935093509350935060006149db89600187878787614407565b60408051602080825281830190925291925060208201818036833701905050955060005b6020811015614a7157818160208110614a1a57614a1a615e8f565b1a60f81b878281518110614a3057614a30615e8f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080614a6981615db0565b9150506149ff565b5050505050509392505050565b60008082806020019051810190614a959190615710565b6040805180820182526bffffffffffffffffffffffff84168082527fffffffff0000000000000000000000000000000000000000000000000000000084166020928301819052601280547fffffffffffffffffffffffffffffffff000000000000000000000000000000001683176c0100000000000000000000000060e088901c021790558351918252918101919091529294509092507fb2b9bfb736b0bfef266985352cfca2a114226362209f5a6e5a2a2ed14383ba5791016136a1565b73ffffffffffffffffffffffffffffffffffffffff8116331415614bd4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161086f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929361010090910416917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005460ff16610b38576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161086f565b60006bffffffffffffffffffffffff821115614d5a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f3620626974730000000000000000000000000000000000000000000000000000606482015260840161086f565b5090565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600f6020908152604080832067ffffffffffffffff8516845290915290205460ff1661079c576040517ff0019fe600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015273ffffffffffffffffffffffffffffffffffffffff8316602482015260440161086f565b67ffffffffffffffff82166000908152600e602052604090208054829190600c90614e449084906c0100000000000000000000000090046bffffffffffffffffffffffff16615cbd565b82546bffffffffffffffffffffffff91821661010093840a908102920219161790915573ffffffffffffffffffffffffffffffffffffffff85166000908152600f6020908152604080832067ffffffffffffffff8089168552925290912080546001945090928492614eba928492900416615c9a565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505050565b828054828255906000526020600020908101928215614f20579160200282015b82811115614f20578251825591602001919060010190614f05565b50614d5a929150615033565b828054828255906000526020600020908101928215614f20579160200282015b82811115614f2057825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190614f4c565b828054614fb290615d5c565b90600052602060002090601f016020900481019282614fd45760008555614f20565b82601f10614fed57805160ff1916838001178555614f20565b82800160010185558215614f205791820182811115614f20578251825591602001919060010190614f05565b5080546000825590600052602060002090810190612d3c91905b5b80821115614d5a5760008155600101615034565b600082601f83011261505957600080fd5b8135602061506e61506983615c38565b615be9565b80838252828201915082860187848660051b890101111561508e57600080fd5b60005b858110156150b65781356150a481615eed565b84529284019290840190600101615091565b5090979650505050505050565b60008083601f8401126150d557600080fd5b50813567ffffffffffffffff8111156150ed57600080fd5b60208301915083602082850101111561510557600080fd5b9250929050565b600082601f83011261511d57600080fd5b813567ffffffffffffffff81111561513757615137615ebe565b61516860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601615be9565b81815284602083860101111561517d57600080fd5b816020850160208301376000918101602001919091529392505050565b803561ffff811681146151ac57600080fd5b919050565b803563ffffffff811681146151ac57600080fd5b803567ffffffffffffffff811681146151ac57600080fd5b6000602082840312156151ef57600080fd5b813561186d81615eed565b6000806000806060858703121561521057600080fd5b843561521b81615eed565b935060208501359250604085013567ffffffffffffffff81111561523e57600080fd5b61524a878288016150c3565b95989497509550505050565b6000806040838503121561526957600080fd5b823561527481615eed565b9150615282602084016151c5565b90509250929050565b6000806040838503121561529e57600080fd5b82356152a981615eed565b915060208301356152b981615f1d565b809150509250929050565b600080602083850312156152d757600080fd5b823567ffffffffffffffff808211156152ef57600080fd5b818501915085601f83011261530357600080fd5b81358181111561531257600080fd5b8660208260051b850101111561532757600080fd5b60209290920196919550909350505050565b60008060006060848603121561534e57600080fd5b833567ffffffffffffffff8082111561536657600080fd5b818601915086601f83011261537a57600080fd5b8135602061538a61506983615c38565b8083825282820191508286018b848660051b89010111156153aa57600080fd5b600096505b848710156153cd5780358352600196909601959183019183016153af565b50975050870135925050808211156153e457600080fd5b6153f087838801615048565b9350604086013591508082111561540657600080fd5b5061541386828701615048565b9150509250925092565b60006020828403121561542f57600080fd5b815161186d81615f0f565b60006020828403121561544c57600080fd5b5035919050565b60006020828403121561546557600080fd5b5051919050565b6000806040838503121561547f57600080fd5b8235915060208301356152b981615f0f565b6000806000604084860312156154a657600080fd5b83359250602084013567ffffffffffffffff8111156154c457600080fd5b6154d0868287016150c3565b9497909650939450505050565b60008060008060008060c087890312156154f657600080fd5b86359550602087013567ffffffffffffffff8082111561551557600080fd5b6155218a838b0161510c565b9650604089013591508082111561553757600080fd5b5061554489828a0161510c565b945050606087013561555581615f1d565b9250608087013561556581615f1d565b915060a087013561557581615eed565b809150509295509295509295565b6000806000806080858703121561559957600080fd5b8451935060208501516155ab81615f1d565b6040860151606090960151949790965092505050565b6000602082840312156155d357600080fd5b61186d8261519a565b6000602082840312156155ee57600080fd5b61186d826151c5565b6000806040838503121561560a57600080fd5b615613836151c5565b915060208301356152b981615eed565b60008060008060008060a0878903121561563c57600080fd5b615645876151c5565b9550602087013567ffffffffffffffff81111561566157600080fd5b61566d89828a016150c3565b909650945061568090506040880161519a565b925061568e606088016151b1565b9150608087013590509295509295509295565b600080600080608085870312156156b757600080fd5b6156c0856151c5565b9350602085013567ffffffffffffffff8111156156dc57600080fd5b6156e88782880161510c565b9350506156f76040860161519a565b9150615705606086016151b1565b905092959194509250565b6000806040838503121561572357600080fd5b825161572e81615f1d565b60208401519092507fffffffff00000000000000000000000000000000000000000000000000000000811681146152b957600080fd5b600080600080600060a0868803121561577c57600080fd5b855161578781615f1d565b8095505060208087015161579a81615f1d565b60408801519095506157ab81615eed565b60608801519094506157bc81615eed565b608088015190935067ffffffffffffffff8111156157d957600080fd5b8701601f810189136157ea57600080fd5b80516157f861506982615c38565b8082825284820191508484018c868560051b870101111561581857600080fd5b600094505b8385101561584457805161583081615eed565b83526001949094019391850191850161581d565b5080955050505050509295509295909350565b600081518084526020808501945080840160005b8381101561589d57815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161586b565b509495945050505050565b6000815180845260005b818110156158ce576020818501810151868301820152016158b2565b818111156158e0576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b8183823760009101908152919050565b600073ffffffffffffffffffffffffffffffffffffffff8089168352808816602084015280871660408401525060c0606083015261596460c08301866158a8565b905061ffff8416608083015263ffffffff831660a0830152979650505050505050565b84815283602082015260606040820152816060820152818360808301376000818301608090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01601019392505050565b838152826020820152606060408201526000615a0160608301846158a8565b95945050505050565b838152606060208201526000615a2360608301856158a8565b828103604084015261110181856158a8565b60208152600061186d60208301846158a8565b6020815267ffffffffffffffff82511660208201526000602083015160c06040840152615a7860e08401826158a8565b905061ffff604085015116606084015263ffffffff6060850151166080840152608084015173ffffffffffffffffffffffffffffffffffffffff80821660a08601528060a08701511660c086015250508091505092915050565b600060808201868352602060808185015281875180845260a086019150828901935060005b81811015615b1357845183529383019391830191600101615af7565b50508481036040860152615b278188615857565b925050508281036060840152615b3d8185615857565b979650505050505050565b6bffffffffffffffffffffffff8516815273ffffffffffffffffffffffffffffffffffffffff8416602082015260ff8316604082015260806060820152600061110160808301846158a8565b6bffffffffffffffffffffffff86811682528516602082015273ffffffffffffffffffffffffffffffffffffffff84811660408301528316606082015260a0608082018190526000906110fe90830184615857565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715615c3057615c30615ebe565b604052919050565b600067ffffffffffffffff821115615c5257615c52615ebe565b5060051b60200190565b600061ffff808316818516808303821115615c7957615c79615e31565b01949350505050565b60008219821115615c9557615c95615e31565b500190565b600067ffffffffffffffff808316818516808303821115615c7957615c79615e31565b60006bffffffffffffffffffffffff808316818516808303821115615c7957615c79615e31565b60006bffffffffffffffffffffffff80831681851681830481118215151615615d0f57615d0f615e31565b02949350505050565b600082821015615d2a57615d2a615e31565b500390565b60006bffffffffffffffffffffffff83811690831681811015615d5457615d54615e31565b039392505050565b600181811c90821680615d7057607f821691505b60208210811415615daa577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415615de257615de2615e31565b5060010190565b600067ffffffffffffffff80831681811415615e0757615e07615e31565b6001019392505050565b600060ff821660ff811415615e2857615e28615e31565b60010192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff81168114612d3c57600080fd5b8015158114612d3c57600080fd5b6bffffffffffffffffffffffff81168114612d3c57600080fdfea164736f6c6343000806000a", -} - -var FunctionsRouterABI = FunctionsRouterMetaData.ABI - -var FunctionsRouterBin = FunctionsRouterMetaData.Bin - -func DeployFunctionsRouter(auth *bind.TransactOpts, backend bind.ContractBackend, timelockBlocks uint16, maximumTimelockBlocks uint16, linkToken common.Address, config []byte) (common.Address, *types.Transaction, *FunctionsRouter, error) { - parsed, err := FunctionsRouterMetaData.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(FunctionsRouterBin), backend, timelockBlocks, maximumTimelockBlocks, linkToken, config) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &FunctionsRouter{FunctionsRouterCaller: FunctionsRouterCaller{contract: contract}, FunctionsRouterTransactor: FunctionsRouterTransactor{contract: contract}, FunctionsRouterFilterer: FunctionsRouterFilterer{contract: contract}}, nil -} - -type FunctionsRouter struct { - address common.Address - abi abi.ABI - FunctionsRouterCaller - FunctionsRouterTransactor - FunctionsRouterFilterer -} - -type FunctionsRouterCaller struct { - contract *bind.BoundContract -} - -type FunctionsRouterTransactor struct { - contract *bind.BoundContract -} - -type FunctionsRouterFilterer struct { - contract *bind.BoundContract -} - -type FunctionsRouterSession struct { - Contract *FunctionsRouter - CallOpts bind.CallOpts - TransactOpts bind.TransactOpts -} - -type FunctionsRouterCallerSession struct { - Contract *FunctionsRouterCaller - CallOpts bind.CallOpts -} - -type FunctionsRouterTransactorSession struct { - Contract *FunctionsRouterTransactor - TransactOpts bind.TransactOpts -} - -type FunctionsRouterRaw struct { - Contract *FunctionsRouter -} - -type FunctionsRouterCallerRaw struct { - Contract *FunctionsRouterCaller -} - -type FunctionsRouterTransactorRaw struct { - Contract *FunctionsRouterTransactor -} - -func NewFunctionsRouter(address common.Address, backend bind.ContractBackend) (*FunctionsRouter, error) { - abi, err := abi.JSON(strings.NewReader(FunctionsRouterABI)) - if err != nil { - return nil, err - } - contract, err := bindFunctionsRouter(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &FunctionsRouter{address: address, abi: abi, FunctionsRouterCaller: FunctionsRouterCaller{contract: contract}, FunctionsRouterTransactor: FunctionsRouterTransactor{contract: contract}, FunctionsRouterFilterer: FunctionsRouterFilterer{contract: contract}}, nil -} - -func NewFunctionsRouterCaller(address common.Address, caller bind.ContractCaller) (*FunctionsRouterCaller, error) { - contract, err := bindFunctionsRouter(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &FunctionsRouterCaller{contract: contract}, nil -} - -func NewFunctionsRouterTransactor(address common.Address, transactor bind.ContractTransactor) (*FunctionsRouterTransactor, error) { - contract, err := bindFunctionsRouter(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &FunctionsRouterTransactor{contract: contract}, nil -} - -func NewFunctionsRouterFilterer(address common.Address, filterer bind.ContractFilterer) (*FunctionsRouterFilterer, error) { - contract, err := bindFunctionsRouter(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &FunctionsRouterFilterer{contract: contract}, nil -} - -func bindFunctionsRouter(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := FunctionsRouterMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -func (_FunctionsRouter *FunctionsRouterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _FunctionsRouter.Contract.FunctionsRouterCaller.contract.Call(opts, result, method, params...) -} - -func (_FunctionsRouter *FunctionsRouterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsRouter.Contract.FunctionsRouterTransactor.contract.Transfer(opts) -} - -func (_FunctionsRouter *FunctionsRouterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _FunctionsRouter.Contract.FunctionsRouterTransactor.contract.Transact(opts, method, params...) -} - -func (_FunctionsRouter *FunctionsRouterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _FunctionsRouter.Contract.contract.Call(opts, result, method, params...) -} - -func (_FunctionsRouter *FunctionsRouterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsRouter.Contract.contract.Transfer(opts) -} - -func (_FunctionsRouter *FunctionsRouterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _FunctionsRouter.Contract.contract.Transact(opts, method, params...) -} - -func (_FunctionsRouter *FunctionsRouterCaller) MAXCONSUMERS(opts *bind.CallOpts) (uint16, error) { - var out []interface{} - err := _FunctionsRouter.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 (_FunctionsRouter *FunctionsRouterSession) MAXCONSUMERS() (uint16, error) { - return _FunctionsRouter.Contract.MAXCONSUMERS(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCallerSession) MAXCONSUMERS() (uint16, error) { - return _FunctionsRouter.Contract.MAXCONSUMERS(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCaller) GetAdminFee(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _FunctionsRouter.contract.Call(opts, &out, "getAdminFee") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_FunctionsRouter *FunctionsRouterSession) GetAdminFee() (*big.Int, error) { - return _FunctionsRouter.Contract.GetAdminFee(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCallerSession) GetAdminFee() (*big.Int, error) { - return _FunctionsRouter.Contract.GetAdminFee(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCaller) GetConfigHash(opts *bind.CallOpts) ([32]byte, error) { - var out []interface{} - err := _FunctionsRouter.contract.Call(opts, &out, "getConfigHash") - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -func (_FunctionsRouter *FunctionsRouterSession) GetConfigHash() ([32]byte, error) { - return _FunctionsRouter.Contract.GetConfigHash(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCallerSession) GetConfigHash() ([32]byte, error) { - return _FunctionsRouter.Contract.GetConfigHash(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCaller) GetConsumer(opts *bind.CallOpts, client common.Address, subscriptionId uint64) (GetConsumer, - - error) { - var out []interface{} - err := _FunctionsRouter.contract.Call(opts, &out, "getConsumer", client, subscriptionId) - - outstruct := new(GetConsumer) - if err != nil { - return *outstruct, err - } - - outstruct.Allowed = *abi.ConvertType(out[0], new(bool)).(*bool) - outstruct.InitiatedRequests = *abi.ConvertType(out[1], new(uint64)).(*uint64) - outstruct.CompletedRequests = *abi.ConvertType(out[2], new(uint64)).(*uint64) - - return *outstruct, err - -} - -func (_FunctionsRouter *FunctionsRouterSession) GetConsumer(client common.Address, subscriptionId uint64) (GetConsumer, - - error) { - return _FunctionsRouter.Contract.GetConsumer(&_FunctionsRouter.CallOpts, client, subscriptionId) -} - -func (_FunctionsRouter *FunctionsRouterCallerSession) GetConsumer(client common.Address, subscriptionId uint64) (GetConsumer, - - error) { - return _FunctionsRouter.Contract.GetConsumer(&_FunctionsRouter.CallOpts, client, subscriptionId) -} - -func (_FunctionsRouter *FunctionsRouterCaller) GetContractById(opts *bind.CallOpts, id [32]byte, useProposed bool) (common.Address, error) { - var out []interface{} - err := _FunctionsRouter.contract.Call(opts, &out, "getContractById", id, useProposed) - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -func (_FunctionsRouter *FunctionsRouterSession) GetContractById(id [32]byte, useProposed bool) (common.Address, error) { - return _FunctionsRouter.Contract.GetContractById(&_FunctionsRouter.CallOpts, id, useProposed) -} - -func (_FunctionsRouter *FunctionsRouterCallerSession) GetContractById(id [32]byte, useProposed bool) (common.Address, error) { - return _FunctionsRouter.Contract.GetContractById(&_FunctionsRouter.CallOpts, id, useProposed) -} - -func (_FunctionsRouter *FunctionsRouterCaller) GetContractById0(opts *bind.CallOpts, id [32]byte) (common.Address, error) { - var out []interface{} - err := _FunctionsRouter.contract.Call(opts, &out, "getContractById0", id) - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -func (_FunctionsRouter *FunctionsRouterSession) GetContractById0(id [32]byte) (common.Address, error) { - return _FunctionsRouter.Contract.GetContractById0(&_FunctionsRouter.CallOpts, id) -} - -func (_FunctionsRouter *FunctionsRouterCallerSession) GetContractById0(id [32]byte) (common.Address, error) { - return _FunctionsRouter.Contract.GetContractById0(&_FunctionsRouter.CallOpts, id) -} - -func (_FunctionsRouter *FunctionsRouterCaller) GetProposedContractSet(opts *bind.CallOpts) (*big.Int, [][32]byte, []common.Address, []common.Address, error) { - var out []interface{} - err := _FunctionsRouter.contract.Call(opts, &out, "getProposedContractSet") - - if err != nil { - return *new(*big.Int), *new([][32]byte), *new([]common.Address), *new([]common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - out1 := *abi.ConvertType(out[1], new([][32]byte)).(*[][32]byte) - out2 := *abi.ConvertType(out[2], new([]common.Address)).(*[]common.Address) - out3 := *abi.ConvertType(out[3], new([]common.Address)).(*[]common.Address) - - return out0, out1, out2, out3, err - -} - -func (_FunctionsRouter *FunctionsRouterSession) GetProposedContractSet() (*big.Int, [][32]byte, []common.Address, []common.Address, error) { - return _FunctionsRouter.Contract.GetProposedContractSet(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCallerSession) GetProposedContractSet() (*big.Int, [][32]byte, []common.Address, []common.Address, error) { - return _FunctionsRouter.Contract.GetProposedContractSet(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCaller) GetSubscription(opts *bind.CallOpts, subscriptionId uint64) (GetSubscription, - - error) { - var out []interface{} - err := _FunctionsRouter.contract.Call(opts, &out, "getSubscription", subscriptionId) - - outstruct := new(GetSubscription) - if err != nil { - return *outstruct, err - } - - outstruct.Balance = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - outstruct.BlockedBalance = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - outstruct.Owner = *abi.ConvertType(out[2], new(common.Address)).(*common.Address) - outstruct.RequestedOwner = *abi.ConvertType(out[3], new(common.Address)).(*common.Address) - outstruct.Consumers = *abi.ConvertType(out[4], new([]common.Address)).(*[]common.Address) - - return *outstruct, err - -} - -func (_FunctionsRouter *FunctionsRouterSession) GetSubscription(subscriptionId uint64) (GetSubscription, - - error) { - return _FunctionsRouter.Contract.GetSubscription(&_FunctionsRouter.CallOpts, subscriptionId) -} - -func (_FunctionsRouter *FunctionsRouterCallerSession) GetSubscription(subscriptionId uint64) (GetSubscription, - - error) { - return _FunctionsRouter.Contract.GetSubscription(&_FunctionsRouter.CallOpts, subscriptionId) -} - -func (_FunctionsRouter *FunctionsRouterCaller) GetSubscriptionCount(opts *bind.CallOpts) (uint64, error) { - var out []interface{} - err := _FunctionsRouter.contract.Call(opts, &out, "getSubscriptionCount") - - if err != nil { - return *new(uint64), err - } - - out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) - - return out0, err - -} - -func (_FunctionsRouter *FunctionsRouterSession) GetSubscriptionCount() (uint64, error) { - return _FunctionsRouter.Contract.GetSubscriptionCount(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCallerSession) GetSubscriptionCount() (uint64, error) { - return _FunctionsRouter.Contract.GetSubscriptionCount(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCaller) GetTotalBalance(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _FunctionsRouter.contract.Call(opts, &out, "getTotalBalance") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_FunctionsRouter *FunctionsRouterSession) GetTotalBalance() (*big.Int, error) { - return _FunctionsRouter.Contract.GetTotalBalance(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCallerSession) GetTotalBalance() (*big.Int, error) { - return _FunctionsRouter.Contract.GetTotalBalance(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCaller) IsPaused(opts *bind.CallOpts) (bool, error) { - var out []interface{} - err := _FunctionsRouter.contract.Call(opts, &out, "isPaused") - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -func (_FunctionsRouter *FunctionsRouterSession) IsPaused() (bool, error) { - return _FunctionsRouter.Contract.IsPaused(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCallerSession) IsPaused() (bool, error) { - return _FunctionsRouter.Contract.IsPaused(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _FunctionsRouter.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 (_FunctionsRouter *FunctionsRouterSession) Owner() (common.Address, error) { - return _FunctionsRouter.Contract.Owner(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCallerSession) Owner() (common.Address, error) { - return _FunctionsRouter.Contract.Owner(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCaller) Paused(opts *bind.CallOpts) (bool, error) { - var out []interface{} - err := _FunctionsRouter.contract.Call(opts, &out, "paused") - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -func (_FunctionsRouter *FunctionsRouterSession) Paused() (bool, error) { - return _FunctionsRouter.Contract.Paused(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCallerSession) Paused() (bool, error) { - return _FunctionsRouter.Contract.Paused(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCaller) PendingRequestExists(opts *bind.CallOpts, subscriptionId uint64) (bool, error) { - var out []interface{} - err := _FunctionsRouter.contract.Call(opts, &out, "pendingRequestExists", subscriptionId) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -func (_FunctionsRouter *FunctionsRouterSession) PendingRequestExists(subscriptionId uint64) (bool, error) { - return _FunctionsRouter.Contract.PendingRequestExists(&_FunctionsRouter.CallOpts, subscriptionId) -} - -func (_FunctionsRouter *FunctionsRouterCallerSession) PendingRequestExists(subscriptionId uint64) (bool, error) { - return _FunctionsRouter.Contract.PendingRequestExists(&_FunctionsRouter.CallOpts, subscriptionId) -} - -func (_FunctionsRouter *FunctionsRouterCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { - var out []interface{} - err := _FunctionsRouter.contract.Call(opts, &out, "typeAndVersion") - - if err != nil { - return *new(string), err - } - - out0 := *abi.ConvertType(out[0], new(string)).(*string) - - return out0, err - -} - -func (_FunctionsRouter *FunctionsRouterSession) TypeAndVersion() (string, error) { - return _FunctionsRouter.Contract.TypeAndVersion(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCallerSession) TypeAndVersion() (string, error) { - return _FunctionsRouter.Contract.TypeAndVersion(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCaller) Version(opts *bind.CallOpts) (uint16, uint16, uint16, error) { - var out []interface{} - err := _FunctionsRouter.contract.Call(opts, &out, "version") - - if err != nil { - return *new(uint16), *new(uint16), *new(uint16), err - } - - out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) - out1 := *abi.ConvertType(out[1], new(uint16)).(*uint16) - out2 := *abi.ConvertType(out[2], new(uint16)).(*uint16) - - return out0, out1, out2, err - -} - -func (_FunctionsRouter *FunctionsRouterSession) Version() (uint16, uint16, uint16, error) { - return _FunctionsRouter.Contract.Version(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterCallerSession) Version() (uint16, uint16, uint16, error) { - return _FunctionsRouter.Contract.Version(&_FunctionsRouter.CallOpts) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "acceptOwnership") -} - -func (_FunctionsRouter *FunctionsRouterSession) AcceptOwnership() (*types.Transaction, error) { - return _FunctionsRouter.Contract.AcceptOwnership(&_FunctionsRouter.TransactOpts) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) AcceptOwnership() (*types.Transaction, error) { - return _FunctionsRouter.Contract.AcceptOwnership(&_FunctionsRouter.TransactOpts) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) AcceptSubscriptionOwnerTransfer(opts *bind.TransactOpts, subscriptionId uint64) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "acceptSubscriptionOwnerTransfer", subscriptionId) -} - -func (_FunctionsRouter *FunctionsRouterSession) AcceptSubscriptionOwnerTransfer(subscriptionId uint64) (*types.Transaction, error) { - return _FunctionsRouter.Contract.AcceptSubscriptionOwnerTransfer(&_FunctionsRouter.TransactOpts, subscriptionId) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) AcceptSubscriptionOwnerTransfer(subscriptionId uint64) (*types.Transaction, error) { - return _FunctionsRouter.Contract.AcceptSubscriptionOwnerTransfer(&_FunctionsRouter.TransactOpts, subscriptionId) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) AddConsumer(opts *bind.TransactOpts, subscriptionId uint64, consumer common.Address) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "addConsumer", subscriptionId, consumer) -} - -func (_FunctionsRouter *FunctionsRouterSession) AddConsumer(subscriptionId uint64, consumer common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.AddConsumer(&_FunctionsRouter.TransactOpts, subscriptionId, consumer) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) AddConsumer(subscriptionId uint64, consumer common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.AddConsumer(&_FunctionsRouter.TransactOpts, subscriptionId, consumer) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) CancelSubscription(opts *bind.TransactOpts, subscriptionId uint64, to common.Address) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "cancelSubscription", subscriptionId, to) -} - -func (_FunctionsRouter *FunctionsRouterSession) CancelSubscription(subscriptionId uint64, to common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.CancelSubscription(&_FunctionsRouter.TransactOpts, subscriptionId, to) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) CancelSubscription(subscriptionId uint64, to common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.CancelSubscription(&_FunctionsRouter.TransactOpts, subscriptionId, to) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "createSubscription") -} - -func (_FunctionsRouter *FunctionsRouterSession) CreateSubscription() (*types.Transaction, error) { - return _FunctionsRouter.Contract.CreateSubscription(&_FunctionsRouter.TransactOpts) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) CreateSubscription() (*types.Transaction, error) { - return _FunctionsRouter.Contract.CreateSubscription(&_FunctionsRouter.TransactOpts) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) Fulfill(opts *bind.TransactOpts, requestId [32]byte, response []byte, err []byte, juelsPerGas *big.Int, costWithoutFulfillment *big.Int, transmitter common.Address) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "fulfill", requestId, response, err, juelsPerGas, costWithoutFulfillment, transmitter) -} - -func (_FunctionsRouter *FunctionsRouterSession) Fulfill(requestId [32]byte, response []byte, err []byte, juelsPerGas *big.Int, costWithoutFulfillment *big.Int, transmitter common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.Fulfill(&_FunctionsRouter.TransactOpts, requestId, response, err, juelsPerGas, costWithoutFulfillment, transmitter) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) Fulfill(requestId [32]byte, response []byte, err []byte, juelsPerGas *big.Int, costWithoutFulfillment *big.Int, transmitter common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.Fulfill(&_FunctionsRouter.TransactOpts, requestId, response, err, juelsPerGas, costWithoutFulfillment, transmitter) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) OnTokenTransfer(opts *bind.TransactOpts, arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "onTokenTransfer", arg0, amount, data) -} - -func (_FunctionsRouter *FunctionsRouterSession) OnTokenTransfer(arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { - return _FunctionsRouter.Contract.OnTokenTransfer(&_FunctionsRouter.TransactOpts, arg0, amount, data) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) OnTokenTransfer(arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { - return _FunctionsRouter.Contract.OnTokenTransfer(&_FunctionsRouter.TransactOpts, arg0, amount, data) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) OracleWithdraw(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "oracleWithdraw", recipient, amount) -} - -func (_FunctionsRouter *FunctionsRouterSession) OracleWithdraw(recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _FunctionsRouter.Contract.OracleWithdraw(&_FunctionsRouter.TransactOpts, recipient, amount) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) OracleWithdraw(recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _FunctionsRouter.Contract.OracleWithdraw(&_FunctionsRouter.TransactOpts, recipient, amount) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) OwnerCancelSubscription(opts *bind.TransactOpts, subscriptionId uint64) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "ownerCancelSubscription", subscriptionId) -} - -func (_FunctionsRouter *FunctionsRouterSession) OwnerCancelSubscription(subscriptionId uint64) (*types.Transaction, error) { - return _FunctionsRouter.Contract.OwnerCancelSubscription(&_FunctionsRouter.TransactOpts, subscriptionId) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) OwnerCancelSubscription(subscriptionId uint64) (*types.Transaction, error) { - return _FunctionsRouter.Contract.OwnerCancelSubscription(&_FunctionsRouter.TransactOpts, subscriptionId) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) ProposeConfigUpdate(opts *bind.TransactOpts, id [32]byte, config []byte) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "proposeConfigUpdate", id, config) -} - -func (_FunctionsRouter *FunctionsRouterSession) ProposeConfigUpdate(id [32]byte, config []byte) (*types.Transaction, error) { - return _FunctionsRouter.Contract.ProposeConfigUpdate(&_FunctionsRouter.TransactOpts, id, config) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) ProposeConfigUpdate(id [32]byte, config []byte) (*types.Transaction, error) { - return _FunctionsRouter.Contract.ProposeConfigUpdate(&_FunctionsRouter.TransactOpts, id, config) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) ProposeContractsUpdate(opts *bind.TransactOpts, proposedContractSetIds [][32]byte, proposedContractSetFromAddresses []common.Address, proposedContractSetToAddresses []common.Address) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "proposeContractsUpdate", proposedContractSetIds, proposedContractSetFromAddresses, proposedContractSetToAddresses) -} - -func (_FunctionsRouter *FunctionsRouterSession) ProposeContractsUpdate(proposedContractSetIds [][32]byte, proposedContractSetFromAddresses []common.Address, proposedContractSetToAddresses []common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.ProposeContractsUpdate(&_FunctionsRouter.TransactOpts, proposedContractSetIds, proposedContractSetFromAddresses, proposedContractSetToAddresses) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) ProposeContractsUpdate(proposedContractSetIds [][32]byte, proposedContractSetFromAddresses []common.Address, proposedContractSetToAddresses []common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.ProposeContractsUpdate(&_FunctionsRouter.TransactOpts, proposedContractSetIds, proposedContractSetFromAddresses, proposedContractSetToAddresses) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) ProposeTimelockBlocks(opts *bind.TransactOpts, blocks uint16) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "proposeTimelockBlocks", blocks) -} - -func (_FunctionsRouter *FunctionsRouterSession) ProposeTimelockBlocks(blocks uint16) (*types.Transaction, error) { - return _FunctionsRouter.Contract.ProposeTimelockBlocks(&_FunctionsRouter.TransactOpts, blocks) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) ProposeTimelockBlocks(blocks uint16) (*types.Transaction, error) { - return _FunctionsRouter.Contract.ProposeTimelockBlocks(&_FunctionsRouter.TransactOpts, blocks) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) RecoverFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "recoverFunds", to) -} - -func (_FunctionsRouter *FunctionsRouterSession) RecoverFunds(to common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.RecoverFunds(&_FunctionsRouter.TransactOpts, to) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) RecoverFunds(to common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.RecoverFunds(&_FunctionsRouter.TransactOpts, to) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) RemoveConsumer(opts *bind.TransactOpts, subscriptionId uint64, consumer common.Address) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "removeConsumer", subscriptionId, consumer) -} - -func (_FunctionsRouter *FunctionsRouterSession) RemoveConsumer(subscriptionId uint64, consumer common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.RemoveConsumer(&_FunctionsRouter.TransactOpts, subscriptionId, consumer) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) RemoveConsumer(subscriptionId uint64, consumer common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.RemoveConsumer(&_FunctionsRouter.TransactOpts, subscriptionId, consumer) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) RequestSubscriptionOwnerTransfer(opts *bind.TransactOpts, subscriptionId uint64, newOwner common.Address) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "requestSubscriptionOwnerTransfer", subscriptionId, newOwner) -} - -func (_FunctionsRouter *FunctionsRouterSession) RequestSubscriptionOwnerTransfer(subscriptionId uint64, newOwner common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.RequestSubscriptionOwnerTransfer(&_FunctionsRouter.TransactOpts, subscriptionId, newOwner) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) RequestSubscriptionOwnerTransfer(subscriptionId uint64, newOwner common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.RequestSubscriptionOwnerTransfer(&_FunctionsRouter.TransactOpts, subscriptionId, newOwner) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) SendRequest(opts *bind.TransactOpts, subscriptionId uint64, data []byte, dataVersion uint16, callbackGasLimit uint32, donId [32]byte) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "sendRequest", subscriptionId, data, dataVersion, callbackGasLimit, donId) -} - -func (_FunctionsRouter *FunctionsRouterSession) SendRequest(subscriptionId uint64, data []byte, dataVersion uint16, callbackGasLimit uint32, donId [32]byte) (*types.Transaction, error) { - return _FunctionsRouter.Contract.SendRequest(&_FunctionsRouter.TransactOpts, subscriptionId, data, dataVersion, callbackGasLimit, donId) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) SendRequest(subscriptionId uint64, data []byte, dataVersion uint16, callbackGasLimit uint32, donId [32]byte) (*types.Transaction, error) { - return _FunctionsRouter.Contract.SendRequest(&_FunctionsRouter.TransactOpts, subscriptionId, data, dataVersion, callbackGasLimit, donId) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) TimeoutRequests(opts *bind.TransactOpts, requestIdsToTimeout [][32]byte) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "timeoutRequests", requestIdsToTimeout) -} - -func (_FunctionsRouter *FunctionsRouterSession) TimeoutRequests(requestIdsToTimeout [][32]byte) (*types.Transaction, error) { - return _FunctionsRouter.Contract.TimeoutRequests(&_FunctionsRouter.TransactOpts, requestIdsToTimeout) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) TimeoutRequests(requestIdsToTimeout [][32]byte) (*types.Transaction, error) { - return _FunctionsRouter.Contract.TimeoutRequests(&_FunctionsRouter.TransactOpts, requestIdsToTimeout) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) TogglePaused(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "togglePaused") -} - -func (_FunctionsRouter *FunctionsRouterSession) TogglePaused() (*types.Transaction, error) { - return _FunctionsRouter.Contract.TogglePaused(&_FunctionsRouter.TransactOpts) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) TogglePaused() (*types.Transaction, error) { - return _FunctionsRouter.Contract.TogglePaused(&_FunctionsRouter.TransactOpts) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "transferOwnership", to) -} - -func (_FunctionsRouter *FunctionsRouterSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.TransferOwnership(&_FunctionsRouter.TransactOpts, to) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _FunctionsRouter.Contract.TransferOwnership(&_FunctionsRouter.TransactOpts, to) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) UpdateConfig(opts *bind.TransactOpts, id [32]byte) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "updateConfig", id) -} - -func (_FunctionsRouter *FunctionsRouterSession) UpdateConfig(id [32]byte) (*types.Transaction, error) { - return _FunctionsRouter.Contract.UpdateConfig(&_FunctionsRouter.TransactOpts, id) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) UpdateConfig(id [32]byte) (*types.Transaction, error) { - return _FunctionsRouter.Contract.UpdateConfig(&_FunctionsRouter.TransactOpts, id) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) UpdateContracts(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "updateContracts") -} - -func (_FunctionsRouter *FunctionsRouterSession) UpdateContracts() (*types.Transaction, error) { - return _FunctionsRouter.Contract.UpdateContracts(&_FunctionsRouter.TransactOpts) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) UpdateContracts() (*types.Transaction, error) { - return _FunctionsRouter.Contract.UpdateContracts(&_FunctionsRouter.TransactOpts) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) UpdateTimelockBlocks(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "updateTimelockBlocks") -} - -func (_FunctionsRouter *FunctionsRouterSession) UpdateTimelockBlocks() (*types.Transaction, error) { - return _FunctionsRouter.Contract.UpdateTimelockBlocks(&_FunctionsRouter.TransactOpts) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) UpdateTimelockBlocks() (*types.Transaction, error) { - return _FunctionsRouter.Contract.UpdateTimelockBlocks(&_FunctionsRouter.TransactOpts) -} - -func (_FunctionsRouter *FunctionsRouterTransactor) ValidateProposedContracts(opts *bind.TransactOpts, id [32]byte, data []byte) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "validateProposedContracts", id, data) -} - -func (_FunctionsRouter *FunctionsRouterSession) ValidateProposedContracts(id [32]byte, data []byte) (*types.Transaction, error) { - return _FunctionsRouter.Contract.ValidateProposedContracts(&_FunctionsRouter.TransactOpts, id, data) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) ValidateProposedContracts(id [32]byte, data []byte) (*types.Transaction, error) { - return _FunctionsRouter.Contract.ValidateProposedContracts(&_FunctionsRouter.TransactOpts, id, data) -} - -type FunctionsRouterConfigProposedIterator struct { - Event *FunctionsRouterConfigProposed - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterConfigProposedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterConfigProposed) - 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(FunctionsRouterConfigProposed) - 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 *FunctionsRouterConfigProposedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterConfigProposedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterConfigProposed struct { - Id [32]byte - FromHash [32]byte - ToBytes []byte - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterConfigProposed(opts *bind.FilterOpts) (*FunctionsRouterConfigProposedIterator, error) { - - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "ConfigProposed") - if err != nil { - return nil, err - } - return &FunctionsRouterConfigProposedIterator{contract: _FunctionsRouter.contract, event: "ConfigProposed", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchConfigProposed(opts *bind.WatchOpts, sink chan<- *FunctionsRouterConfigProposed) (event.Subscription, error) { - - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "ConfigProposed") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRouterConfigProposed) - if err := _FunctionsRouter.contract.UnpackLog(event, "ConfigProposed", 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 (_FunctionsRouter *FunctionsRouterFilterer) ParseConfigProposed(log types.Log) (*FunctionsRouterConfigProposed, error) { - event := new(FunctionsRouterConfigProposed) - if err := _FunctionsRouter.contract.UnpackLog(event, "ConfigProposed", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRouterConfigSetIterator struct { - Event *FunctionsRouterConfigSet - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterConfigSetIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterConfigSet) - 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(FunctionsRouterConfigSet) - 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 *FunctionsRouterConfigSetIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterConfigSetIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterConfigSet struct { - AdminFee *big.Int - HandleOracleFulfillmentSelector [4]byte - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterConfigSet(opts *bind.FilterOpts) (*FunctionsRouterConfigSetIterator, error) { - - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "ConfigSet") - if err != nil { - return nil, err - } - return &FunctionsRouterConfigSetIterator{contract: _FunctionsRouter.contract, event: "ConfigSet", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *FunctionsRouterConfigSet) (event.Subscription, error) { - - logs, sub, err := _FunctionsRouter.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(FunctionsRouterConfigSet) - if err := _FunctionsRouter.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 (_FunctionsRouter *FunctionsRouterFilterer) ParseConfigSet(log types.Log) (*FunctionsRouterConfigSet, error) { - event := new(FunctionsRouterConfigSet) - if err := _FunctionsRouter.contract.UnpackLog(event, "ConfigSet", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRouterConfigUpdatedIterator struct { - Event *FunctionsRouterConfigUpdated - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterConfigUpdatedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterConfigUpdated) - 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(FunctionsRouterConfigUpdated) - 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 *FunctionsRouterConfigUpdatedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterConfigUpdatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterConfigUpdated struct { - Id [32]byte - FromHash [32]byte - ToBytes []byte - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterConfigUpdated(opts *bind.FilterOpts) (*FunctionsRouterConfigUpdatedIterator, error) { - - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "ConfigUpdated") - if err != nil { - return nil, err - } - return &FunctionsRouterConfigUpdatedIterator{contract: _FunctionsRouter.contract, event: "ConfigUpdated", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchConfigUpdated(opts *bind.WatchOpts, sink chan<- *FunctionsRouterConfigUpdated) (event.Subscription, error) { - - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "ConfigUpdated") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRouterConfigUpdated) - if err := _FunctionsRouter.contract.UnpackLog(event, "ConfigUpdated", 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 (_FunctionsRouter *FunctionsRouterFilterer) ParseConfigUpdated(log types.Log) (*FunctionsRouterConfigUpdated, error) { - event := new(FunctionsRouterConfigUpdated) - if err := _FunctionsRouter.contract.UnpackLog(event, "ConfigUpdated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRouterContractProposedIterator struct { - Event *FunctionsRouterContractProposed - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterContractProposedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterContractProposed) - 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(FunctionsRouterContractProposed) - 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 *FunctionsRouterContractProposedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterContractProposedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterContractProposed struct { - ProposedContractSetId [32]byte - ProposedContractSetFromAddress common.Address - ProposedContractSetToAddress common.Address - TimelockEndBlock *big.Int - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterContractProposed(opts *bind.FilterOpts) (*FunctionsRouterContractProposedIterator, error) { - - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "ContractProposed") - if err != nil { - return nil, err - } - return &FunctionsRouterContractProposedIterator{contract: _FunctionsRouter.contract, event: "ContractProposed", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchContractProposed(opts *bind.WatchOpts, sink chan<- *FunctionsRouterContractProposed) (event.Subscription, error) { - - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "ContractProposed") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRouterContractProposed) - if err := _FunctionsRouter.contract.UnpackLog(event, "ContractProposed", 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 (_FunctionsRouter *FunctionsRouterFilterer) ParseContractProposed(log types.Log) (*FunctionsRouterContractProposed, error) { - event := new(FunctionsRouterContractProposed) - if err := _FunctionsRouter.contract.UnpackLog(event, "ContractProposed", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRouterContractUpdatedIterator struct { - Event *FunctionsRouterContractUpdated - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterContractUpdatedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterContractUpdated) - 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(FunctionsRouterContractUpdated) - 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 *FunctionsRouterContractUpdatedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterContractUpdatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterContractUpdated struct { - ProposedContractSetId [32]byte - ProposedContractSetFromAddress common.Address - ProposedContractSetToAddress common.Address - Major uint16 - Minor uint16 - Patch uint16 - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterContractUpdated(opts *bind.FilterOpts) (*FunctionsRouterContractUpdatedIterator, error) { - - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "ContractUpdated") - if err != nil { - return nil, err - } - return &FunctionsRouterContractUpdatedIterator{contract: _FunctionsRouter.contract, event: "ContractUpdated", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchContractUpdated(opts *bind.WatchOpts, sink chan<- *FunctionsRouterContractUpdated) (event.Subscription, error) { - - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "ContractUpdated") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRouterContractUpdated) - if err := _FunctionsRouter.contract.UnpackLog(event, "ContractUpdated", 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 (_FunctionsRouter *FunctionsRouterFilterer) ParseContractUpdated(log types.Log) (*FunctionsRouterContractUpdated, error) { - event := new(FunctionsRouterContractUpdated) - if err := _FunctionsRouter.contract.UnpackLog(event, "ContractUpdated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRouterFundsRecoveredIterator struct { - Event *FunctionsRouterFundsRecovered - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterFundsRecoveredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterFundsRecovered) - 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(FunctionsRouterFundsRecovered) - 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 *FunctionsRouterFundsRecoveredIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterFundsRecoveredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterFundsRecovered struct { - To common.Address - Amount *big.Int - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterFundsRecovered(opts *bind.FilterOpts) (*FunctionsRouterFundsRecoveredIterator, error) { - - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "FundsRecovered") - if err != nil { - return nil, err - } - return &FunctionsRouterFundsRecoveredIterator{contract: _FunctionsRouter.contract, event: "FundsRecovered", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *FunctionsRouterFundsRecovered) (event.Subscription, error) { - - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "FundsRecovered") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRouterFundsRecovered) - if err := _FunctionsRouter.contract.UnpackLog(event, "FundsRecovered", 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 (_FunctionsRouter *FunctionsRouterFilterer) ParseFundsRecovered(log types.Log) (*FunctionsRouterFundsRecovered, error) { - event := new(FunctionsRouterFundsRecovered) - if err := _FunctionsRouter.contract.UnpackLog(event, "FundsRecovered", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRouterOwnershipTransferRequestedIterator struct { - Event *FunctionsRouterOwnershipTransferRequested - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterOwnershipTransferRequestedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterOwnershipTransferRequested) - 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(FunctionsRouterOwnershipTransferRequested) - 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 *FunctionsRouterOwnershipTransferRequestedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterOwnershipTransferRequestedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterOwnershipTransferRequested struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsRouterOwnershipTransferRequestedIterator, 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 := _FunctionsRouter.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) - if err != nil { - return nil, err - } - return &FunctionsRouterOwnershipTransferRequestedIterator{contract: _FunctionsRouter.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsRouterOwnershipTransferRequested, 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 := _FunctionsRouter.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(FunctionsRouterOwnershipTransferRequested) - if err := _FunctionsRouter.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 (_FunctionsRouter *FunctionsRouterFilterer) ParseOwnershipTransferRequested(log types.Log) (*FunctionsRouterOwnershipTransferRequested, error) { - event := new(FunctionsRouterOwnershipTransferRequested) - if err := _FunctionsRouter.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRouterOwnershipTransferredIterator struct { - Event *FunctionsRouterOwnershipTransferred - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterOwnershipTransferredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterOwnershipTransferred) - 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(FunctionsRouterOwnershipTransferred) - 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 *FunctionsRouterOwnershipTransferredIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterOwnershipTransferred struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsRouterOwnershipTransferredIterator, 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 := _FunctionsRouter.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) - if err != nil { - return nil, err - } - return &FunctionsRouterOwnershipTransferredIterator{contract: _FunctionsRouter.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *FunctionsRouterOwnershipTransferred, 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 := _FunctionsRouter.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(FunctionsRouterOwnershipTransferred) - if err := _FunctionsRouter.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 (_FunctionsRouter *FunctionsRouterFilterer) ParseOwnershipTransferred(log types.Log) (*FunctionsRouterOwnershipTransferred, error) { - event := new(FunctionsRouterOwnershipTransferred) - if err := _FunctionsRouter.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRouterPausedIterator struct { - Event *FunctionsRouterPaused - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterPausedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterPaused) - 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(FunctionsRouterPaused) - 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 *FunctionsRouterPausedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterPausedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterPaused struct { - Account common.Address - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterPaused(opts *bind.FilterOpts) (*FunctionsRouterPausedIterator, error) { - - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "Paused") - if err != nil { - return nil, err - } - return &FunctionsRouterPausedIterator{contract: _FunctionsRouter.contract, event: "Paused", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *FunctionsRouterPaused) (event.Subscription, error) { - - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "Paused") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRouterPaused) - if err := _FunctionsRouter.contract.UnpackLog(event, "Paused", 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 (_FunctionsRouter *FunctionsRouterFilterer) ParsePaused(log types.Log) (*FunctionsRouterPaused, error) { - event := new(FunctionsRouterPaused) - if err := _FunctionsRouter.contract.UnpackLog(event, "Paused", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRouterRequestEndIterator struct { - Event *FunctionsRouterRequestEnd - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterRequestEndIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterRequestEnd) - 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(FunctionsRouterRequestEnd) - 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 *FunctionsRouterRequestEndIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterRequestEndIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterRequestEnd struct { - RequestId [32]byte - SubscriptionId uint64 - TotalCostJuels *big.Int - Transmitter common.Address - ResultCode uint8 - Response []byte - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterRequestEnd(opts *bind.FilterOpts, requestId [][32]byte, subscriptionId []uint64) (*FunctionsRouterRequestEndIterator, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "RequestEnd", requestIdRule, subscriptionIdRule) - if err != nil { - return nil, err - } - return &FunctionsRouterRequestEndIterator{contract: _FunctionsRouter.contract, event: "RequestEnd", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchRequestEnd(opts *bind.WatchOpts, sink chan<- *FunctionsRouterRequestEnd, requestId [][32]byte, subscriptionId []uint64) (event.Subscription, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "RequestEnd", requestIdRule, subscriptionIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRouterRequestEnd) - if err := _FunctionsRouter.contract.UnpackLog(event, "RequestEnd", 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 (_FunctionsRouter *FunctionsRouterFilterer) ParseRequestEnd(log types.Log) (*FunctionsRouterRequestEnd, error) { - event := new(FunctionsRouterRequestEnd) - if err := _FunctionsRouter.contract.UnpackLog(event, "RequestEnd", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRouterRequestStartIterator struct { - Event *FunctionsRouterRequestStart - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterRequestStartIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterRequestStart) - 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(FunctionsRouterRequestStart) - 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 *FunctionsRouterRequestStartIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterRequestStartIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterRequestStart struct { - RequestId [32]byte - DonId [32]byte - SubscriptionId uint64 - SubscriptionOwner common.Address - RequestingContract common.Address - RequestInitiator common.Address - Data []byte - DataVersion uint16 - CallbackGasLimit uint32 - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterRequestStart(opts *bind.FilterOpts, requestId [][32]byte, donId [][32]byte, subscriptionId []uint64) (*FunctionsRouterRequestStartIterator, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - var donIdRule []interface{} - for _, donIdItem := range donId { - donIdRule = append(donIdRule, donIdItem) - } - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "RequestStart", requestIdRule, donIdRule, subscriptionIdRule) - if err != nil { - return nil, err - } - return &FunctionsRouterRequestStartIterator{contract: _FunctionsRouter.contract, event: "RequestStart", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchRequestStart(opts *bind.WatchOpts, sink chan<- *FunctionsRouterRequestStart, requestId [][32]byte, donId [][32]byte, subscriptionId []uint64) (event.Subscription, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - var donIdRule []interface{} - for _, donIdItem := range donId { - donIdRule = append(donIdRule, donIdItem) - } - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "RequestStart", requestIdRule, donIdRule, subscriptionIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRouterRequestStart) - if err := _FunctionsRouter.contract.UnpackLog(event, "RequestStart", 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 (_FunctionsRouter *FunctionsRouterFilterer) ParseRequestStart(log types.Log) (*FunctionsRouterRequestStart, error) { - event := new(FunctionsRouterRequestStart) - if err := _FunctionsRouter.contract.UnpackLog(event, "RequestStart", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRouterSubscriptionCanceledIterator struct { - Event *FunctionsRouterSubscriptionCanceled - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterSubscriptionCanceledIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterSubscriptionCanceled) - 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(FunctionsRouterSubscriptionCanceled) - 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 *FunctionsRouterSubscriptionCanceledIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterSubscriptionCanceledIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterSubscriptionCanceled struct { - SubscriptionId uint64 - FundsRecipient common.Address - FundsAmount *big.Int - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterSubscriptionCanceled(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRouterSubscriptionCanceledIterator, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "SubscriptionCanceled", subscriptionIdRule) - if err != nil { - return nil, err - } - return &FunctionsRouterSubscriptionCanceledIterator{contract: _FunctionsRouter.contract, event: "SubscriptionCanceled", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchSubscriptionCanceled(opts *bind.WatchOpts, sink chan<- *FunctionsRouterSubscriptionCanceled, subscriptionId []uint64) (event.Subscription, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "SubscriptionCanceled", subscriptionIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRouterSubscriptionCanceled) - if err := _FunctionsRouter.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 (_FunctionsRouter *FunctionsRouterFilterer) ParseSubscriptionCanceled(log types.Log) (*FunctionsRouterSubscriptionCanceled, error) { - event := new(FunctionsRouterSubscriptionCanceled) - if err := _FunctionsRouter.contract.UnpackLog(event, "SubscriptionCanceled", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRouterSubscriptionConsumerAddedIterator struct { - Event *FunctionsRouterSubscriptionConsumerAdded - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterSubscriptionConsumerAddedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterSubscriptionConsumerAdded) - 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(FunctionsRouterSubscriptionConsumerAdded) - 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 *FunctionsRouterSubscriptionConsumerAddedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterSubscriptionConsumerAddedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterSubscriptionConsumerAdded struct { - SubscriptionId uint64 - Consumer common.Address - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterSubscriptionConsumerAdded(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRouterSubscriptionConsumerAddedIterator, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "SubscriptionConsumerAdded", subscriptionIdRule) - if err != nil { - return nil, err - } - return &FunctionsRouterSubscriptionConsumerAddedIterator{contract: _FunctionsRouter.contract, event: "SubscriptionConsumerAdded", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchSubscriptionConsumerAdded(opts *bind.WatchOpts, sink chan<- *FunctionsRouterSubscriptionConsumerAdded, subscriptionId []uint64) (event.Subscription, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "SubscriptionConsumerAdded", subscriptionIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRouterSubscriptionConsumerAdded) - if err := _FunctionsRouter.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 (_FunctionsRouter *FunctionsRouterFilterer) ParseSubscriptionConsumerAdded(log types.Log) (*FunctionsRouterSubscriptionConsumerAdded, error) { - event := new(FunctionsRouterSubscriptionConsumerAdded) - if err := _FunctionsRouter.contract.UnpackLog(event, "SubscriptionConsumerAdded", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRouterSubscriptionConsumerRemovedIterator struct { - Event *FunctionsRouterSubscriptionConsumerRemoved - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterSubscriptionConsumerRemovedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterSubscriptionConsumerRemoved) - 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(FunctionsRouterSubscriptionConsumerRemoved) - 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 *FunctionsRouterSubscriptionConsumerRemovedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterSubscriptionConsumerRemovedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterSubscriptionConsumerRemoved struct { - SubscriptionId uint64 - Consumer common.Address - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterSubscriptionConsumerRemoved(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRouterSubscriptionConsumerRemovedIterator, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "SubscriptionConsumerRemoved", subscriptionIdRule) - if err != nil { - return nil, err - } - return &FunctionsRouterSubscriptionConsumerRemovedIterator{contract: _FunctionsRouter.contract, event: "SubscriptionConsumerRemoved", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchSubscriptionConsumerRemoved(opts *bind.WatchOpts, sink chan<- *FunctionsRouterSubscriptionConsumerRemoved, subscriptionId []uint64) (event.Subscription, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "SubscriptionConsumerRemoved", subscriptionIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRouterSubscriptionConsumerRemoved) - if err := _FunctionsRouter.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 (_FunctionsRouter *FunctionsRouterFilterer) ParseSubscriptionConsumerRemoved(log types.Log) (*FunctionsRouterSubscriptionConsumerRemoved, error) { - event := new(FunctionsRouterSubscriptionConsumerRemoved) - if err := _FunctionsRouter.contract.UnpackLog(event, "SubscriptionConsumerRemoved", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRouterSubscriptionCreatedIterator struct { - Event *FunctionsRouterSubscriptionCreated - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterSubscriptionCreatedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterSubscriptionCreated) - 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(FunctionsRouterSubscriptionCreated) - 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 *FunctionsRouterSubscriptionCreatedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterSubscriptionCreatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterSubscriptionCreated struct { - SubscriptionId uint64 - Owner common.Address - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterSubscriptionCreated(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRouterSubscriptionCreatedIterator, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "SubscriptionCreated", subscriptionIdRule) - if err != nil { - return nil, err - } - return &FunctionsRouterSubscriptionCreatedIterator{contract: _FunctionsRouter.contract, event: "SubscriptionCreated", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchSubscriptionCreated(opts *bind.WatchOpts, sink chan<- *FunctionsRouterSubscriptionCreated, subscriptionId []uint64) (event.Subscription, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "SubscriptionCreated", subscriptionIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRouterSubscriptionCreated) - if err := _FunctionsRouter.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 (_FunctionsRouter *FunctionsRouterFilterer) ParseSubscriptionCreated(log types.Log) (*FunctionsRouterSubscriptionCreated, error) { - event := new(FunctionsRouterSubscriptionCreated) - if err := _FunctionsRouter.contract.UnpackLog(event, "SubscriptionCreated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRouterSubscriptionFundedIterator struct { - Event *FunctionsRouterSubscriptionFunded - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterSubscriptionFundedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterSubscriptionFunded) - 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(FunctionsRouterSubscriptionFunded) - 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 *FunctionsRouterSubscriptionFundedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterSubscriptionFundedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterSubscriptionFunded struct { - SubscriptionId uint64 - OldBalance *big.Int - NewBalance *big.Int - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterSubscriptionFunded(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRouterSubscriptionFundedIterator, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "SubscriptionFunded", subscriptionIdRule) - if err != nil { - return nil, err - } - return &FunctionsRouterSubscriptionFundedIterator{contract: _FunctionsRouter.contract, event: "SubscriptionFunded", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchSubscriptionFunded(opts *bind.WatchOpts, sink chan<- *FunctionsRouterSubscriptionFunded, subscriptionId []uint64) (event.Subscription, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "SubscriptionFunded", subscriptionIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRouterSubscriptionFunded) - if err := _FunctionsRouter.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 (_FunctionsRouter *FunctionsRouterFilterer) ParseSubscriptionFunded(log types.Log) (*FunctionsRouterSubscriptionFunded, error) { - event := new(FunctionsRouterSubscriptionFunded) - if err := _FunctionsRouter.contract.UnpackLog(event, "SubscriptionFunded", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRouterSubscriptionOwnerTransferRequestedIterator struct { - Event *FunctionsRouterSubscriptionOwnerTransferRequested - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterSubscriptionOwnerTransferRequestedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterSubscriptionOwnerTransferRequested) - 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(FunctionsRouterSubscriptionOwnerTransferRequested) - 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 *FunctionsRouterSubscriptionOwnerTransferRequestedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterSubscriptionOwnerTransferRequestedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterSubscriptionOwnerTransferRequested struct { - SubscriptionId uint64 - From common.Address - To common.Address - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterSubscriptionOwnerTransferRequested(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRouterSubscriptionOwnerTransferRequestedIterator, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "SubscriptionOwnerTransferRequested", subscriptionIdRule) - if err != nil { - return nil, err - } - return &FunctionsRouterSubscriptionOwnerTransferRequestedIterator{contract: _FunctionsRouter.contract, event: "SubscriptionOwnerTransferRequested", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchSubscriptionOwnerTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsRouterSubscriptionOwnerTransferRequested, subscriptionId []uint64) (event.Subscription, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "SubscriptionOwnerTransferRequested", subscriptionIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRouterSubscriptionOwnerTransferRequested) - if err := _FunctionsRouter.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 (_FunctionsRouter *FunctionsRouterFilterer) ParseSubscriptionOwnerTransferRequested(log types.Log) (*FunctionsRouterSubscriptionOwnerTransferRequested, error) { - event := new(FunctionsRouterSubscriptionOwnerTransferRequested) - if err := _FunctionsRouter.contract.UnpackLog(event, "SubscriptionOwnerTransferRequested", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRouterSubscriptionOwnerTransferredIterator struct { - Event *FunctionsRouterSubscriptionOwnerTransferred - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterSubscriptionOwnerTransferredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterSubscriptionOwnerTransferred) - 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(FunctionsRouterSubscriptionOwnerTransferred) - 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 *FunctionsRouterSubscriptionOwnerTransferredIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterSubscriptionOwnerTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterSubscriptionOwnerTransferred struct { - SubscriptionId uint64 - From common.Address - To common.Address - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterSubscriptionOwnerTransferred(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRouterSubscriptionOwnerTransferredIterator, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "SubscriptionOwnerTransferred", subscriptionIdRule) - if err != nil { - return nil, err - } - return &FunctionsRouterSubscriptionOwnerTransferredIterator{contract: _FunctionsRouter.contract, event: "SubscriptionOwnerTransferred", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchSubscriptionOwnerTransferred(opts *bind.WatchOpts, sink chan<- *FunctionsRouterSubscriptionOwnerTransferred, subscriptionId []uint64) (event.Subscription, error) { - - var subscriptionIdRule []interface{} - for _, subscriptionIdItem := range subscriptionId { - subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem) - } - - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "SubscriptionOwnerTransferred", subscriptionIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRouterSubscriptionOwnerTransferred) - if err := _FunctionsRouter.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 (_FunctionsRouter *FunctionsRouterFilterer) ParseSubscriptionOwnerTransferred(log types.Log) (*FunctionsRouterSubscriptionOwnerTransferred, error) { - event := new(FunctionsRouterSubscriptionOwnerTransferred) - if err := _FunctionsRouter.contract.UnpackLog(event, "SubscriptionOwnerTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRouterTimeLockProposedIterator struct { - Event *FunctionsRouterTimeLockProposed - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterTimeLockProposedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterTimeLockProposed) - 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(FunctionsRouterTimeLockProposed) - 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 *FunctionsRouterTimeLockProposedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterTimeLockProposedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterTimeLockProposed struct { - From uint16 - To uint16 - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterTimeLockProposed(opts *bind.FilterOpts) (*FunctionsRouterTimeLockProposedIterator, error) { - - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "TimeLockProposed") - if err != nil { - return nil, err - } - return &FunctionsRouterTimeLockProposedIterator{contract: _FunctionsRouter.contract, event: "TimeLockProposed", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchTimeLockProposed(opts *bind.WatchOpts, sink chan<- *FunctionsRouterTimeLockProposed) (event.Subscription, error) { - - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "TimeLockProposed") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRouterTimeLockProposed) - if err := _FunctionsRouter.contract.UnpackLog(event, "TimeLockProposed", 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 (_FunctionsRouter *FunctionsRouterFilterer) ParseTimeLockProposed(log types.Log) (*FunctionsRouterTimeLockProposed, error) { - event := new(FunctionsRouterTimeLockProposed) - if err := _FunctionsRouter.contract.UnpackLog(event, "TimeLockProposed", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRouterTimeLockUpdatedIterator struct { - Event *FunctionsRouterTimeLockUpdated - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterTimeLockUpdatedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterTimeLockUpdated) - 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(FunctionsRouterTimeLockUpdated) - 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 *FunctionsRouterTimeLockUpdatedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterTimeLockUpdatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterTimeLockUpdated struct { - From uint16 - To uint16 - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterTimeLockUpdated(opts *bind.FilterOpts) (*FunctionsRouterTimeLockUpdatedIterator, error) { - - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "TimeLockUpdated") - if err != nil { - return nil, err - } - return &FunctionsRouterTimeLockUpdatedIterator{contract: _FunctionsRouter.contract, event: "TimeLockUpdated", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchTimeLockUpdated(opts *bind.WatchOpts, sink chan<- *FunctionsRouterTimeLockUpdated) (event.Subscription, error) { - - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "TimeLockUpdated") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRouterTimeLockUpdated) - if err := _FunctionsRouter.contract.UnpackLog(event, "TimeLockUpdated", 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 (_FunctionsRouter *FunctionsRouterFilterer) ParseTimeLockUpdated(log types.Log) (*FunctionsRouterTimeLockUpdated, error) { - event := new(FunctionsRouterTimeLockUpdated) - if err := _FunctionsRouter.contract.UnpackLog(event, "TimeLockUpdated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type FunctionsRouterUnpausedIterator struct { - Event *FunctionsRouterUnpaused - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *FunctionsRouterUnpausedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(FunctionsRouterUnpaused) - 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(FunctionsRouterUnpaused) - 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 *FunctionsRouterUnpausedIterator) Error() error { - return it.fail -} - -func (it *FunctionsRouterUnpausedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type FunctionsRouterUnpaused struct { - Account common.Address - Raw types.Log -} - -func (_FunctionsRouter *FunctionsRouterFilterer) FilterUnpaused(opts *bind.FilterOpts) (*FunctionsRouterUnpausedIterator, error) { - - logs, sub, err := _FunctionsRouter.contract.FilterLogs(opts, "Unpaused") - if err != nil { - return nil, err - } - return &FunctionsRouterUnpausedIterator{contract: _FunctionsRouter.contract, event: "Unpaused", logs: logs, sub: sub}, nil -} - -func (_FunctionsRouter *FunctionsRouterFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *FunctionsRouterUnpaused) (event.Subscription, error) { - - logs, sub, err := _FunctionsRouter.contract.WatchLogs(opts, "Unpaused") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(FunctionsRouterUnpaused) - if err := _FunctionsRouter.contract.UnpackLog(event, "Unpaused", 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 (_FunctionsRouter *FunctionsRouterFilterer) ParseUnpaused(log types.Log) (*FunctionsRouterUnpaused, error) { - event := new(FunctionsRouterUnpaused) - if err := _FunctionsRouter.contract.UnpackLog(event, "Unpaused", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type GetConsumer struct { - Allowed bool - InitiatedRequests uint64 - CompletedRequests uint64 -} -type GetSubscription struct { - Balance *big.Int - BlockedBalance *big.Int - Owner common.Address - RequestedOwner common.Address - Consumers []common.Address -} - -func (_FunctionsRouter *FunctionsRouter) ParseLog(log types.Log) (generated.AbigenLog, error) { - switch log.Topics[0] { - case _FunctionsRouter.abi.Events["ConfigProposed"].ID: - return _FunctionsRouter.ParseConfigProposed(log) - case _FunctionsRouter.abi.Events["ConfigSet"].ID: - return _FunctionsRouter.ParseConfigSet(log) - case _FunctionsRouter.abi.Events["ConfigUpdated"].ID: - return _FunctionsRouter.ParseConfigUpdated(log) - case _FunctionsRouter.abi.Events["ContractProposed"].ID: - return _FunctionsRouter.ParseContractProposed(log) - case _FunctionsRouter.abi.Events["ContractUpdated"].ID: - return _FunctionsRouter.ParseContractUpdated(log) - case _FunctionsRouter.abi.Events["FundsRecovered"].ID: - return _FunctionsRouter.ParseFundsRecovered(log) - case _FunctionsRouter.abi.Events["OwnershipTransferRequested"].ID: - return _FunctionsRouter.ParseOwnershipTransferRequested(log) - case _FunctionsRouter.abi.Events["OwnershipTransferred"].ID: - return _FunctionsRouter.ParseOwnershipTransferred(log) - case _FunctionsRouter.abi.Events["Paused"].ID: - return _FunctionsRouter.ParsePaused(log) - case _FunctionsRouter.abi.Events["RequestEnd"].ID: - return _FunctionsRouter.ParseRequestEnd(log) - case _FunctionsRouter.abi.Events["RequestStart"].ID: - return _FunctionsRouter.ParseRequestStart(log) - case _FunctionsRouter.abi.Events["SubscriptionCanceled"].ID: - return _FunctionsRouter.ParseSubscriptionCanceled(log) - case _FunctionsRouter.abi.Events["SubscriptionConsumerAdded"].ID: - return _FunctionsRouter.ParseSubscriptionConsumerAdded(log) - case _FunctionsRouter.abi.Events["SubscriptionConsumerRemoved"].ID: - return _FunctionsRouter.ParseSubscriptionConsumerRemoved(log) - case _FunctionsRouter.abi.Events["SubscriptionCreated"].ID: - return _FunctionsRouter.ParseSubscriptionCreated(log) - case _FunctionsRouter.abi.Events["SubscriptionFunded"].ID: - return _FunctionsRouter.ParseSubscriptionFunded(log) - case _FunctionsRouter.abi.Events["SubscriptionOwnerTransferRequested"].ID: - return _FunctionsRouter.ParseSubscriptionOwnerTransferRequested(log) - case _FunctionsRouter.abi.Events["SubscriptionOwnerTransferred"].ID: - return _FunctionsRouter.ParseSubscriptionOwnerTransferred(log) - case _FunctionsRouter.abi.Events["TimeLockProposed"].ID: - return _FunctionsRouter.ParseTimeLockProposed(log) - case _FunctionsRouter.abi.Events["TimeLockUpdated"].ID: - return _FunctionsRouter.ParseTimeLockUpdated(log) - case _FunctionsRouter.abi.Events["Unpaused"].ID: - return _FunctionsRouter.ParseUnpaused(log) - - default: - return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) - } -} - -func (FunctionsRouterConfigProposed) Topic() common.Hash { - return common.HexToHash("0x0fcfd32a68209b42944376bc5f4bf72c41ba0f378cf60434f84390b82c9844cf") -} - -func (FunctionsRouterConfigSet) Topic() common.Hash { - return common.HexToHash("0xb2b9bfb736b0bfef266985352cfca2a114226362209f5a6e5a2a2ed14383ba57") -} - -func (FunctionsRouterConfigUpdated) Topic() common.Hash { - return common.HexToHash("0xc07626096b49b0462a576c9a7878cf0675e784bb4832584c1289c11664e55f47") -} - -func (FunctionsRouterContractProposed) Topic() common.Hash { - return common.HexToHash("0x72a33d2f293a0a70fad221bb610d3d6b52aed2d840adae1fa721071fbd290cfd") -} - -func (FunctionsRouterContractUpdated) Topic() common.Hash { - return common.HexToHash("0xf17ce6b5bbeda6598ac50e505071ddbd27c188c5ecaf9126b42c951c9c4b61e9") -} - -func (FunctionsRouterFundsRecovered) Topic() common.Hash { - return common.HexToHash("0x59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600") -} - -func (FunctionsRouterOwnershipTransferRequested) Topic() common.Hash { - return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") -} - -func (FunctionsRouterOwnershipTransferred) Topic() common.Hash { - return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") -} - -func (FunctionsRouterPaused) Topic() common.Hash { - return common.HexToHash("0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258") -} - -func (FunctionsRouterRequestEnd) Topic() common.Hash { - return common.HexToHash("0x526019d853b0b88e828dbdc124746afde5a47053256d2a0872a025ab145b0520") -} - -func (FunctionsRouterRequestStart) Topic() common.Hash { - return common.HexToHash("0x7c720ccd20069b8311a6be4ba1cf3294d09eb247aa5d73a8502054b6e68a2f54") -} - -func (FunctionsRouterSubscriptionCanceled) Topic() common.Hash { - return common.HexToHash("0xe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd49815") -} - -func (FunctionsRouterSubscriptionConsumerAdded) Topic() common.Hash { - return common.HexToHash("0x43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e0") -} - -func (FunctionsRouterSubscriptionConsumerRemoved) Topic() common.Hash { - return common.HexToHash("0x182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b") -} - -func (FunctionsRouterSubscriptionCreated) Topic() common.Hash { - return common.HexToHash("0x464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf") -} - -func (FunctionsRouterSubscriptionFunded) Topic() common.Hash { - return common.HexToHash("0xd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f8") -} - -func (FunctionsRouterSubscriptionOwnerTransferRequested) Topic() common.Hash { - return common.HexToHash("0x69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be") -} - -func (FunctionsRouterSubscriptionOwnerTransferred) Topic() common.Hash { - return common.HexToHash("0x6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f0") -} - -func (FunctionsRouterTimeLockProposed) Topic() common.Hash { - return common.HexToHash("0x391ced87fc414ac6e67620b6432a8df0e27da63c8cc6782941fb535ac9e06c0a") -} - -func (FunctionsRouterTimeLockUpdated) Topic() common.Hash { - return common.HexToHash("0xbda3a518f5d5dbadc2e16a279c572f58eeddb114eb084747e012080e64c54d1d") -} - -func (FunctionsRouterUnpaused) Topic() common.Hash { - return common.HexToHash("0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa") -} - -func (_FunctionsRouter *FunctionsRouter) Address() common.Address { - return _FunctionsRouter.address -} - -type FunctionsRouterInterface interface { - MAXCONSUMERS(opts *bind.CallOpts) (uint16, error) - - GetAdminFee(opts *bind.CallOpts) (*big.Int, error) - - GetConfigHash(opts *bind.CallOpts) ([32]byte, error) - - GetConsumer(opts *bind.CallOpts, client common.Address, subscriptionId uint64) (GetConsumer, - - error) - - GetContractById(opts *bind.CallOpts, id [32]byte, useProposed bool) (common.Address, error) - - GetContractById0(opts *bind.CallOpts, id [32]byte) (common.Address, error) - - GetProposedContractSet(opts *bind.CallOpts) (*big.Int, [][32]byte, []common.Address, []common.Address, error) - - GetSubscription(opts *bind.CallOpts, subscriptionId uint64) (GetSubscription, - - error) - - GetSubscriptionCount(opts *bind.CallOpts) (uint64, error) - - GetTotalBalance(opts *bind.CallOpts) (*big.Int, error) - - IsPaused(opts *bind.CallOpts) (bool, error) - - Owner(opts *bind.CallOpts) (common.Address, error) - - Paused(opts *bind.CallOpts) (bool, error) - - PendingRequestExists(opts *bind.CallOpts, subscriptionId uint64) (bool, error) - - TypeAndVersion(opts *bind.CallOpts) (string, error) - - Version(opts *bind.CallOpts) (uint16, uint16, uint16, error) - - AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) - - AcceptSubscriptionOwnerTransfer(opts *bind.TransactOpts, subscriptionId uint64) (*types.Transaction, error) - - AddConsumer(opts *bind.TransactOpts, subscriptionId uint64, consumer common.Address) (*types.Transaction, error) - - CancelSubscription(opts *bind.TransactOpts, subscriptionId uint64, to common.Address) (*types.Transaction, error) - - CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) - - Fulfill(opts *bind.TransactOpts, requestId [32]byte, response []byte, err []byte, juelsPerGas *big.Int, costWithoutFulfillment *big.Int, transmitter common.Address) (*types.Transaction, error) - - OnTokenTransfer(opts *bind.TransactOpts, arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) - - OracleWithdraw(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) - - OwnerCancelSubscription(opts *bind.TransactOpts, subscriptionId uint64) (*types.Transaction, error) - - ProposeConfigUpdate(opts *bind.TransactOpts, id [32]byte, config []byte) (*types.Transaction, error) - - ProposeContractsUpdate(opts *bind.TransactOpts, proposedContractSetIds [][32]byte, proposedContractSetFromAddresses []common.Address, proposedContractSetToAddresses []common.Address) (*types.Transaction, error) - - ProposeTimelockBlocks(opts *bind.TransactOpts, blocks uint16) (*types.Transaction, error) - - RecoverFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) - - RemoveConsumer(opts *bind.TransactOpts, subscriptionId uint64, consumer common.Address) (*types.Transaction, error) - - RequestSubscriptionOwnerTransfer(opts *bind.TransactOpts, subscriptionId uint64, newOwner common.Address) (*types.Transaction, error) - - SendRequest(opts *bind.TransactOpts, subscriptionId uint64, data []byte, dataVersion uint16, callbackGasLimit uint32, donId [32]byte) (*types.Transaction, error) - - TimeoutRequests(opts *bind.TransactOpts, requestIdsToTimeout [][32]byte) (*types.Transaction, error) - - TogglePaused(opts *bind.TransactOpts) (*types.Transaction, error) - - TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) - - UpdateConfig(opts *bind.TransactOpts, id [32]byte) (*types.Transaction, error) - - UpdateContracts(opts *bind.TransactOpts) (*types.Transaction, error) - - UpdateTimelockBlocks(opts *bind.TransactOpts) (*types.Transaction, error) - - ValidateProposedContracts(opts *bind.TransactOpts, id [32]byte, data []byte) (*types.Transaction, error) - - FilterConfigProposed(opts *bind.FilterOpts) (*FunctionsRouterConfigProposedIterator, error) - - WatchConfigProposed(opts *bind.WatchOpts, sink chan<- *FunctionsRouterConfigProposed) (event.Subscription, error) - - ParseConfigProposed(log types.Log) (*FunctionsRouterConfigProposed, error) - - FilterConfigSet(opts *bind.FilterOpts) (*FunctionsRouterConfigSetIterator, error) - - WatchConfigSet(opts *bind.WatchOpts, sink chan<- *FunctionsRouterConfigSet) (event.Subscription, error) - - ParseConfigSet(log types.Log) (*FunctionsRouterConfigSet, error) - - FilterConfigUpdated(opts *bind.FilterOpts) (*FunctionsRouterConfigUpdatedIterator, error) - - WatchConfigUpdated(opts *bind.WatchOpts, sink chan<- *FunctionsRouterConfigUpdated) (event.Subscription, error) - - ParseConfigUpdated(log types.Log) (*FunctionsRouterConfigUpdated, error) - - FilterContractProposed(opts *bind.FilterOpts) (*FunctionsRouterContractProposedIterator, error) - - WatchContractProposed(opts *bind.WatchOpts, sink chan<- *FunctionsRouterContractProposed) (event.Subscription, error) - - ParseContractProposed(log types.Log) (*FunctionsRouterContractProposed, error) - - FilterContractUpdated(opts *bind.FilterOpts) (*FunctionsRouterContractUpdatedIterator, error) - - WatchContractUpdated(opts *bind.WatchOpts, sink chan<- *FunctionsRouterContractUpdated) (event.Subscription, error) - - ParseContractUpdated(log types.Log) (*FunctionsRouterContractUpdated, error) - - FilterFundsRecovered(opts *bind.FilterOpts) (*FunctionsRouterFundsRecoveredIterator, error) - - WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *FunctionsRouterFundsRecovered) (event.Subscription, error) - - ParseFundsRecovered(log types.Log) (*FunctionsRouterFundsRecovered, error) - - FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsRouterOwnershipTransferRequestedIterator, error) - - WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsRouterOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) - - ParseOwnershipTransferRequested(log types.Log) (*FunctionsRouterOwnershipTransferRequested, error) - - FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsRouterOwnershipTransferredIterator, error) - - WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *FunctionsRouterOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) - - ParseOwnershipTransferred(log types.Log) (*FunctionsRouterOwnershipTransferred, error) - - FilterPaused(opts *bind.FilterOpts) (*FunctionsRouterPausedIterator, error) - - WatchPaused(opts *bind.WatchOpts, sink chan<- *FunctionsRouterPaused) (event.Subscription, error) - - ParsePaused(log types.Log) (*FunctionsRouterPaused, error) - - FilterRequestEnd(opts *bind.FilterOpts, requestId [][32]byte, subscriptionId []uint64) (*FunctionsRouterRequestEndIterator, error) - - WatchRequestEnd(opts *bind.WatchOpts, sink chan<- *FunctionsRouterRequestEnd, requestId [][32]byte, subscriptionId []uint64) (event.Subscription, error) - - ParseRequestEnd(log types.Log) (*FunctionsRouterRequestEnd, error) - - FilterRequestStart(opts *bind.FilterOpts, requestId [][32]byte, donId [][32]byte, subscriptionId []uint64) (*FunctionsRouterRequestStartIterator, error) - - WatchRequestStart(opts *bind.WatchOpts, sink chan<- *FunctionsRouterRequestStart, requestId [][32]byte, donId [][32]byte, subscriptionId []uint64) (event.Subscription, error) - - ParseRequestStart(log types.Log) (*FunctionsRouterRequestStart, error) - - FilterSubscriptionCanceled(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRouterSubscriptionCanceledIterator, error) - - WatchSubscriptionCanceled(opts *bind.WatchOpts, sink chan<- *FunctionsRouterSubscriptionCanceled, subscriptionId []uint64) (event.Subscription, error) - - ParseSubscriptionCanceled(log types.Log) (*FunctionsRouterSubscriptionCanceled, error) - - FilterSubscriptionConsumerAdded(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRouterSubscriptionConsumerAddedIterator, error) - - WatchSubscriptionConsumerAdded(opts *bind.WatchOpts, sink chan<- *FunctionsRouterSubscriptionConsumerAdded, subscriptionId []uint64) (event.Subscription, error) - - ParseSubscriptionConsumerAdded(log types.Log) (*FunctionsRouterSubscriptionConsumerAdded, error) - - FilterSubscriptionConsumerRemoved(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRouterSubscriptionConsumerRemovedIterator, error) - - WatchSubscriptionConsumerRemoved(opts *bind.WatchOpts, sink chan<- *FunctionsRouterSubscriptionConsumerRemoved, subscriptionId []uint64) (event.Subscription, error) - - ParseSubscriptionConsumerRemoved(log types.Log) (*FunctionsRouterSubscriptionConsumerRemoved, error) - - FilterSubscriptionCreated(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRouterSubscriptionCreatedIterator, error) - - WatchSubscriptionCreated(opts *bind.WatchOpts, sink chan<- *FunctionsRouterSubscriptionCreated, subscriptionId []uint64) (event.Subscription, error) - - ParseSubscriptionCreated(log types.Log) (*FunctionsRouterSubscriptionCreated, error) - - FilterSubscriptionFunded(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRouterSubscriptionFundedIterator, error) - - WatchSubscriptionFunded(opts *bind.WatchOpts, sink chan<- *FunctionsRouterSubscriptionFunded, subscriptionId []uint64) (event.Subscription, error) - - ParseSubscriptionFunded(log types.Log) (*FunctionsRouterSubscriptionFunded, error) - - FilterSubscriptionOwnerTransferRequested(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRouterSubscriptionOwnerTransferRequestedIterator, error) - - WatchSubscriptionOwnerTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsRouterSubscriptionOwnerTransferRequested, subscriptionId []uint64) (event.Subscription, error) - - ParseSubscriptionOwnerTransferRequested(log types.Log) (*FunctionsRouterSubscriptionOwnerTransferRequested, error) - - FilterSubscriptionOwnerTransferred(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsRouterSubscriptionOwnerTransferredIterator, error) - - WatchSubscriptionOwnerTransferred(opts *bind.WatchOpts, sink chan<- *FunctionsRouterSubscriptionOwnerTransferred, subscriptionId []uint64) (event.Subscription, error) - - ParseSubscriptionOwnerTransferred(log types.Log) (*FunctionsRouterSubscriptionOwnerTransferred, error) - - FilterTimeLockProposed(opts *bind.FilterOpts) (*FunctionsRouterTimeLockProposedIterator, error) - - WatchTimeLockProposed(opts *bind.WatchOpts, sink chan<- *FunctionsRouterTimeLockProposed) (event.Subscription, error) - - ParseTimeLockProposed(log types.Log) (*FunctionsRouterTimeLockProposed, error) - - FilterTimeLockUpdated(opts *bind.FilterOpts) (*FunctionsRouterTimeLockUpdatedIterator, error) - - WatchTimeLockUpdated(opts *bind.WatchOpts, sink chan<- *FunctionsRouterTimeLockUpdated) (event.Subscription, error) - - ParseTimeLockUpdated(log types.Log) (*FunctionsRouterTimeLockUpdated, error) - - FilterUnpaused(opts *bind.FilterOpts) (*FunctionsRouterUnpausedIterator, error) - - WatchUnpaused(opts *bind.WatchOpts, sink chan<- *FunctionsRouterUnpaused) (event.Subscription, error) - - ParseUnpaused(log types.Log) (*FunctionsRouterUnpaused, error) - - ParseLog(log types.Log) (generated.AbigenLog, error) - - Address() common.Address -} diff --git a/core/gethwrappers/generated/gas_wrapper_mock/gas_wrapper_mock.go b/core/gethwrappers/generated/gas_wrapper_mock/gas_wrapper_mock.go new file mode 100644 index 00000000000..b0420097b43 --- /dev/null +++ b/core/gethwrappers/generated/gas_wrapper_mock/gas_wrapper_mock.go @@ -0,0 +1,614 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package gas_wrapper_mock + +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 KeeperRegistryCheckUpkeepGasUsageWrapperMockMetaData = &bind.MetaData{ + ABI: "[{\"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\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"emitOwnershipTransferRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"emitOwnershipTransferred\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"}],\"name\":\"measureCheckGas\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_mockGas\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_mockPayload\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_mockResult\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"result\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"gas\",\"type\":\"uint256\"}],\"name\":\"setMeasureCheckGasResult\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b506106b9806100206000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c8063846811931161005b57806384681193146100d5578063b019b4e8146100f2578063b023145014610105578063f7420bc21461011a57600080fd5b80632dae06f51461008257806356343496146100975780636bf49030146100b3575b600080fd5b610095610090366004610466565b61012d565b005b6100a060025481565b6040519081526020015b60405180910390f35b6100c66100c1366004610556565b610174565b6040516100aa939291906105e4565b6000546100e29060ff1681565b60405190151581526020016100aa565b610095610100366004610433565b610227565b61010d610285565b6040516100aa919061060f565b610095610128366004610433565b610313565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016841515179055815161016c906001906020850190610371565b506002555050565b6000606060008060009054906101000a900460ff16600160025481805461019a90610629565b80601f01602080910402602001604051908101604052809291908181526020018280546101c690610629565b80156102135780601f106101e857610100808354040283529160200191610213565b820191906000526020600020905b8154815290600101906020018083116101f657829003601f168201915b505050505091509250925092509250925092565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6001805461029290610629565b80601f01602080910402602001604051908101604052809291908181526020018280546102be90610629565b801561030b5780601f106102e05761010080835404028352916020019161030b565b820191906000526020600020905b8154815290600101906020018083116102ee57829003601f168201915b505050505081565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127860405160405180910390a35050565b82805461037d90610629565b90600052602060002090601f01602090048101928261039f57600085556103e5565b82601f106103b857805160ff19168380011785556103e5565b828001600101855582156103e5579182015b828111156103e55782518255916020019190600101906103ca565b506103f19291506103f5565b5090565b5b808211156103f157600081556001016103f6565b803573ffffffffffffffffffffffffffffffffffffffff8116811461042e57600080fd5b919050565b6000806040838503121561044657600080fd5b61044f8361040a565b915061045d6020840161040a565b90509250929050565b60008060006060848603121561047b57600080fd5b8335801515811461048b57600080fd5b9250602084013567ffffffffffffffff808211156104a857600080fd5b818601915086601f8301126104bc57600080fd5b8135818111156104ce576104ce61067d565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156105145761051461067d565b8160405282815289602084870101111561052d57600080fd5b826020860160208301376000602084830101528096505050505050604084013590509250925092565b6000806040838503121561056957600080fd5b8235915061045d6020840161040a565b6000815180845260005b8181101561059f57602081850181015186830182015201610583565b818111156105b1576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b83151581526060602082015260006105ff6060830185610579565b9050826040830152949350505050565b6020815260006106226020830184610579565b9392505050565b600181811c9082168061063d57607f821691505b60208210811415610677577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", +} + +var KeeperRegistryCheckUpkeepGasUsageWrapperMockABI = KeeperRegistryCheckUpkeepGasUsageWrapperMockMetaData.ABI + +var KeeperRegistryCheckUpkeepGasUsageWrapperMockBin = KeeperRegistryCheckUpkeepGasUsageWrapperMockMetaData.Bin + +func DeployKeeperRegistryCheckUpkeepGasUsageWrapperMock(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *KeeperRegistryCheckUpkeepGasUsageWrapperMock, error) { + parsed, err := KeeperRegistryCheckUpkeepGasUsageWrapperMockMetaData.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(KeeperRegistryCheckUpkeepGasUsageWrapperMockBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &KeeperRegistryCheckUpkeepGasUsageWrapperMock{KeeperRegistryCheckUpkeepGasUsageWrapperMockCaller: KeeperRegistryCheckUpkeepGasUsageWrapperMockCaller{contract: contract}, KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactor: KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactor{contract: contract}, KeeperRegistryCheckUpkeepGasUsageWrapperMockFilterer: KeeperRegistryCheckUpkeepGasUsageWrapperMockFilterer{contract: contract}}, nil +} + +type KeeperRegistryCheckUpkeepGasUsageWrapperMock struct { + address common.Address + abi abi.ABI + KeeperRegistryCheckUpkeepGasUsageWrapperMockCaller + KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactor + KeeperRegistryCheckUpkeepGasUsageWrapperMockFilterer +} + +type KeeperRegistryCheckUpkeepGasUsageWrapperMockCaller struct { + contract *bind.BoundContract +} + +type KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactor struct { + contract *bind.BoundContract +} + +type KeeperRegistryCheckUpkeepGasUsageWrapperMockFilterer struct { + contract *bind.BoundContract +} + +type KeeperRegistryCheckUpkeepGasUsageWrapperMockSession struct { + Contract *KeeperRegistryCheckUpkeepGasUsageWrapperMock + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type KeeperRegistryCheckUpkeepGasUsageWrapperMockCallerSession struct { + Contract *KeeperRegistryCheckUpkeepGasUsageWrapperMockCaller + CallOpts bind.CallOpts +} + +type KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactorSession struct { + Contract *KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactor + TransactOpts bind.TransactOpts +} + +type KeeperRegistryCheckUpkeepGasUsageWrapperMockRaw struct { + Contract *KeeperRegistryCheckUpkeepGasUsageWrapperMock +} + +type KeeperRegistryCheckUpkeepGasUsageWrapperMockCallerRaw struct { + Contract *KeeperRegistryCheckUpkeepGasUsageWrapperMockCaller +} + +type KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactorRaw struct { + Contract *KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactor +} + +func NewKeeperRegistryCheckUpkeepGasUsageWrapperMock(address common.Address, backend bind.ContractBackend) (*KeeperRegistryCheckUpkeepGasUsageWrapperMock, error) { + abi, err := abi.JSON(strings.NewReader(KeeperRegistryCheckUpkeepGasUsageWrapperMockABI)) + if err != nil { + return nil, err + } + contract, err := bindKeeperRegistryCheckUpkeepGasUsageWrapperMock(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &KeeperRegistryCheckUpkeepGasUsageWrapperMock{address: address, abi: abi, KeeperRegistryCheckUpkeepGasUsageWrapperMockCaller: KeeperRegistryCheckUpkeepGasUsageWrapperMockCaller{contract: contract}, KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactor: KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactor{contract: contract}, KeeperRegistryCheckUpkeepGasUsageWrapperMockFilterer: KeeperRegistryCheckUpkeepGasUsageWrapperMockFilterer{contract: contract}}, nil +} + +func NewKeeperRegistryCheckUpkeepGasUsageWrapperMockCaller(address common.Address, caller bind.ContractCaller) (*KeeperRegistryCheckUpkeepGasUsageWrapperMockCaller, error) { + contract, err := bindKeeperRegistryCheckUpkeepGasUsageWrapperMock(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &KeeperRegistryCheckUpkeepGasUsageWrapperMockCaller{contract: contract}, nil +} + +func NewKeeperRegistryCheckUpkeepGasUsageWrapperMockTransactor(address common.Address, transactor bind.ContractTransactor) (*KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactor, error) { + contract, err := bindKeeperRegistryCheckUpkeepGasUsageWrapperMock(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactor{contract: contract}, nil +} + +func NewKeeperRegistryCheckUpkeepGasUsageWrapperMockFilterer(address common.Address, filterer bind.ContractFilterer) (*KeeperRegistryCheckUpkeepGasUsageWrapperMockFilterer, error) { + contract, err := bindKeeperRegistryCheckUpkeepGasUsageWrapperMock(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &KeeperRegistryCheckUpkeepGasUsageWrapperMockFilterer{contract: contract}, nil +} + +func bindKeeperRegistryCheckUpkeepGasUsageWrapperMock(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := KeeperRegistryCheckUpkeepGasUsageWrapperMockMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.Contract.KeeperRegistryCheckUpkeepGasUsageWrapperMockCaller.contract.Call(opts, result, method, params...) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.Contract.KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactor.contract.Transfer(opts) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.Contract.KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactor.contract.Transact(opts, method, params...) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.Contract.contract.Call(opts, result, method, params...) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.Contract.contract.Transfer(opts) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.Contract.contract.Transact(opts, method, params...) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockCaller) SMockGas(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _KeeperRegistryCheckUpkeepGasUsageWrapperMock.contract.Call(opts, &out, "s_mockGas") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockSession) SMockGas() (*big.Int, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.Contract.SMockGas(&_KeeperRegistryCheckUpkeepGasUsageWrapperMock.CallOpts) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockCallerSession) SMockGas() (*big.Int, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.Contract.SMockGas(&_KeeperRegistryCheckUpkeepGasUsageWrapperMock.CallOpts) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockCaller) SMockPayload(opts *bind.CallOpts) ([]byte, error) { + var out []interface{} + err := _KeeperRegistryCheckUpkeepGasUsageWrapperMock.contract.Call(opts, &out, "s_mockPayload") + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockSession) SMockPayload() ([]byte, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.Contract.SMockPayload(&_KeeperRegistryCheckUpkeepGasUsageWrapperMock.CallOpts) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockCallerSession) SMockPayload() ([]byte, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.Contract.SMockPayload(&_KeeperRegistryCheckUpkeepGasUsageWrapperMock.CallOpts) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockCaller) SMockResult(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _KeeperRegistryCheckUpkeepGasUsageWrapperMock.contract.Call(opts, &out, "s_mockResult") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockSession) SMockResult() (bool, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.Contract.SMockResult(&_KeeperRegistryCheckUpkeepGasUsageWrapperMock.CallOpts) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockCallerSession) SMockResult() (bool, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.Contract.SMockResult(&_KeeperRegistryCheckUpkeepGasUsageWrapperMock.CallOpts) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactor) EmitOwnershipTransferRequested(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.contract.Transact(opts, "emitOwnershipTransferRequested", from, to) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockSession) EmitOwnershipTransferRequested(from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.Contract.EmitOwnershipTransferRequested(&_KeeperRegistryCheckUpkeepGasUsageWrapperMock.TransactOpts, from, to) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactorSession) EmitOwnershipTransferRequested(from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.Contract.EmitOwnershipTransferRequested(&_KeeperRegistryCheckUpkeepGasUsageWrapperMock.TransactOpts, from, to) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactor) EmitOwnershipTransferred(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.contract.Transact(opts, "emitOwnershipTransferred", from, to) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockSession) EmitOwnershipTransferred(from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.Contract.EmitOwnershipTransferred(&_KeeperRegistryCheckUpkeepGasUsageWrapperMock.TransactOpts, from, to) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactorSession) EmitOwnershipTransferred(from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.Contract.EmitOwnershipTransferred(&_KeeperRegistryCheckUpkeepGasUsageWrapperMock.TransactOpts, from, to) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactor) MeasureCheckGas(opts *bind.TransactOpts, id *big.Int, from common.Address) (*types.Transaction, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.contract.Transact(opts, "measureCheckGas", id, from) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockSession) MeasureCheckGas(id *big.Int, from common.Address) (*types.Transaction, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.Contract.MeasureCheckGas(&_KeeperRegistryCheckUpkeepGasUsageWrapperMock.TransactOpts, id, from) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactorSession) MeasureCheckGas(id *big.Int, from common.Address) (*types.Transaction, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.Contract.MeasureCheckGas(&_KeeperRegistryCheckUpkeepGasUsageWrapperMock.TransactOpts, id, from) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactor) SetMeasureCheckGasResult(opts *bind.TransactOpts, result bool, payload []byte, gas *big.Int) (*types.Transaction, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.contract.Transact(opts, "setMeasureCheckGasResult", result, payload, gas) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockSession) SetMeasureCheckGasResult(result bool, payload []byte, gas *big.Int) (*types.Transaction, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.Contract.SetMeasureCheckGasResult(&_KeeperRegistryCheckUpkeepGasUsageWrapperMock.TransactOpts, result, payload, gas) +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockTransactorSession) SetMeasureCheckGasResult(result bool, payload []byte, gas *big.Int) (*types.Transaction, error) { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.Contract.SetMeasureCheckGasResult(&_KeeperRegistryCheckUpkeepGasUsageWrapperMock.TransactOpts, result, payload, gas) +} + +type KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferRequestedIterator struct { + Event *KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferRequested) + 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(KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferRequested) + 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 *KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferRequestedIterator, 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 := _KeeperRegistryCheckUpkeepGasUsageWrapperMock.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferRequestedIterator{contract: _KeeperRegistryCheckUpkeepGasUsageWrapperMock.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferRequested, 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 := _KeeperRegistryCheckUpkeepGasUsageWrapperMock.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(KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferRequested) + if err := _KeeperRegistryCheckUpkeepGasUsageWrapperMock.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 (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockFilterer) ParseOwnershipTransferRequested(log types.Log) (*KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferRequested, error) { + event := new(KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferRequested) + if err := _KeeperRegistryCheckUpkeepGasUsageWrapperMock.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferredIterator struct { + Event *KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferred) + 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(KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferred) + 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 *KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferredIterator, 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 := _KeeperRegistryCheckUpkeepGasUsageWrapperMock.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferredIterator{contract: _KeeperRegistryCheckUpkeepGasUsageWrapperMock.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferred, 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 := _KeeperRegistryCheckUpkeepGasUsageWrapperMock.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(KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferred) + if err := _KeeperRegistryCheckUpkeepGasUsageWrapperMock.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 (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMockFilterer) ParseOwnershipTransferred(log types.Log) (*KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferred, error) { + event := new(KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferred) + if err := _KeeperRegistryCheckUpkeepGasUsageWrapperMock.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMock) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _KeeperRegistryCheckUpkeepGasUsageWrapperMock.abi.Events["OwnershipTransferRequested"].ID: + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.ParseOwnershipTransferRequested(log) + case _KeeperRegistryCheckUpkeepGasUsageWrapperMock.abi.Events["OwnershipTransferred"].ID: + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.ParseOwnershipTransferred(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (_KeeperRegistryCheckUpkeepGasUsageWrapperMock *KeeperRegistryCheckUpkeepGasUsageWrapperMock) Address() common.Address { + return _KeeperRegistryCheckUpkeepGasUsageWrapperMock.address +} + +type KeeperRegistryCheckUpkeepGasUsageWrapperMockInterface interface { + SMockGas(opts *bind.CallOpts) (*big.Int, error) + + SMockPayload(opts *bind.CallOpts) ([]byte, error) + + SMockResult(opts *bind.CallOpts) (bool, error) + + EmitOwnershipTransferRequested(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) + + EmitOwnershipTransferred(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) + + MeasureCheckGas(opts *bind.TransactOpts, id *big.Int, from common.Address) (*types.Transaction, error) + + SetMeasureCheckGasResult(opts *bind.TransactOpts, result bool, payload []byte, gas *big.Int) (*types.Transaction, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*KeeperRegistryCheckUpkeepGasUsageWrapperMockOwnershipTransferred, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1/i_keeper_registry_master_wrapper_2_1.go b/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1/i_keeper_registry_master_wrapper_2_1.go index 2eb8dfa9aaa..c43f32103de 100644 --- a/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1/i_keeper_registry_master_wrapper_2_1.go +++ b/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1/i_keeper_registry_master_wrapper_2_1.go @@ -75,7 +75,7 @@ type KeeperRegistryBase21UpkeepInfo struct { } var IKeeperRegistryMasterMetaData = &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\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"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\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"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\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"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\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"upkeepTriggerID\",\"type\":\"bytes32\"}],\"name\":\"CancelledUpkeepReport\",\"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\":\"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\":\"bytes32\",\"name\":\"upkeepTriggerID\",\"type\":\"bytes32\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"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\":\"bytes32\",\"name\":\"upkeepTriggerID\",\"type\":\"bytes32\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"upkeepTriggerID\",\"type\":\"bytes32\"}],\"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\":\"bytes32\",\"name\":\"upkeepTriggerID\",\"type\":\"bytes32\"}],\"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\":\"nonpayable\",\"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\":\"nonpayable\",\"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\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"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\":\"linkNative\",\"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\":\"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\":\"linkNative\",\"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\":\"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\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCancellationDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCheckGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConditionalGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"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\":\"getLinkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkNativeFeedAddress\",\"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\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"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\":\"getMode\",\"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\":[{\"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\":\"structKeeperRegistryBase2_1.State\",\"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\":\"structKeeperRegistryBase2_1.OnchainConfig\",\"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\":\"getTransmitGasOverhead\",\"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\":\"structKeeperRegistryBase2_1.UpkeepInfo\",\"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\":\"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\":\"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\":[],\"name\":\"recoverFunds\",\"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\":\"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\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"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\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setAdminPrivilegeConfig\",\"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\":\"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\":\"structKeeperRegistryBase2_1.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"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\"},{\"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\":\"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\":[{\"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\":\"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\":\"upkeepTranscoderVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawOwnerFunds\",\"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\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"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\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"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\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"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\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"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\":\"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\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"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\":\"nonpayable\",\"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\":\"nonpayable\",\"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\":\"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\":\"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\":\"linkNative\",\"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\":\"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\":\"linkNative\",\"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\":\"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\":\"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\":[],\"name\":\"getCancellationDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConditionalGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"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\":\"getLinkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkNativeFeedAddress\",\"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\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"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\":\"getMode\",\"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\":[{\"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\":\"structKeeperRegistryBase2_1.State\",\"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\":\"structKeeperRegistryBase2_1.OnchainConfig\",\"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\":[{\"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\":\"structKeeperRegistryBase2_1.UpkeepInfo\",\"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\":[{\"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\":[{\"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\":[],\"name\":\"recoverFunds\",\"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\":\"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\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"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\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setAdminPrivilegeConfig\",\"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\":\"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\":\"structKeeperRegistryBase2_1.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"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\":[{\"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\":\"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\":\"upkeepTranscoderVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawOwnerFunds\",\"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 IKeeperRegistryMasterABI = IKeeperRegistryMasterMetaData.ABI @@ -262,31 +262,31 @@ func (_IKeeperRegistryMaster *IKeeperRegistryMasterCallerSession) GetAdminPrivil return _IKeeperRegistryMaster.Contract.GetAdminPrivilegeConfig(&_IKeeperRegistryMaster.CallOpts, admin) } -func (_IKeeperRegistryMaster *IKeeperRegistryMasterCaller) GetBalance(opts *bind.CallOpts, id *big.Int) (*big.Int, error) { +func (_IKeeperRegistryMaster *IKeeperRegistryMasterCaller) GetAutomationForwarderLogic(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _IKeeperRegistryMaster.contract.Call(opts, &out, "getBalance", id) + err := _IKeeperRegistryMaster.contract.Call(opts, &out, "getAutomationForwarderLogic") if err != nil { - return *new(*big.Int), err + return *new(common.Address), err } - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) return out0, err } -func (_IKeeperRegistryMaster *IKeeperRegistryMasterSession) GetBalance(id *big.Int) (*big.Int, error) { - return _IKeeperRegistryMaster.Contract.GetBalance(&_IKeeperRegistryMaster.CallOpts, id) +func (_IKeeperRegistryMaster *IKeeperRegistryMasterSession) GetAutomationForwarderLogic() (common.Address, error) { + return _IKeeperRegistryMaster.Contract.GetAutomationForwarderLogic(&_IKeeperRegistryMaster.CallOpts) } -func (_IKeeperRegistryMaster *IKeeperRegistryMasterCallerSession) GetBalance(id *big.Int) (*big.Int, error) { - return _IKeeperRegistryMaster.Contract.GetBalance(&_IKeeperRegistryMaster.CallOpts, id) +func (_IKeeperRegistryMaster *IKeeperRegistryMasterCallerSession) GetAutomationForwarderLogic() (common.Address, error) { + return _IKeeperRegistryMaster.Contract.GetAutomationForwarderLogic(&_IKeeperRegistryMaster.CallOpts) } -func (_IKeeperRegistryMaster *IKeeperRegistryMasterCaller) GetCancellationDelay(opts *bind.CallOpts) (*big.Int, error) { +func (_IKeeperRegistryMaster *IKeeperRegistryMasterCaller) GetBalance(opts *bind.CallOpts, id *big.Int) (*big.Int, error) { var out []interface{} - err := _IKeeperRegistryMaster.contract.Call(opts, &out, "getCancellationDelay") + err := _IKeeperRegistryMaster.contract.Call(opts, &out, "getBalance", id) if err != nil { return *new(*big.Int), err @@ -298,17 +298,17 @@ func (_IKeeperRegistryMaster *IKeeperRegistryMasterCaller) GetCancellationDelay( } -func (_IKeeperRegistryMaster *IKeeperRegistryMasterSession) GetCancellationDelay() (*big.Int, error) { - return _IKeeperRegistryMaster.Contract.GetCancellationDelay(&_IKeeperRegistryMaster.CallOpts) +func (_IKeeperRegistryMaster *IKeeperRegistryMasterSession) GetBalance(id *big.Int) (*big.Int, error) { + return _IKeeperRegistryMaster.Contract.GetBalance(&_IKeeperRegistryMaster.CallOpts, id) } -func (_IKeeperRegistryMaster *IKeeperRegistryMasterCallerSession) GetCancellationDelay() (*big.Int, error) { - return _IKeeperRegistryMaster.Contract.GetCancellationDelay(&_IKeeperRegistryMaster.CallOpts) +func (_IKeeperRegistryMaster *IKeeperRegistryMasterCallerSession) GetBalance(id *big.Int) (*big.Int, error) { + return _IKeeperRegistryMaster.Contract.GetBalance(&_IKeeperRegistryMaster.CallOpts, id) } -func (_IKeeperRegistryMaster *IKeeperRegistryMasterCaller) GetCheckGasOverhead(opts *bind.CallOpts) (*big.Int, error) { +func (_IKeeperRegistryMaster *IKeeperRegistryMasterCaller) GetCancellationDelay(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _IKeeperRegistryMaster.contract.Call(opts, &out, "getCheckGasOverhead") + err := _IKeeperRegistryMaster.contract.Call(opts, &out, "getCancellationDelay") if err != nil { return *new(*big.Int), err @@ -320,12 +320,12 @@ func (_IKeeperRegistryMaster *IKeeperRegistryMasterCaller) GetCheckGasOverhead(o } -func (_IKeeperRegistryMaster *IKeeperRegistryMasterSession) GetCheckGasOverhead() (*big.Int, error) { - return _IKeeperRegistryMaster.Contract.GetCheckGasOverhead(&_IKeeperRegistryMaster.CallOpts) +func (_IKeeperRegistryMaster *IKeeperRegistryMasterSession) GetCancellationDelay() (*big.Int, error) { + return _IKeeperRegistryMaster.Contract.GetCancellationDelay(&_IKeeperRegistryMaster.CallOpts) } -func (_IKeeperRegistryMaster *IKeeperRegistryMasterCallerSession) GetCheckGasOverhead() (*big.Int, error) { - return _IKeeperRegistryMaster.Contract.GetCheckGasOverhead(&_IKeeperRegistryMaster.CallOpts) +func (_IKeeperRegistryMaster *IKeeperRegistryMasterCallerSession) GetCancellationDelay() (*big.Int, error) { + return _IKeeperRegistryMaster.Contract.GetCancellationDelay(&_IKeeperRegistryMaster.CallOpts) } func (_IKeeperRegistryMaster *IKeeperRegistryMasterCaller) GetConditionalGasOverhead(opts *bind.CallOpts) (*big.Int, error) { @@ -677,28 +677,6 @@ func (_IKeeperRegistryMaster *IKeeperRegistryMasterCallerSession) GetState() (Ge return _IKeeperRegistryMaster.Contract.GetState(&_IKeeperRegistryMaster.CallOpts) } -func (_IKeeperRegistryMaster *IKeeperRegistryMasterCaller) GetTransmitGasOverhead(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _IKeeperRegistryMaster.contract.Call(opts, &out, "getTransmitGasOverhead") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_IKeeperRegistryMaster *IKeeperRegistryMasterSession) GetTransmitGasOverhead() (*big.Int, error) { - return _IKeeperRegistryMaster.Contract.GetTransmitGasOverhead(&_IKeeperRegistryMaster.CallOpts) -} - -func (_IKeeperRegistryMaster *IKeeperRegistryMasterCallerSession) GetTransmitGasOverhead() (*big.Int, error) { - return _IKeeperRegistryMaster.Contract.GetTransmitGasOverhead(&_IKeeperRegistryMaster.CallOpts) -} - func (_IKeeperRegistryMaster *IKeeperRegistryMasterCaller) GetTransmitterInfo(opts *bind.CallOpts, query common.Address) (GetTransmitterInfo, error) { @@ -820,6 +798,28 @@ func (_IKeeperRegistryMaster *IKeeperRegistryMasterCallerSession) GetUpkeepTrigg return _IKeeperRegistryMaster.Contract.GetUpkeepTriggerConfig(&_IKeeperRegistryMaster.CallOpts, upkeepId) } +func (_IKeeperRegistryMaster *IKeeperRegistryMasterCaller) HasDedupKey(opts *bind.CallOpts, dedupKey [32]byte) (bool, error) { + var out []interface{} + err := _IKeeperRegistryMaster.contract.Call(opts, &out, "hasDedupKey", dedupKey) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_IKeeperRegistryMaster *IKeeperRegistryMasterSession) HasDedupKey(dedupKey [32]byte) (bool, error) { + return _IKeeperRegistryMaster.Contract.HasDedupKey(&_IKeeperRegistryMaster.CallOpts, dedupKey) +} + +func (_IKeeperRegistryMaster *IKeeperRegistryMasterCallerSession) HasDedupKey(dedupKey [32]byte) (bool, error) { + return _IKeeperRegistryMaster.Contract.HasDedupKey(&_IKeeperRegistryMaster.CallOpts, dedupKey) +} + func (_IKeeperRegistryMaster *IKeeperRegistryMasterCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, error) { @@ -1042,16 +1042,16 @@ func (_IKeeperRegistryMaster *IKeeperRegistryMasterTransactorSession) CheckCallb return _IKeeperRegistryMaster.Contract.CheckCallback(&_IKeeperRegistryMaster.TransactOpts, id, values, extraData) } -func (_IKeeperRegistryMaster *IKeeperRegistryMasterTransactor) CheckUpkeep(opts *bind.TransactOpts, id *big.Int, checkData []byte) (*types.Transaction, error) { - return _IKeeperRegistryMaster.contract.Transact(opts, "checkUpkeep", id, checkData) +func (_IKeeperRegistryMaster *IKeeperRegistryMasterTransactor) CheckUpkeep(opts *bind.TransactOpts, id *big.Int, triggerData []byte) (*types.Transaction, error) { + return _IKeeperRegistryMaster.contract.Transact(opts, "checkUpkeep", id, triggerData) } -func (_IKeeperRegistryMaster *IKeeperRegistryMasterSession) CheckUpkeep(id *big.Int, checkData []byte) (*types.Transaction, error) { - return _IKeeperRegistryMaster.Contract.CheckUpkeep(&_IKeeperRegistryMaster.TransactOpts, id, checkData) +func (_IKeeperRegistryMaster *IKeeperRegistryMasterSession) CheckUpkeep(id *big.Int, triggerData []byte) (*types.Transaction, error) { + return _IKeeperRegistryMaster.Contract.CheckUpkeep(&_IKeeperRegistryMaster.TransactOpts, id, triggerData) } -func (_IKeeperRegistryMaster *IKeeperRegistryMasterTransactorSession) CheckUpkeep(id *big.Int, checkData []byte) (*types.Transaction, error) { - return _IKeeperRegistryMaster.Contract.CheckUpkeep(&_IKeeperRegistryMaster.TransactOpts, id, checkData) +func (_IKeeperRegistryMaster *IKeeperRegistryMasterTransactorSession) CheckUpkeep(id *big.Int, triggerData []byte) (*types.Transaction, error) { + return _IKeeperRegistryMaster.Contract.CheckUpkeep(&_IKeeperRegistryMaster.TransactOpts, id, triggerData) } func (_IKeeperRegistryMaster *IKeeperRegistryMasterTransactor) CheckUpkeep0(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) { @@ -1186,28 +1186,28 @@ func (_IKeeperRegistryMaster *IKeeperRegistryMasterTransactorSession) SetAdminPr return _IKeeperRegistryMaster.Contract.SetAdminPrivilegeConfig(&_IKeeperRegistryMaster.TransactOpts, admin, newPrivilegeConfig) } -func (_IKeeperRegistryMaster *IKeeperRegistryMasterTransactor) SetConfig(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig KeeperRegistryBase21OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { - return _IKeeperRegistryMaster.contract.Transact(opts, "setConfig", signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +func (_IKeeperRegistryMaster *IKeeperRegistryMasterTransactor) SetConfig(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _IKeeperRegistryMaster.contract.Transact(opts, "setConfig", signers, transmitters, f, onchainConfigBytes, offchainConfigVersion, offchainConfig) } -func (_IKeeperRegistryMaster *IKeeperRegistryMasterSession) SetConfig(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig KeeperRegistryBase21OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { - return _IKeeperRegistryMaster.Contract.SetConfig(&_IKeeperRegistryMaster.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +func (_IKeeperRegistryMaster *IKeeperRegistryMasterSession) SetConfig(signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _IKeeperRegistryMaster.Contract.SetConfig(&_IKeeperRegistryMaster.TransactOpts, signers, transmitters, f, onchainConfigBytes, offchainConfigVersion, offchainConfig) } -func (_IKeeperRegistryMaster *IKeeperRegistryMasterTransactorSession) SetConfig(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig KeeperRegistryBase21OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { - return _IKeeperRegistryMaster.Contract.SetConfig(&_IKeeperRegistryMaster.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +func (_IKeeperRegistryMaster *IKeeperRegistryMasterTransactorSession) SetConfig(signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _IKeeperRegistryMaster.Contract.SetConfig(&_IKeeperRegistryMaster.TransactOpts, signers, transmitters, f, onchainConfigBytes, offchainConfigVersion, offchainConfig) } -func (_IKeeperRegistryMaster *IKeeperRegistryMasterTransactor) SetConfig0(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { - return _IKeeperRegistryMaster.contract.Transact(opts, "setConfig0", signers, transmitters, f, onchainConfigBytes, offchainConfigVersion, offchainConfig) +func (_IKeeperRegistryMaster *IKeeperRegistryMasterTransactor) SetConfigTypeSafe(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig KeeperRegistryBase21OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _IKeeperRegistryMaster.contract.Transact(opts, "setConfigTypeSafe", signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) } -func (_IKeeperRegistryMaster *IKeeperRegistryMasterSession) SetConfig0(signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { - return _IKeeperRegistryMaster.Contract.SetConfig0(&_IKeeperRegistryMaster.TransactOpts, signers, transmitters, f, onchainConfigBytes, offchainConfigVersion, offchainConfig) +func (_IKeeperRegistryMaster *IKeeperRegistryMasterSession) SetConfigTypeSafe(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig KeeperRegistryBase21OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _IKeeperRegistryMaster.Contract.SetConfigTypeSafe(&_IKeeperRegistryMaster.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) } -func (_IKeeperRegistryMaster *IKeeperRegistryMasterTransactorSession) SetConfig0(signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { - return _IKeeperRegistryMaster.Contract.SetConfig0(&_IKeeperRegistryMaster.TransactOpts, signers, transmitters, f, onchainConfigBytes, offchainConfigVersion, offchainConfig) +func (_IKeeperRegistryMaster *IKeeperRegistryMasterTransactorSession) SetConfigTypeSafe(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig KeeperRegistryBase21OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _IKeeperRegistryMaster.Contract.SetConfigTypeSafe(&_IKeeperRegistryMaster.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) } func (_IKeeperRegistryMaster *IKeeperRegistryMasterTransactor) SetPayees(opts *bind.TransactOpts, payees []common.Address) (*types.Transaction, error) { @@ -1615,9 +1615,9 @@ func (it *IKeeperRegistryMasterCancelledUpkeepReportIterator) Close() error { } type IKeeperRegistryMasterCancelledUpkeepReport struct { - Id *big.Int - UpkeepTriggerID [32]byte - Raw types.Log + Id *big.Int + Trigger []byte + Raw types.Log } func (_IKeeperRegistryMaster *IKeeperRegistryMasterFilterer) FilterCancelledUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*IKeeperRegistryMasterCancelledUpkeepReportIterator, error) { @@ -1807,6 +1807,133 @@ func (_IKeeperRegistryMaster *IKeeperRegistryMasterFilterer) ParseConfigSet(log return event, nil } +type IKeeperRegistryMasterDedupKeyAddedIterator struct { + Event *IKeeperRegistryMasterDedupKeyAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IKeeperRegistryMasterDedupKeyAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IKeeperRegistryMasterDedupKeyAdded) + 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(IKeeperRegistryMasterDedupKeyAdded) + 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 *IKeeperRegistryMasterDedupKeyAddedIterator) Error() error { + return it.fail +} + +func (it *IKeeperRegistryMasterDedupKeyAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IKeeperRegistryMasterDedupKeyAdded struct { + DedupKey [32]byte + Raw types.Log +} + +func (_IKeeperRegistryMaster *IKeeperRegistryMasterFilterer) FilterDedupKeyAdded(opts *bind.FilterOpts, dedupKey [][32]byte) (*IKeeperRegistryMasterDedupKeyAddedIterator, error) { + + var dedupKeyRule []interface{} + for _, dedupKeyItem := range dedupKey { + dedupKeyRule = append(dedupKeyRule, dedupKeyItem) + } + + logs, sub, err := _IKeeperRegistryMaster.contract.FilterLogs(opts, "DedupKeyAdded", dedupKeyRule) + if err != nil { + return nil, err + } + return &IKeeperRegistryMasterDedupKeyAddedIterator{contract: _IKeeperRegistryMaster.contract, event: "DedupKeyAdded", logs: logs, sub: sub}, nil +} + +func (_IKeeperRegistryMaster *IKeeperRegistryMasterFilterer) WatchDedupKeyAdded(opts *bind.WatchOpts, sink chan<- *IKeeperRegistryMasterDedupKeyAdded, dedupKey [][32]byte) (event.Subscription, error) { + + var dedupKeyRule []interface{} + for _, dedupKeyItem := range dedupKey { + dedupKeyRule = append(dedupKeyRule, dedupKeyItem) + } + + logs, sub, err := _IKeeperRegistryMaster.contract.WatchLogs(opts, "DedupKeyAdded", dedupKeyRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IKeeperRegistryMasterDedupKeyAdded) + if err := _IKeeperRegistryMaster.contract.UnpackLog(event, "DedupKeyAdded", 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 (_IKeeperRegistryMaster *IKeeperRegistryMasterFilterer) ParseDedupKeyAdded(log types.Log) (*IKeeperRegistryMasterDedupKeyAdded, error) { + event := new(IKeeperRegistryMasterDedupKeyAdded) + if err := _IKeeperRegistryMaster.contract.UnpackLog(event, "DedupKeyAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type IKeeperRegistryMasterFundsAddedIterator struct { Event *IKeeperRegistryMasterFundsAdded @@ -2134,9 +2261,9 @@ func (it *IKeeperRegistryMasterInsufficientFundsUpkeepReportIterator) Close() er } type IKeeperRegistryMasterInsufficientFundsUpkeepReport struct { - Id *big.Int - UpkeepTriggerID [32]byte - Raw types.Log + Id *big.Int + Trigger []byte + Raw types.Log } func (_IKeeperRegistryMaster *IKeeperRegistryMasterFilterer) FilterInsufficientFundsUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*IKeeperRegistryMasterInsufficientFundsUpkeepReportIterator, error) { @@ -3322,9 +3449,9 @@ func (it *IKeeperRegistryMasterReorgedUpkeepReportIterator) Close() error { } type IKeeperRegistryMasterReorgedUpkeepReport struct { - Id *big.Int - UpkeepTriggerID [32]byte - Raw types.Log + Id *big.Int + Trigger []byte + Raw types.Log } func (_IKeeperRegistryMaster *IKeeperRegistryMasterFilterer) FilterReorgedUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*IKeeperRegistryMasterReorgedUpkeepReportIterator, error) { @@ -3450,9 +3577,9 @@ func (it *IKeeperRegistryMasterStaleUpkeepReportIterator) Close() error { } type IKeeperRegistryMasterStaleUpkeepReport struct { - Id *big.Int - UpkeepTriggerID [32]byte - Raw types.Log + Id *big.Int + Trigger []byte + Raw types.Log } func (_IKeeperRegistryMaster *IKeeperRegistryMasterFilterer) FilterStaleUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*IKeeperRegistryMasterStaleUpkeepReportIterator, error) { @@ -4879,13 +5006,13 @@ func (it *IKeeperRegistryMasterUpkeepPerformedIterator) Close() error { } type IKeeperRegistryMasterUpkeepPerformed struct { - Id *big.Int - Success bool - TotalPayment *big.Int - GasUsed *big.Int - GasOverhead *big.Int - UpkeepTriggerID [32]byte - Raw types.Log + Id *big.Int + Success bool + TotalPayment *big.Int + GasUsed *big.Int + GasOverhead *big.Int + Trigger []byte + Raw types.Log } func (_IKeeperRegistryMaster *IKeeperRegistryMasterFilterer) FilterUpkeepPerformed(opts *bind.FilterOpts, id []*big.Int, success []bool) (*IKeeperRegistryMasterUpkeepPerformedIterator, error) { @@ -5636,6 +5763,8 @@ func (_IKeeperRegistryMaster *IKeeperRegistryMaster) ParseLog(log types.Log) (ge return _IKeeperRegistryMaster.ParseCancelledUpkeepReport(log) case _IKeeperRegistryMaster.abi.Events["ConfigSet"].ID: return _IKeeperRegistryMaster.ParseConfigSet(log) + case _IKeeperRegistryMaster.abi.Events["DedupKeyAdded"].ID: + return _IKeeperRegistryMaster.ParseDedupKeyAdded(log) case _IKeeperRegistryMaster.abi.Events["FundsAdded"].ID: return _IKeeperRegistryMaster.ParseFundsAdded(log) case _IKeeperRegistryMaster.abi.Events["FundsWithdrawn"].ID: @@ -5705,13 +5834,17 @@ func (IKeeperRegistryMasterAdminPrivilegeConfigSet) Topic() common.Hash { } func (IKeeperRegistryMasterCancelledUpkeepReport) Topic() common.Hash { - return common.HexToHash("0x846af3fdde418e2757c00c4cf8c6827e65ac4179753128c454922ccd7963886d") + return common.HexToHash("0xc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636") } func (IKeeperRegistryMasterConfigSet) Topic() common.Hash { return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") } +func (IKeeperRegistryMasterDedupKeyAdded) Topic() common.Hash { + return common.HexToHash("0xa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f2") +} + func (IKeeperRegistryMasterFundsAdded) Topic() common.Hash { return common.HexToHash("0xafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa734891506203") } @@ -5721,7 +5854,7 @@ func (IKeeperRegistryMasterFundsWithdrawn) Topic() common.Hash { } func (IKeeperRegistryMasterInsufficientFundsUpkeepReport) Topic() common.Hash { - return common.HexToHash("0xfcb5fa059ae0ddeeac53240ccaa0a8ad80993b33e18e8821f1e1cbc53481240e") + return common.HexToHash("0x377c8b0c126ae5248d27aca1c76fac4608aff85673ee3caf09747e1044549e02") } func (IKeeperRegistryMasterOwnerFundsWithdrawn) Topic() common.Hash { @@ -5757,11 +5890,11 @@ func (IKeeperRegistryMasterPaymentWithdrawn) Topic() common.Hash { } func (IKeeperRegistryMasterReorgedUpkeepReport) Topic() common.Hash { - return common.HexToHash("0x07c4f19521a82d67071422fca888431cac8267935db8abe73e354791a3d38868") + return common.HexToHash("0x6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301") } func (IKeeperRegistryMasterStaleUpkeepReport) Topic() common.Hash { - return common.HexToHash("0x909d8c7e883c6d2d53a5fb2dbb9ec57875a53c3769c099230027312ffb2a6b11") + return common.HexToHash("0x405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8") } func (IKeeperRegistryMasterTransmitted) Topic() common.Hash { @@ -5805,7 +5938,7 @@ func (IKeeperRegistryMasterUpkeepPaused) Topic() common.Hash { } func (IKeeperRegistryMasterUpkeepPerformed) Topic() common.Hash { - return common.HexToHash("0xdacc0b3d36199a5f78afb27c76cd01bf100f605edf5ee0c0e23055b0553b68c6") + return common.HexToHash("0xad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b") } func (IKeeperRegistryMasterUpkeepPrivilegeConfigSet) Topic() common.Hash { @@ -5839,12 +5972,12 @@ type IKeeperRegistryMasterInterface interface { GetAdminPrivilegeConfig(opts *bind.CallOpts, admin common.Address) ([]byte, error) + GetAutomationForwarderLogic(opts *bind.CallOpts) (common.Address, error) + GetBalance(opts *bind.CallOpts, id *big.Int) (*big.Int, error) GetCancellationDelay(opts *bind.CallOpts) (*big.Int, error) - GetCheckGasOverhead(opts *bind.CallOpts) (*big.Int, error) - GetConditionalGasOverhead(opts *bind.CallOpts) (*big.Int, error) GetFastGasFeedAddress(opts *bind.CallOpts) (common.Address, error) @@ -5879,8 +6012,6 @@ type IKeeperRegistryMasterInterface interface { error) - GetTransmitGasOverhead(opts *bind.CallOpts) (*big.Int, error) - GetTransmitterInfo(opts *bind.CallOpts, query common.Address) (GetTransmitterInfo, error) @@ -5893,6 +6024,8 @@ type IKeeperRegistryMasterInterface interface { GetUpkeepTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) + HasDedupKey(opts *bind.CallOpts, dedupKey [32]byte) (bool, error) + LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, error) @@ -5921,7 +6054,7 @@ type IKeeperRegistryMasterInterface interface { CheckCallback(opts *bind.TransactOpts, id *big.Int, values [][]byte, extraData []byte) (*types.Transaction, error) - CheckUpkeep(opts *bind.TransactOpts, id *big.Int, checkData []byte) (*types.Transaction, error) + CheckUpkeep(opts *bind.TransactOpts, id *big.Int, triggerData []byte) (*types.Transaction, error) CheckUpkeep0(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) @@ -5945,9 +6078,9 @@ type IKeeperRegistryMasterInterface interface { SetAdminPrivilegeConfig(opts *bind.TransactOpts, admin common.Address, newPrivilegeConfig []byte) (*types.Transaction, error) - SetConfig(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig KeeperRegistryBase21OnchainConfig, offchainConfigVersion uint64, offchainConfig []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) - SetConfig0(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) + SetConfigTypeSafe(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig KeeperRegistryBase21OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) SetPayees(opts *bind.TransactOpts, payees []common.Address) (*types.Transaction, error) @@ -6003,6 +6136,12 @@ type IKeeperRegistryMasterInterface interface { ParseConfigSet(log types.Log) (*IKeeperRegistryMasterConfigSet, error) + FilterDedupKeyAdded(opts *bind.FilterOpts, dedupKey [][32]byte) (*IKeeperRegistryMasterDedupKeyAddedIterator, error) + + WatchDedupKeyAdded(opts *bind.WatchOpts, sink chan<- *IKeeperRegistryMasterDedupKeyAdded, dedupKey [][32]byte) (event.Subscription, error) + + ParseDedupKeyAdded(log types.Log) (*IKeeperRegistryMasterDedupKeyAdded, error) + FilterFundsAdded(opts *bind.FilterOpts, id []*big.Int, from []common.Address) (*IKeeperRegistryMasterFundsAddedIterator, error) WatchFundsAdded(opts *bind.WatchOpts, sink chan<- *IKeeperRegistryMasterFundsAdded, id []*big.Int, from []common.Address) (event.Subscription, error) diff --git a/core/gethwrappers/generated/i_log_automation/i_log_automation.go b/core/gethwrappers/generated/i_log_automation/i_log_automation.go index fda92f01c40..122c7f2ce7d 100644 --- a/core/gethwrappers/generated/i_log_automation/i_log_automation.go +++ b/core/gethwrappers/generated/i_log_automation/i_log_automation.go @@ -40,7 +40,7 @@ type Log struct { } var ILogAutomationMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"txIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"log\",\"type\":\"tuple\"}],\"name\":\"checkLog\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"txIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"log\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"}],\"name\":\"checkLog\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", } var ILogAutomationABI = ILogAutomationMetaData.ABI @@ -161,16 +161,16 @@ func (_ILogAutomation *ILogAutomationTransactorRaw) Transact(opts *bind.Transact return _ILogAutomation.Contract.contract.Transact(opts, method, params...) } -func (_ILogAutomation *ILogAutomationTransactor) CheckLog(opts *bind.TransactOpts, log Log) (*types.Transaction, error) { - return _ILogAutomation.contract.Transact(opts, "checkLog", log) +func (_ILogAutomation *ILogAutomationTransactor) CheckLog(opts *bind.TransactOpts, log Log, checkData []byte) (*types.Transaction, error) { + return _ILogAutomation.contract.Transact(opts, "checkLog", log, checkData) } -func (_ILogAutomation *ILogAutomationSession) CheckLog(log Log) (*types.Transaction, error) { - return _ILogAutomation.Contract.CheckLog(&_ILogAutomation.TransactOpts, log) +func (_ILogAutomation *ILogAutomationSession) CheckLog(log Log, checkData []byte) (*types.Transaction, error) { + return _ILogAutomation.Contract.CheckLog(&_ILogAutomation.TransactOpts, log, checkData) } -func (_ILogAutomation *ILogAutomationTransactorSession) CheckLog(log Log) (*types.Transaction, error) { - return _ILogAutomation.Contract.CheckLog(&_ILogAutomation.TransactOpts, log) +func (_ILogAutomation *ILogAutomationTransactorSession) CheckLog(log Log, checkData []byte) (*types.Transaction, error) { + return _ILogAutomation.Contract.CheckLog(&_ILogAutomation.TransactOpts, log, checkData) } func (_ILogAutomation *ILogAutomationTransactor) PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error) { @@ -190,7 +190,7 @@ func (_ILogAutomation *ILogAutomation) Address() common.Address { } type ILogAutomationInterface interface { - CheckLog(opts *bind.TransactOpts, log Log) (*types.Transaction, error) + CheckLog(opts *bind.TransactOpts, log Log, checkData []byte) (*types.Transaction, error) PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error) diff --git a/core/gethwrappers/generated/keeper_registrar_wrapper1_2_mock/keeper_registrar_wrapper1_2_mock.go b/core/gethwrappers/generated/keeper_registrar_wrapper1_2_mock/keeper_registrar_wrapper1_2_mock.go new file mode 100644 index 00000000000..ea4c49f7c88 --- /dev/null +++ b/core/gethwrappers/generated/keeper_registrar_wrapper1_2_mock/keeper_registrar_wrapper1_2_mock.go @@ -0,0 +1,1492 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package keeper_registrar_wrapper1_2_mock + +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 KeeperRegistrarMockMetaData = &bind.MetaData{ + ABI: "[{\"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\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"autoApproveConfigType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"keeperRegistry\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"minLINKJuels\",\"type\":\"uint96\"}],\"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\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"source\",\"type\":\"uint8\"}],\"name\":\"RegistrationRequested\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"emitAutoApproveAllowedSenderSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"autoApproveConfigType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"keeperRegistry\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"minLINKJuels\",\"type\":\"uint96\"}],\"name\":\"emitConfigChanged\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"emitOwnershipTransferRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"emitOwnershipTransferred\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"displayName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"emitRegistrationApproved\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"emitRegistrationRejected\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedEmail\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint8\",\"name\":\"source\",\"type\":\"uint8\"}],\"name\":\"emitRegistrationRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRegistrationConfig\",\"outputs\":[{\"internalType\":\"enumKeeperRegistrar1_2Mock.AutoApproveType\",\"name\":\"autoApproveConfigType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"approvedCount\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"keeperRegistry\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minLINKJuels\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_approvedCount\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_autoApproveConfigType\",\"outputs\":[{\"internalType\":\"enumKeeperRegistrar1_2Mock.AutoApproveType\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_autoApproveMaxAllowed\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_keeperRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_minLINKJuels\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enumKeeperRegistrar1_2Mock.AutoApproveType\",\"name\":\"_autoApproveConfigType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"_autoApproveMaxAllowed\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_approvedCount\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_keeperRegistry\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_minLINKJuels\",\"type\":\"uint256\"}],\"name\":\"setRegistrationConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50610ba0806100206000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063aee052f31161008c578063b59d75eb11610066578063b59d75eb14610259578063bb98fe561461026c578063ca40bcd314610285578063f7420bc21461029857600080fd5b8063aee052f314610220578063b019b4e814610233578063b49fd35b1461024657600080fd5b806384638bb6116100c857806384638bb61461014a578063850af0cb146101645780639e105f95146101bb578063adeab0b71461020d57600080fd5b80631701f938146100ef5780634882b5bd1461010457806355e8b24814610120575b600080fd5b6101026100fd36600461093a565b6102ab565b005b61010d60015481565b6040519081526020015b60405180910390f35b60005461013590610100900463ffffffff1681565b60405163ffffffff9091168152602001610117565b6000546101579060ff1681565b6040516101179190610a34565b6000546001546040516101179260ff811692610100820463ffffffff90811693650100000000008404909116926901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff169190610a48565b6000546101e8906901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610117565b61010261021b366004610789565b610322565b61010261022e366004610888565b610350565b61010261024136600461071a565b61038e565b6101026102543660046108d8565b6103ec565b6101026102673660046107a2565b6104e9565b6000546101359065010000000000900463ffffffff1681565b61010261029336600461074d565b610551565b6101026102a636600461071a565b6105a7565b6040805160ff8616815263ffffffff8516602082015273ffffffffffffffffffffffffffffffffffffffff8416818301526bffffffffffffffffffffffff8316606082015290517f6293a703ec7145dfa23c5cde2e627d6a02e153fc2e9c03b14d1e22cbb4a7e9cd9181900360800190a150505050565b60405181907f3663fb28ebc87645eb972c9dad8521bf665c623f287e79f1c56f1eb374b82a2290600090a250565b80837fb9a292fb7e3edd920cd2d2829a3615a640c43fd7de0a0820aa0668feb4c37d4b846040516103819190610a98565b60405180910390a3505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080548691907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600183600281111561042957610429610b35565b0217905550600080547fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff1661010063ffffffff968716027fffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffff1617650100000000009490951693909302939093177fffffff0000000000000000000000000000000000000000ffffffffffffffffff16690100000000000000000073ffffffffffffffffffffffffffffffffffffffff929092169190910217905560015550565b8060ff168673ffffffffffffffffffffffffffffffffffffffff168a7fc3f5df4aefec026f610a3fcb08f19476492d69d2cb78b1c2eba259a8820e6a788b8b8a8a8a8a60405161053e96959493929190610ab2565b60405180910390a4505050505050505050565b8173ffffffffffffffffffffffffffffffffffffffff167f20c6237dac83526a849285a9f79d08a483291bdd3a056a0ef9ae94ecee1ad3568260405161059b911515815260200190565b60405180910390a25050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127860405160405180910390a35050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461062957600080fd5b919050565b600082601f83011261063f57600080fd5b813567ffffffffffffffff8082111561065a5761065a610b64565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156106a0576106a0610b64565b816040528381528660208588010111156106b957600080fd5b836020870160208301376000602085830101528094505050505092915050565b803563ffffffff8116811461062957600080fd5b803560ff8116811461062957600080fd5b80356bffffffffffffffffffffffff8116811461062957600080fd5b6000806040838503121561072d57600080fd5b61073683610605565b915061074460208401610605565b90509250929050565b6000806040838503121561076057600080fd5b61076983610605565b91506020830135801515811461077e57600080fd5b809150509250929050565b60006020828403121561079b57600080fd5b5035919050565b60008060008060008060008060006101208a8c0312156107c157600080fd5b8935985060208a013567ffffffffffffffff808211156107e057600080fd5b6107ec8d838e0161062e565b995060408c013591508082111561080257600080fd5b61080e8d838e0161062e565b985061081c60608d01610605565b975061082a60808d016106d9565b965061083860a08d01610605565b955060c08c013591508082111561084e57600080fd5b5061085b8c828d0161062e565b93505061086a60e08b016106fe565b91506108796101008b016106ed565b90509295985092959850929598565b60008060006060848603121561089d57600080fd5b83359250602084013567ffffffffffffffff8111156108bb57600080fd5b6108c78682870161062e565b925050604084013590509250925092565b600080600080600060a086880312156108f057600080fd5b8535600381106108ff57600080fd5b945061090d602087016106d9565b935061091b604087016106d9565b925061092960608701610605565b949793965091946080013592915050565b6000806000806080858703121561095057600080fd5b610959856106ed565b9350610967602086016106d9565b925061097560408601610605565b9150610983606086016106fe565b905092959194509250565b6000815180845260005b818110156109b457602081850181015186830182015201610998565b818111156109c6576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60038110610a30577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b60208101610a4282846109f9565b92915050565b60a08101610a5682886109f9565b63ffffffff808716602084015280861660408401525073ffffffffffffffffffffffffffffffffffffffff841660608301528260808301529695505050505050565b602081526000610aab602083018461098e565b9392505050565b60c081526000610ac560c083018961098e565b8281036020840152610ad7818961098e565b905063ffffffff8716604084015273ffffffffffffffffffffffffffffffffffffffff861660608401528281036080840152610b13818661098e565b9150506bffffffffffffffffffffffff831660a0830152979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", +} + +var KeeperRegistrarMockABI = KeeperRegistrarMockMetaData.ABI + +var KeeperRegistrarMockBin = KeeperRegistrarMockMetaData.Bin + +func DeployKeeperRegistrarMock(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *KeeperRegistrarMock, error) { + parsed, err := KeeperRegistrarMockMetaData.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(KeeperRegistrarMockBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &KeeperRegistrarMock{KeeperRegistrarMockCaller: KeeperRegistrarMockCaller{contract: contract}, KeeperRegistrarMockTransactor: KeeperRegistrarMockTransactor{contract: contract}, KeeperRegistrarMockFilterer: KeeperRegistrarMockFilterer{contract: contract}}, nil +} + +type KeeperRegistrarMock struct { + address common.Address + abi abi.ABI + KeeperRegistrarMockCaller + KeeperRegistrarMockTransactor + KeeperRegistrarMockFilterer +} + +type KeeperRegistrarMockCaller struct { + contract *bind.BoundContract +} + +type KeeperRegistrarMockTransactor struct { + contract *bind.BoundContract +} + +type KeeperRegistrarMockFilterer struct { + contract *bind.BoundContract +} + +type KeeperRegistrarMockSession struct { + Contract *KeeperRegistrarMock + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type KeeperRegistrarMockCallerSession struct { + Contract *KeeperRegistrarMockCaller + CallOpts bind.CallOpts +} + +type KeeperRegistrarMockTransactorSession struct { + Contract *KeeperRegistrarMockTransactor + TransactOpts bind.TransactOpts +} + +type KeeperRegistrarMockRaw struct { + Contract *KeeperRegistrarMock +} + +type KeeperRegistrarMockCallerRaw struct { + Contract *KeeperRegistrarMockCaller +} + +type KeeperRegistrarMockTransactorRaw struct { + Contract *KeeperRegistrarMockTransactor +} + +func NewKeeperRegistrarMock(address common.Address, backend bind.ContractBackend) (*KeeperRegistrarMock, error) { + abi, err := abi.JSON(strings.NewReader(KeeperRegistrarMockABI)) + if err != nil { + return nil, err + } + contract, err := bindKeeperRegistrarMock(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &KeeperRegistrarMock{address: address, abi: abi, KeeperRegistrarMockCaller: KeeperRegistrarMockCaller{contract: contract}, KeeperRegistrarMockTransactor: KeeperRegistrarMockTransactor{contract: contract}, KeeperRegistrarMockFilterer: KeeperRegistrarMockFilterer{contract: contract}}, nil +} + +func NewKeeperRegistrarMockCaller(address common.Address, caller bind.ContractCaller) (*KeeperRegistrarMockCaller, error) { + contract, err := bindKeeperRegistrarMock(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &KeeperRegistrarMockCaller{contract: contract}, nil +} + +func NewKeeperRegistrarMockTransactor(address common.Address, transactor bind.ContractTransactor) (*KeeperRegistrarMockTransactor, error) { + contract, err := bindKeeperRegistrarMock(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &KeeperRegistrarMockTransactor{contract: contract}, nil +} + +func NewKeeperRegistrarMockFilterer(address common.Address, filterer bind.ContractFilterer) (*KeeperRegistrarMockFilterer, error) { + contract, err := bindKeeperRegistrarMock(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &KeeperRegistrarMockFilterer{contract: contract}, nil +} + +func bindKeeperRegistrarMock(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := KeeperRegistrarMockMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _KeeperRegistrarMock.Contract.KeeperRegistrarMockCaller.contract.Call(opts, result, method, params...) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _KeeperRegistrarMock.Contract.KeeperRegistrarMockTransactor.contract.Transfer(opts) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _KeeperRegistrarMock.Contract.KeeperRegistrarMockTransactor.contract.Transact(opts, method, params...) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _KeeperRegistrarMock.Contract.contract.Call(opts, result, method, params...) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _KeeperRegistrarMock.Contract.contract.Transfer(opts) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _KeeperRegistrarMock.Contract.contract.Transact(opts, method, params...) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockCaller) GetRegistrationConfig(opts *bind.CallOpts) (GetRegistrationConfig, + + error) { + var out []interface{} + err := _KeeperRegistrarMock.contract.Call(opts, &out, "getRegistrationConfig") + + outstruct := new(GetRegistrationConfig) + if err != nil { + return *outstruct, err + } + + outstruct.AutoApproveConfigType = *abi.ConvertType(out[0], new(uint8)).(*uint8) + outstruct.AutoApproveMaxAllowed = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.ApprovedCount = *abi.ConvertType(out[2], new(uint32)).(*uint32) + outstruct.KeeperRegistry = *abi.ConvertType(out[3], new(common.Address)).(*common.Address) + outstruct.MinLINKJuels = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockSession) GetRegistrationConfig() (GetRegistrationConfig, + + error) { + return _KeeperRegistrarMock.Contract.GetRegistrationConfig(&_KeeperRegistrarMock.CallOpts) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockCallerSession) GetRegistrationConfig() (GetRegistrationConfig, + + error) { + return _KeeperRegistrarMock.Contract.GetRegistrationConfig(&_KeeperRegistrarMock.CallOpts) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockCaller) SApprovedCount(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _KeeperRegistrarMock.contract.Call(opts, &out, "s_approvedCount") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockSession) SApprovedCount() (uint32, error) { + return _KeeperRegistrarMock.Contract.SApprovedCount(&_KeeperRegistrarMock.CallOpts) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockCallerSession) SApprovedCount() (uint32, error) { + return _KeeperRegistrarMock.Contract.SApprovedCount(&_KeeperRegistrarMock.CallOpts) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockCaller) SAutoApproveConfigType(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _KeeperRegistrarMock.contract.Call(opts, &out, "s_autoApproveConfigType") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockSession) SAutoApproveConfigType() (uint8, error) { + return _KeeperRegistrarMock.Contract.SAutoApproveConfigType(&_KeeperRegistrarMock.CallOpts) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockCallerSession) SAutoApproveConfigType() (uint8, error) { + return _KeeperRegistrarMock.Contract.SAutoApproveConfigType(&_KeeperRegistrarMock.CallOpts) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockCaller) SAutoApproveMaxAllowed(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _KeeperRegistrarMock.contract.Call(opts, &out, "s_autoApproveMaxAllowed") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockSession) SAutoApproveMaxAllowed() (uint32, error) { + return _KeeperRegistrarMock.Contract.SAutoApproveMaxAllowed(&_KeeperRegistrarMock.CallOpts) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockCallerSession) SAutoApproveMaxAllowed() (uint32, error) { + return _KeeperRegistrarMock.Contract.SAutoApproveMaxAllowed(&_KeeperRegistrarMock.CallOpts) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockCaller) SKeeperRegistry(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _KeeperRegistrarMock.contract.Call(opts, &out, "s_keeperRegistry") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockSession) SKeeperRegistry() (common.Address, error) { + return _KeeperRegistrarMock.Contract.SKeeperRegistry(&_KeeperRegistrarMock.CallOpts) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockCallerSession) SKeeperRegistry() (common.Address, error) { + return _KeeperRegistrarMock.Contract.SKeeperRegistry(&_KeeperRegistrarMock.CallOpts) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockCaller) SMinLINKJuels(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _KeeperRegistrarMock.contract.Call(opts, &out, "s_minLINKJuels") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockSession) SMinLINKJuels() (*big.Int, error) { + return _KeeperRegistrarMock.Contract.SMinLINKJuels(&_KeeperRegistrarMock.CallOpts) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockCallerSession) SMinLINKJuels() (*big.Int, error) { + return _KeeperRegistrarMock.Contract.SMinLINKJuels(&_KeeperRegistrarMock.CallOpts) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockTransactor) EmitAutoApproveAllowedSenderSet(opts *bind.TransactOpts, senderAddress common.Address, allowed bool) (*types.Transaction, error) { + return _KeeperRegistrarMock.contract.Transact(opts, "emitAutoApproveAllowedSenderSet", senderAddress, allowed) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockSession) EmitAutoApproveAllowedSenderSet(senderAddress common.Address, allowed bool) (*types.Transaction, error) { + return _KeeperRegistrarMock.Contract.EmitAutoApproveAllowedSenderSet(&_KeeperRegistrarMock.TransactOpts, senderAddress, allowed) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockTransactorSession) EmitAutoApproveAllowedSenderSet(senderAddress common.Address, allowed bool) (*types.Transaction, error) { + return _KeeperRegistrarMock.Contract.EmitAutoApproveAllowedSenderSet(&_KeeperRegistrarMock.TransactOpts, senderAddress, allowed) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockTransactor) EmitConfigChanged(opts *bind.TransactOpts, autoApproveConfigType uint8, autoApproveMaxAllowed uint32, keeperRegistry common.Address, minLINKJuels *big.Int) (*types.Transaction, error) { + return _KeeperRegistrarMock.contract.Transact(opts, "emitConfigChanged", autoApproveConfigType, autoApproveMaxAllowed, keeperRegistry, minLINKJuels) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockSession) EmitConfigChanged(autoApproveConfigType uint8, autoApproveMaxAllowed uint32, keeperRegistry common.Address, minLINKJuels *big.Int) (*types.Transaction, error) { + return _KeeperRegistrarMock.Contract.EmitConfigChanged(&_KeeperRegistrarMock.TransactOpts, autoApproveConfigType, autoApproveMaxAllowed, keeperRegistry, minLINKJuels) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockTransactorSession) EmitConfigChanged(autoApproveConfigType uint8, autoApproveMaxAllowed uint32, keeperRegistry common.Address, minLINKJuels *big.Int) (*types.Transaction, error) { + return _KeeperRegistrarMock.Contract.EmitConfigChanged(&_KeeperRegistrarMock.TransactOpts, autoApproveConfigType, autoApproveMaxAllowed, keeperRegistry, minLINKJuels) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockTransactor) EmitOwnershipTransferRequested(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistrarMock.contract.Transact(opts, "emitOwnershipTransferRequested", from, to) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockSession) EmitOwnershipTransferRequested(from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistrarMock.Contract.EmitOwnershipTransferRequested(&_KeeperRegistrarMock.TransactOpts, from, to) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockTransactorSession) EmitOwnershipTransferRequested(from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistrarMock.Contract.EmitOwnershipTransferRequested(&_KeeperRegistrarMock.TransactOpts, from, to) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockTransactor) EmitOwnershipTransferred(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistrarMock.contract.Transact(opts, "emitOwnershipTransferred", from, to) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockSession) EmitOwnershipTransferred(from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistrarMock.Contract.EmitOwnershipTransferred(&_KeeperRegistrarMock.TransactOpts, from, to) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockTransactorSession) EmitOwnershipTransferred(from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistrarMock.Contract.EmitOwnershipTransferred(&_KeeperRegistrarMock.TransactOpts, from, to) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockTransactor) EmitRegistrationApproved(opts *bind.TransactOpts, hash [32]byte, displayName string, upkeepId *big.Int) (*types.Transaction, error) { + return _KeeperRegistrarMock.contract.Transact(opts, "emitRegistrationApproved", hash, displayName, upkeepId) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockSession) EmitRegistrationApproved(hash [32]byte, displayName string, upkeepId *big.Int) (*types.Transaction, error) { + return _KeeperRegistrarMock.Contract.EmitRegistrationApproved(&_KeeperRegistrarMock.TransactOpts, hash, displayName, upkeepId) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockTransactorSession) EmitRegistrationApproved(hash [32]byte, displayName string, upkeepId *big.Int) (*types.Transaction, error) { + return _KeeperRegistrarMock.Contract.EmitRegistrationApproved(&_KeeperRegistrarMock.TransactOpts, hash, displayName, upkeepId) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockTransactor) EmitRegistrationRejected(opts *bind.TransactOpts, hash [32]byte) (*types.Transaction, error) { + return _KeeperRegistrarMock.contract.Transact(opts, "emitRegistrationRejected", hash) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockSession) EmitRegistrationRejected(hash [32]byte) (*types.Transaction, error) { + return _KeeperRegistrarMock.Contract.EmitRegistrationRejected(&_KeeperRegistrarMock.TransactOpts, hash) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockTransactorSession) EmitRegistrationRejected(hash [32]byte) (*types.Transaction, error) { + return _KeeperRegistrarMock.Contract.EmitRegistrationRejected(&_KeeperRegistrarMock.TransactOpts, hash) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockTransactor) EmitRegistrationRequested(opts *bind.TransactOpts, hash [32]byte, name string, encryptedEmail []byte, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, checkData []byte, amount *big.Int, source uint8) (*types.Transaction, error) { + return _KeeperRegistrarMock.contract.Transact(opts, "emitRegistrationRequested", hash, name, encryptedEmail, upkeepContract, gasLimit, adminAddress, checkData, amount, source) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockSession) EmitRegistrationRequested(hash [32]byte, name string, encryptedEmail []byte, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, checkData []byte, amount *big.Int, source uint8) (*types.Transaction, error) { + return _KeeperRegistrarMock.Contract.EmitRegistrationRequested(&_KeeperRegistrarMock.TransactOpts, hash, name, encryptedEmail, upkeepContract, gasLimit, adminAddress, checkData, amount, source) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockTransactorSession) EmitRegistrationRequested(hash [32]byte, name string, encryptedEmail []byte, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, checkData []byte, amount *big.Int, source uint8) (*types.Transaction, error) { + return _KeeperRegistrarMock.Contract.EmitRegistrationRequested(&_KeeperRegistrarMock.TransactOpts, hash, name, encryptedEmail, upkeepContract, gasLimit, adminAddress, checkData, amount, source) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockTransactor) SetRegistrationConfig(opts *bind.TransactOpts, _autoApproveConfigType uint8, _autoApproveMaxAllowed uint32, _approvedCount uint32, _keeperRegistry common.Address, _minLINKJuels *big.Int) (*types.Transaction, error) { + return _KeeperRegistrarMock.contract.Transact(opts, "setRegistrationConfig", _autoApproveConfigType, _autoApproveMaxAllowed, _approvedCount, _keeperRegistry, _minLINKJuels) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockSession) SetRegistrationConfig(_autoApproveConfigType uint8, _autoApproveMaxAllowed uint32, _approvedCount uint32, _keeperRegistry common.Address, _minLINKJuels *big.Int) (*types.Transaction, error) { + return _KeeperRegistrarMock.Contract.SetRegistrationConfig(&_KeeperRegistrarMock.TransactOpts, _autoApproveConfigType, _autoApproveMaxAllowed, _approvedCount, _keeperRegistry, _minLINKJuels) +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockTransactorSession) SetRegistrationConfig(_autoApproveConfigType uint8, _autoApproveMaxAllowed uint32, _approvedCount uint32, _keeperRegistry common.Address, _minLINKJuels *big.Int) (*types.Transaction, error) { + return _KeeperRegistrarMock.Contract.SetRegistrationConfig(&_KeeperRegistrarMock.TransactOpts, _autoApproveConfigType, _autoApproveMaxAllowed, _approvedCount, _keeperRegistry, _minLINKJuels) +} + +type KeeperRegistrarMockAutoApproveAllowedSenderSetIterator struct { + Event *KeeperRegistrarMockAutoApproveAllowedSenderSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistrarMockAutoApproveAllowedSenderSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistrarMockAutoApproveAllowedSenderSet) + 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(KeeperRegistrarMockAutoApproveAllowedSenderSet) + 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 *KeeperRegistrarMockAutoApproveAllowedSenderSetIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistrarMockAutoApproveAllowedSenderSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistrarMockAutoApproveAllowedSenderSet struct { + SenderAddress common.Address + Allowed bool + Raw types.Log +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockFilterer) FilterAutoApproveAllowedSenderSet(opts *bind.FilterOpts, senderAddress []common.Address) (*KeeperRegistrarMockAutoApproveAllowedSenderSetIterator, error) { + + var senderAddressRule []interface{} + for _, senderAddressItem := range senderAddress { + senderAddressRule = append(senderAddressRule, senderAddressItem) + } + + logs, sub, err := _KeeperRegistrarMock.contract.FilterLogs(opts, "AutoApproveAllowedSenderSet", senderAddressRule) + if err != nil { + return nil, err + } + return &KeeperRegistrarMockAutoApproveAllowedSenderSetIterator{contract: _KeeperRegistrarMock.contract, event: "AutoApproveAllowedSenderSet", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockFilterer) WatchAutoApproveAllowedSenderSet(opts *bind.WatchOpts, sink chan<- *KeeperRegistrarMockAutoApproveAllowedSenderSet, senderAddress []common.Address) (event.Subscription, error) { + + var senderAddressRule []interface{} + for _, senderAddressItem := range senderAddress { + senderAddressRule = append(senderAddressRule, senderAddressItem) + } + + logs, sub, err := _KeeperRegistrarMock.contract.WatchLogs(opts, "AutoApproveAllowedSenderSet", senderAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(KeeperRegistrarMockAutoApproveAllowedSenderSet) + if err := _KeeperRegistrarMock.contract.UnpackLog(event, "AutoApproveAllowedSenderSet", 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 (_KeeperRegistrarMock *KeeperRegistrarMockFilterer) ParseAutoApproveAllowedSenderSet(log types.Log) (*KeeperRegistrarMockAutoApproveAllowedSenderSet, error) { + event := new(KeeperRegistrarMockAutoApproveAllowedSenderSet) + if err := _KeeperRegistrarMock.contract.UnpackLog(event, "AutoApproveAllowedSenderSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistrarMockConfigChangedIterator struct { + Event *KeeperRegistrarMockConfigChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistrarMockConfigChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistrarMockConfigChanged) + 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(KeeperRegistrarMockConfigChanged) + 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 *KeeperRegistrarMockConfigChangedIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistrarMockConfigChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistrarMockConfigChanged struct { + AutoApproveConfigType uint8 + AutoApproveMaxAllowed uint32 + KeeperRegistry common.Address + MinLINKJuels *big.Int + Raw types.Log +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockFilterer) FilterConfigChanged(opts *bind.FilterOpts) (*KeeperRegistrarMockConfigChangedIterator, error) { + + logs, sub, err := _KeeperRegistrarMock.contract.FilterLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return &KeeperRegistrarMockConfigChangedIterator{contract: _KeeperRegistrarMock.contract, event: "ConfigChanged", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockFilterer) WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *KeeperRegistrarMockConfigChanged) (event.Subscription, error) { + + logs, sub, err := _KeeperRegistrarMock.contract.WatchLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(KeeperRegistrarMockConfigChanged) + if err := _KeeperRegistrarMock.contract.UnpackLog(event, "ConfigChanged", 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 (_KeeperRegistrarMock *KeeperRegistrarMockFilterer) ParseConfigChanged(log types.Log) (*KeeperRegistrarMockConfigChanged, error) { + event := new(KeeperRegistrarMockConfigChanged) + if err := _KeeperRegistrarMock.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistrarMockOwnershipTransferRequestedIterator struct { + Event *KeeperRegistrarMockOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistrarMockOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistrarMockOwnershipTransferRequested) + 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(KeeperRegistrarMockOwnershipTransferRequested) + 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 *KeeperRegistrarMockOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistrarMockOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistrarMockOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeeperRegistrarMockOwnershipTransferRequestedIterator, 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 := _KeeperRegistrarMock.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &KeeperRegistrarMockOwnershipTransferRequestedIterator{contract: _KeeperRegistrarMock.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *KeeperRegistrarMockOwnershipTransferRequested, 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 := _KeeperRegistrarMock.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(KeeperRegistrarMockOwnershipTransferRequested) + if err := _KeeperRegistrarMock.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 (_KeeperRegistrarMock *KeeperRegistrarMockFilterer) ParseOwnershipTransferRequested(log types.Log) (*KeeperRegistrarMockOwnershipTransferRequested, error) { + event := new(KeeperRegistrarMockOwnershipTransferRequested) + if err := _KeeperRegistrarMock.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistrarMockOwnershipTransferredIterator struct { + Event *KeeperRegistrarMockOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistrarMockOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistrarMockOwnershipTransferred) + 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(KeeperRegistrarMockOwnershipTransferred) + 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 *KeeperRegistrarMockOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistrarMockOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistrarMockOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeeperRegistrarMockOwnershipTransferredIterator, 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 := _KeeperRegistrarMock.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &KeeperRegistrarMockOwnershipTransferredIterator{contract: _KeeperRegistrarMock.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *KeeperRegistrarMockOwnershipTransferred, 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 := _KeeperRegistrarMock.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(KeeperRegistrarMockOwnershipTransferred) + if err := _KeeperRegistrarMock.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 (_KeeperRegistrarMock *KeeperRegistrarMockFilterer) ParseOwnershipTransferred(log types.Log) (*KeeperRegistrarMockOwnershipTransferred, error) { + event := new(KeeperRegistrarMockOwnershipTransferred) + if err := _KeeperRegistrarMock.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistrarMockRegistrationApprovedIterator struct { + Event *KeeperRegistrarMockRegistrationApproved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistrarMockRegistrationApprovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistrarMockRegistrationApproved) + 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(KeeperRegistrarMockRegistrationApproved) + 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 *KeeperRegistrarMockRegistrationApprovedIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistrarMockRegistrationApprovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistrarMockRegistrationApproved struct { + Hash [32]byte + DisplayName string + UpkeepId *big.Int + Raw types.Log +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockFilterer) FilterRegistrationApproved(opts *bind.FilterOpts, hash [][32]byte, upkeepId []*big.Int) (*KeeperRegistrarMockRegistrationApprovedIterator, error) { + + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + + var upkeepIdRule []interface{} + for _, upkeepIdItem := range upkeepId { + upkeepIdRule = append(upkeepIdRule, upkeepIdItem) + } + + logs, sub, err := _KeeperRegistrarMock.contract.FilterLogs(opts, "RegistrationApproved", hashRule, upkeepIdRule) + if err != nil { + return nil, err + } + return &KeeperRegistrarMockRegistrationApprovedIterator{contract: _KeeperRegistrarMock.contract, event: "RegistrationApproved", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockFilterer) WatchRegistrationApproved(opts *bind.WatchOpts, sink chan<- *KeeperRegistrarMockRegistrationApproved, hash [][32]byte, upkeepId []*big.Int) (event.Subscription, error) { + + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + + var upkeepIdRule []interface{} + for _, upkeepIdItem := range upkeepId { + upkeepIdRule = append(upkeepIdRule, upkeepIdItem) + } + + logs, sub, err := _KeeperRegistrarMock.contract.WatchLogs(opts, "RegistrationApproved", hashRule, upkeepIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(KeeperRegistrarMockRegistrationApproved) + if err := _KeeperRegistrarMock.contract.UnpackLog(event, "RegistrationApproved", 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 (_KeeperRegistrarMock *KeeperRegistrarMockFilterer) ParseRegistrationApproved(log types.Log) (*KeeperRegistrarMockRegistrationApproved, error) { + event := new(KeeperRegistrarMockRegistrationApproved) + if err := _KeeperRegistrarMock.contract.UnpackLog(event, "RegistrationApproved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistrarMockRegistrationRejectedIterator struct { + Event *KeeperRegistrarMockRegistrationRejected + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistrarMockRegistrationRejectedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistrarMockRegistrationRejected) + 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(KeeperRegistrarMockRegistrationRejected) + 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 *KeeperRegistrarMockRegistrationRejectedIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistrarMockRegistrationRejectedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistrarMockRegistrationRejected struct { + Hash [32]byte + Raw types.Log +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockFilterer) FilterRegistrationRejected(opts *bind.FilterOpts, hash [][32]byte) (*KeeperRegistrarMockRegistrationRejectedIterator, error) { + + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + + logs, sub, err := _KeeperRegistrarMock.contract.FilterLogs(opts, "RegistrationRejected", hashRule) + if err != nil { + return nil, err + } + return &KeeperRegistrarMockRegistrationRejectedIterator{contract: _KeeperRegistrarMock.contract, event: "RegistrationRejected", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockFilterer) WatchRegistrationRejected(opts *bind.WatchOpts, sink chan<- *KeeperRegistrarMockRegistrationRejected, hash [][32]byte) (event.Subscription, error) { + + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + + logs, sub, err := _KeeperRegistrarMock.contract.WatchLogs(opts, "RegistrationRejected", hashRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(KeeperRegistrarMockRegistrationRejected) + if err := _KeeperRegistrarMock.contract.UnpackLog(event, "RegistrationRejected", 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 (_KeeperRegistrarMock *KeeperRegistrarMockFilterer) ParseRegistrationRejected(log types.Log) (*KeeperRegistrarMockRegistrationRejected, error) { + event := new(KeeperRegistrarMockRegistrationRejected) + if err := _KeeperRegistrarMock.contract.UnpackLog(event, "RegistrationRejected", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistrarMockRegistrationRequestedIterator struct { + Event *KeeperRegistrarMockRegistrationRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistrarMockRegistrationRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistrarMockRegistrationRequested) + 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(KeeperRegistrarMockRegistrationRequested) + 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 *KeeperRegistrarMockRegistrationRequestedIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistrarMockRegistrationRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistrarMockRegistrationRequested struct { + Hash [32]byte + Name string + EncryptedEmail []byte + UpkeepContract common.Address + GasLimit uint32 + AdminAddress common.Address + CheckData []byte + Amount *big.Int + Source uint8 + Raw types.Log +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockFilterer) FilterRegistrationRequested(opts *bind.FilterOpts, hash [][32]byte, upkeepContract []common.Address, source []uint8) (*KeeperRegistrarMockRegistrationRequestedIterator, error) { + + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + + var upkeepContractRule []interface{} + for _, upkeepContractItem := range upkeepContract { + upkeepContractRule = append(upkeepContractRule, upkeepContractItem) + } + + var sourceRule []interface{} + for _, sourceItem := range source { + sourceRule = append(sourceRule, sourceItem) + } + + logs, sub, err := _KeeperRegistrarMock.contract.FilterLogs(opts, "RegistrationRequested", hashRule, upkeepContractRule, sourceRule) + if err != nil { + return nil, err + } + return &KeeperRegistrarMockRegistrationRequestedIterator{contract: _KeeperRegistrarMock.contract, event: "RegistrationRequested", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistrarMock *KeeperRegistrarMockFilterer) WatchRegistrationRequested(opts *bind.WatchOpts, sink chan<- *KeeperRegistrarMockRegistrationRequested, hash [][32]byte, upkeepContract []common.Address, source []uint8) (event.Subscription, error) { + + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + + var upkeepContractRule []interface{} + for _, upkeepContractItem := range upkeepContract { + upkeepContractRule = append(upkeepContractRule, upkeepContractItem) + } + + var sourceRule []interface{} + for _, sourceItem := range source { + sourceRule = append(sourceRule, sourceItem) + } + + logs, sub, err := _KeeperRegistrarMock.contract.WatchLogs(opts, "RegistrationRequested", hashRule, upkeepContractRule, sourceRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(KeeperRegistrarMockRegistrationRequested) + if err := _KeeperRegistrarMock.contract.UnpackLog(event, "RegistrationRequested", 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 (_KeeperRegistrarMock *KeeperRegistrarMockFilterer) ParseRegistrationRequested(log types.Log) (*KeeperRegistrarMockRegistrationRequested, error) { + event := new(KeeperRegistrarMockRegistrationRequested) + if err := _KeeperRegistrarMock.contract.UnpackLog(event, "RegistrationRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetRegistrationConfig struct { + AutoApproveConfigType uint8 + AutoApproveMaxAllowed uint32 + ApprovedCount uint32 + KeeperRegistry common.Address + MinLINKJuels *big.Int +} + +func (_KeeperRegistrarMock *KeeperRegistrarMock) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _KeeperRegistrarMock.abi.Events["AutoApproveAllowedSenderSet"].ID: + return _KeeperRegistrarMock.ParseAutoApproveAllowedSenderSet(log) + case _KeeperRegistrarMock.abi.Events["ConfigChanged"].ID: + return _KeeperRegistrarMock.ParseConfigChanged(log) + case _KeeperRegistrarMock.abi.Events["OwnershipTransferRequested"].ID: + return _KeeperRegistrarMock.ParseOwnershipTransferRequested(log) + case _KeeperRegistrarMock.abi.Events["OwnershipTransferred"].ID: + return _KeeperRegistrarMock.ParseOwnershipTransferred(log) + case _KeeperRegistrarMock.abi.Events["RegistrationApproved"].ID: + return _KeeperRegistrarMock.ParseRegistrationApproved(log) + case _KeeperRegistrarMock.abi.Events["RegistrationRejected"].ID: + return _KeeperRegistrarMock.ParseRegistrationRejected(log) + case _KeeperRegistrarMock.abi.Events["RegistrationRequested"].ID: + return _KeeperRegistrarMock.ParseRegistrationRequested(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (KeeperRegistrarMockAutoApproveAllowedSenderSet) Topic() common.Hash { + return common.HexToHash("0x20c6237dac83526a849285a9f79d08a483291bdd3a056a0ef9ae94ecee1ad356") +} + +func (KeeperRegistrarMockConfigChanged) Topic() common.Hash { + return common.HexToHash("0x6293a703ec7145dfa23c5cde2e627d6a02e153fc2e9c03b14d1e22cbb4a7e9cd") +} + +func (KeeperRegistrarMockOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (KeeperRegistrarMockOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (KeeperRegistrarMockRegistrationApproved) Topic() common.Hash { + return common.HexToHash("0xb9a292fb7e3edd920cd2d2829a3615a640c43fd7de0a0820aa0668feb4c37d4b") +} + +func (KeeperRegistrarMockRegistrationRejected) Topic() common.Hash { + return common.HexToHash("0x3663fb28ebc87645eb972c9dad8521bf665c623f287e79f1c56f1eb374b82a22") +} + +func (KeeperRegistrarMockRegistrationRequested) Topic() common.Hash { + return common.HexToHash("0xc3f5df4aefec026f610a3fcb08f19476492d69d2cb78b1c2eba259a8820e6a78") +} + +func (_KeeperRegistrarMock *KeeperRegistrarMock) Address() common.Address { + return _KeeperRegistrarMock.address +} + +type KeeperRegistrarMockInterface interface { + GetRegistrationConfig(opts *bind.CallOpts) (GetRegistrationConfig, + + error) + + SApprovedCount(opts *bind.CallOpts) (uint32, error) + + SAutoApproveConfigType(opts *bind.CallOpts) (uint8, error) + + SAutoApproveMaxAllowed(opts *bind.CallOpts) (uint32, error) + + SKeeperRegistry(opts *bind.CallOpts) (common.Address, error) + + SMinLINKJuels(opts *bind.CallOpts) (*big.Int, error) + + EmitAutoApproveAllowedSenderSet(opts *bind.TransactOpts, senderAddress common.Address, allowed bool) (*types.Transaction, error) + + EmitConfigChanged(opts *bind.TransactOpts, autoApproveConfigType uint8, autoApproveMaxAllowed uint32, keeperRegistry common.Address, minLINKJuels *big.Int) (*types.Transaction, error) + + EmitOwnershipTransferRequested(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) + + EmitOwnershipTransferred(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) + + EmitRegistrationApproved(opts *bind.TransactOpts, hash [32]byte, displayName string, upkeepId *big.Int) (*types.Transaction, error) + + EmitRegistrationRejected(opts *bind.TransactOpts, hash [32]byte) (*types.Transaction, error) + + EmitRegistrationRequested(opts *bind.TransactOpts, hash [32]byte, name string, encryptedEmail []byte, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, checkData []byte, amount *big.Int, source uint8) (*types.Transaction, error) + + SetRegistrationConfig(opts *bind.TransactOpts, _autoApproveConfigType uint8, _autoApproveMaxAllowed uint32, _approvedCount uint32, _keeperRegistry common.Address, _minLINKJuels *big.Int) (*types.Transaction, error) + + FilterAutoApproveAllowedSenderSet(opts *bind.FilterOpts, senderAddress []common.Address) (*KeeperRegistrarMockAutoApproveAllowedSenderSetIterator, error) + + WatchAutoApproveAllowedSenderSet(opts *bind.WatchOpts, sink chan<- *KeeperRegistrarMockAutoApproveAllowedSenderSet, senderAddress []common.Address) (event.Subscription, error) + + ParseAutoApproveAllowedSenderSet(log types.Log) (*KeeperRegistrarMockAutoApproveAllowedSenderSet, error) + + FilterConfigChanged(opts *bind.FilterOpts) (*KeeperRegistrarMockConfigChangedIterator, error) + + WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *KeeperRegistrarMockConfigChanged) (event.Subscription, error) + + ParseConfigChanged(log types.Log) (*KeeperRegistrarMockConfigChanged, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeeperRegistrarMockOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *KeeperRegistrarMockOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*KeeperRegistrarMockOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeeperRegistrarMockOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *KeeperRegistrarMockOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*KeeperRegistrarMockOwnershipTransferred, error) + + FilterRegistrationApproved(opts *bind.FilterOpts, hash [][32]byte, upkeepId []*big.Int) (*KeeperRegistrarMockRegistrationApprovedIterator, error) + + WatchRegistrationApproved(opts *bind.WatchOpts, sink chan<- *KeeperRegistrarMockRegistrationApproved, hash [][32]byte, upkeepId []*big.Int) (event.Subscription, error) + + ParseRegistrationApproved(log types.Log) (*KeeperRegistrarMockRegistrationApproved, error) + + FilterRegistrationRejected(opts *bind.FilterOpts, hash [][32]byte) (*KeeperRegistrarMockRegistrationRejectedIterator, error) + + WatchRegistrationRejected(opts *bind.WatchOpts, sink chan<- *KeeperRegistrarMockRegistrationRejected, hash [][32]byte) (event.Subscription, error) + + ParseRegistrationRejected(log types.Log) (*KeeperRegistrarMockRegistrationRejected, error) + + FilterRegistrationRequested(opts *bind.FilterOpts, hash [][32]byte, upkeepContract []common.Address, source []uint8) (*KeeperRegistrarMockRegistrationRequestedIterator, error) + + WatchRegistrationRequested(opts *bind.WatchOpts, sink chan<- *KeeperRegistrarMockRegistrationRequested, hash [][32]byte, upkeepContract []common.Address, source []uint8) (event.Subscription, error) + + ParseRegistrationRequested(log types.Log) (*KeeperRegistrarMockRegistrationRequested, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/keeper_registry_logic_a_wrapper_2_1/keeper_registry_logic_a_wrapper_2_1.go b/core/gethwrappers/generated/keeper_registry_logic_a_wrapper_2_1/keeper_registry_logic_a_wrapper_2_1.go index 5c283a0181f..48c4d75e8b3 100644 --- a/core/gethwrappers/generated/keeper_registry_logic_a_wrapper_2_1/keeper_registry_logic_a_wrapper_2_1.go +++ b/core/gethwrappers/generated/keeper_registry_logic_a_wrapper_2_1/keeper_registry_logic_a_wrapper_2_1.go @@ -31,8 +31,8 @@ var ( ) var KeeperRegistryLogicAMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractKeeperRegistryLogicB2_1\",\"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\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"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\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"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\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"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\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"upkeepTriggerID\",\"type\":\"bytes32\"}],\"name\":\"CancelledUpkeepReport\",\"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\":\"bytes32\",\"name\":\"upkeepTriggerID\",\"type\":\"bytes32\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"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\":\"bytes32\",\"name\":\"upkeepTriggerID\",\"type\":\"bytes32\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"upkeepTriggerID\",\"type\":\"bytes32\"}],\"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\":\"bytes32\",\"name\":\"upkeepTriggerID\",\"type\":\"bytes32\"}],\"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\":\"nonpayable\",\"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\":\"nonpayable\",\"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\":\"enumKeeperRegistryBase2_1.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\":\"checkData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumKeeperRegistryBase2_1.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\":\"linkNative\",\"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\":\"enumKeeperRegistryBase2_1.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\":\"linkNative\",\"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\":\"enumKeeperRegistryBase2_1.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\":[{\"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\":\"enumKeeperRegistryBase2_1.Trigger\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"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\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"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\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101206040523480156200001257600080fd5b5060405162005fa238038062005fa2833981016040819052620000359162000374565b80816001600160a01b0316634b4fd03b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b91906200039b565b826001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000100919062000374565b836001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000165919062000374565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca919062000374565b3380600081620002215760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b038481169190911790915581161562000254576200025481620002b0565b5050508360028111156200026c576200026c620003be565b60e0816002811115620002835762000283620003be565b9052506001600160a01b0392831660805290821660a052811660c052919091166101005250620003d49050565b336001600160a01b038216036200030a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000218565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200037157600080fd5b50565b6000602082840312156200038757600080fd5b815162000394816200035b565b9392505050565b600060208284031215620003ae57600080fd5b8151600381106200039457600080fd5b634e487b7160e01b600052602160045260246000fd5b60805160a05160c05160e05161010051615b666200043c6000396000818161010e01526101a901526000818161345c01528181613692015281816139180152613ac0015260006132280152600061330c015260008181611e2201526123f50152615b666000f3fe60806040523480156200001157600080fd5b50600436106200010c5760003560e01c806385c1b0ba11620000a5578063c8048022116200006f578063c804802214620002b7578063ce7dc5b414620002ce578063f2fde38b14620002e5578063f7d334ba14620002fc576200010c565b806385c1b0ba14620002535780638da5cb5b146200026a5780638e86139b1462000289578063948108f714620002a0576200010c565b80634ee88d3511620000e75780634ee88d3514620001ef5780636ded9eae146200020657806371791aa0146200021d57806379ba50971462000249576200010c565b806328f32f38146200015457806329c5efad146200017e578063349e8cca14620001a7575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156200014d573d6000f35b3d6000fd5b005b6200016b6200016536600462004134565b62000313565b6040519081526020015b60405180910390f35b620001956200018f3660046200421a565b62000636565b60405162000175949392919062004342565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200162000175565b62000152620002003660046200437f565b62000878565b6200016b62000217366004620043cf565b620008e0565b620002346200022e3660046200421a565b62000946565b60405162000175979695949392919062004482565b620001526200112f565b6200015262000264366004620044d4565b62001232565b60005473ffffffffffffffffffffffffffffffffffffffff16620001c9565b620001526200029a36600462004561565b62001ea3565b62000152620002b1366004620045c4565b62002223565b62000152620002c8366004620045f3565b620024c5565b62000195620002df366004620046c9565b6200289b565b62000152620002f636600462004740565b6200296b565b620002346200030d366004620045f3565b62002983565b6000805473ffffffffffffffffffffffffffffffffffffffff1633148015906200034757506200034560093362002a55565b155b156200037f576040517fd48b678b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200038a8662002a89565b90506000818a306040516200039f9062003ede565b92835273ffffffffffffffffffffffffffffffffffffffff9182166020840152166040820152606001604051809103906000f080158015620003e5573d6000803e3d6000fd5b509050620004c9826040518061010001604052806000151581526020018c63ffffffff16815260200163ffffffff801681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff168152602001600063ffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff168152508a89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92508a915062002c2d9050565b6014805474010000000000000000000000000000000000000000900463ffffffff169080620004f8836200478f565b91906101000a81548163ffffffff021916908363ffffffff16021790555050817fbae366358c023f887e791d7a62f2e4316f1026bd77f6fb49501a917b3bc5d0128a8a6040516200057192919063ffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a2817fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d8787604051620005ad929190620047fe565b60405180910390a2817f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d566485604051620005e7919062004814565b60405180910390a2817f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf48508460405162000621919062004814565b60405180910390a25098975050505050505050565b600060606000806200064762003066565b60008681526004602090815260409182902082516101008082018552825460ff81161515835263ffffffff91810482169483019490945265010000000000840481169482019490945273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009093048316606082015260018201546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490931660c0840152600201541660e08201525a60e0820151601454604051929450600092839273ffffffffffffffffffffffffffffffffffffffff16916c01000000000000000000000000900463ffffffff169062000767908b9062004829565b60006040518083038160008787f1925050503d8060008114620007a7576040519150601f19603f3d011682016040523d82523d6000602084013e620007ac565b606091505b50915091505a620007be908562004847565b935081620007e95760006040518060200160405280600081525060079650965096505050506200086f565b80806020019051810190620007ff9190620048b8565b9097509550866200082d5760006040518060200160405280600081525060049650965096505050506200086f565b601554865164010000000090910463ffffffff1610156200086b5760006040518060200160405280600081525060059650965096505050506200086f565b5050505b92959194509250565b6200088383620030a1565b6000838152601a602052604090206200089e828483620049ad565b50827f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d56648383604051620008d3929190620047fe565b60405180910390a2505050565b60006200093a88888860008989604051806020016040528060008152508a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506200031392505050565b98975050505050505050565b6000606060008060008060006200095c62003066565b6000620009698a62003157565b905060006012604051806101200160405290816000820160009054906101000a900460ff1660ff1660ff1681526020016000820160019054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160059054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160099054906101000a900462ffffff1662ffffff1662ffffff16815260200160008201600c9054906101000a900461ffff1661ffff1661ffff16815260200160008201600e9054906101000a900460ff1615151515815260200160008201600f9054906101000a900460ff161515151581526020016000820160109054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160008201601c9054906101000a900463ffffffff1663ffffffff1663ffffffff168152505090506000600460008d8152602001908152602001600020604051806101000160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160059054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160099054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160018201600c9054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff1681526020016001820160189054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505090508160a001511562000ce4576000604051806020016040528060008152506009600084602001516000808263ffffffff169250995099509950995099509950995050505062001123565b604081015163ffffffff9081161462000d35576000604051806020016040528060008152506001600084602001516000808263ffffffff169250995099509950995099509950995050505062001123565b80511562000d7b576000604051806020016040528060008152506002600084602001516000808263ffffffff169250995099509950995099509950995050505062001123565b62000d868262003205565b602083015160155492975090955060009162000db8918591879190640100000000900463ffffffff168a8a87620033f7565b9050806bffffffffffffffffffffffff168260a001516bffffffffffffffffffffffff16101562000e22576000604051806020016040528060008152506006600085602001516000808263ffffffff1692509a509a509a509a509a509a509a505050505062001123565b6060600085600181111562000e3b5762000e3b620042d7565b0362000efb576040517f6e04ff0d000000000000000000000000000000000000000000000000000000009062000e76908f9060240162004814565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152905062000f42565b60405162000f30907fbe61b77500000000000000000000000000000000000000000000000000000000908f9060200162004ad5565b60405160208183030381529060405290505b5a60e0840151601454604051929b50600092839273ffffffffffffffffffffffffffffffffffffffff16916c01000000000000000000000000900463ffffffff169062000f9190869062004829565b60006040518083038160008787f1925050503d806000811462000fd1576040519150601f19603f3d011682016040523d82523d6000602084013e62000fd6565b606091505b50915091505a62000fe8908c62004847565b9a5081620010685760155481516801000000000000000090910463ffffffff1610156200104557505060408051602080820190925260008082529490910151939c509a50600899505063ffffffff90911695506200112392505050565b602090940151939b5060039a505063ffffffff9092169650620011239350505050565b808060200190518101906200107e9190620048b8565b909e509c508d620010bf57505060408051602080820190925260008082529490910151939c509a50600499505063ffffffff90911695506200112392505050565b6015548d5164010000000090910463ffffffff1610156200111057505060408051602080820190925260008082529490910151939c509a50600599505063ffffffff90911695506200112392505050565b505050506020015163ffffffff16945050505b92959891949750929550565b60015473ffffffffffffffffffffffffffffffffffffffff163314620011b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600173ffffffffffffffffffffffffffffffffffffffff821660009081526019602052604090205460ff166003811115620012715762001271620042d7565b14158015620012bd5750600373ffffffffffffffffffffffffffffffffffffffff821660009081526019602052604090205460ff166003811115620012ba57620012ba620042d7565b14155b15620012f5576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6013546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1662001355576040517fd12d7d8d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082900362001391576040517f2c2fc94100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526000808567ffffffffffffffff811115620013f057620013f062003fe1565b6040519080825280602002602001820160405280156200141a578160200160208202803683370190505b50905060008667ffffffffffffffff8111156200143b576200143b62003fe1565b604051908082528060200260200182016040528015620014ca57816020015b604080516101008101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816200145a5790505b50905060008767ffffffffffffffff811115620014eb57620014eb62003fe1565b6040519080825280602002602001820160405280156200152057816020015b60608152602001906001900390816200150a5790505b50905060008867ffffffffffffffff81111562001541576200154162003fe1565b6040519080825280602002602001820160405280156200157657816020015b6060815260200190600190039081620015605790505b50905060008967ffffffffffffffff81111562001597576200159762003fe1565b604051908082528060200260200182016040528015620015cc57816020015b6060815260200190600190039081620015b65790505b50905060005b8a81101562001be7578b8b82818110620015f057620015f062004b1f565b6020908102929092013560008181526004845260409081902081516101008082018452825460ff81161515835263ffffffff91810482169783019790975265010000000000870481169382019390935273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009096048616606082015260018201546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490921660c08301526002015490931660e08401529a50909850620016dc905089620030a1565b60608801516040517f1a5da6c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c8116600483015290911690631a5da6c890602401600060405180830381600087803b1580156200174c57600080fd5b505af115801562001761573d6000803e3d6000fd5b50505050878582815181106200177b576200177b62004b1f565b6020026020010181905250600560008a815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16868281518110620017cf57620017cf62004b1f565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015260008a815260079091526040902080546200180e9062004905565b80601f01602080910402602001604051908101604052809291908181526020018280546200183c9062004905565b80156200188d5780601f1062001861576101008083540402835291602001916200188d565b820191906000526020600020905b8154815290600101906020018083116200186f57829003601f168201915b5050505050848281518110620018a757620018a762004b1f565b6020026020010181905250601a60008a81526020019081526020016000208054620018d29062004905565b80601f0160208091040260200160405190810160405280929190818152602001828054620019009062004905565b8015620019515780601f10620019255761010080835404028352916020019162001951565b820191906000526020600020905b8154815290600101906020018083116200193357829003601f168201915b50505050508382815181106200196b576200196b62004b1f565b6020026020010181905250601b60008a81526020019081526020016000208054620019969062004905565b80601f0160208091040260200160405190810160405280929190818152602001828054620019c49062004905565b801562001a155780601f10620019e95761010080835404028352916020019162001a15565b820191906000526020600020905b815481529060010190602001808311620019f757829003601f168201915b505050505082828151811062001a2f5762001a2f62004b1f565b60200260200101819052508760a001516bffffffffffffffffffffffff168762001a5a919062004b4e565b60008a815260046020908152604080832080547fffffff00000000000000000000000000000000000000000000000000000000001681556001810180547fffffffff0000000000000000000000000000000000000000000000000000000016905560020180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556007909152812091985062001afa919062003eec565b6000898152601a6020526040812062001b139162003eec565b6000898152601b6020526040812062001b2c9162003eec565b600089815260066020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905562001b6d60028a62003448565b5060a0880151604080516bffffffffffffffffffffffff909216825273ffffffffffffffffffffffffffffffffffffffff8c1660208301528a917fb38647142fbb1ea4c000fc4569b37a4e9a9f6313317b84ee3e5326c1a6cd06ff910160405180910390a28062001bde8162004b64565b915050620015d2565b508560185462001bf8919062004847565b60185560405160009062001c1d908d908d9088908a9089908990899060200162004c4b565b60405160208183030381529060405290508973ffffffffffffffffffffffffffffffffffffffff16638e86139b6013600001600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c71249ab60038e73ffffffffffffffffffffffffffffffffffffffff1663aab9edd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001cd9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001cff919062004dc5565b866040518463ffffffff1660e01b815260040162001d209392919062004dea565b600060405180830381865afa15801562001d3e573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405262001d86919081019062004e11565b6040518263ffffffff1660e01b815260040162001da4919062004814565b600060405180830381600087803b15801562001dbf57600080fd5b505af115801562001dd4573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d81166004830152602482018b90527f000000000000000000000000000000000000000000000000000000000000000016925063a9059cbb91506044016020604051808303816000875af115801562001e6e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001e94919062004e4a565b50505050505050505050505050565b60023360009081526019602052604090205460ff16600381111562001ecc5762001ecc620042d7565b1415801562001f02575060033360009081526019602052604090205460ff16600381111562001eff5762001eff620042d7565b14155b1562001f3a576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808080808062001f4f878901896200504a565b95509550955095509550955060005b86518110156200221857600073ffffffffffffffffffffffffffffffffffffffff1686828151811062001f955762001f9562004b1f565b60200260200101516060015173ffffffffffffffffffffffffffffffffffffffff1603620020a55786818151811062001fd25762001fd262004b1f565b602002602001015186828151811062001fef5762001fef62004b1f565b602002602001015160e00151306040516200200a9062003ede565b92835273ffffffffffffffffffffffffffffffffffffffff9182166020840152166040820152606001604051809103906000f08015801562002050573d6000803e3d6000fd5b5086828151811062002066576200206662004b1f565b60200260200101516060019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b6200215d878281518110620020be57620020be62004b1f565b6020026020010151878381518110620020db57620020db62004b1f565b6020026020010151878481518110620020f857620020f862004b1f565b602002602001015187858151811062002115576200211562004b1f565b602002602001015187868151811062002132576200213262004b1f565b60200260200101518787815181106200214f576200214f62004b1f565b602002602001015162002c2d565b86818151811062002172576200217262004b1f565b60200260200101517f74931a144e43a50694897f241d973aecb5024c0e910f9bb80a163ea3c1cf5a71878381518110620021b057620021b062004b1f565b602002602001015160a0015133604051620021fb9291906bffffffffffffffffffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a2806200220f8162004b64565b91505062001f5e565b505050505050505050565b60008281526004602090815260409182902082516101008082018552825460ff81161515835263ffffffff918104821694830194909452650100000000008404811694820185905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009094048416606083015260018301546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a084015278010000000000000000000000000000000000000000000000009004811660c083015260029092015490921660e083015290911462002330576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818160a0015162002342919062005152565b600084815260046020526040902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff166c010000000000000000000000006bffffffffffffffffffffffff93841602179055601854620023aa9184169062004b4e565b6018556040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526bffffffffffffffffffffffff831660448201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906323b872dd906064016020604051808303816000875af115801562002454573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200247a919062004e4a565b506040516bffffffffffffffffffffffff83168152339084907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a3505050565b600081815260046020908152604080832081516101008082018452825460ff81161515835263ffffffff918104821695830195909552650100000000008504811693820184905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009095048516606083015260018301546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a084015278010000000000000000000000000000000000000000000000009004811660c083015260029092015490931660e0840152919291141590620025bd60005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161490508180156200261857508080156200261657506200260962003456565b836040015163ffffffff16115b155b1562002650576040517ffbc0357800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8015801562002683575060008481526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b15620026bb576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000620026c762003456565b905081620026df57620026dc60328262004b4e565b90505b6000858152600460205260409020805463ffffffff80841665010000000000027fffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffff909216919091179091556200273b9060029087906200344816565b5060135460808501516bffffffffffffffffffffffff9182169160009116821115620027a45760808601516200277290836200517a565b90508560a001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115620027a4575060a08501515b808660a00151620027b691906200517a565b600088815260046020526040902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff166c010000000000000000000000006bffffffffffffffffffffffff938416021790556014546200281e9183911662005152565b601480547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff9290921691909117905560405167ffffffffffffffff84169088907f91cb3bb75cfbd718bbfccc56b7f53d92d7048ef4ca39a3b7b7c6d4af1f79118190600090a350505050505050565b60006060600080620028ac62003066565b6000634b56a42e60e01b888888604051602401620028cd93929190620051a2565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152905062002958898262000636565b929c919b50995090975095505050505050565b6200297562003512565b620029808162003595565b50565b60006060600080600080600062002a3e88600760008b81526020019081526020016000208054620029b49062004905565b80601f0160208091040260200160405190810160405280929190818152602001828054620029e29062004905565b801562002a335780601f1062002a075761010080835404028352916020019162002a33565b820191906000526020600020905b81548152906001019060200180831162002a1557829003601f168201915b505050505062000946565b959e949d50929b5090995097509550909350915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b90505b92915050565b600080600062002ab0600162002a9e62003456565b62002aaa919062004847565b6200368c565b601454604080516020810193909352309083015274010000000000000000000000000000000000000000900463ffffffff166060820152608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083015201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060045b600f81101562002bbc578282828151811062002b785762002b7862004b1f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508062002bb38162004b64565b91505062002b58565b5083600181111562002bd25762002bd2620042d7565b60f81b81600f8151811062002beb5762002beb62004b1f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535062002c2581620051d6565b949350505050565b6012546e010000000000000000000000000000900460ff161562002c7d576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e085015173ffffffffffffffffffffffffffffffffffffffff163b62002cd0576040517f09ee12d500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601554835163ffffffff909116101562002d16576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108fc856020015163ffffffff16108062002d545750601454602086015163ffffffff70010000000000000000000000000000000090920482169116115b1562002d8c576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008681526004602052604090206002015473ffffffffffffffffffffffffffffffffffffffff161562002dec576040517f6e3b930b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600086815260046020908152604080832088518154848b0151848c015160608d015173ffffffffffffffffffffffffffffffffffffffff9081166901000000000000000000027fffffff0000000000000000000000000000000000000000ffffffffffffffffff63ffffffff9384166501000000000002167fffffff000000000000000000000000000000000000000000000000ffffffffff948416610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff971515979097167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009096169590951795909517929092169290921792909217835560808b015160018401805460a08e015160c08f01519094167801000000000000000000000000000000000000000000000000027fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff6bffffffffffffffffffffffff9586166c01000000000000000000000000027fffffffffffffffff0000000000000000000000000000000000000000000000009093169590941694909417179190911691909117905560e08a0151600290920180549282167fffffffffffffffffffffffff0000000000000000000000000000000000000000938416179055600584528285208054918a16919092161790556007909152902062002ff4848262005219565b508460a001516bffffffffffffffffffffffff1660185462003017919062004b4e565b6018556000868152601a6020526040902062003034838262005219565b506000868152601b602052604090206200304f828262005219565b506200305d600287620037fb565b50505050505050565b32156200309f576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314620030ff576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090205465010000000000900463ffffffff9081161462002980576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818160045b600f811015620031ec577fff000000000000000000000000000000000000000000000000000000000000008216838260208110620031a057620031a062004b1f565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614620031d757506000949350505050565b80620031e38162004b64565b9150506200315e565b5081600f1a600181111562002c255762002c25620042d7565b6000806000836060015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa15801562003292573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620032b891906200535b565b5094509092505050600081131580620032d057508142105b80620032f55750828015620032f55750620032ec824262004847565b8463ffffffff16105b15620033065760165495506200330a565b8095505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa15801562003376573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200339c91906200535b565b5094509092505050600081131580620033b457508142105b80620033d95750828015620033d95750620033d0824262004847565b8463ffffffff16105b15620033ea576017549450620033ee565b8094505b50505050915091565b6000806200340b88878b6000015162003809565b9050600080620034288b8a63ffffffff16858a8a60018b620038df565b909250905062003439818362005152565b9b9a5050505050505050505050565b600062002a80838362003d81565b600060017f000000000000000000000000000000000000000000000000000000000000000060028111156200348f576200348f620042d7565b036200350d57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620034e2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620035089190620053b0565b905090565b504390565b60005473ffffffffffffffffffffffffffffffffffffffff1633146200309f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401620011ad565b3373ffffffffffffffffffffffffffffffffffffffff82160362003616576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620011ad565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060017f00000000000000000000000000000000000000000000000000000000000000006002811115620036c557620036c5620042d7565b03620037f1576000606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200371a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620037409190620053b0565b905080831015806200375e57506101006200375c848362004847565b115b156200376d5750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815260048101849052606490632b407a8290602401602060405180830381865afa158015620037c4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620037ea9190620053b0565b9392505050565b504090565b919050565b600062002a80838362003e8c565b60008080856001811115620038225762003822620042d7565b0362003833575062015f906200388d565b60018560018111156200384a576200384a620042d7565b036200385b57506201adb06200388d565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b620038a063ffffffff85166014620053ca565b620038ad8460016200540a565b620038be9060ff16611d4c620053ca565b620038ca908362004b4e565b620038d6919062004b4e565b95945050505050565b6000806000896080015161ffff1687620038fa9190620053ca565b9050838015620039095750803a105b156200391257503a5b600060027f000000000000000000000000000000000000000000000000000000000000000060028111156200394b576200394b620042d7565b0362003abc576040805160008152602081019091528515620039af5760003660405180608001604052806048815260200162005b1260489139604051602001620039989392919062005426565b604051602081830303815290604052905062003a1d565b601554620039cd90640100000000900463ffffffff1660046200544f565b63ffffffff1667ffffffffffffffff811115620039ee57620039ee62003fe1565b6040519080825280601f01601f19166020018201604052801562003a19576020820181803683370190505b5090505b6040517f49948e0e00000000000000000000000000000000000000000000000000000000815273420000000000000000000000000000000000000f906349948e0e9062003a6f90849060040162004814565b602060405180830381865afa15801562003a8d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003ab39190620053b0565b91505062003c26565b60017f0000000000000000000000000000000000000000000000000000000000000000600281111562003af35762003af3620042d7565b0362003c2657841562003b7b57606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562003b4d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003b739190620053b0565b905062003c26565b6000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c060405180830381865afa15801562003bca573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003bf091906200547e565b505060155492945062003c1593505050640100000000900463ffffffff1682620053ca565b62003c22906010620053ca565b9150505b8462003c4557808b6080015161ffff1662003c429190620053ca565b90505b62003c5561ffff871682620054c9565b90506000878262003c678c8e62004b4e565b62003c739086620053ca565b62003c7f919062004b4e565b62003c9390670de0b6b3a7640000620053ca565b62003c9f9190620054c9565b905060008c6040015163ffffffff1664e8d4a5100062003cc09190620053ca565b898e6020015163ffffffff16858f8862003cdb9190620053ca565b62003ce7919062004b4e565b62003cf790633b9aca00620053ca565b62003d039190620053ca565b62003d0f9190620054c9565b62003d1b919062004b4e565b90506b033b2e3c9fd0803ce800000062003d36828462004b4e565b111562003d6f576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909c909b509950505050505050505050565b6000818152600183016020526040812054801562003e7a57600062003da860018362004847565b855490915060009062003dbe9060019062004847565b905081811462003e2a57600086600001828154811062003de25762003de262004b1f565b906000526020600020015490508087600001848154811062003e085762003e0862004b1f565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062003e3e5762003e3e62005505565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062002a83565b600091505062002a83565b5092915050565b600081815260018301602052604081205462003ed55750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562002a83565b50600062002a83565b6105dd806200553583390190565b50805462003efa9062004905565b6000825580601f1062003f0b575050565b601f0160209004906000526020600020908101906200298091905b8082111562003f3c576000815560010162003f26565b5090565b73ffffffffffffffffffffffffffffffffffffffff811681146200298057600080fd5b8035620037f68162003f40565b803563ffffffff81168114620037f657600080fd5b803560028110620037f657600080fd5b60008083601f84011262003fa857600080fd5b50813567ffffffffffffffff81111562003fc157600080fd5b60208301915083602082850101111562003fda57600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff8111828210171562004037576200403762003fe1565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171562004087576200408762003fe1565b604052919050565b600067ffffffffffffffff821115620040ac57620040ac62003fe1565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112620040ea57600080fd5b813562004101620040fb826200408f565b6200403d565b8181528460208386010111156200411757600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060008060e0898b0312156200415157600080fd5b88356200415e8162003f40565b97506200416e60208a0162003f70565b96506040890135620041808162003f40565b95506200419060608a0162003f85565b9450608089013567ffffffffffffffff80821115620041ae57600080fd5b620041bc8c838d0162003f95565b909650945060a08b0135915080821115620041d657600080fd5b620041e48c838d01620040d8565b935060c08b0135915080821115620041fb57600080fd5b506200420a8b828c01620040d8565b9150509295985092959890939650565b600080604083850312156200422e57600080fd5b82359150602083013567ffffffffffffffff8111156200424d57600080fd5b6200425b85828601620040d8565b9150509250929050565b60005b838110156200428257818101518382015260200162004268565b50506000910152565b60008151808452620042a581602086016020860162004265565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600a81106200433e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b84151581526080602082015260006200435f60808301866200428b565b905062004370604083018562004306565b82606083015295945050505050565b6000806000604084860312156200439557600080fd5b83359250602084013567ffffffffffffffff811115620043b457600080fd5b620043c28682870162003f95565b9497909650939450505050565b600080600080600080600060a0888a031215620043eb57600080fd5b8735620043f88162003f40565b9650620044086020890162003f70565b955060408801356200441a8162003f40565b9450606088013567ffffffffffffffff808211156200443857600080fd5b620044468b838c0162003f95565b909650945060808a01359150808211156200446057600080fd5b506200446f8a828b0162003f95565b989b979a50959850939692959293505050565b871515815260e0602082015260006200449f60e08301896200428b565b9050620044b0604083018862004306565b8560608301528460808301528360a08301528260c083015298975050505050505050565b600080600060408486031215620044ea57600080fd5b833567ffffffffffffffff808211156200450357600080fd5b818601915086601f8301126200451857600080fd5b8135818111156200452857600080fd5b8760208260051b85010111156200453e57600080fd5b60209283019550935050840135620045568162003f40565b809150509250925092565b600080602083850312156200457557600080fd5b823567ffffffffffffffff8111156200458d57600080fd5b6200459b8582860162003f95565b90969095509350505050565b80356bffffffffffffffffffffffff81168114620037f657600080fd5b60008060408385031215620045d857600080fd5b82359150620045ea60208401620045a7565b90509250929050565b6000602082840312156200460657600080fd5b5035919050565b600067ffffffffffffffff8211156200462a576200462a62003fe1565b5060051b60200190565b600082601f8301126200464657600080fd5b8135602062004659620040fb836200460d565b82815260059290921b840181019181810190868411156200467957600080fd5b8286015b84811015620046be57803567ffffffffffffffff8111156200469f5760008081fd5b620046af8986838b0101620040d8565b8452509183019183016200467d565b509695505050505050565b60008060008060608587031215620046e057600080fd5b84359350602085013567ffffffffffffffff808211156200470057600080fd5b6200470e8883890162004634565b945060408701359150808211156200472557600080fd5b50620047348782880162003f95565b95989497509550505050565b6000602082840312156200475357600080fd5b8135620037ea8162003f40565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600063ffffffff808316818103620047ab57620047ab62004760565b6001019392505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60208152600062002c25602083018486620047b5565b60208152600062002a8060208301846200428b565b600082516200483d81846020870162004265565b9190910192915050565b8181038181111562002a835762002a8362004760565b80151581146200298057600080fd5b600082601f8301126200487e57600080fd5b81516200488f620040fb826200408f565b818152846020838601011115620048a557600080fd5b62002c2582602083016020870162004265565b60008060408385031215620048cc57600080fd5b8251620048d9816200485d565b602084015190925067ffffffffffffffff811115620048f757600080fd5b6200425b858286016200486c565b600181811c908216806200491a57607f821691505b60208210810362004954577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f821115620049a857600081815260208120601f850160051c81016020861015620049835750805b601f850160051c820191505b81811015620049a4578281556001016200498f565b5050505b505050565b67ffffffffffffffff831115620049c857620049c862003fe1565b620049e083620049d9835462004905565b836200495a565b6000601f84116001811462004a355760008515620049fe5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835562004ace565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101562004a86578685013582556020948501946001909201910162004a64565b508682101562004ac2577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b7fffffffff00000000000000000000000000000000000000000000000000000000831681526000825162004b1181600485016020870162004265565b919091016004019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8082018082111562002a835762002a8362004760565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362004b985762004b9862004760565b5060010190565b600081518084526020808501945080840160005b8381101562004be757815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010162004bb3565b509495945050505050565b600081518084526020808501808196508360051b8101915082860160005b8581101562004c3e57828403895262004c2b8483516200428b565b9885019893509084019060010162004c10565b5091979650505050505050565b600060c0808352888184015260e07f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8a111562004c8757600080fd5b8960051b808c83870137840184810382016020808701919091528a518383018190528b82019261010092919083019060005b8181101562004d5a5785518051151584528481015163ffffffff9081168686015260408083015182169086015260608083015173ffffffffffffffffffffffffffffffffffffffff908116918701919091526080808401516bffffffffffffffffffffffff9081169188019190915260a080850151909116908701528a8301519091168a860152908801511687840152948301949184019160010162004cb9565b5050878103604089015262004d70818d62004b9f565b95505050505050828103606084015262004d8b818762004bf2565b9050828103608084015262004da1818662004bf2565b905082810360a084015262004db7818562004bf2565b9a9950505050505050505050565b60006020828403121562004dd857600080fd5b815160ff81168114620037ea57600080fd5b60ff8416815260ff83166020820152606060408201526000620038d660608301846200428b565b60006020828403121562004e2457600080fd5b815167ffffffffffffffff81111562004e3c57600080fd5b62002c25848285016200486c565b60006020828403121562004e5d57600080fd5b8151620037ea816200485d565b600082601f83011262004e7c57600080fd5b8135602062004e8f620040fb836200460d565b82815260059290921b8401810191818101908684111562004eaf57600080fd5b8286015b84811015620046be578035835291830191830162004eb3565b600082601f83011262004ede57600080fd5b8135602062004ef1620040fb836200460d565b82815260089290921b8401810191818101908684111562004f1157600080fd5b8286015b84811015620046be57610100818903121562004f315760008081fd5b62004f3b62004010565b813562004f48816200485d565b815262004f5782860162003f70565b85820152604062004f6a81840162003f70565b90820152606062004f7d83820162003f63565b90820152608062004f90838201620045a7565b9082015260a062004fa3838201620045a7565b9082015260c062004fb683820162003f70565b9082015260e062004fc983820162003f63565b908201528352918301916101000162004f15565b600082601f83011262004fef57600080fd5b8135602062005002620040fb836200460d565b82815260059290921b840181019181810190868411156200502257600080fd5b8286015b84811015620046be5780356200503c8162003f40565b835291830191830162005026565b60008060008060008060c087890312156200506457600080fd5b863567ffffffffffffffff808211156200507d57600080fd5b6200508b8a838b0162004e6a565b97506020890135915080821115620050a257600080fd5b620050b08a838b0162004ecc565b96506040890135915080821115620050c757600080fd5b620050d58a838b0162004fdd565b95506060890135915080821115620050ec57600080fd5b620050fa8a838b0162004634565b945060808901359150808211156200511157600080fd5b6200511f8a838b0162004634565b935060a08901359150808211156200513657600080fd5b506200514589828a0162004634565b9150509295509295509295565b6bffffffffffffffffffffffff81811683821601908082111562003e855762003e8562004760565b6bffffffffffffffffffffffff82811682821603908082111562003e855762003e8562004760565b604081526000620051b7604083018662004bf2565b8281036020840152620051cc818587620047b5565b9695505050505050565b8051602080830151919081101562004954577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b815167ffffffffffffffff81111562005236576200523662003fe1565b6200524e8162005247845462004905565b846200495a565b602080601f831160018114620052a457600084156200526d5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555620049a4565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015620052f357888601518255948401946001909101908401620052d2565b50858210156200533057878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b805169ffffffffffffffffffff81168114620037f657600080fd5b600080600080600060a086880312156200537457600080fd5b6200537f8662005340565b9450602086015193506040860151925060608601519150620053a46080870162005340565b90509295509295909350565b600060208284031215620053c357600080fd5b5051919050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161562005405576200540562004760565b500290565b60ff818116838216019081111562002a835762002a8362004760565b8284823760008382016000815283516200544581836020880162004265565b0195945050505050565b600063ffffffff8083168185168183048111821515161562005475576200547562004760565b02949350505050565b60008060008060008060c087890312156200549857600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b60008262005500577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe60c060405234801561001057600080fd5b506040516105dd3803806105dd83398101604081905261002f91610073565b600080546001600160a01b0319166001600160a01b039283161790551660805260a0526100af565b80516001600160a01b038116811461006e57600080fd5b919050565b60008060006060848603121561008857600080fd5b8351925061009860208501610057565b91506100a660408501610057565b90509250925092565b60805160a0516105026100db600039600061014c015260008181610177015261028901526105026000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c806379188d161161005057806379188d161461011d5780638ee489b214610147578063f00e6a2a1461017557600080fd5b8063181f5a77146100775780631a5da6c8146100c95780635ab1bd53146100de575b600080fd5b6100b36040518060400160405280601981526020017f4175746f6d6174696f6e466f7277617264657220312e302e300000000000000081525081565b6040516100c09190610304565b60405180910390f35b6100dc6100d7366004610370565b61019b565b005b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c0565b61013061012b3660046103dc565b610233565b6040805192151583526020830191909152016100c0565b6040517f000000000000000000000000000000000000000000000000000000000000000081526020016100c0565b7f00000000000000000000000000000000000000000000000000000000000000006100f8565b60005473ffffffffffffffffffffffffffffffffffffffff1633146101ec576040517fea8e4eb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60008054819073ffffffffffffffffffffffffffffffffffffffff163314610287576040517fea8e4eb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000005a91505a6113888110156102bb57600080fd5b6113888103905085604082048203116102d357600080fd5b50803b6102df57600080fd5b6000808551602087016000858af192505a6102fa90836104b5565b9150509250929050565b600060208083528351808285015260005b8181101561033157858101830151858201604001528201610315565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006020828403121561038257600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146103a657600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080604083850312156103ef57600080fd5b82359150602083013567ffffffffffffffff8082111561040e57600080fd5b818501915085601f83011261042257600080fd5b813581811115610434576104346103ad565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561047a5761047a6103ad565b8160405282815288602084870101111561049357600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b818103818111156104ef577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9291505056fea164736f6c6343000810000a307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000810000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractKeeperRegistryLogicB2_1\",\"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\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"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\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"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\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"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\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"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\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"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\":\"nonpayable\",\"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\":\"nonpayable\",\"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\":\"enumKeeperRegistryBase2_1.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\":\"enumKeeperRegistryBase2_1.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\":\"linkNative\",\"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\":\"enumKeeperRegistryBase2_1.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\":\"linkNative\",\"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\":\"enumKeeperRegistryBase2_1.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\":[{\"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\":\"enumKeeperRegistryBase2_1.Trigger\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"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\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"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\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101406040523480156200001257600080fd5b50604051620061d1380380620061d18339810160408190526200003591620003df565b80816001600160a01b0316634b4fd03b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b919062000406565b826001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001009190620003df565b836001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001659190620003df565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca9190620003df565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f9190620003df565b3380600081620002865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620002b957620002b9816200031b565b505050846002811115620002d157620002d162000429565b60e0816002811115620002e857620002e862000429565b9052506001600160a01b0393841660805291831660a052821660c0528116610100529190911661012052506200043f9050565b336001600160a01b03821603620003755760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200027d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b0381168114620003dc57600080fd5b50565b600060208284031215620003f257600080fd5b8151620003ff81620003c6565b9392505050565b6000602082840312156200041957600080fd5b815160038110620003ff57600080fd5b634e487b7160e01b600052602160045260246000fd5b60805160a05160c05160e0516101005161012051615d18620004b96000396000818161010e01526101a90152600081816103e10152611fa10152600081816135370152818161376d015281816139b50152613b5d015260006130e1015260006131c5015260008181611de301526123af0152615d186000f3fe60806040523480156200001157600080fd5b50600436106200010c5760003560e01c806385c1b0ba11620000a5578063c8048022116200006f578063c804802214620002b7578063ce7dc5b414620002ce578063f2fde38b14620002e5578063f7d334ba14620002fc576200010c565b806385c1b0ba14620002535780638da5cb5b146200026a5780638e86139b1462000289578063948108f714620002a0576200010c565b80634ee88d3511620000e75780634ee88d3514620001ef5780636ded9eae146200020657806371791aa0146200021d57806379ba50971462000249576200010c565b806328f32f38146200015457806329c5efad146200017e578063349e8cca14620001a7575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156200014d573d6000f35b3d6000fd5b005b6200016b62000165366004620041ea565b62000313565b6040519081526020015b60405180910390f35b620001956200018f366004620042d0565b6200068c565b604051620001759493929190620043f8565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200162000175565b620001526200020036600462004435565b62000930565b6200016b6200021736600462004485565b62000998565b620002346200022e366004620042d0565b620009fe565b60405162000175979695949392919062004538565b62000152620010f0565b62000152620002643660046200458a565b620011f3565b60005473ffffffffffffffffffffffffffffffffffffffff16620001c9565b620001526200029a36600462004617565b62001e64565b62000152620002b13660046200467a565b620021ec565b62000152620002c8366004620046a9565b6200247f565b62000195620002df3660046200477f565b62002846565b62000152620002f6366004620047f6565b62002916565b620002346200030d366004620046a9565b6200292e565b6000805473ffffffffffffffffffffffffffffffffffffffff163314801590620003475750620003456009336200296c565b155b156200037f576040517fd48b678b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff89163b620003ce576040517f09ee12d500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b620003d986620029a0565b9050600089307f00000000000000000000000000000000000000000000000000000000000000006040516200040e9062003f7b565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f08015801562000458573d6000803e3d6000fd5b5090506200051f826040518060e001604052806000151581526020018c63ffffffff16815260200163ffffffff801681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff168152602001600063ffffffff168152508a89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92508a915062002b449050565b6014805474010000000000000000000000000000000000000000900463ffffffff1690806200054e8362004845565b91906101000a81548163ffffffff021916908363ffffffff16021790555050817fbae366358c023f887e791d7a62f2e4316f1026bd77f6fb49501a917b3bc5d0128a8a604051620005c792919063ffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a2817fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d878760405162000603929190620048b4565b60405180910390a2817f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d5664856040516200063d9190620048ca565b60405180910390a2817f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf485084604051620006779190620048ca565b60405180910390a25098975050505050505050565b600060606000806200069d62002f1f565b600086815260046020908152604091829020825160e081018452815460ff811615158252610100810463ffffffff90811694830194909452650100000000008104841694820194909452690100000000000000000090930473ffffffffffffffffffffffffffffffffffffffff166060840152600101546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a0840152780100000000000000000000000000000000000000000000000090041660c08201525a9150600080826060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620007b7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620007dd9190620048ec565b73ffffffffffffffffffffffffffffffffffffffff166013600101600c9054906101000a900463ffffffff1663ffffffff16896040516200081f91906200490c565b60006040518083038160008787f1925050503d80600081146200085f576040519150601f19603f3d011682016040523d82523d6000602084013e62000864565b606091505b50915091505a6200087690856200492a565b935081620008a157600060405180602001604052806000815250600796509650965050505062000927565b80806020019051810190620008b791906200499b565b909750955086620008e557600060405180602001604052806000815250600496509650965050505062000927565b601554865164010000000090910463ffffffff1610156200092357600060405180602001604052806000815250600596509650965050505062000927565b5050505b92959194509250565b6200093b8362002f5a565b6000838152601a602052604090206200095682848362004a90565b50827f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d566483836040516200098b929190620048b4565b60405180910390a2505050565b6000620009f288888860008989604051806020016040528060008152508a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506200031392505050565b98975050505050505050565b60006060600080600080600062000a1462002f1f565b600062000a218a62003010565b905060006012604051806101200160405290816000820160009054906101000a900460ff1660ff1660ff1681526020016000820160019054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160059054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160099054906101000a900462ffffff1662ffffff1662ffffff16815260200160008201600c9054906101000a900461ffff1661ffff1661ffff16815260200160008201600e9054906101000a900460ff1615151515815260200160008201600f9054906101000a900460ff161515151581526020016000820160109054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160008201601c9054906101000a900463ffffffff1663ffffffff1663ffffffff168152505090506000600460008d81526020019081526020016000206040518060e00160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160059054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160099054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160018201600c9054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff1681526020016001820160189054906101000a900463ffffffff1663ffffffff1663ffffffff168152505090508160a001511562000d45576000604051806020016040528060008152506009600084602001516000808263ffffffff1692509950995099509950995099509950505050620010e4565b604081015163ffffffff9081161462000d96576000604051806020016040528060008152506001600084602001516000808263ffffffff1692509950995099509950995099509950505050620010e4565b80511562000ddc576000604051806020016040528060008152506002600084602001516000808263ffffffff1692509950995099509950995099509950505050620010e4565b62000de782620030be565b602083015160155492975090955060009162000e19918591879190640100000000900463ffffffff168a8a87620032b0565b9050806bffffffffffffffffffffffff168260a001516bffffffffffffffffffffffff16101562000e83576000604051806020016040528060008152506006600085602001516000808263ffffffff1692509a509a509a509a509a509a509a5050505050620010e4565b600062000e928e868f62003301565b90505a9850600080846060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000eea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f109190620048ec565b73ffffffffffffffffffffffffffffffffffffffff166013600101600c9054906101000a900463ffffffff1663ffffffff168460405162000f5291906200490c565b60006040518083038160008787f1925050503d806000811462000f92576040519150601f19603f3d011682016040523d82523d6000602084013e62000f97565b606091505b50915091505a62000fa9908c6200492a565b9a5081620010295760155481516801000000000000000090910463ffffffff1610156200100657505060408051602080820190925260008082529490910151939c509a50600899505063ffffffff9091169550620010e492505050565b602090940151939b5060039a505063ffffffff9092169650620010e49350505050565b808060200190518101906200103f91906200499b565b909e509c508d6200108057505060408051602080820190925260008082529490910151939c509a50600499505063ffffffff9091169550620010e492505050565b6015548d5164010000000090910463ffffffff161015620010d157505060408051602080820190925260008082529490910151939c509a50600599505063ffffffff9091169550620010e492505050565b505050506020015163ffffffff16945050505b92959891949750929550565b60015473ffffffffffffffffffffffffffffffffffffffff16331462001177576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600173ffffffffffffffffffffffffffffffffffffffff821660009081526019602052604090205460ff1660038111156200123257620012326200438d565b141580156200127e5750600373ffffffffffffffffffffffffffffffffffffffff821660009081526019602052604090205460ff1660038111156200127b576200127b6200438d565b14155b15620012b6576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6013546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1662001316576040517fd12d7d8d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082900362001352576040517f2c2fc94100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081018290526000808567ffffffffffffffff811115620013a957620013a962004071565b604051908082528060200260200182016040528015620013d3578160200160208202803683370190505b50905060008667ffffffffffffffff811115620013f457620013f462004071565b6040519080825280602002602001820160405280156200147b57816020015b6040805160e08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181620014135790505b50905060008767ffffffffffffffff8111156200149c576200149c62004071565b604051908082528060200260200182016040528015620014d157816020015b6060815260200190600190039081620014bb5790505b50905060008867ffffffffffffffff811115620014f257620014f262004071565b6040519080825280602002602001820160405280156200152757816020015b6060815260200190600190039081620015115790505b50905060008967ffffffffffffffff81111562001548576200154862004071565b6040519080825280602002602001820160405280156200157d57816020015b6060815260200190600190039081620015675790505b50905060005b8a81101562001b61578b8b82818110620015a157620015a162004bb8565b60209081029290920135600081815260048452604090819020815160e081018352815460ff811615158252610100810463ffffffff90811697830197909752650100000000008104871693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490931660c08401529a509098506200168090508962002f5a565b60608801516040517f1a5da6c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c8116600483015290911690631a5da6c890602401600060405180830381600087803b158015620016f057600080fd5b505af115801562001705573d6000803e3d6000fd5b50505050878582815181106200171f576200171f62004bb8565b6020026020010181905250600560008a815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1686828151811062001773576200177362004bb8565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015260008a81526007909152604090208054620017b290620049e8565b80601f0160208091040260200160405190810160405280929190818152602001828054620017e090620049e8565b8015620018315780601f10620018055761010080835404028352916020019162001831565b820191906000526020600020905b8154815290600101906020018083116200181357829003601f168201915b50505050508482815181106200184b576200184b62004bb8565b6020026020010181905250601a60008a815260200190815260200160002080546200187690620049e8565b80601f0160208091040260200160405190810160405280929190818152602001828054620018a490620049e8565b8015620018f55780601f10620018c957610100808354040283529160200191620018f5565b820191906000526020600020905b815481529060010190602001808311620018d757829003601f168201915b50505050508382815181106200190f576200190f62004bb8565b6020026020010181905250601b60008a815260200190815260200160002080546200193a90620049e8565b80601f01602080910402602001604051908101604052809291908181526020018280546200196890620049e8565b8015620019b95780601f106200198d57610100808354040283529160200191620019b9565b820191906000526020600020905b8154815290600101906020018083116200199b57829003601f168201915b5050505050828281518110620019d357620019d362004bb8565b60200260200101819052508760a001516bffffffffffffffffffffffff1687620019fe919062004be7565b60008a815260046020908152604080832080547fffffff000000000000000000000000000000000000000000000000000000000016815560010180547fffffffff000000000000000000000000000000000000000000000000000000001690556007909152812091985062001a74919062003f89565b6000898152601a6020526040812062001a8d9162003f89565b6000898152601b6020526040812062001aa69162003f89565b600089815260066020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905562001ae760028a62003523565b5060a0880151604080516bffffffffffffffffffffffff909216825273ffffffffffffffffffffffffffffffffffffffff8c1660208301528a917fb38647142fbb1ea4c000fc4569b37a4e9a9f6313317b84ee3e5326c1a6cd06ff910160405180910390a28062001b588162004bfd565b91505062001583565b508560185462001b7291906200492a565b60185560008b8b868167ffffffffffffffff81111562001b965762001b9662004071565b60405190808252806020026020018201604052801562001bc0578160200160208202803683370190505b508988888860405160200162001bde98979695949392919062004da3565b60405160208183030381529060405290508973ffffffffffffffffffffffffffffffffffffffff16638e86139b6013600001600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c71249ab60038e73ffffffffffffffffffffffffffffffffffffffff1663aab9edd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001c9a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001cc0919062004e73565b866040518463ffffffff1660e01b815260040162001ce19392919062004e98565b600060405180830381865afa15801562001cff573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405262001d47919081019062004ebf565b6040518263ffffffff1660e01b815260040162001d659190620048ca565b600060405180830381600087803b15801562001d8057600080fd5b505af115801562001d95573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d81166004830152602482018b90527f000000000000000000000000000000000000000000000000000000000000000016925063a9059cbb91506044016020604051808303816000875af115801562001e2f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001e55919062004ef8565b50505050505050505050505050565b60023360009081526019602052604090205460ff16600381111562001e8d5762001e8d6200438d565b1415801562001ec3575060033360009081526019602052604090205460ff16600381111562001ec05762001ec06200438d565b14155b1562001efb576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080808080808062001f11888a018a620050f0565b965096509650965096509650965060005b8751811015620021e057600073ffffffffffffffffffffffffffffffffffffffff1687828151811062001f595762001f5962004bb8565b60200260200101516060015173ffffffffffffffffffffffffffffffffffffffff16036200206d5785818151811062001f965762001f9662004bb8565b6020026020010151307f000000000000000000000000000000000000000000000000000000000000000060405162001fce9062003f7b565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f08015801562002018573d6000803e3d6000fd5b508782815181106200202e576200202e62004bb8565b60200260200101516060019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b6200212588828151811062002086576200208662004bb8565b6020026020010151888381518110620020a357620020a362004bb8565b6020026020010151878481518110620020c057620020c062004bb8565b6020026020010151878581518110620020dd57620020dd62004bb8565b6020026020010151878681518110620020fa57620020fa62004bb8565b602002602001015187878151811062002117576200211762004bb8565b602002602001015162002b44565b8781815181106200213a576200213a62004bb8565b60200260200101517f74931a144e43a50694897f241d973aecb5024c0e910f9bb80a163ea3c1cf5a7188838151811062002178576200217862004bb8565b602002602001015160a0015133604051620021c39291906bffffffffffffffffffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a280620021d78162004bfd565b91505062001f22565b50505050505050505050565b600082815260046020908152604091829020825160e081018452815460ff81161515825263ffffffff6101008204811694830194909452650100000000008104841694820185905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a083015278010000000000000000000000000000000000000000000000009004821660c08201529114620022ea576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818160a00151620022fc919062005221565b600084815260046020526040902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff166c010000000000000000000000006bffffffffffffffffffffffff93841602179055601854620023649184169062004be7565b6018556040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526bffffffffffffffffffffffff831660448201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906323b872dd906064016020604051808303816000875af11580156200240e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002434919062004ef8565b506040516bffffffffffffffffffffffff83168152339084907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a3505050565b6000818152600460209081526040808320815160e081018352815460ff81161515825263ffffffff6101008204811695830195909552650100000000008104851693820184905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a083015278010000000000000000000000000000000000000000000000009004831660c082015292911415906200256860005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16149050818015620025c35750808015620025c15750620025b462003531565b836040015163ffffffff16115b155b15620025fb576040517ffbc0357800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b801580156200262e575060008481526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b1562002666576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006200267262003531565b9050816200268a576200268760328262004be7565b90505b6000858152600460205260409020805463ffffffff80841665010000000000027fffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffff90921691909117909155620026e69060029087906200352316565b5060135460808501516bffffffffffffffffffffffff91821691600091168211156200274f5760808601516200271d908362005249565b90508560a001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff1611156200274f575060a08501515b808660a0015162002761919062005249565b600088815260046020526040902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff166c010000000000000000000000006bffffffffffffffffffffffff93841602179055601454620027c99183911662005221565b601480547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff9290921691909117905560405167ffffffffffffffff84169088907f91cb3bb75cfbd718bbfccc56b7f53d92d7048ef4ca39a3b7b7c6d4af1f79118190600090a350505050505050565b600060606000806200285762002f1f565b6000634b56a42e60e01b888888604051602401620028789392919062005271565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915290506200290389826200068c565b929c919b50995090975095505050505050565b62002920620035ed565b6200292b8162003670565b50565b600060606000806000806000620029558860405180602001604052806000815250620009fe565b959e949d50929b5090995097509550909350915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b90505b92915050565b6000806000620029c76001620029b562003531565b620029c191906200492a565b62003767565b601454604080516020810193909352309083015274010000000000000000000000000000000000000000900463ffffffff166060820152608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083015201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060045b600f81101562002ad3578282828151811062002a8f5762002a8f62004bb8565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508062002aca8162004bfd565b91505062002a6f565b5083600181111562002ae95762002ae96200438d565b60f81b81600f8151811062002b025762002b0262004bb8565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535062002b3c81620052a5565b949350505050565b6012546e010000000000000000000000000000900460ff161562002b94576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601554835163ffffffff909116101562002bda576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108fc856020015163ffffffff16108062002c185750601454602086015163ffffffff70010000000000000000000000000000000090920482169116115b1562002c50576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000868152600460205260409020546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff161562002cba576040517f6e3b930b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000868152600460209081526040808320885181548a8501518b85015160608d01517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009093169315157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169390931761010063ffffffff92831602177fffffff000000000000000000000000000000000000000000000000ffffffffff1665010000000000938216939093027fffffff0000000000000000000000000000000000000000ffffffffffffffffff1692909217690100000000000000000073ffffffffffffffffffffffffffffffffffffffff9283160217835560808b01516001909301805460a08d015160c08e01516bffffffffffffffffffffffff9687167fffffffffffffffff000000000000000000000000000000000000000000000000909316929092176c010000000000000000000000009690911695909502949094177fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009490931693909302919091179091556005835281842080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169189169190911790556007909152902062002ead8482620052e8565b508460a001516bffffffffffffffffffffffff1660185462002ed0919062004be7565b6018556000868152601a6020526040902062002eed8382620052e8565b506000868152601b6020526040902062002f088282620052e8565b5062002f16600287620038cf565b50505050505050565b321562002f58576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff16331462002fb8576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090205465010000000000900463ffffffff908116146200292b576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818160045b600f811015620030a5577fff00000000000000000000000000000000000000000000000000000000000000821683826020811062003059576200305962004bb8565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146200309057506000949350505050565b806200309c8162004bfd565b91505062003017565b5081600f1a600181111562002b3c5762002b3c6200438d565b6000806000836060015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156200314b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200317191906200542a565b50945090925050506000811315806200318957508142105b80620031ae5750828015620031ae5750620031a582426200492a565b8463ffffffff16105b15620031bf576016549550620031c3565b8095505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156200322f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200325591906200542a565b50945090925050506000811315806200326d57508142105b806200329257508280156200329257506200328982426200492a565b8463ffffffff16105b15620032a3576017549450620032a7565b8094505b50505050915091565b600080620032c488878b60000151620038dd565b9050600080620032e18b8a63ffffffff16858a8a60018b6200397c565b9092509050620032f2818362005221565b9b9a5050505050505050505050565b606060008360018111156200331a576200331a6200438d565b03620033e7576000848152600760205260409081902090517f6e04ff0d0000000000000000000000000000000000000000000000000000000091620033629160240162005522565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915290506200351c565b6001836001811115620033fe57620033fe6200438d565b03620034ea576000828060200190518101906200341c919062005599565b6000868152600760205260409081902090519192507f40691db4000000000000000000000000000000000000000000000000000000009162003463918491602401620056ad565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915291506200351c9050565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9392505050565b600062002997838362003e1e565b600060017f000000000000000000000000000000000000000000000000000000000000000060028111156200356a576200356a6200438d565b03620035e857606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620035bd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620035e3919062005775565b905090565b504390565b60005473ffffffffffffffffffffffffffffffffffffffff16331462002f58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016200116e565b3373ffffffffffffffffffffffffffffffffffffffff821603620036f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200116e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060017f00000000000000000000000000000000000000000000000000000000000000006002811115620037a057620037a06200438d565b03620038c5576000606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620037f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200381b919062005775565b905080831015806200383957506101006200383784836200492a565b115b15620038485750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815260048101849052606490632b407a8290602401602060405180830381865afa1580156200389f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200351c919062005775565b504090565b919050565b600062002997838362003f29565b60008080856001811115620038f657620038f66200438d565b0362003907575062015f906200392a565b60018560018111156200391e576200391e6200438d565b03620034ea57506201adb05b6200393d63ffffffff851660146200578f565b6200394a846001620057cf565b6200395b9060ff16611d4c6200578f565b62003967908362004be7565b62003973919062004be7565b95945050505050565b6000806000896080015161ffff16876200399791906200578f565b9050838015620039a65750803a105b15620039af57503a5b600060027f00000000000000000000000000000000000000000000000000000000000000006002811115620039e857620039e86200438d565b0362003b5957604080516000815260208101909152851562003a4c5760003660405180608001604052806048815260200162005cc46048913960405160200162003a3593929190620057eb565b604051602081830303815290604052905062003aba565b60155462003a6a90640100000000900463ffffffff16600462005814565b63ffffffff1667ffffffffffffffff81111562003a8b5762003a8b62004071565b6040519080825280601f01601f19166020018201604052801562003ab6576020820181803683370190505b5090505b6040517f49948e0e00000000000000000000000000000000000000000000000000000000815273420000000000000000000000000000000000000f906349948e0e9062003b0c908490600401620048ca565b602060405180830381865afa15801562003b2a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003b50919062005775565b91505062003cc3565b60017f0000000000000000000000000000000000000000000000000000000000000000600281111562003b905762003b906200438d565b0362003cc357841562003c1857606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562003bea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003c10919062005775565b905062003cc3565b6000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c060405180830381865afa15801562003c67573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003c8d919062005843565b505060155492945062003cb293505050640100000000900463ffffffff16826200578f565b62003cbf9060106200578f565b9150505b8462003ce257808b6080015161ffff1662003cdf91906200578f565b90505b62003cf261ffff8716826200588e565b90506000878262003d048c8e62004be7565b62003d1090866200578f565b62003d1c919062004be7565b62003d3090670de0b6b3a76400006200578f565b62003d3c91906200588e565b905060008c6040015163ffffffff1664e8d4a5100062003d5d91906200578f565b898e6020015163ffffffff16858f8862003d7891906200578f565b62003d84919062004be7565b62003d9490633b9aca006200578f565b62003da091906200578f565b62003dac91906200588e565b62003db8919062004be7565b90506b033b2e3c9fd0803ce800000062003dd3828462004be7565b111562003e0c576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909c909b509950505050505050505050565b6000818152600183016020526040812054801562003f1757600062003e456001836200492a565b855490915060009062003e5b906001906200492a565b905081811462003ec757600086600001828154811062003e7f5762003e7f62004bb8565b906000526020600020015490508087600001848154811062003ea55762003ea562004bb8565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062003edb5762003edb620058ca565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200299a565b60009150506200299a565b5092915050565b600081815260018301602052604081205462003f72575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200299a565b5060006200299a565b6103ca80620058fa83390190565b50805462003f9790620049e8565b6000825580601f1062003fa8575050565b601f0160209004906000526020600020908101906200292b91905b8082111562003fd9576000815560010162003fc3565b5090565b73ffffffffffffffffffffffffffffffffffffffff811681146200292b57600080fd5b803563ffffffff81168114620038ca57600080fd5b803560028110620038ca57600080fd5b60008083601f8401126200403857600080fd5b50813567ffffffffffffffff8111156200405157600080fd5b6020830191508360208285010111156200406a57600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160e0810167ffffffffffffffff81118282101715620040c657620040c662004071565b60405290565b604051610100810167ffffffffffffffff81118282101715620040c657620040c662004071565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156200413d576200413d62004071565b604052919050565b600067ffffffffffffffff82111562004162576200416262004071565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112620041a057600080fd5b8135620041b7620041b18262004145565b620040f3565b818152846020838601011115620041cd57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060008060e0898b0312156200420757600080fd5b8835620042148162003fdd565b97506200422460208a0162004000565b96506040890135620042368162003fdd565b95506200424660608a0162004015565b9450608089013567ffffffffffffffff808211156200426457600080fd5b620042728c838d0162004025565b909650945060a08b01359150808211156200428c57600080fd5b6200429a8c838d016200418e565b935060c08b0135915080821115620042b157600080fd5b50620042c08b828c016200418e565b9150509295985092959890939650565b60008060408385031215620042e457600080fd5b82359150602083013567ffffffffffffffff8111156200430357600080fd5b62004311858286016200418e565b9150509250929050565b60005b83811015620043385781810151838201526020016200431e565b50506000910152565b600081518084526200435b8160208601602086016200431b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600a8110620043f4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b841515815260806020820152600062004415608083018662004341565b9050620044266040830185620043bc565b82606083015295945050505050565b6000806000604084860312156200444b57600080fd5b83359250602084013567ffffffffffffffff8111156200446a57600080fd5b620044788682870162004025565b9497909650939450505050565b600080600080600080600060a0888a031215620044a157600080fd5b8735620044ae8162003fdd565b9650620044be6020890162004000565b95506040880135620044d08162003fdd565b9450606088013567ffffffffffffffff80821115620044ee57600080fd5b620044fc8b838c0162004025565b909650945060808a01359150808211156200451657600080fd5b50620045258a828b0162004025565b989b979a50959850939692959293505050565b871515815260e0602082015260006200455560e083018962004341565b9050620045666040830188620043bc565b8560608301528460808301528360a08301528260c083015298975050505050505050565b600080600060408486031215620045a057600080fd5b833567ffffffffffffffff80821115620045b957600080fd5b818601915086601f830112620045ce57600080fd5b813581811115620045de57600080fd5b8760208260051b8501011115620045f457600080fd5b602092830195509350508401356200460c8162003fdd565b809150509250925092565b600080602083850312156200462b57600080fd5b823567ffffffffffffffff8111156200464357600080fd5b620046518582860162004025565b90969095509350505050565b80356bffffffffffffffffffffffff81168114620038ca57600080fd5b600080604083850312156200468e57600080fd5b82359150620046a0602084016200465d565b90509250929050565b600060208284031215620046bc57600080fd5b5035919050565b600067ffffffffffffffff821115620046e057620046e062004071565b5060051b60200190565b600082601f830112620046fc57600080fd5b813560206200470f620041b183620046c3565b82815260059290921b840181019181810190868411156200472f57600080fd5b8286015b848110156200477457803567ffffffffffffffff811115620047555760008081fd5b620047658986838b01016200418e565b84525091830191830162004733565b509695505050505050565b600080600080606085870312156200479657600080fd5b84359350602085013567ffffffffffffffff80821115620047b657600080fd5b620047c488838901620046ea565b94506040870135915080821115620047db57600080fd5b50620047ea8782880162004025565b95989497509550505050565b6000602082840312156200480957600080fd5b81356200351c8162003fdd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600063ffffffff80831681810362004861576200486162004816565b6001019392505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60208152600062002b3c6020830184866200486b565b60208152600062002997602083018462004341565b8051620038ca8162003fdd565b600060208284031215620048ff57600080fd5b81516200351c8162003fdd565b60008251620049208184602087016200431b565b9190910192915050565b818103818111156200299a576200299a62004816565b80151581146200292b57600080fd5b600082601f8301126200496157600080fd5b815162004972620041b18262004145565b8181528460208386010111156200498857600080fd5b62002b3c8260208301602087016200431b565b60008060408385031215620049af57600080fd5b8251620049bc8162004940565b602084015190925067ffffffffffffffff811115620049da57600080fd5b62004311858286016200494f565b600181811c90821680620049fd57607f821691505b60208210810362004a37577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111562004a8b57600081815260208120601f850160051c8101602086101562004a665750805b601f850160051c820191505b8181101562004a875782815560010162004a72565b5050505b505050565b67ffffffffffffffff83111562004aab5762004aab62004071565b62004ac38362004abc8354620049e8565b8362004a3d565b6000601f84116001811462004b18576000851562004ae15750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835562004bb1565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101562004b69578685013582556020948501946001909201910162004b47565b508682101562004ba5577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b808201808211156200299a576200299a62004816565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362004c315762004c3162004816565b5060010190565b600081518084526020808501945080840160005b8381101562004cf75781518051151588528381015163ffffffff908116858a01526040808301519091169089015260608082015173ffffffffffffffffffffffffffffffffffffffff16908901526080808201516bffffffffffffffffffffffff169089015260a08082015162004cd2828b01826bffffffffffffffffffffffff169052565b505060c09081015163ffffffff169088015260e0909601959082019060010162004c4c565b509495945050505050565b600081518084526020808501945080840160005b8381101562004cf757815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010162004d16565b600081518084526020808501808196508360051b8101915082860160005b8581101562004d9657828403895262004d8384835162004341565b9885019893509084019060010162004d68565b5091979650505050505050565b60e081528760e082015260006101007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8a111562004de057600080fd5b8960051b808c8386013783018381038201602085015262004e048282018b62004c38565b915050828103604084015262004e1b818962004d02565b9050828103606084015262004e31818862004d02565b9050828103608084015262004e47818762004d4a565b905082810360a084015262004e5d818662004d4a565b905082810360c0840152620032f2818562004d4a565b60006020828403121562004e8657600080fd5b815160ff811681146200351c57600080fd5b60ff8416815260ff8316602082015260606040820152600062003973606083018462004341565b60006020828403121562004ed257600080fd5b815167ffffffffffffffff81111562004eea57600080fd5b62002b3c848285016200494f565b60006020828403121562004f0b57600080fd5b81516200351c8162004940565b600082601f83011262004f2a57600080fd5b8135602062004f3d620041b183620046c3565b82815260059290921b8401810191818101908684111562004f5d57600080fd5b8286015b8481101562004774578035835291830191830162004f61565b600082601f83011262004f8c57600080fd5b8135602062004f9f620041b183620046c3565b82815260e0928302850182019282820191908785111562004fbf57600080fd5b8387015b85811015620050765781818a03121562004fdd5760008081fd5b62004fe7620040a0565b813562004ff48162004940565b81526200500382870162004000565b8682015260406200501681840162004000565b908201526060828101356200502b8162003fdd565b9082015260806200503e8382016200465d565b9082015260a0620050518382016200465d565b9082015260c06200506483820162004000565b90820152845292840192810162004fc3565b5090979650505050505050565b600082601f8301126200509557600080fd5b81356020620050a8620041b183620046c3565b82815260059290921b84018101918181019086841115620050c857600080fd5b8286015b8481101562004774578035620050e28162003fdd565b8352918301918301620050cc565b600080600080600080600060e0888a0312156200510c57600080fd5b873567ffffffffffffffff808211156200512557600080fd5b620051338b838c0162004f18565b985060208a01359150808211156200514a57600080fd5b620051588b838c0162004f7a565b975060408a01359150808211156200516f57600080fd5b6200517d8b838c0162005083565b965060608a01359150808211156200519457600080fd5b620051a28b838c0162005083565b955060808a0135915080821115620051b957600080fd5b620051c78b838c01620046ea565b945060a08a0135915080821115620051de57600080fd5b620051ec8b838c01620046ea565b935060c08a01359150808211156200520357600080fd5b50620052128a828b01620046ea565b91505092959891949750929550565b6bffffffffffffffffffffffff81811683821601908082111562003f225762003f2262004816565b6bffffffffffffffffffffffff82811682821603908082111562003f225762003f2262004816565b60408152600062005286604083018662004d4a565b82810360208401526200529b8185876200486b565b9695505050505050565b8051602080830151919081101562004a37577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b815167ffffffffffffffff81111562005305576200530562004071565b6200531d81620053168454620049e8565b8462004a3d565b602080601f8311600181146200537357600084156200533c5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855562004a87565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015620053c257888601518255948401946001909101908401620053a1565b5085821015620053ff57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b805169ffffffffffffffffffff81168114620038ca57600080fd5b600080600080600060a086880312156200544357600080fd5b6200544e866200540f565b945060208601519350604086015192506060860151915062005473608087016200540f565b90509295509295909350565b600081546200548e81620049e8565b808552602060018381168015620054ae5760018114620054e75762005517565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b890101955062005517565b866000528260002060005b858110156200550f5781548a8201860152908301908401620054f2565b890184019650505b505050505092915050565b6020815260006200299760208301846200547f565b600082601f8301126200554957600080fd5b815160206200555c620041b183620046c3565b82815260059290921b840181019181810190868411156200557c57600080fd5b8286015b8481101562004774578051835291830191830162005580565b600060208284031215620055ac57600080fd5b815167ffffffffffffffff80821115620055c557600080fd5b908301906101008286031215620055db57600080fd5b620055e5620040cc565b82518152602083015160208201526040830151604082015260608301516060820152608083015160808201526200561f60a08401620048df565b60a082015260c0830151828111156200563757600080fd5b620056458782860162005537565b60c08301525060e0830151828111156200565e57600080fd5b6200566c878286016200494f565b60e08301525095945050505050565b600081518084526020808501945080840160005b8381101562004cf7578151875295820195908201906001016200568f565b60408152825160408201526020830151606082015260408301516080820152606083015160a0820152608083015160c082015273ffffffffffffffffffffffffffffffffffffffff60a08401511660e0820152600060c0840151610100808185015250620057206101408401826200567b565b905060e08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0848303016101208501526200575e828262004341565b91505082810360208401526200397381856200547f565b6000602082840312156200578857600080fd5b5051919050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615620057ca57620057ca62004816565b500290565b60ff81811683821601908111156200299a576200299a62004816565b8284823760008382016000815283516200580a8183602088016200431b565b0195945050505050565b600063ffffffff808316818516818304811182151516156200583a576200583a62004816565b02949350505050565b60008060008060008060c087890312156200585d57600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b600082620058c5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe60c060405234801561001057600080fd5b506040516103ca3803806103ca83398101604081905261002f91610076565b600080546001600160a01b0319166001600160a01b039384161790559181166080521660a0526100b9565b80516001600160a01b038116811461007157600080fd5b919050565b60008060006060848603121561008b57600080fd5b6100948461005a565b92506100a26020850161005a565b91506100b06040850161005a565b90509250925092565b60805160a0516102e76100e36000396000603801526000818160c4015261011701526102e76000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806379188d161461007b578063f00e6a2a146100aa575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610076573d6000f35b3d6000fd5b61008e6100893660046101c1565b6100ee565b6040805192151583526020830191909152015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526020016100a1565b60008054819073ffffffffffffffffffffffffffffffffffffffff16331461011557600080fd5b7f00000000000000000000000000000000000000000000000000000000000000005a91505a61138881101561014957600080fd5b61138881039050856040820482031161016157600080fd5b50803b61016d57600080fd5b6000808551602087016000858af192505a610188908361029a565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080604083850312156101d457600080fd5b82359150602083013567ffffffffffffffff808211156101f357600080fd5b818501915085601f83011261020757600080fd5b81358181111561021957610219610192565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561025f5761025f610192565b8160405282815288602084870101111561027857600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b818103818111156102d4577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9291505056fea164736f6c6343000810000a307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000810000a", } var KeeperRegistryLogicAABI = KeeperRegistryLogicAMetaData.ABI @@ -263,16 +263,16 @@ func (_KeeperRegistryLogicA *KeeperRegistryLogicATransactorSession) CheckCallbac return _KeeperRegistryLogicA.Contract.CheckCallback(&_KeeperRegistryLogicA.TransactOpts, id, values, extraData) } -func (_KeeperRegistryLogicA *KeeperRegistryLogicATransactor) CheckUpkeep(opts *bind.TransactOpts, id *big.Int, checkData []byte) (*types.Transaction, error) { - return _KeeperRegistryLogicA.contract.Transact(opts, "checkUpkeep", id, checkData) +func (_KeeperRegistryLogicA *KeeperRegistryLogicATransactor) CheckUpkeep(opts *bind.TransactOpts, id *big.Int, triggerData []byte) (*types.Transaction, error) { + return _KeeperRegistryLogicA.contract.Transact(opts, "checkUpkeep", id, triggerData) } -func (_KeeperRegistryLogicA *KeeperRegistryLogicASession) CheckUpkeep(id *big.Int, checkData []byte) (*types.Transaction, error) { - return _KeeperRegistryLogicA.Contract.CheckUpkeep(&_KeeperRegistryLogicA.TransactOpts, id, checkData) +func (_KeeperRegistryLogicA *KeeperRegistryLogicASession) CheckUpkeep(id *big.Int, triggerData []byte) (*types.Transaction, error) { + return _KeeperRegistryLogicA.Contract.CheckUpkeep(&_KeeperRegistryLogicA.TransactOpts, id, triggerData) } -func (_KeeperRegistryLogicA *KeeperRegistryLogicATransactorSession) CheckUpkeep(id *big.Int, checkData []byte) (*types.Transaction, error) { - return _KeeperRegistryLogicA.Contract.CheckUpkeep(&_KeeperRegistryLogicA.TransactOpts, id, checkData) +func (_KeeperRegistryLogicA *KeeperRegistryLogicATransactorSession) CheckUpkeep(id *big.Int, triggerData []byte) (*types.Transaction, error) { + return _KeeperRegistryLogicA.Contract.CheckUpkeep(&_KeeperRegistryLogicA.TransactOpts, id, triggerData) } func (_KeeperRegistryLogicA *KeeperRegistryLogicATransactor) CheckUpkeep0(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) { @@ -572,9 +572,9 @@ func (it *KeeperRegistryLogicACancelledUpkeepReportIterator) Close() error { } type KeeperRegistryLogicACancelledUpkeepReport struct { - Id *big.Int - UpkeepTriggerID [32]byte - Raw types.Log + Id *big.Int + Trigger []byte + Raw types.Log } func (_KeeperRegistryLogicA *KeeperRegistryLogicAFilterer) FilterCancelledUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*KeeperRegistryLogicACancelledUpkeepReportIterator, error) { @@ -639,6 +639,133 @@ func (_KeeperRegistryLogicA *KeeperRegistryLogicAFilterer) ParseCancelledUpkeepR return event, nil } +type KeeperRegistryLogicADedupKeyAddedIterator struct { + Event *KeeperRegistryLogicADedupKeyAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistryLogicADedupKeyAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistryLogicADedupKeyAdded) + 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(KeeperRegistryLogicADedupKeyAdded) + 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 *KeeperRegistryLogicADedupKeyAddedIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistryLogicADedupKeyAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistryLogicADedupKeyAdded struct { + DedupKey [32]byte + Raw types.Log +} + +func (_KeeperRegistryLogicA *KeeperRegistryLogicAFilterer) FilterDedupKeyAdded(opts *bind.FilterOpts, dedupKey [][32]byte) (*KeeperRegistryLogicADedupKeyAddedIterator, error) { + + var dedupKeyRule []interface{} + for _, dedupKeyItem := range dedupKey { + dedupKeyRule = append(dedupKeyRule, dedupKeyItem) + } + + logs, sub, err := _KeeperRegistryLogicA.contract.FilterLogs(opts, "DedupKeyAdded", dedupKeyRule) + if err != nil { + return nil, err + } + return &KeeperRegistryLogicADedupKeyAddedIterator{contract: _KeeperRegistryLogicA.contract, event: "DedupKeyAdded", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistryLogicA *KeeperRegistryLogicAFilterer) WatchDedupKeyAdded(opts *bind.WatchOpts, sink chan<- *KeeperRegistryLogicADedupKeyAdded, dedupKey [][32]byte) (event.Subscription, error) { + + var dedupKeyRule []interface{} + for _, dedupKeyItem := range dedupKey { + dedupKeyRule = append(dedupKeyRule, dedupKeyItem) + } + + logs, sub, err := _KeeperRegistryLogicA.contract.WatchLogs(opts, "DedupKeyAdded", dedupKeyRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(KeeperRegistryLogicADedupKeyAdded) + if err := _KeeperRegistryLogicA.contract.UnpackLog(event, "DedupKeyAdded", 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 (_KeeperRegistryLogicA *KeeperRegistryLogicAFilterer) ParseDedupKeyAdded(log types.Log) (*KeeperRegistryLogicADedupKeyAdded, error) { + event := new(KeeperRegistryLogicADedupKeyAdded) + if err := _KeeperRegistryLogicA.contract.UnpackLog(event, "DedupKeyAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type KeeperRegistryLogicAFundsAddedIterator struct { Event *KeeperRegistryLogicAFundsAdded @@ -966,9 +1093,9 @@ func (it *KeeperRegistryLogicAInsufficientFundsUpkeepReportIterator) Close() err } type KeeperRegistryLogicAInsufficientFundsUpkeepReport struct { - Id *big.Int - UpkeepTriggerID [32]byte - Raw types.Log + Id *big.Int + Trigger []byte + Raw types.Log } func (_KeeperRegistryLogicA *KeeperRegistryLogicAFilterer) FilterInsufficientFundsUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*KeeperRegistryLogicAInsufficientFundsUpkeepReportIterator, error) { @@ -2154,9 +2281,9 @@ func (it *KeeperRegistryLogicAReorgedUpkeepReportIterator) Close() error { } type KeeperRegistryLogicAReorgedUpkeepReport struct { - Id *big.Int - UpkeepTriggerID [32]byte - Raw types.Log + Id *big.Int + Trigger []byte + Raw types.Log } func (_KeeperRegistryLogicA *KeeperRegistryLogicAFilterer) FilterReorgedUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*KeeperRegistryLogicAReorgedUpkeepReportIterator, error) { @@ -2282,9 +2409,9 @@ func (it *KeeperRegistryLogicAStaleUpkeepReportIterator) Close() error { } type KeeperRegistryLogicAStaleUpkeepReport struct { - Id *big.Int - UpkeepTriggerID [32]byte - Raw types.Log + Id *big.Int + Trigger []byte + Raw types.Log } func (_KeeperRegistryLogicA *KeeperRegistryLogicAFilterer) FilterStaleUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*KeeperRegistryLogicAStaleUpkeepReportIterator, error) { @@ -3593,13 +3720,13 @@ func (it *KeeperRegistryLogicAUpkeepPerformedIterator) Close() error { } type KeeperRegistryLogicAUpkeepPerformed struct { - Id *big.Int - Success bool - TotalPayment *big.Int - GasUsed *big.Int - GasOverhead *big.Int - UpkeepTriggerID [32]byte - Raw types.Log + Id *big.Int + Success bool + TotalPayment *big.Int + GasUsed *big.Int + GasOverhead *big.Int + Trigger []byte + Raw types.Log } func (_KeeperRegistryLogicA *KeeperRegistryLogicAFilterer) FilterUpkeepPerformed(opts *bind.FilterOpts, id []*big.Int, success []bool) (*KeeperRegistryLogicAUpkeepPerformedIterator, error) { @@ -4319,6 +4446,8 @@ func (_KeeperRegistryLogicA *KeeperRegistryLogicA) ParseLog(log types.Log) (gene return _KeeperRegistryLogicA.ParseAdminPrivilegeConfigSet(log) case _KeeperRegistryLogicA.abi.Events["CancelledUpkeepReport"].ID: return _KeeperRegistryLogicA.ParseCancelledUpkeepReport(log) + case _KeeperRegistryLogicA.abi.Events["DedupKeyAdded"].ID: + return _KeeperRegistryLogicA.ParseDedupKeyAdded(log) case _KeeperRegistryLogicA.abi.Events["FundsAdded"].ID: return _KeeperRegistryLogicA.ParseFundsAdded(log) case _KeeperRegistryLogicA.abi.Events["FundsWithdrawn"].ID: @@ -4386,7 +4515,11 @@ func (KeeperRegistryLogicAAdminPrivilegeConfigSet) Topic() common.Hash { } func (KeeperRegistryLogicACancelledUpkeepReport) Topic() common.Hash { - return common.HexToHash("0x846af3fdde418e2757c00c4cf8c6827e65ac4179753128c454922ccd7963886d") + return common.HexToHash("0xc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636") +} + +func (KeeperRegistryLogicADedupKeyAdded) Topic() common.Hash { + return common.HexToHash("0xa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f2") } func (KeeperRegistryLogicAFundsAdded) Topic() common.Hash { @@ -4398,7 +4531,7 @@ func (KeeperRegistryLogicAFundsWithdrawn) Topic() common.Hash { } func (KeeperRegistryLogicAInsufficientFundsUpkeepReport) Topic() common.Hash { - return common.HexToHash("0xfcb5fa059ae0ddeeac53240ccaa0a8ad80993b33e18e8821f1e1cbc53481240e") + return common.HexToHash("0x377c8b0c126ae5248d27aca1c76fac4608aff85673ee3caf09747e1044549e02") } func (KeeperRegistryLogicAOwnerFundsWithdrawn) Topic() common.Hash { @@ -4434,11 +4567,11 @@ func (KeeperRegistryLogicAPaymentWithdrawn) Topic() common.Hash { } func (KeeperRegistryLogicAReorgedUpkeepReport) Topic() common.Hash { - return common.HexToHash("0x07c4f19521a82d67071422fca888431cac8267935db8abe73e354791a3d38868") + return common.HexToHash("0x6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301") } func (KeeperRegistryLogicAStaleUpkeepReport) Topic() common.Hash { - return common.HexToHash("0x909d8c7e883c6d2d53a5fb2dbb9ec57875a53c3769c099230027312ffb2a6b11") + return common.HexToHash("0x405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8") } func (KeeperRegistryLogicAUnpaused) Topic() common.Hash { @@ -4478,7 +4611,7 @@ func (KeeperRegistryLogicAUpkeepPaused) Topic() common.Hash { } func (KeeperRegistryLogicAUpkeepPerformed) Topic() common.Hash { - return common.HexToHash("0xdacc0b3d36199a5f78afb27c76cd01bf100f605edf5ee0c0e23055b0553b68c6") + return common.HexToHash("0xad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b") } func (KeeperRegistryLogicAUpkeepPrivilegeConfigSet) Topic() common.Hash { @@ -4518,7 +4651,7 @@ type KeeperRegistryLogicAInterface interface { CheckCallback(opts *bind.TransactOpts, id *big.Int, values [][]byte, extraData []byte) (*types.Transaction, error) - CheckUpkeep(opts *bind.TransactOpts, id *big.Int, checkData []byte) (*types.Transaction, error) + CheckUpkeep(opts *bind.TransactOpts, id *big.Int, triggerData []byte) (*types.Transaction, error) CheckUpkeep0(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) @@ -4550,6 +4683,12 @@ type KeeperRegistryLogicAInterface interface { ParseCancelledUpkeepReport(log types.Log) (*KeeperRegistryLogicACancelledUpkeepReport, error) + FilterDedupKeyAdded(opts *bind.FilterOpts, dedupKey [][32]byte) (*KeeperRegistryLogicADedupKeyAddedIterator, error) + + WatchDedupKeyAdded(opts *bind.WatchOpts, sink chan<- *KeeperRegistryLogicADedupKeyAdded, dedupKey [][32]byte) (event.Subscription, error) + + ParseDedupKeyAdded(log types.Log) (*KeeperRegistryLogicADedupKeyAdded, error) + FilterFundsAdded(opts *bind.FilterOpts, id []*big.Int, from []common.Address) (*KeeperRegistryLogicAFundsAddedIterator, error) WatchFundsAdded(opts *bind.WatchOpts, sink chan<- *KeeperRegistryLogicAFundsAdded, id []*big.Int, from []common.Address) (event.Subscription, error) diff --git a/core/gethwrappers/generated/keeper_registry_logic_b_wrapper_2_1/keeper_registry_logic_b_wrapper_2_1.go b/core/gethwrappers/generated/keeper_registry_logic_b_wrapper_2_1/keeper_registry_logic_b_wrapper_2_1.go index 9494d6d6aae..15330fb8219 100644 --- a/core/gethwrappers/generated/keeper_registry_logic_b_wrapper_2_1/keeper_registry_logic_b_wrapper_2_1.go +++ b/core/gethwrappers/generated/keeper_registry_logic_b_wrapper_2_1/keeper_registry_logic_b_wrapper_2_1.go @@ -75,15 +75,15 @@ type KeeperRegistryBase21UpkeepInfo struct { } var KeeperRegistryLogicBMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"enumKeeperRegistryBase2_1.Mode\",\"name\":\"mode\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fastGasFeed\",\"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\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"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\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"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\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"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\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"upkeepTriggerID\",\"type\":\"bytes32\"}],\"name\":\"CancelledUpkeepReport\",\"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\":\"bytes32\",\"name\":\"upkeepTriggerID\",\"type\":\"bytes32\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"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\":\"bytes32\",\"name\":\"upkeepTriggerID\",\"type\":\"bytes32\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"upkeepTriggerID\",\"type\":\"bytes32\"}],\"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\":\"bytes32\",\"name\":\"upkeepTriggerID\",\"type\":\"bytes32\"}],\"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\"},{\"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\":\"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\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCancellationDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCheckGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConditionalGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"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\":\"contractAutomationForwarder\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkNativeFeedAddress\",\"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\":\"enumKeeperRegistryBase2_1.Trigger\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"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\":\"getMode\",\"outputs\":[{\"internalType\":\"enumKeeperRegistryBase2_1.Mode\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"}],\"name\":\"getPeerRegistryMigrationPermission\",\"outputs\":[{\"internalType\":\"enumKeeperRegistryBase2_1.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\":[{\"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\":\"structKeeperRegistryBase2_1.State\",\"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\":\"structKeeperRegistryBase2_1.OnchainConfig\",\"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\":\"getTransmitGasOverhead\",\"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\":\"enumKeeperRegistryBase2_1.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\":\"structKeeperRegistryBase2_1.UpkeepInfo\",\"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\":\"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\":[],\"name\":\"recoverFunds\",\"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\":\"enumKeeperRegistryBase2_1.MigrationPermission\",\"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\":\"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\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"unpauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTranscoderVersion\",\"outputs\":[{\"internalType\":\"enumUpkeepFormat\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawOwnerFunds\",\"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\"}]", - Bin: "0x6101006040523480156200001257600080fd5b5060405162004eb838038062004eb88339810160408190526200003591620001e1565b838383833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c38162000119565b505050836002811115620000db57620000db62000243565b60e0816002811115620000f257620000f262000243565b9052506001600160a01b0392831660805290821660a0521660c05250620002599350505050565b336001600160a01b03821603620001735760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001dc57600080fd5b919050565b60008060008060808587031215620001f857600080fd5b8451600381106200020857600080fd5b93506200021860208601620001c4565b92506200022860408601620001c4565b91506200023860608601620001c4565b905092959194509250565b634e487b7160e01b600052602160045260246000fd5b60805160a05160c05160e051614bdf620002d9600039600081816104fb0152818161329d0152818161382001526139b301526000818161058301526130910152600081816106cc015261316b01526000818161075a01528181611b7b01528181611e51015281816122c9015281816127eb015261286f0152614bdf6000f3fe608060405234801561001057600080fd5b50600436106103365760003560e01c806379ea9943116101b2578063b148ab6b116100f9578063cd7f71b5116100a2578063eb5dcd6c1161007c578063eb5dcd6c146107ad578063ed56b3e1146107c0578063f2fde38b14610833578063faa3e9961461084657600080fd5b8063cd7f71b51461077e578063d2b441ab14610791578063d76326481461079a57600080fd5b8063b79550be116100d3578063b79550be14610730578063c7c3a19a14610738578063ca30e6031461075857600080fd5b8063b148ab6b14610703578063b6511a2a14610716578063b657bc9c1461071d57600080fd5b8063a710b2211161015b578063abc76ae011610135578063abc76ae0146106c2578063b10b673c146106ca578063b121e147146106f057600080fd5b8063a710b2211461068d578063a72aa27e146106a0578063aab9edd6146106b357600080fd5b80638765ecbe1161018c5780638765ecbe146106495780638da5cb5b1461065c5780638dcf0fe71461067a57600080fd5b806379ea9943146105f65780637d9b97e0146106395780638456cb591461064157600080fd5b80633f4ba83a116102815780635165f2f51161022a5780636709d0e5116102045780636709d0e514610581578063671d36ed146105c8578063744bfe61146105db57806379ba5097146105ee57600080fd5b80635165f2f5146105485780635b6aa71c1461055b5780636209e1e91461056e57600080fd5b80634b4fd03b1161025b5780634b4fd03b146104f95780634ca16c521461051f5780635147cd591461052857600080fd5b80633f4ba83a1461047b578063421d183b1461048357806348013d7b146104e957600080fd5b80631a2af011116102e3578063232c1cc5116102bd578063232c1cc5146104585780632d9c718f1461045f5780633b9cce591461046857600080fd5b80631a2af011146103d45780631e010439146103e7578063207b65161461044557600080fd5b80631865c57d116103145780631865c57d14610388578063187256e8146103a157806319d97a94146103b457600080fd5b8063050ee65d1461033b57806306e3b632146103535780630b7d33e614610373575b600080fd5b6201adb05b6040519081526020015b60405180910390f35b610366610361366004613d3e565b61088c565b60405161034a9190613d60565b610386610381366004613ded565b6109a9565b005b610390610a63565b60405161034a959493929190613ff0565b6103866103af36600461412e565b610e7c565b6103c76103c2366004614169565b610eed565b60405161034a91906141f0565b6103866103e2366004614203565b610f8f565b6104286103f5366004614169565b6000908152600460205260409020600101546c0100000000000000000000000090046bffffffffffffffffffffffff1690565b6040516bffffffffffffffffffffffff909116815260200161034a565b6103c7610453366004614169565b611095565b6014610340565b62061a80610340565b61038661047636600461422f565b6110b2565b610386611308565b6104966104913660046142a4565b61136e565b60408051951515865260ff90941660208601526bffffffffffffffffffffffff9283169385019390935216606083015273ffffffffffffffffffffffffffffffffffffffff16608082015260a00161034a565b60005b60405161034a91906142fe565b7f00000000000000000000000000000000000000000000000000000000000000006104ec565b62015f90610340565b61053b610536366004614169565b6114a1565b60405161034a9190614311565b610386610556366004614169565b6114ac565b610428610569366004614339565b61162e565b6103c761057c3660046142a4565b611760565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161034a565b6103866105d6366004614369565b611794565b6103866105e9366004614203565b61186e565b610386611c77565b6105a3610604366004614169565b6000908152600460205260409020546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b610386611d79565b610386611ed4565b610386610657366004614169565b611f45565b60005473ffffffffffffffffffffffffffffffffffffffff166105a3565b610386610688366004613ded565b6120ca565b61038661069b3660046143a3565b61211f565b6103866106ae3660046143cd565b61239b565b6040516003815260200161034a565b611d4c610340565b7f00000000000000000000000000000000000000000000000000000000000000006105a3565b6103866106fe3660046142a4565b612490565b610386610711366004614169565b612588565b6032610340565b61042861072b366004614169565b612785565b6103866127b2565b61074b610746366004614169565b61290e565b60405161034a91906143f0565b7f00000000000000000000000000000000000000000000000000000000000000006105a3565b61038661078c366004613ded565b612c42565b620f4240610340565b6104286107a8366004614169565b612cd9565b6103866107bb3660046143a3565b612ce4565b61081a6107ce3660046142a4565b73ffffffffffffffffffffffffffffffffffffffff166000908152600c602090815260409182902082518084019093525460ff8082161515808552610100909204169290910182905291565b60408051921515835260ff90911660208301520161034a565b6103866108413660046142a4565b612e42565b61087f6108543660046142a4565b73ffffffffffffffffffffffffffffffffffffffff1660009081526019602052604090205460ff1690565b60405161034a9190614527565b6060600061089a6002612e56565b90508084106108d5576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006108e1848661456a565b9050818111806108ef575083155b6108f957806108fb565b815b90506000610909868361457d565b67ffffffffffffffff81111561092157610921614590565b60405190808252806020026020018201604052801561094a578160200160208202803683370190505b50905060005b815181101561099d5761096e610966888361456a565b600290612e60565b828281518110610980576109806145bf565b602090810291909101015280610995816145ee565b915050610950565b50925050505b92915050565b6015546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314610a0a576040517f77c3599200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152601c60205260409020610a238284836146c8565b50827f2fd8d70753a007014349d4591843cc031c2dd7a260d7dd82eca8253686ae77698383604051610a569291906147e3565b60405180910390a2505050565b6040805161014081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810191909152604080516101e08101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e08201839052610100820183905261012082018390526101408201839052610160820183905261018082018390526101a08201526101c0810191909152604080516101408101825260145463ffffffff7401000000000000000000000000000000000000000082041682526bffffffffffffffffffffffff908116602083015260185492820192909252601254700100000000000000000000000000000000900490911660608281019190915290819060009060808101610bb06002612e56565b81526014547801000000000000000000000000000000000000000000000000810463ffffffff9081166020808501919091527c0100000000000000000000000000000000000000000000000000000000808404831660408087019190915260115460608088019190915260125492830485166080808901919091526e010000000000000000000000000000840460ff16151560a09889015282516101e081018452610100808604881682526501000000000086048816968201969096526c010000000000000000000000008089048816948201949094526901000000000000000000850462ffffff16928101929092529282900461ffff16928101929092526013546bffffffffffffffffffffffff811696830196909652700100000000000000000000000000000000909404831660c082015260155480841660e0830152640100000000810484169282019290925268010000000000000000909104909116610120820152601654610140820152601754610160820152910473ffffffffffffffffffffffffffffffffffffffff166101808201529095506101a08101610d586009612e73565b81526015546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16602091820152601254600d80546040805182860281018601909152818152949850899489949293600e9360ff909116928591830182828015610dfb57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610dd0575b5050505050925081805480602002602001604051908101604052809291908181526020018280548015610e6457602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610e39575b50505050509150945094509450945094509091929394565b610e84612e80565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260196020526040902080548291907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836003811115610ee457610ee46142bf565b02179055505050565b6000818152601c60205260409020805460609190610f0a90614626565b80601f0160208091040260200160405190810160405280929190818152602001828054610f3690614626565b8015610f835780601f10610f5857610100808354040283529160200191610f83565b820191906000526020600020905b815481529060010190602001808311610f6657829003601f168201915b50505050509050919050565b610f9882612f03565b3373ffffffffffffffffffffffffffffffffffffffff821603610fe7576040517f8c8728c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff8281169116146110915760008281526006602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851690811790915590519091339185917fb1cbb2c4b8480034c27e06da5f096b8233a8fd4497028593a41ff6df79726b3591a45b5050565b6000818152601a60205260409020805460609190610f0a90614626565b6110ba612e80565b600e5481146110f5576040517fcf54c06a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b600e548110156112c7576000600e8281548110611117576111176145bf565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff908116808452600f90925260408320549193501690858585818110611161576111616145bf565b905060200201602081019061117691906142a4565b905073ffffffffffffffffffffffffffffffffffffffff81161580611209575073ffffffffffffffffffffffffffffffffffffffff8216158015906111e757508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b8015611209575073ffffffffffffffffffffffffffffffffffffffff81811614155b15611240576040517fb387a23800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff818116146112b15773ffffffffffffffffffffffffffffffffffffffff8381166000908152600f6020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169183169190911790555b50505080806112bf906145ee565b9150506110f8565b507fa46de38886467c59be07a0675f14781206a5477d871628af46c2443822fcb725600e83836040516112fc93929190614830565b60405180910390a15050565b611310612e80565b601280547fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e0100000000000000000000000000009004909116606082015282918291829182919082906114485760608201516012546000916114349170010000000000000000000000000000000090046bffffffffffffffffffffffff166148e0565b600e549091506114449082614934565b9150505b81516020830151604084015161145f90849061495f565b6060949094015173ffffffffffffffffffffffffffffffffffffffff9a8b166000908152600f6020526040902054929b919a9499509750921694509092505050565b60006109a382612fb7565b6114b581612f03565b60008181526004602090815260409182902082516101008082018552825460ff8116151580845263ffffffff92820483169584019590955265010000000000810482169583019590955273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009095048516606083015260018301546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a0840152780100000000000000000000000000000000000000000000000090041660c082015260029091015490921660e08301526115bf576040517f1b88a78400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556115fe600283613062565b5060405182907f7bada562044eb163f6b4003c4553e4e62825344c0418eea087bed5ee05a4745690600090a25050565b604080516101208101825260125460ff808216835263ffffffff6101008084048216602086015265010000000000840482169585019590955262ffffff6901000000000000000000840416606085015261ffff6c0100000000000000000000000084041660808501526e01000000000000000000000000000083048216151560a08501526f010000000000000000000000000000008304909116151560c08401526bffffffffffffffffffffffff70010000000000000000000000000000000083041660e08401527c01000000000000000000000000000000000000000000000000000000009091041691810191909152600090818061172d8361306e565b91509150611756838787601360020160049054906101000a900463ffffffff168686600061324c565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601d60205260409020805460609190610f0a90614626565b6015546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1633146117f5576040517f77c3599200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000908152601d602052604090206118258284836146c8565b508273ffffffffffffffffffffffffffffffffffffffff167f7c44b4eb59ee7873514e7e43e7718c269d872965938b288aa143befca62f99d28383604051610a569291906147e3565b6012546f01000000000000000000000000000000900460ff16156118be576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601280547fffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff166f0100000000000000000000000000000017905573ffffffffffffffffffffffffffffffffffffffff8116611945576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020908152604080832081516101008082018452825460ff81161515835263ffffffff91810482168387015265010000000000810482168386015273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091048116606084015260018401546bffffffffffffffffffffffff80821660808601526c0100000000000000000000000082041660a08501527801000000000000000000000000000000000000000000000000900490911660c0830152600290920154821660e082015286855260059093529220549091163314611a58576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611a60613297565b816040015163ffffffff161115611aa3576040517fff84e5dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152600460205260409020600101546018546c010000000000000000000000009091046bffffffffffffffffffffffff1690611ae390829061457d565b60185560008481526004602081905260409182902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff16905590517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116928201929092526bffffffffffffffffffffffff831660248201527f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303816000875af1158015611bc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bea9190614984565b50604080516bffffffffffffffffffffffff8316815273ffffffffffffffffffffffffffffffffffffffff8516602082015285917ff3b5906e5672f3e524854103bcafbbdba80dbdfeca2c35e116127b1060a68318910160405180910390a25050601280547fffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff1690555050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611cfd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611d81612e80565b6014546018546bffffffffffffffffffffffff90911690611da390829061457d565b601855601480547fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001690556040516bffffffffffffffffffffffff821681527f1d07d0b0be43d3e5fee41a80b579af370affee03fa595bf56d5d4c19328162f19060200160405180910390a16040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526bffffffffffffffffffffffff821660248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb906044015b6020604051808303816000875af1158015611eb0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110919190614984565b611edc612e80565b601280547fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff166e0100000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001611364565b611f4e81612f03565b60008181526004602090815260409182902082516101008082018552825460ff8116158015845263ffffffff92820483169584019590955265010000000000810482169583019590955273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009095048516606083015260018301546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a0840152780100000000000000000000000000000000000000000000000090041660c082015260029091015490921660e0830152612058576040517f514b6c2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561209a60028361334c565b5060405182907f8ab10247ce168c27748e656ecf852b951fcaac790c18106b19aa0ae57a8b741f90600090a25050565b6120d383612f03565b6000838152601b602052604090206120ec8284836146c8565b50827f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf48508383604051610a569291906147e3565b73ffffffffffffffffffffffffffffffffffffffff811661216c576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600f60205260409020541633146121cc576040517fcebf515b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254600e5460009161220391859170010000000000000000000000000000000090046bffffffffffffffffffffffff1690613358565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff16905560185490915061226d906bffffffffffffffffffffffff83169061457d565b6018556040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526bffffffffffffffffffffffff831660248301527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015612312573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123369190614984565b5060405133815273ffffffffffffffffffffffffffffffffffffffff808416916bffffffffffffffffffffffff8416918616907f9819093176a1851202c7bcfa46845809b4e47c261866550e94ed3775d2f406989060200160405180910390a4505050565b6108fc8163ffffffff1610806123d0575060145463ffffffff7001000000000000000000000000000000009091048116908216115b15612407576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61241082612f03565b60008281526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010063ffffffff861690810291909117909155915191825283917fc24c07e655ce79fba8a589778987d3c015bc6af1632bb20cf9182e02a65d972c910160405180910390a25050565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152601060205260409020541633146124f0576040517f6752e7aa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8181166000818152600f602090815260408083208054337fffffffffffffffffffffffff000000000000000000000000000000000000000080831682179093556010909452828520805490921690915590519416939092849290917f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b39190a45050565b60008181526004602090815260409182902082516101008082018552825460ff81161515835263ffffffff918104821694830194909452650100000000008404811694820185905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009094048416606083015260018301546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a084015278010000000000000000000000000000000000000000000000009004811660c083015260029092015490921660e0830152909114612694576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff1633146126f1576040517f6352a85300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526005602090815260408083208054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821790935560069094528285208054909216909155905173ffffffffffffffffffffffffffffffffffffffff90911692839186917f5cff4db96bef051785e999f44bfcd21c18823e034fb92dd376e3db4ce0feeb2c91a4505050565b60006109a361279383612fb7565b600084815260046020526040902054610100900463ffffffff1661162e565b6127ba612e80565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612847573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061286b91906149a6565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33601854846128b8919061457d565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526024820152604401611e91565b604080516101408101825260008082526020820181905260609282018390528282018190526080820181905260a0820181905260c0820181905260e08201819052610100820152610120810191909152600082815260046020908152604080832081516101008082018452825460ff81161515835263ffffffff918104821683870190815265010000000000820483168487015273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009092048216606085015260018501546bffffffffffffffffffffffff80821660808701526c0100000000000000000000000082041660a086015278010000000000000000000000000000000000000000000000009004831660c0850152600290940154811660e084019081528551610140810187529051909116815292511682850152868552600790935292819020805492939291830191612a6390614626565b80601f0160208091040260200160405190810160405280929190818152602001828054612a8f90614626565b8015612adc5780601f10612ab157610100808354040283529160200191612adc565b820191906000526020600020905b815481529060010190602001808311612abf57829003601f168201915b505050505081526020018260a001516bffffffffffffffffffffffff1681526020016005600086815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001826040015163ffffffff1667ffffffffffffffff1681526020018260c0015163ffffffff16815260200182608001516bffffffffffffffffffffffff168152602001826000015115158152602001601b60008681526020019081526020016000208054612bb990614626565b80601f0160208091040260200160405190810160405280929190818152602001828054612be590614626565b8015612c325780601f10612c0757610100808354040283529160200191612c32565b820191906000526020600020905b815481529060010190602001808311612c1557829003601f168201915b5050505050815250915050919050565b612c4b83612f03565b60155463ffffffff16811115612c8d576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152600760205260409020612ca68284836146c8565b50827fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d8383604051610a569291906147e3565b60006109a382612785565b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600f6020526040902054163314612d44576040517fcebf515b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603612d93576040517f8c8728c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152601060205260409020548116908216146110915773ffffffffffffffffffffffffffffffffffffffff82811660008181526010602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169486169485179055513392917f84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e3836791a45050565b612e4a612e80565b612e5381613560565b50565b60006109a3825490565b6000612e6c8383613655565b9392505050565b60606000612e6c8361367f565b60005473ffffffffffffffffffffffffffffffffffffffff163314612f01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401611cf4565b565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314612f60576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090205465010000000000900463ffffffff90811614612e53576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818160045b600f811015613044577fff000000000000000000000000000000000000000000000000000000000000008216838260208110612ffc57612ffc6145bf565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461303257506000949350505050565b8061303c816145ee565b915050612fbe565b5081600f1a600181111561305a5761305a6142bf565b949350505050565b6000612e6c83836136da565b6000806000836060015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156130fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061311e91906149d9565b509450909250505060008113158061313557508142105b806131565750828015613156575061314d824261457d565b8463ffffffff16105b15613165576016549550613169565b8095505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156131d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131f891906149d9565b509450909250505060008113158061320f57508142105b8061323057508280156132305750613227824261457d565b8463ffffffff16105b1561323f576017549450613243565b8094505b50505050915091565b60008061325e88878b60000151613729565b90506000806132798b8a63ffffffff16858a8a60018b6137eb565b9092509050613288818361495f565b9b9a5050505050505050505050565b600060017f000000000000000000000000000000000000000000000000000000000000000060028111156132cd576132cd6142bf565b0361334757606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561331e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061334291906149a6565b905090565b504390565b6000612e6c8383613c44565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e01000000000000000000000000000090049091166060820152906135545760008160600151856133f091906148e0565b905060006133fe8583614934565b90508083604001818151613412919061495f565b6bffffffffffffffffffffffff1690525061342d8582614a29565b8360600181815161343e919061495f565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036135df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401611cf4565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600082600001828154811061366c5761366c6145bf565b9060005260206000200154905092915050565b606081600001805480602002602001604051908101604052809291908181526020018280548015610f8357602002820191906000526020600020905b8154815260200190600101908083116136bb5750505050509050919050565b6000818152600183016020526040812054613721575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556109a3565b5060006109a3565b6000808085600181111561373f5761373f6142bf565b0361374e575062015f906137a3565b6001856001811115613762576137626142bf565b0361377157506201adb06137a3565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6137b463ffffffff85166014614a5d565b6137bf846001614a9a565b6137ce9060ff16611d4c614a5d565b6137d8908361456a565b6137e2919061456a565b95945050505050565b6000806000896080015161ffff16876138049190614a5d565b90508380156138125750803a105b1561381a57503a5b600060027f00000000000000000000000000000000000000000000000000000000000000006002811115613850576138506142bf565b036139af5760408051600081526020810190915285156138ae57600036604051806080016040528060488152602001614b8b6048913960405160200161389893929190614ab3565b6040516020818303038152906040529050613916565b6015546138ca90640100000000900463ffffffff166004614ada565b63ffffffff1667ffffffffffffffff8111156138e8576138e8614590565b6040519080825280601f01601f191660200182016040528015613912576020820181803683370190505b5090505b6040517f49948e0e00000000000000000000000000000000000000000000000000000000815273420000000000000000000000000000000000000f906349948e0e906139669084906004016141f0565b602060405180830381865afa158015613983573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139a791906149a6565b915050613b09565b60017f000000000000000000000000000000000000000000000000000000000000000060028111156139e3576139e36142bf565b03613b09578415613a6557606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613a3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a5e91906149a6565b9050613b09565b6000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c060405180830381865afa158015613ab3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ad79190614afd565b5050601554929450613afa93505050640100000000900463ffffffff1682614a5d565b613b05906010614a5d565b9150505b84613b2557808b6080015161ffff16613b229190614a5d565b90505b613b3361ffff871682614b47565b905060008782613b438c8e61456a565b613b4d9086614a5d565b613b57919061456a565b613b6990670de0b6b3a7640000614a5d565b613b739190614b47565b905060008c6040015163ffffffff1664e8d4a51000613b929190614a5d565b898e6020015163ffffffff16858f88613bab9190614a5d565b613bb5919061456a565b613bc390633b9aca00614a5d565b613bcd9190614a5d565b613bd79190614b47565b613be1919061456a565b90506b033b2e3c9fd0803ce8000000613bfa828461456a565b1115613c32576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909c909b509950505050505050505050565b60008181526001830160205260408120548015613d2d576000613c6860018361457d565b8554909150600090613c7c9060019061457d565b9050818114613ce1576000866000018281548110613c9c57613c9c6145bf565b9060005260206000200154905080876000018481548110613cbf57613cbf6145bf565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613cf257613cf2614b5b565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506109a3565b60009150506109a3565b5092915050565b60008060408385031215613d5157600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b81811015613d9857835183529284019291840191600101613d7c565b50909695505050505050565b60008083601f840112613db657600080fd5b50813567ffffffffffffffff811115613dce57600080fd5b602083019150836020828501011115613de657600080fd5b9250929050565b600080600060408486031215613e0257600080fd5b83359250602084013567ffffffffffffffff811115613e2057600080fd5b613e2c86828701613da4565b9497909650939450505050565b600081518084526020808501945080840160005b83811015613e7f57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613e4d565b509495945050505050565b805163ffffffff16825260006101e06020830151613eb0602086018263ffffffff169052565b506040830151613ec8604086018263ffffffff169052565b506060830151613edf606086018262ffffff169052565b506080830151613ef5608086018261ffff169052565b5060a0830151613f1560a08601826bffffffffffffffffffffffff169052565b5060c0830151613f2d60c086018263ffffffff169052565b5060e0830151613f4560e086018263ffffffff169052565b506101008381015163ffffffff908116918601919091526101208085015190911690850152610140808401519085015261016080840151908501526101808084015173ffffffffffffffffffffffffffffffffffffffff16908501526101a080840151818601839052613fba83870182613e39565b925050506101c080840151613fe68287018273ffffffffffffffffffffffffffffffffffffffff169052565b5090949350505050565b855163ffffffff16815260006101c0602088015161401e60208501826bffffffffffffffffffffffff169052565b5060408801516040840152606088015161404860608501826bffffffffffffffffffffffff169052565b506080880151608084015260a088015161406a60a085018263ffffffff169052565b5060c088015161408260c085018263ffffffff169052565b5060e088015160e0840152610100808901516140a58286018263ffffffff169052565b50506101208881015115159084015261014083018190526140c881840188613e8a565b90508281036101608401526140dd8187613e39565b90508281036101808401526140f28186613e39565b9150506117566101a083018460ff169052565b803573ffffffffffffffffffffffffffffffffffffffff8116811461412957600080fd5b919050565b6000806040838503121561414157600080fd5b61414a83614105565b915060208301356004811061415e57600080fd5b809150509250929050565b60006020828403121561417b57600080fd5b5035919050565b60005b8381101561419d578181015183820152602001614185565b50506000910152565b600081518084526141be816020860160208601614182565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612e6c60208301846141a6565b6000806040838503121561421657600080fd5b8235915061422660208401614105565b90509250929050565b6000806020838503121561424257600080fd5b823567ffffffffffffffff8082111561425a57600080fd5b818501915085601f83011261426e57600080fd5b81358181111561427d57600080fd5b8660208260051b850101111561429257600080fd5b60209290920196919550909350505050565b6000602082840312156142b657600080fd5b612e6c82614105565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612e5357612e536142bf565b6020810161430b836142ee565b91905290565b602081016002831061430b5761430b6142bf565b803563ffffffff8116811461412957600080fd5b6000806040838503121561434c57600080fd5b82356002811061435b57600080fd5b915061422660208401614325565b60008060006040848603121561437e57600080fd5b61438784614105565b9250602084013567ffffffffffffffff811115613e2057600080fd5b600080604083850312156143b657600080fd5b6143bf83614105565b915061422660208401614105565b600080604083850312156143e057600080fd5b8235915061422660208401614325565b6020815261441760208201835173ffffffffffffffffffffffffffffffffffffffff169052565b60006020830151614430604084018263ffffffff169052565b50604083015161014080606085015261444d6101608501836141a6565b9150606085015161446e60808601826bffffffffffffffffffffffff169052565b50608085015173ffffffffffffffffffffffffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015163ffffffff811660e08601525060e08501516101006144da818701836bffffffffffffffffffffffff169052565b86015190506101206144ef8682018315159052565b8601518584037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00183870152905061175683826141a6565b602081016004831061430b5761430b6142bf565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156109a3576109a361453b565b818103818111156109a3576109a361453b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361461f5761461f61453b565b5060010190565b600181811c9082168061463a57607f821691505b602082108103614673577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156146c357600081815260208120601f850160051c810160208610156146a05750805b601f850160051c820191505b818110156146bf578281556001016146ac565b5050505b505050565b67ffffffffffffffff8311156146e0576146e0614590565b6146f4836146ee8354614626565b83614679565b6000601f84116001811461474657600085156147105750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556147dc565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156147955786850135825560209485019460019092019101614775565b50868210156147d0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000604082016040835280865480835260608501915087600052602092508260002060005b8281101561488757815473ffffffffffffffffffffffffffffffffffffffff1684529284019260019182019101614855565b505050838103828501528481528590820160005b868110156148d45773ffffffffffffffffffffffffffffffffffffffff6148c184614105565b168252918301919083019060010161489b565b50979650505050505050565b6bffffffffffffffffffffffff828116828216039080821115613d3757613d3761453b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006bffffffffffffffffffffffff8084168061495357614953614905565b92169190910492915050565b6bffffffffffffffffffffffff818116838216019080821115613d3757613d3761453b565b60006020828403121561499657600080fd5b81518015158114612e6c57600080fd5b6000602082840312156149b857600080fd5b5051919050565b805169ffffffffffffffffffff8116811461412957600080fd5b600080600080600060a086880312156149f157600080fd5b6149fa866149bf565b9450602086015193506040860151925060608601519150614a1d608087016149bf565b90509295509295909350565b60006bffffffffffffffffffffffff80831681851681830481118215151615614a5457614a5461453b565b02949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614a9557614a9561453b565b500290565b60ff81811683821601908111156109a3576109a361453b565b828482376000838201600081528351614ad0818360208801614182565b0195945050505050565b600063ffffffff80831681851681830481118215151615614a5457614a5461453b565b60008060008060008060c08789031215614b1657600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b600082614b5657614b56614905565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000810000a", + ABI: "[{\"inputs\":[{\"internalType\":\"enumKeeperRegistryBase2_1.Mode\",\"name\":\"mode\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fastGasFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"automationForwarderLogic\",\"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\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"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\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"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\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"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\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"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\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"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\"},{\"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\":\"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\":\"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\":[],\"name\":\"getCancellationDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConditionalGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"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\":\"contractIAutomationForwarder\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkNativeFeedAddress\",\"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\":\"enumKeeperRegistryBase2_1.Trigger\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"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\":\"getMode\",\"outputs\":[{\"internalType\":\"enumKeeperRegistryBase2_1.Mode\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"}],\"name\":\"getPeerRegistryMigrationPermission\",\"outputs\":[{\"internalType\":\"enumKeeperRegistryBase2_1.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\":[{\"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\":\"structKeeperRegistryBase2_1.State\",\"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\":\"structKeeperRegistryBase2_1.OnchainConfig\",\"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\":[{\"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\":\"enumKeeperRegistryBase2_1.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\":\"structKeeperRegistryBase2_1.UpkeepInfo\",\"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\":[{\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"hasDedupKey\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"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\":[],\"name\":\"recoverFunds\",\"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\":\"enumKeeperRegistryBase2_1.MigrationPermission\",\"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\":\"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\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"unpauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTranscoderVersion\",\"outputs\":[{\"internalType\":\"enumUpkeepFormat\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawOwnerFunds\",\"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\"}]", + Bin: "0x6101206040523480156200001257600080fd5b5060405162004fbc38038062004fbc8339810160408190526200003591620001e9565b84848484843380600081620000915760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c457620000c48162000121565b505050846002811115620000dc57620000dc6200025e565b60e0816002811115620000f357620000f36200025e565b9052506001600160a01b0393841660805291831660a052821660c05216610100525062000274945050505050565b336001600160a01b038216036200017b5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000088565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001e457600080fd5b919050565b600080600080600060a086880312156200020257600080fd5b8551600381106200021257600080fd5b94506200022260208701620001cc565b93506200023260408701620001cc565b92506200024260608701620001cc565b91506200025260808701620001cc565b90509295509295909350565b634e487b7160e01b600052602160045260246000fd5b60805160a05160c05160e05161010051614cbd620002ff600039600061058701526000818161052501528181613352015281816138d50152613a680152600081816105f4015261314601526000818161071c01526132200152600081816107aa01528181611bab01528181611e81015281816122ee0152818161280101526128850152614cbd6000f3fe608060405234801561001057600080fd5b50600436106103365760003560e01c806379ba5097116101b2578063b121e147116100f9578063ca30e603116100a2578063eb5dcd6c1161007c578063eb5dcd6c146107f4578063ed56b3e114610807578063f2fde38b1461087a578063faa3e9961461088d57600080fd5b8063ca30e603146107a8578063cd7f71b5146107ce578063d7632648146107e157600080fd5b8063b657bc9c116100d3578063b657bc9c1461076d578063b79550be14610780578063c7c3a19a1461078857600080fd5b8063b121e14714610740578063b148ab6b14610753578063b6511a2a1461076657600080fd5b80638dcf0fe71161015b578063aab9edd611610135578063aab9edd614610703578063abc76ae014610712578063b10b673c1461071a57600080fd5b80638dcf0fe7146106ca578063a710b221146106dd578063a72aa27e146106f057600080fd5b80638456cb591161018c5780638456cb59146106915780638765ecbe146106995780638da5cb5b146106ac57600080fd5b806379ba50971461063e57806379ea9943146106465780637d9b97e01461068957600080fd5b8063421d183b116102815780635165f2f51161022a5780636209e1e9116102045780636209e1e9146105df5780636709d0e5146105f2578063671d36ed14610618578063744bfe611461062b57600080fd5b80635165f2f5146105725780635425d8ac146105855780635b6aa71c146105cc57600080fd5b80634b4fd03b1161025b5780634b4fd03b146105235780634ca16c52146105495780635147cd591461055257600080fd5b8063421d183b1461047a57806344cb70b8146104e057806348013d7b1461051357600080fd5b80631a2af011116102e3578063232c1cc5116102bd578063232c1cc5146104585780633b9cce591461045f5780633f4ba83a1461047257600080fd5b80631a2af011146103d45780631e010439146103e7578063207b65161461044557600080fd5b80631865c57d116103145780631865c57d14610388578063187256e8146103a157806319d97a94146103b457600080fd5b8063050ee65d1461033b57806306e3b632146103535780630b7d33e614610373575b600080fd5b6201adb05b6040519081526020015b60405180910390f35b610366610361366004613df3565b6108d3565b60405161034a9190613e15565b610386610381366004613ea2565b6109f0565b005b610390610aaa565b60405161034a9594939291906140a5565b6103866103af3660046141dc565b610ec3565b6103c76103c2366004614219565b610f34565b60405161034a91906142a0565b6103866103e23660046142b3565b610fd6565b6104286103f5366004614219565b6000908152600460205260409020600101546c0100000000000000000000000090046bffffffffffffffffffffffff1690565b6040516bffffffffffffffffffffffff909116815260200161034a565b6103c7610453366004614219565b6110dc565b6014610340565b61038661046d3660046142d8565b6110f9565b61038661134f565b61048d61048836600461434d565b6113b5565b60408051951515865260ff90941660208601526bffffffffffffffffffffffff9283169385019390935216606083015273ffffffffffffffffffffffffffffffffffffffff16608082015260a00161034a565b6105036104ee366004614219565b60009081526008602052604090205460ff1690565b604051901515815260200161034a565b60005b60405161034a91906143a9565b7f0000000000000000000000000000000000000000000000000000000000000000610516565b62015f90610340565b610565610560366004614219565b6114e8565b60405161034a91906143bc565b610386610580366004614219565b6114f3565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161034a565b6104286105da3660046143e9565b61166a565b6103c76105ed36600461434d565b61179c565b7f00000000000000000000000000000000000000000000000000000000000000006105a7565b610386610626366004614422565b6117d0565b6103866106393660046142b3565b6118aa565b610386611ca7565b6105a7610654366004614219565b6000908152600460205260409020546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b610386611da9565b610386611f04565b6103866106a7366004614219565b611f75565b60005473ffffffffffffffffffffffffffffffffffffffff166105a7565b6103866106d8366004613ea2565b6120ef565b6103866106eb36600461445e565b612144565b6103866106fe36600461448c565b6123c0565b6040516003815260200161034a565b611d4c610340565b7f00000000000000000000000000000000000000000000000000000000000000006105a7565b61038661074e36600461434d565b6124b5565b610386610761366004614219565b6125ad565b6032610340565b61042861077b366004614219565b61279b565b6103866127c8565b61079b610796366004614219565b612924565b60405161034a91906144af565b7f00000000000000000000000000000000000000000000000000000000000000006105a7565b6103866107dc366004613ea2565b612cf7565b6104286107ef366004614219565b612d8e565b61038661080236600461445e565b612d99565b61086161081536600461434d565b73ffffffffffffffffffffffffffffffffffffffff166000908152600c602090815260409182902082518084019093525460ff8082161515808552610100909204169290910182905291565b60408051921515835260ff90911660208301520161034a565b61038661088836600461434d565b612ef7565b6108c661089b36600461434d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526019602052604090205460ff1690565b60405161034a91906145e6565b606060006108e16002612f0b565b905080841061091c576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006109288486614629565b905081811180610936575083155b6109405780610942565b815b90506000610950868361463c565b67ffffffffffffffff8111156109685761096861464f565b604051908082528060200260200182016040528015610991578160200160208202803683370190505b50905060005b81518110156109e4576109b56109ad8883614629565b600290612f15565b8282815181106109c7576109c761467e565b6020908102919091010152806109dc816146ad565b915050610997565b50925050505b92915050565b6015546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314610a51576040517f77c3599200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152601c60205260409020610a6a828483614787565b50827f2fd8d70753a007014349d4591843cc031c2dd7a260d7dd82eca8253686ae77698383604051610a9d9291906148a2565b60405180910390a2505050565b6040805161014081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810191909152604080516101e08101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e08201839052610100820183905261012082018390526101408201839052610160820183905261018082018390526101a08201526101c0810191909152604080516101408101825260145463ffffffff7401000000000000000000000000000000000000000082041682526bffffffffffffffffffffffff908116602083015260185492820192909252601254700100000000000000000000000000000000900490911660608281019190915290819060009060808101610bf76002612f0b565b81526014547801000000000000000000000000000000000000000000000000810463ffffffff9081166020808501919091527c0100000000000000000000000000000000000000000000000000000000808404831660408087019190915260115460608088019190915260125492830485166080808901919091526e010000000000000000000000000000840460ff16151560a09889015282516101e081018452610100808604881682526501000000000086048816968201969096526c010000000000000000000000008089048816948201949094526901000000000000000000850462ffffff16928101929092529282900461ffff16928101929092526013546bffffffffffffffffffffffff811696830196909652700100000000000000000000000000000000909404831660c082015260155480841660e0830152640100000000810484169282019290925268010000000000000000909104909116610120820152601654610140820152601754610160820152910473ffffffffffffffffffffffffffffffffffffffff166101808201529095506101a08101610d9f6009612f28565b81526015546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16602091820152601254600d80546040805182860281018601909152818152949850899489949293600e9360ff909116928591830182828015610e4257602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610e17575b5050505050925081805480602002602001604051908101604052809291908181526020018280548015610eab57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610e80575b50505050509150945094509450945094509091929394565b610ecb612f35565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260196020526040902080548291907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836003811115610f2b57610f2b61436a565b02179055505050565b6000818152601c60205260409020805460609190610f51906146e5565b80601f0160208091040260200160405190810160405280929190818152602001828054610f7d906146e5565b8015610fca5780601f10610f9f57610100808354040283529160200191610fca565b820191906000526020600020905b815481529060010190602001808311610fad57829003601f168201915b50505050509050919050565b610fdf82612fb8565b3373ffffffffffffffffffffffffffffffffffffffff82160361102e576040517f8c8728c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff8281169116146110d85760008281526006602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851690811790915590519091339185917fb1cbb2c4b8480034c27e06da5f096b8233a8fd4497028593a41ff6df79726b3591a45b5050565b6000818152601a60205260409020805460609190610f51906146e5565b611101612f35565b600e54811461113c576040517fcf54c06a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b600e5481101561130e576000600e828154811061115e5761115e61467e565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff908116808452600f909252604083205491935016908585858181106111a8576111a861467e565b90506020020160208101906111bd919061434d565b905073ffffffffffffffffffffffffffffffffffffffff81161580611250575073ffffffffffffffffffffffffffffffffffffffff82161580159061122e57508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b8015611250575073ffffffffffffffffffffffffffffffffffffffff81811614155b15611287576040517fb387a23800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff818116146112f85773ffffffffffffffffffffffffffffffffffffffff8381166000908152600f6020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169183169190911790555b5050508080611306906146ad565b91505061113f565b507fa46de38886467c59be07a0675f14781206a5477d871628af46c2443822fcb725600e8383604051611343939291906148ef565b60405180910390a15050565b611357612f35565b601280547fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e01000000000000000000000000000090049091166060820152829182918291829190829061148f57606082015160125460009161147b9170010000000000000000000000000000000090046bffffffffffffffffffffffff166149a1565b600e5490915061148b90826149f5565b9150505b8151602083015160408401516114a6908490614a20565b6060949094015173ffffffffffffffffffffffffffffffffffffffff9a8b166000908152600f6020526040902054929b919a9499509750921694509092505050565b60006109ea8261306c565b6114fc81612fb8565b600081815260046020908152604091829020825160e081018452815460ff8116151580835263ffffffff610100830481169584019590955265010000000000820485169583019590955273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c0820152906115fb576040517f1b88a78400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905561163a600283613117565b5060405182907f7bada562044eb163f6b4003c4553e4e62825344c0418eea087bed5ee05a4745690600090a25050565b604080516101208101825260125460ff808216835263ffffffff6101008084048216602086015265010000000000840482169585019590955262ffffff6901000000000000000000840416606085015261ffff6c0100000000000000000000000084041660808501526e01000000000000000000000000000083048216151560a08501526f010000000000000000000000000000008304909116151560c08401526bffffffffffffffffffffffff70010000000000000000000000000000000083041660e08401527c01000000000000000000000000000000000000000000000000000000009091041691810191909152600090818061176983613123565b91509150611792838787601360020160049054906101000a900463ffffffff1686866000613301565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601d60205260409020805460609190610f51906146e5565b6015546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314611831576040517f77c3599200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000908152601d60205260409020611861828483614787565b508273ffffffffffffffffffffffffffffffffffffffff167f7c44b4eb59ee7873514e7e43e7718c269d872965938b288aa143befca62f99d28383604051610a9d9291906148a2565b6012546f01000000000000000000000000000000900460ff16156118fa576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601280547fffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff166f0100000000000000000000000000000017905573ffffffffffffffffffffffffffffffffffffffff8116611981576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600460209081526040808320815160e081018352815460ff81161515825263ffffffff610100820481168387015265010000000000820481168386015273ffffffffffffffffffffffffffffffffffffffff6901000000000000000000909204821660608401526001909301546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a08401527801000000000000000000000000000000000000000000000000900490921660c082015286855260059093529220549091163314611a88576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611a9061334c565b816040015163ffffffff161115611ad3576040517fff84e5dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152600460205260409020600101546018546c010000000000000000000000009091046bffffffffffffffffffffffff1690611b1390829061463c565b60185560008481526004602081905260409182902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff16905590517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116928201929092526bffffffffffffffffffffffff831660248201527f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303816000875af1158015611bf6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c1a9190614a45565b50604080516bffffffffffffffffffffffff8316815273ffffffffffffffffffffffffffffffffffffffff8516602082015285917ff3b5906e5672f3e524854103bcafbbdba80dbdfeca2c35e116127b1060a68318910160405180910390a25050601280547fffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff1690555050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611d2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611db1612f35565b6014546018546bffffffffffffffffffffffff90911690611dd390829061463c565b601855601480547fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001690556040516bffffffffffffffffffffffff821681527f1d07d0b0be43d3e5fee41a80b579af370affee03fa595bf56d5d4c19328162f19060200160405180910390a16040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526bffffffffffffffffffffffff821660248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb906044015b6020604051808303816000875af1158015611ee0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d89190614a45565b611f0c612f35565b601280547fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff166e0100000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258906020016113ab565b611f7e81612fb8565b600081815260046020908152604091829020825160e081018452815460ff8116158015835263ffffffff610100830481169584019590955265010000000000820485169583019590955273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c08201529061207d576040517f514b6c2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556120bf600283613401565b5060405182907f8ab10247ce168c27748e656ecf852b951fcaac790c18106b19aa0ae57a8b741f90600090a25050565b6120f883612fb8565b6000838152601b60205260409020612111828483614787565b50827f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf48508383604051610a9d9291906148a2565b73ffffffffffffffffffffffffffffffffffffffff8116612191576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600f60205260409020541633146121f1576040517fcebf515b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254600e5460009161222891859170010000000000000000000000000000000090046bffffffffffffffffffffffff169061340d565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff169055601854909150612292906bffffffffffffffffffffffff83169061463c565b6018556040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526bffffffffffffffffffffffff831660248301527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015612337573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061235b9190614a45565b5060405133815273ffffffffffffffffffffffffffffffffffffffff808416916bffffffffffffffffffffffff8416918616907f9819093176a1851202c7bcfa46845809b4e47c261866550e94ed3775d2f406989060200160405180910390a4505050565b6108fc8163ffffffff1610806123f5575060145463ffffffff7001000000000000000000000000000000009091048116908216115b1561242c576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61243582612fb8565b60008281526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010063ffffffff861690810291909117909155915191825283917fc24c07e655ce79fba8a589778987d3c015bc6af1632bb20cf9182e02a65d972c910160405180910390a25050565b73ffffffffffffffffffffffffffffffffffffffff818116600090815260106020526040902054163314612515576040517f6752e7aa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8181166000818152600f602090815260408083208054337fffffffffffffffffffffffff000000000000000000000000000000000000000080831682179093556010909452828520805490921690915590519416939092849290917f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b39190a45050565b600081815260046020908152604091829020825160e081018452815460ff81161515825263ffffffff6101008204811694830194909452650100000000008104841694820185905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a083015278010000000000000000000000000000000000000000000000009004821660c082015291146126aa576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff163314612707576040517f6352a85300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526005602090815260408083208054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821790935560069094528285208054909216909155905173ffffffffffffffffffffffffffffffffffffffff90911692839186917f5cff4db96bef051785e999f44bfcd21c18823e034fb92dd376e3db4ce0feeb2c91a4505050565b60006109ea6127a98361306c565b600084815260046020526040902054610100900463ffffffff1661166a565b6127d0612f35565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561285d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128819190614a67565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33601854846128ce919061463c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526024820152604401611ec1565b604080516101408101825260008082526020820181905260609282018390528282018190526080820181905260a0820181905260c0820181905260e082018190526101008201526101208101919091526000828152600460209081526040808320815160e081018352815460ff811615158252610100810463ffffffff90811695830195909552650100000000008104851693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff16606083018190526001909101546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a08401527801000000000000000000000000000000000000000000000000900490921660c0820152919015612abc57816060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ab79190614a80565b612abf565b60005b90506040518061014001604052808273ffffffffffffffffffffffffffffffffffffffff168152602001836020015163ffffffff168152602001600760008781526020019081526020016000208054612b17906146e5565b80601f0160208091040260200160405190810160405280929190818152602001828054612b43906146e5565b8015612b905780601f10612b6557610100808354040283529160200191612b90565b820191906000526020600020905b815481529060010190602001808311612b7357829003601f168201915b505050505081526020018360a001516bffffffffffffffffffffffff1681526020016005600087815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001836040015163ffffffff1667ffffffffffffffff1681526020018360c0015163ffffffff16815260200183608001516bffffffffffffffffffffffff168152602001836000015115158152602001601b60008781526020019081526020016000208054612c6d906146e5565b80601f0160208091040260200160405190810160405280929190818152602001828054612c99906146e5565b8015612ce65780601f10612cbb57610100808354040283529160200191612ce6565b820191906000526020600020905b815481529060010190602001808311612cc957829003601f168201915b505050505081525092505050919050565b612d0083612fb8565b60155463ffffffff16811115612d42576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152600760205260409020612d5b828483614787565b50827fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d8383604051610a9d9291906148a2565b60006109ea8261279b565b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600f6020526040902054163314612df9576040517fcebf515b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603612e48576040517f8c8728c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152601060205260409020548116908216146110d85773ffffffffffffffffffffffffffffffffffffffff82811660008181526010602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169486169485179055513392917f84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e3836791a45050565b612eff612f35565b612f0881613615565b50565b60006109ea825490565b6000612f21838361370a565b9392505050565b60606000612f2183613734565b60005473ffffffffffffffffffffffffffffffffffffffff163314612fb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401611d24565b565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314613015576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090205465010000000000900463ffffffff90811614612f08576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818160045b600f8110156130f9577fff0000000000000000000000000000000000000000000000000000000000000082168382602081106130b1576130b161467e565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146130e757506000949350505050565b806130f1816146ad565b915050613073565b5081600f1a600181111561310f5761310f61436a565b949350505050565b6000612f21838361378f565b6000806000836060015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156131af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131d39190614ab7565b50945090925050506000811315806131ea57508142105b8061320b575082801561320b5750613202824261463c565b8463ffffffff16105b1561321a57601654955061321e565b8095505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613289573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132ad9190614ab7565b50945090925050506000811315806132c457508142105b806132e557508280156132e557506132dc824261463c565b8463ffffffff16105b156132f45760175494506132f8565b8094505b50505050915091565b60008061331388878b600001516137de565b905060008061332e8b8a63ffffffff16858a8a60018b6138a0565b909250905061333d8183614a20565b9b9a5050505050505050505050565b600060017f000000000000000000000000000000000000000000000000000000000000000060028111156133825761338261436a565b036133fc57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156133d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133f79190614a67565b905090565b504390565b6000612f218383613cf9565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e01000000000000000000000000000090049091166060820152906136095760008160600151856134a591906149a1565b905060006134b385836149f5565b905080836040018181516134c79190614a20565b6bffffffffffffffffffffffff169052506134e28582614b07565b836060018181516134f39190614a20565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401611d24565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008260000182815481106137215761372161467e565b9060005260206000200154905092915050565b606081600001805480602002602001604051908101604052809291908181526020018280548015610fca57602002820191906000526020600020905b8154815260200190600101908083116137705750505050509050919050565b60008181526001830160205260408120546137d6575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556109ea565b5060006109ea565b600080808560018111156137f4576137f461436a565b03613803575062015f90613858565b60018560018111156138175761381761436a565b0361382657506201adb0613858565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61386963ffffffff85166014614b3b565b613874846001614b78565b6138839060ff16611d4c614b3b565b61388d9083614629565b6138979190614629565b95945050505050565b6000806000896080015161ffff16876138b99190614b3b565b90508380156138c75750803a105b156138cf57503a5b600060027f000000000000000000000000000000000000000000000000000000000000000060028111156139055761390561436a565b03613a6457604080516000815260208101909152851561396357600036604051806080016040528060488152602001614c696048913960405160200161394d93929190614b91565b60405160208183030381529060405290506139cb565b60155461397f90640100000000900463ffffffff166004614bb8565b63ffffffff1667ffffffffffffffff81111561399d5761399d61464f565b6040519080825280601f01601f1916602001820160405280156139c7576020820181803683370190505b5090505b6040517f49948e0e00000000000000000000000000000000000000000000000000000000815273420000000000000000000000000000000000000f906349948e0e90613a1b9084906004016142a0565b602060405180830381865afa158015613a38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a5c9190614a67565b915050613bbe565b60017f00000000000000000000000000000000000000000000000000000000000000006002811115613a9857613a9861436a565b03613bbe578415613b1a57606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613aef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b139190614a67565b9050613bbe565b6000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c060405180830381865afa158015613b68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b8c9190614bdb565b5050601554929450613baf93505050640100000000900463ffffffff1682614b3b565b613bba906010614b3b565b9150505b84613bda57808b6080015161ffff16613bd79190614b3b565b90505b613be861ffff871682614c25565b905060008782613bf88c8e614629565b613c029086614b3b565b613c0c9190614629565b613c1e90670de0b6b3a7640000614b3b565b613c289190614c25565b905060008c6040015163ffffffff1664e8d4a51000613c479190614b3b565b898e6020015163ffffffff16858f88613c609190614b3b565b613c6a9190614629565b613c7890633b9aca00614b3b565b613c829190614b3b565b613c8c9190614c25565b613c969190614629565b90506b033b2e3c9fd0803ce8000000613caf8284614629565b1115613ce7576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909c909b509950505050505050505050565b60008181526001830160205260408120548015613de2576000613d1d60018361463c565b8554909150600090613d319060019061463c565b9050818114613d96576000866000018281548110613d5157613d5161467e565b9060005260206000200154905080876000018481548110613d7457613d7461467e565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613da757613da7614c39565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506109ea565b60009150506109ea565b5092915050565b60008060408385031215613e0657600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b81811015613e4d57835183529284019291840191600101613e31565b50909695505050505050565b60008083601f840112613e6b57600080fd5b50813567ffffffffffffffff811115613e8357600080fd5b602083019150836020828501011115613e9b57600080fd5b9250929050565b600080600060408486031215613eb757600080fd5b83359250602084013567ffffffffffffffff811115613ed557600080fd5b613ee186828701613e59565b9497909650939450505050565b600081518084526020808501945080840160005b83811015613f3457815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613f02565b509495945050505050565b805163ffffffff16825260006101e06020830151613f65602086018263ffffffff169052565b506040830151613f7d604086018263ffffffff169052565b506060830151613f94606086018262ffffff169052565b506080830151613faa608086018261ffff169052565b5060a0830151613fca60a08601826bffffffffffffffffffffffff169052565b5060c0830151613fe260c086018263ffffffff169052565b5060e0830151613ffa60e086018263ffffffff169052565b506101008381015163ffffffff908116918601919091526101208085015190911690850152610140808401519085015261016080840151908501526101808084015173ffffffffffffffffffffffffffffffffffffffff16908501526101a08084015181860183905261406f83870182613eee565b925050506101c08084015161409b8287018273ffffffffffffffffffffffffffffffffffffffff169052565b5090949350505050565b855163ffffffff16815260006101c060208801516140d360208501826bffffffffffffffffffffffff169052565b506040880151604084015260608801516140fd60608501826bffffffffffffffffffffffff169052565b506080880151608084015260a088015161411f60a085018263ffffffff169052565b5060c088015161413760c085018263ffffffff169052565b5060e088015160e08401526101008089015161415a8286018263ffffffff169052565b505061012088810151151590840152610140830181905261417d81840188613f3f565b90508281036101608401526141928187613eee565b90508281036101808401526141a78186613eee565b9150506117926101a083018460ff169052565b73ffffffffffffffffffffffffffffffffffffffff81168114612f0857600080fd5b600080604083850312156141ef57600080fd5b82356141fa816141ba565b915060208301356004811061420e57600080fd5b809150509250929050565b60006020828403121561422b57600080fd5b5035919050565b60005b8381101561424d578181015183820152602001614235565b50506000910152565b6000815180845261426e816020860160208601614232565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612f216020830184614256565b600080604083850312156142c657600080fd5b82359150602083013561420e816141ba565b600080602083850312156142eb57600080fd5b823567ffffffffffffffff8082111561430357600080fd5b818501915085601f83011261431757600080fd5b81358181111561432657600080fd5b8660208260051b850101111561433b57600080fd5b60209290920196919550909350505050565b60006020828403121561435f57600080fd5b8135612f21816141ba565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612f0857612f0861436a565b602081016143b683614399565b91905290565b60208101600283106143b6576143b661436a565b803563ffffffff811681146143e457600080fd5b919050565b600080604083850312156143fc57600080fd5b82356002811061440b57600080fd5b9150614419602084016143d0565b90509250929050565b60008060006040848603121561443757600080fd5b8335614442816141ba565b9250602084013567ffffffffffffffff811115613ed557600080fd5b6000806040838503121561447157600080fd5b823561447c816141ba565b9150602083013561420e816141ba565b6000806040838503121561449f57600080fd5b82359150614419602084016143d0565b602081526144d660208201835173ffffffffffffffffffffffffffffffffffffffff169052565b600060208301516144ef604084018263ffffffff169052565b50604083015161014080606085015261450c610160850183614256565b9150606085015161452d60808601826bffffffffffffffffffffffff169052565b50608085015173ffffffffffffffffffffffffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015163ffffffff811660e08601525060e0850151610100614599818701836bffffffffffffffffffffffff169052565b86015190506101206145ae8682018315159052565b8601518584037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018387015290506117928382614256565b60208101600483106143b6576143b661436a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156109ea576109ea6145fa565b818103818111156109ea576109ea6145fa565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036146de576146de6145fa565b5060010190565b600181811c908216806146f957607f821691505b602082108103614732577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111561478257600081815260208120601f850160051c8101602086101561475f5750805b601f850160051c820191505b8181101561477e5782815560010161476b565b5050505b505050565b67ffffffffffffffff83111561479f5761479f61464f565b6147b3836147ad83546146e5565b83614738565b6000601f84116001811461480557600085156147cf5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561489b565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156148545786850135825560209485019460019092019101614834565b508682101561488f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000604082016040835280865480835260608501915087600052602092508260002060005b8281101561494657815473ffffffffffffffffffffffffffffffffffffffff1684529284019260019182019101614914565b505050838103828501528481528590820160005b8681101561499557823561496d816141ba565b73ffffffffffffffffffffffffffffffffffffffff168252918301919083019060010161495a565b50979650505050505050565b6bffffffffffffffffffffffff828116828216039080821115613dec57613dec6145fa565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006bffffffffffffffffffffffff80841680614a1457614a146149c6565b92169190910492915050565b6bffffffffffffffffffffffff818116838216019080821115613dec57613dec6145fa565b600060208284031215614a5757600080fd5b81518015158114612f2157600080fd5b600060208284031215614a7957600080fd5b5051919050565b600060208284031215614a9257600080fd5b8151612f21816141ba565b805169ffffffffffffffffffff811681146143e457600080fd5b600080600080600060a08688031215614acf57600080fd5b614ad886614a9d565b9450602086015193506040860151925060608601519150614afb60808701614a9d565b90509295509295909350565b60006bffffffffffffffffffffffff80831681851681830481118215151615614b3257614b326145fa565b02949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614b7357614b736145fa565b500290565b60ff81811683821601908111156109ea576109ea6145fa565b828482376000838201600081528351614bae818360208801614232565b0195945050505050565b600063ffffffff80831681851681830481118215151615614b3257614b326145fa565b60008060008060008060c08789031215614bf457600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b600082614c3457614c346149c6565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000810000a", } var KeeperRegistryLogicBABI = KeeperRegistryLogicBMetaData.ABI var KeeperRegistryLogicBBin = KeeperRegistryLogicBMetaData.Bin -func DeployKeeperRegistryLogicB(auth *bind.TransactOpts, backend bind.ContractBackend, mode uint8, link common.Address, linkNativeFeed common.Address, fastGasFeed common.Address) (common.Address, *types.Transaction, *KeeperRegistryLogicB, error) { +func DeployKeeperRegistryLogicB(auth *bind.TransactOpts, backend bind.ContractBackend, mode uint8, link common.Address, linkNativeFeed common.Address, fastGasFeed common.Address, automationForwarderLogic common.Address) (common.Address, *types.Transaction, *KeeperRegistryLogicB, error) { parsed, err := KeeperRegistryLogicBMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -92,7 +92,7 @@ func DeployKeeperRegistryLogicB(auth *bind.TransactOpts, backend bind.ContractBa return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(KeeperRegistryLogicBBin), backend, mode, link, linkNativeFeed, fastGasFeed) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(KeeperRegistryLogicBBin), backend, mode, link, linkNativeFeed, fastGasFeed, automationForwarderLogic) if err != nil { return common.Address{}, nil, nil, err } @@ -259,31 +259,31 @@ func (_KeeperRegistryLogicB *KeeperRegistryLogicBCallerSession) GetAdminPrivileg return _KeeperRegistryLogicB.Contract.GetAdminPrivilegeConfig(&_KeeperRegistryLogicB.CallOpts, admin) } -func (_KeeperRegistryLogicB *KeeperRegistryLogicBCaller) GetBalance(opts *bind.CallOpts, id *big.Int) (*big.Int, error) { +func (_KeeperRegistryLogicB *KeeperRegistryLogicBCaller) GetAutomationForwarderLogic(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _KeeperRegistryLogicB.contract.Call(opts, &out, "getBalance", id) + err := _KeeperRegistryLogicB.contract.Call(opts, &out, "getAutomationForwarderLogic") if err != nil { - return *new(*big.Int), err + return *new(common.Address), err } - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) return out0, err } -func (_KeeperRegistryLogicB *KeeperRegistryLogicBSession) GetBalance(id *big.Int) (*big.Int, error) { - return _KeeperRegistryLogicB.Contract.GetBalance(&_KeeperRegistryLogicB.CallOpts, id) +func (_KeeperRegistryLogicB *KeeperRegistryLogicBSession) GetAutomationForwarderLogic() (common.Address, error) { + return _KeeperRegistryLogicB.Contract.GetAutomationForwarderLogic(&_KeeperRegistryLogicB.CallOpts) } -func (_KeeperRegistryLogicB *KeeperRegistryLogicBCallerSession) GetBalance(id *big.Int) (*big.Int, error) { - return _KeeperRegistryLogicB.Contract.GetBalance(&_KeeperRegistryLogicB.CallOpts, id) +func (_KeeperRegistryLogicB *KeeperRegistryLogicBCallerSession) GetAutomationForwarderLogic() (common.Address, error) { + return _KeeperRegistryLogicB.Contract.GetAutomationForwarderLogic(&_KeeperRegistryLogicB.CallOpts) } -func (_KeeperRegistryLogicB *KeeperRegistryLogicBCaller) GetCancellationDelay(opts *bind.CallOpts) (*big.Int, error) { +func (_KeeperRegistryLogicB *KeeperRegistryLogicBCaller) GetBalance(opts *bind.CallOpts, id *big.Int) (*big.Int, error) { var out []interface{} - err := _KeeperRegistryLogicB.contract.Call(opts, &out, "getCancellationDelay") + err := _KeeperRegistryLogicB.contract.Call(opts, &out, "getBalance", id) if err != nil { return *new(*big.Int), err @@ -295,17 +295,17 @@ func (_KeeperRegistryLogicB *KeeperRegistryLogicBCaller) GetCancellationDelay(op } -func (_KeeperRegistryLogicB *KeeperRegistryLogicBSession) GetCancellationDelay() (*big.Int, error) { - return _KeeperRegistryLogicB.Contract.GetCancellationDelay(&_KeeperRegistryLogicB.CallOpts) +func (_KeeperRegistryLogicB *KeeperRegistryLogicBSession) GetBalance(id *big.Int) (*big.Int, error) { + return _KeeperRegistryLogicB.Contract.GetBalance(&_KeeperRegistryLogicB.CallOpts, id) } -func (_KeeperRegistryLogicB *KeeperRegistryLogicBCallerSession) GetCancellationDelay() (*big.Int, error) { - return _KeeperRegistryLogicB.Contract.GetCancellationDelay(&_KeeperRegistryLogicB.CallOpts) +func (_KeeperRegistryLogicB *KeeperRegistryLogicBCallerSession) GetBalance(id *big.Int) (*big.Int, error) { + return _KeeperRegistryLogicB.Contract.GetBalance(&_KeeperRegistryLogicB.CallOpts, id) } -func (_KeeperRegistryLogicB *KeeperRegistryLogicBCaller) GetCheckGasOverhead(opts *bind.CallOpts) (*big.Int, error) { +func (_KeeperRegistryLogicB *KeeperRegistryLogicBCaller) GetCancellationDelay(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _KeeperRegistryLogicB.contract.Call(opts, &out, "getCheckGasOverhead") + err := _KeeperRegistryLogicB.contract.Call(opts, &out, "getCancellationDelay") if err != nil { return *new(*big.Int), err @@ -317,12 +317,12 @@ func (_KeeperRegistryLogicB *KeeperRegistryLogicBCaller) GetCheckGasOverhead(opt } -func (_KeeperRegistryLogicB *KeeperRegistryLogicBSession) GetCheckGasOverhead() (*big.Int, error) { - return _KeeperRegistryLogicB.Contract.GetCheckGasOverhead(&_KeeperRegistryLogicB.CallOpts) +func (_KeeperRegistryLogicB *KeeperRegistryLogicBSession) GetCancellationDelay() (*big.Int, error) { + return _KeeperRegistryLogicB.Contract.GetCancellationDelay(&_KeeperRegistryLogicB.CallOpts) } -func (_KeeperRegistryLogicB *KeeperRegistryLogicBCallerSession) GetCheckGasOverhead() (*big.Int, error) { - return _KeeperRegistryLogicB.Contract.GetCheckGasOverhead(&_KeeperRegistryLogicB.CallOpts) +func (_KeeperRegistryLogicB *KeeperRegistryLogicBCallerSession) GetCancellationDelay() (*big.Int, error) { + return _KeeperRegistryLogicB.Contract.GetCancellationDelay(&_KeeperRegistryLogicB.CallOpts) } func (_KeeperRegistryLogicB *KeeperRegistryLogicBCaller) GetConditionalGasOverhead(opts *bind.CallOpts) (*big.Int, error) { @@ -674,28 +674,6 @@ func (_KeeperRegistryLogicB *KeeperRegistryLogicBCallerSession) GetState() (GetS return _KeeperRegistryLogicB.Contract.GetState(&_KeeperRegistryLogicB.CallOpts) } -func (_KeeperRegistryLogicB *KeeperRegistryLogicBCaller) GetTransmitGasOverhead(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _KeeperRegistryLogicB.contract.Call(opts, &out, "getTransmitGasOverhead") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_KeeperRegistryLogicB *KeeperRegistryLogicBSession) GetTransmitGasOverhead() (*big.Int, error) { - return _KeeperRegistryLogicB.Contract.GetTransmitGasOverhead(&_KeeperRegistryLogicB.CallOpts) -} - -func (_KeeperRegistryLogicB *KeeperRegistryLogicBCallerSession) GetTransmitGasOverhead() (*big.Int, error) { - return _KeeperRegistryLogicB.Contract.GetTransmitGasOverhead(&_KeeperRegistryLogicB.CallOpts) -} - func (_KeeperRegistryLogicB *KeeperRegistryLogicBCaller) GetTransmitterInfo(opts *bind.CallOpts, query common.Address) (GetTransmitterInfo, error) { @@ -817,6 +795,28 @@ func (_KeeperRegistryLogicB *KeeperRegistryLogicBCallerSession) GetUpkeepTrigger return _KeeperRegistryLogicB.Contract.GetUpkeepTriggerConfig(&_KeeperRegistryLogicB.CallOpts, upkeepId) } +func (_KeeperRegistryLogicB *KeeperRegistryLogicBCaller) HasDedupKey(opts *bind.CallOpts, dedupKey [32]byte) (bool, error) { + var out []interface{} + err := _KeeperRegistryLogicB.contract.Call(opts, &out, "hasDedupKey", dedupKey) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_KeeperRegistryLogicB *KeeperRegistryLogicBSession) HasDedupKey(dedupKey [32]byte) (bool, error) { + return _KeeperRegistryLogicB.Contract.HasDedupKey(&_KeeperRegistryLogicB.CallOpts, dedupKey) +} + +func (_KeeperRegistryLogicB *KeeperRegistryLogicBCallerSession) HasDedupKey(dedupKey [32]byte) (bool, error) { + return _KeeperRegistryLogicB.Contract.HasDedupKey(&_KeeperRegistryLogicB.CallOpts, dedupKey) +} + func (_KeeperRegistryLogicB *KeeperRegistryLogicBCaller) Owner(opts *bind.CallOpts) (common.Address, error) { var out []interface{} err := _KeeperRegistryLogicB.contract.Call(opts, &out, "owner") @@ -1324,9 +1324,9 @@ func (it *KeeperRegistryLogicBCancelledUpkeepReportIterator) Close() error { } type KeeperRegistryLogicBCancelledUpkeepReport struct { - Id *big.Int - UpkeepTriggerID [32]byte - Raw types.Log + Id *big.Int + Trigger []byte + Raw types.Log } func (_KeeperRegistryLogicB *KeeperRegistryLogicBFilterer) FilterCancelledUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*KeeperRegistryLogicBCancelledUpkeepReportIterator, error) { @@ -1391,6 +1391,133 @@ func (_KeeperRegistryLogicB *KeeperRegistryLogicBFilterer) ParseCancelledUpkeepR return event, nil } +type KeeperRegistryLogicBDedupKeyAddedIterator struct { + Event *KeeperRegistryLogicBDedupKeyAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistryLogicBDedupKeyAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistryLogicBDedupKeyAdded) + 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(KeeperRegistryLogicBDedupKeyAdded) + 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 *KeeperRegistryLogicBDedupKeyAddedIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistryLogicBDedupKeyAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistryLogicBDedupKeyAdded struct { + DedupKey [32]byte + Raw types.Log +} + +func (_KeeperRegistryLogicB *KeeperRegistryLogicBFilterer) FilterDedupKeyAdded(opts *bind.FilterOpts, dedupKey [][32]byte) (*KeeperRegistryLogicBDedupKeyAddedIterator, error) { + + var dedupKeyRule []interface{} + for _, dedupKeyItem := range dedupKey { + dedupKeyRule = append(dedupKeyRule, dedupKeyItem) + } + + logs, sub, err := _KeeperRegistryLogicB.contract.FilterLogs(opts, "DedupKeyAdded", dedupKeyRule) + if err != nil { + return nil, err + } + return &KeeperRegistryLogicBDedupKeyAddedIterator{contract: _KeeperRegistryLogicB.contract, event: "DedupKeyAdded", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistryLogicB *KeeperRegistryLogicBFilterer) WatchDedupKeyAdded(opts *bind.WatchOpts, sink chan<- *KeeperRegistryLogicBDedupKeyAdded, dedupKey [][32]byte) (event.Subscription, error) { + + var dedupKeyRule []interface{} + for _, dedupKeyItem := range dedupKey { + dedupKeyRule = append(dedupKeyRule, dedupKeyItem) + } + + logs, sub, err := _KeeperRegistryLogicB.contract.WatchLogs(opts, "DedupKeyAdded", dedupKeyRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(KeeperRegistryLogicBDedupKeyAdded) + if err := _KeeperRegistryLogicB.contract.UnpackLog(event, "DedupKeyAdded", 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 (_KeeperRegistryLogicB *KeeperRegistryLogicBFilterer) ParseDedupKeyAdded(log types.Log) (*KeeperRegistryLogicBDedupKeyAdded, error) { + event := new(KeeperRegistryLogicBDedupKeyAdded) + if err := _KeeperRegistryLogicB.contract.UnpackLog(event, "DedupKeyAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type KeeperRegistryLogicBFundsAddedIterator struct { Event *KeeperRegistryLogicBFundsAdded @@ -1718,9 +1845,9 @@ func (it *KeeperRegistryLogicBInsufficientFundsUpkeepReportIterator) Close() err } type KeeperRegistryLogicBInsufficientFundsUpkeepReport struct { - Id *big.Int - UpkeepTriggerID [32]byte - Raw types.Log + Id *big.Int + Trigger []byte + Raw types.Log } func (_KeeperRegistryLogicB *KeeperRegistryLogicBFilterer) FilterInsufficientFundsUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*KeeperRegistryLogicBInsufficientFundsUpkeepReportIterator, error) { @@ -2906,9 +3033,9 @@ func (it *KeeperRegistryLogicBReorgedUpkeepReportIterator) Close() error { } type KeeperRegistryLogicBReorgedUpkeepReport struct { - Id *big.Int - UpkeepTriggerID [32]byte - Raw types.Log + Id *big.Int + Trigger []byte + Raw types.Log } func (_KeeperRegistryLogicB *KeeperRegistryLogicBFilterer) FilterReorgedUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*KeeperRegistryLogicBReorgedUpkeepReportIterator, error) { @@ -3034,9 +3161,9 @@ func (it *KeeperRegistryLogicBStaleUpkeepReportIterator) Close() error { } type KeeperRegistryLogicBStaleUpkeepReport struct { - Id *big.Int - UpkeepTriggerID [32]byte - Raw types.Log + Id *big.Int + Trigger []byte + Raw types.Log } func (_KeeperRegistryLogicB *KeeperRegistryLogicBFilterer) FilterStaleUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*KeeperRegistryLogicBStaleUpkeepReportIterator, error) { @@ -4345,13 +4472,13 @@ func (it *KeeperRegistryLogicBUpkeepPerformedIterator) Close() error { } type KeeperRegistryLogicBUpkeepPerformed struct { - Id *big.Int - Success bool - TotalPayment *big.Int - GasUsed *big.Int - GasOverhead *big.Int - UpkeepTriggerID [32]byte - Raw types.Log + Id *big.Int + Success bool + TotalPayment *big.Int + GasUsed *big.Int + GasOverhead *big.Int + Trigger []byte + Raw types.Log } func (_KeeperRegistryLogicB *KeeperRegistryLogicBFilterer) FilterUpkeepPerformed(opts *bind.FilterOpts, id []*big.Int, success []bool) (*KeeperRegistryLogicBUpkeepPerformedIterator, error) { @@ -5090,6 +5217,8 @@ func (_KeeperRegistryLogicB *KeeperRegistryLogicB) ParseLog(log types.Log) (gene return _KeeperRegistryLogicB.ParseAdminPrivilegeConfigSet(log) case _KeeperRegistryLogicB.abi.Events["CancelledUpkeepReport"].ID: return _KeeperRegistryLogicB.ParseCancelledUpkeepReport(log) + case _KeeperRegistryLogicB.abi.Events["DedupKeyAdded"].ID: + return _KeeperRegistryLogicB.ParseDedupKeyAdded(log) case _KeeperRegistryLogicB.abi.Events["FundsAdded"].ID: return _KeeperRegistryLogicB.ParseFundsAdded(log) case _KeeperRegistryLogicB.abi.Events["FundsWithdrawn"].ID: @@ -5157,7 +5286,11 @@ func (KeeperRegistryLogicBAdminPrivilegeConfigSet) Topic() common.Hash { } func (KeeperRegistryLogicBCancelledUpkeepReport) Topic() common.Hash { - return common.HexToHash("0x846af3fdde418e2757c00c4cf8c6827e65ac4179753128c454922ccd7963886d") + return common.HexToHash("0xc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636") +} + +func (KeeperRegistryLogicBDedupKeyAdded) Topic() common.Hash { + return common.HexToHash("0xa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f2") } func (KeeperRegistryLogicBFundsAdded) Topic() common.Hash { @@ -5169,7 +5302,7 @@ func (KeeperRegistryLogicBFundsWithdrawn) Topic() common.Hash { } func (KeeperRegistryLogicBInsufficientFundsUpkeepReport) Topic() common.Hash { - return common.HexToHash("0xfcb5fa059ae0ddeeac53240ccaa0a8ad80993b33e18e8821f1e1cbc53481240e") + return common.HexToHash("0x377c8b0c126ae5248d27aca1c76fac4608aff85673ee3caf09747e1044549e02") } func (KeeperRegistryLogicBOwnerFundsWithdrawn) Topic() common.Hash { @@ -5205,11 +5338,11 @@ func (KeeperRegistryLogicBPaymentWithdrawn) Topic() common.Hash { } func (KeeperRegistryLogicBReorgedUpkeepReport) Topic() common.Hash { - return common.HexToHash("0x07c4f19521a82d67071422fca888431cac8267935db8abe73e354791a3d38868") + return common.HexToHash("0x6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301") } func (KeeperRegistryLogicBStaleUpkeepReport) Topic() common.Hash { - return common.HexToHash("0x909d8c7e883c6d2d53a5fb2dbb9ec57875a53c3769c099230027312ffb2a6b11") + return common.HexToHash("0x405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8") } func (KeeperRegistryLogicBUnpaused) Topic() common.Hash { @@ -5249,7 +5382,7 @@ func (KeeperRegistryLogicBUpkeepPaused) Topic() common.Hash { } func (KeeperRegistryLogicBUpkeepPerformed) Topic() common.Hash { - return common.HexToHash("0xdacc0b3d36199a5f78afb27c76cd01bf100f605edf5ee0c0e23055b0553b68c6") + return common.HexToHash("0xad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b") } func (KeeperRegistryLogicBUpkeepPrivilegeConfigSet) Topic() common.Hash { @@ -5281,12 +5414,12 @@ type KeeperRegistryLogicBInterface interface { GetAdminPrivilegeConfig(opts *bind.CallOpts, admin common.Address) ([]byte, error) + GetAutomationForwarderLogic(opts *bind.CallOpts) (common.Address, error) + GetBalance(opts *bind.CallOpts, id *big.Int) (*big.Int, error) GetCancellationDelay(opts *bind.CallOpts) (*big.Int, error) - GetCheckGasOverhead(opts *bind.CallOpts) (*big.Int, error) - GetConditionalGasOverhead(opts *bind.CallOpts) (*big.Int, error) GetFastGasFeedAddress(opts *bind.CallOpts) (common.Address, error) @@ -5321,8 +5454,6 @@ type KeeperRegistryLogicBInterface interface { error) - GetTransmitGasOverhead(opts *bind.CallOpts) (*big.Int, error) - GetTransmitterInfo(opts *bind.CallOpts, query common.Address) (GetTransmitterInfo, error) @@ -5335,6 +5466,8 @@ type KeeperRegistryLogicBInterface interface { GetUpkeepTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) + HasDedupKey(opts *bind.CallOpts, dedupKey [32]byte) (bool, error) + Owner(opts *bind.CallOpts) (common.Address, error) UpkeepTranscoderVersion(opts *bind.CallOpts) (uint8, error) @@ -5395,6 +5528,12 @@ type KeeperRegistryLogicBInterface interface { ParseCancelledUpkeepReport(log types.Log) (*KeeperRegistryLogicBCancelledUpkeepReport, error) + FilterDedupKeyAdded(opts *bind.FilterOpts, dedupKey [][32]byte) (*KeeperRegistryLogicBDedupKeyAddedIterator, error) + + WatchDedupKeyAdded(opts *bind.WatchOpts, sink chan<- *KeeperRegistryLogicBDedupKeyAdded, dedupKey [][32]byte) (event.Subscription, error) + + ParseDedupKeyAdded(log types.Log) (*KeeperRegistryLogicBDedupKeyAdded, error) + FilterFundsAdded(opts *bind.FilterOpts, id []*big.Int, from []common.Address) (*KeeperRegistryLogicBFundsAddedIterator, error) WatchFundsAdded(opts *bind.WatchOpts, sink chan<- *KeeperRegistryLogicBFundsAdded, id []*big.Int, from []common.Address) (event.Subscription, error) diff --git a/core/gethwrappers/generated/keeper_registry_wrapper1_1_mock/keeper_registry_wrapper1_1_mock.go b/core/gethwrappers/generated/keeper_registry_wrapper1_1_mock/keeper_registry_wrapper1_1_mock.go new file mode 100644 index 00000000000..d7bfc132eb5 --- /dev/null +++ b/core/gethwrappers/generated/keeper_registry_wrapper1_1_mock/keeper_registry_wrapper1_1_mock.go @@ -0,0 +1,3083 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package keeper_registry_wrapper1_1_mock + +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 KeeperRegistryMockMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint24\",\"name\":\"blockCountPerTurn\",\"type\":\"uint24\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"}],\"name\":\"FlatFeeSet\",\"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\":false,\"internalType\":\"address[]\",\"name\":\"keepers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"KeepersUpdated\",\"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\":true,\"internalType\":\"address\",\"name\":\"keeper\",\"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\":\"keeper\",\"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\":\"keeper\",\"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\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"RegistrarChanged\",\"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\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"executeGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"maxLinkPayment\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"adjustedGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkEth\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"blockCountPerTurn\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"}],\"name\":\"emitConfigSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"}],\"name\":\"emitFlatFeeSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"emitFundsAdded\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"emitFundsWithdrawn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"keepers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"emitKeepersUpdated\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"emitOwnershipTransferRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"emitOwnershipTransferred\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"emitPaused\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"keeper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"emitPayeeshipTransferRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"keeper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"emitPayeeshipTransferred\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"emitPaymentWithdrawn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"emitRegistrarChanged\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"emitUnpaused\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"emitUpkeepCanceled\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"emitUpkeepPerformed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"executeGas\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"emitUpkeepRegistered\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCanceledUpkeepList\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"blockCountPerTurn\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getKeeperList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalanceForUpkeep\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getUpkeep\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"executeGas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"lastKeeper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"maxValidBlocknumber\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getUpkeepCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_canceledUpkeepList\",\"type\":\"uint256[]\"}],\"name\":\"setCanceledUpkeepList\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"maxLinkPayment\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"adjustedGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkEth\",\"type\":\"uint256\"}],\"name\":\"setCheckUpkeepData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"_blockCountPerTurn\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"_checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"_stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"_gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"_fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_fallbackLinkPrice\",\"type\":\"uint256\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_keepers\",\"type\":\"address[]\"}],\"name\":\"setKeeperList\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minBalance\",\"type\":\"uint96\"}],\"name\":\"setMinBalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"setPerformUpkeepSuccess\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_executeGas\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"_balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"_maxValidBlocknumber\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"_lastKeeper\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_checkData\",\"type\":\"bytes\"}],\"name\":\"setUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_upkeepCount\",\"type\":\"uint256\"}],\"name\":\"setUpkeepCount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50611fb6806100206000396000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c8063999a73bb1161010f578063c3f909d4116100a2578063db30a38611610071578063db30a38614610d76578063f7420bc214610dd7578063fecf27c914610e12578063ffc1d91c14610e2c576101f0565b8063c3f909d414610aed578063c41b813a14610b45578063c7c3a19a14610c12578063d5b16ded14610d31576101f0565b8063b019b4e8116100de578063b019b4e814610996578063b34362d7146109d1578063b657bc9c14610a0c578063c2030c8b14610a4a576101f0565b8063999a73bb146107b857806399e1a39b146108df5780639ec3ce4b14610924578063a6e95ed014610957576101f0565b806358e1e734116101875780637be5c756116101565780637be5c756146106b557806381d2c40c146106e8578063825bea391461073e5780638a8aa1651461076f576101f0565b806358e1e7341461056b57806367923e95146105b0578063749e9cc9146105fd5780637bbaf1ea1461062a576101f0565b80633e2d7056116101c35780633e2d7056146103815780634a16a9ad146103a65780634e6575e01461048a5780635181feaa146104ad576101f0565b806315a126ea146101f55780631ffe6c971461024d578063284403761461035c5780632cb6864d14610379575b600080fd5b6101fd610ecf565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610239578181015183820152602001610221565b505050509050019250505060405180910390f35b61035a600480360361010081101561026457600080fd5b81359173ffffffffffffffffffffffffffffffffffffffff602082013581169263ffffffff604084013516926bffffffffffffffffffffffff60608201351692608082013581169267ffffffffffffffff60a0840135169260c08101359092169190810190610100810160e08201356401000000008111156102e557600080fd5b8201836020820111156102f757600080fd5b8035906020019184600183028401116401000000008311171561031957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610f3e945050505050565b005b61035a6004803603602081101561037257600080fd5b503561117b565b6101fd611180565b61035a6004803603604081101561039757600080fd5b508035906020013515156111d7565b61035a600480360360a08110156103bc57600080fd5b813591602081013515159173ffffffffffffffffffffffffffffffffffffffff604083013516916bffffffffffffffffffffffff6060820135169181019060a08101608082013564010000000081111561041557600080fd5b82018360208201111561042757600080fd5b8035906020019184600183028401116401000000008311171561044957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611215945050505050565b61035a600480360360208110156104a057600080fd5b503563ffffffff166112e6565b61035a600480360360c08110156104c357600080fd5b813591908101906040810160208201356401000000008111156104e557600080fd5b8201836020820111156104f757600080fd5b8035906020019184600183028401116401000000008311171561051957600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505082359350505060208101359060408101359060600135611322565b61035a6004803603606081101561058157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020810135821691604090910135166113a0565b61035a600480360360608110156105c657600080fd5b50803590602081013573ffffffffffffffffffffffffffffffffffffffff1690604001356bffffffffffffffffffffffff16611416565b61035a6004803603604081101561061357600080fd5b508035906020013567ffffffffffffffff16611476565b6106a16004803603604081101561064057600080fd5b8135919081019060408101602082013564010000000081111561066257600080fd5b82018360208201111561067457600080fd5b8035906020019184600183028401116401000000008311171561069657600080fd5b5090925090506114b1565b604080519115158252519081900360200190f35b61035a600480360360208110156106cb57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166114c8565b61035a600480360360e08110156106fe57600080fd5b5063ffffffff813581169162ffffff60208201358116926040830135169160608101359091169061ffff6080820135169060a08101359060c00135611514565b61035a6004803603604081101561075457600080fd5b50803590602001356bffffffffffffffffffffffff16611589565b61035a6004803603608081101561078557600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013591604082013581169160600135166115d4565b61035a600480360360408110156107ce57600080fd5b8101906020810181356401000000008111156107e957600080fd5b8201836020820111156107fb57600080fd5b8035906020019184602083028401116401000000008311171561081d57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561086d57600080fd5b82018360208201111561087f57600080fd5b803590602001918460208302840111640100000000831117156108a157600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611656945050505050565b61035a600480360360608110156108f557600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013582169160409091013516611715565b61035a6004803603602081101561093a57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661178b565b61035a6004803603606081101561096d57600080fd5b508035906020810135906040013573ffffffffffffffffffffffffffffffffffffffff166117d7565b61035a600480360360408110156109ac57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602001351661182b565b61035a600480360360408110156109e757600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516611889565b610a2960048036036020811015610a2257600080fd5b50356118e7565b604080516bffffffffffffffffffffffff9092168252519081900360200190f35b61035a60048036036020811015610a6057600080fd5b810190602081018135640100000000811115610a7b57600080fd5b820183602082011115610a8d57600080fd5b80359060200191846020830284011164010000000083111715610aaf57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611907945050505050565b610af561191e565b6040805163ffffffff988916815262ffffff9788166020820152959097168588015292909416606084015261ffff16608083015260a082019290925260c081019190915290519081900360e00190f35b610b7e60048036036040811015610b5b57600080fd5b508035906020013573ffffffffffffffffffffffffffffffffffffffff1661198e565b6040518080602001868152602001858152602001848152602001838152602001828103825287818151815260200191508051906020019080838360005b83811015610bd3578181015183820152602001610bbb565b50505050905090810190601f168015610c005780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390f35b610c2f60048036036020811015610c2857600080fd5b5035611a76565b604051808873ffffffffffffffffffffffffffffffffffffffff1681526020018763ffffffff16815260200180602001866bffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018367ffffffffffffffff168152602001828103825287818151815260200191508051906020019080838360005b83811015610cf0578181015183820152602001610cd8565b50505050905090810190601f168015610d1d5780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390f35b61035a60048036036060811015610d4757600080fd5b50803590602081013563ffffffff16906040013573ffffffffffffffffffffffffffffffffffffffff16611c1f565b61035a6004803603610100811015610d8d57600080fd5b5063ffffffff8135811691602081013582169162ffffff604083013581169260608101359092169160808101359091169061ffff60a0820135169060c08101359060e00135611c79565b61035a60048036036040811015610ded57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516611ddd565b610e1a611e3b565b60408051918252519081900360200190f35b61035a60048036036020811015610e4257600080fd5b810190602081018135640100000000811115610e5d57600080fd5b820183602082011115610e6f57600080fd5b80359060200191846020830284011164010000000083111715610e9157600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611e41945050505050565b60606002805480602002602001604051908101604052809291908181526020018280548015610f3457602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610f09575b5050505050905090565b60006040518060c001604052808973ffffffffffffffffffffffffffffffffffffffff1681526020018863ffffffff168152602001876bffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018567ffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff16815250905080600660008b815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060408201518160010160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550606082015181600101600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060808201518160020160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060a08201518160020160086101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505081600760008b8152602001908152602001600020908051906020019061116f929190611e54565b50505050505050505050565b600055565b60606001805480602002602001604051908101604052809291908181526020018280548015610f3457602002820191906000526020600020905b8154815260200190600101908083116111ba575050505050905090565b6000918252600a602052604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b8273ffffffffffffffffffffffffffffffffffffffff16841515867fcaacad83e47cc45c280d487ec84184eee2fa3b54ebaa393bda7549f13da228f6858560405180836bffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b838110156112a457818101518382015260200161128c565b50505050905090810190601f1680156112d15780820380516001836020036101000a031916815260200191505b50935050505060405180910390a45050505050565b6040805163ffffffff8316815290517f17b46a44a823646eef686b7824df2962de896bc9a012a60b67694c5cbf184d8b9181900360200190a150565b6040805160a0810182528681526020808201879052818301869052606082018590526080820184905260008981526009825292909220815180519293919261136d9284920190611e54565b50602082015160018201556040820151600282015560608201516003820155608090910151600490910155505050505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b360405160405180910390a4505050565b604080516bffffffffffffffffffffffff83168152905173ffffffffffffffffffffffffffffffffffffffff84169185917fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039181900360200190a3505050565b60405167ffffffffffffffff82169083907f91cb3bb75cfbd718bbfccc56b7f53d92d7048ef4ca39a3b7b7c6d4af1f79118190600090a35050565b50506000908152600a602052604090205460ff1690565b6040805173ffffffffffffffffffffffffffffffffffffffff8316815290517f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2589181900360200190a150565b6040805163ffffffff808a16825262ffffff808a166020840152908816828401528616606082015261ffff8516608082015260a0810184905260c0810183905290517feb3c06937e6595fd80ec1add18a195026d5cf65f122cc3ffedbfb18a9ed80b399181900360e00190a150505050505050565b60009182526008602052604090912080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff909216919091179055565b8173ffffffffffffffffffffffffffffffffffffffff16838573ffffffffffffffffffffffffffffffffffffffff167f9819093176a1851202c7bcfa46845809b4e47c261866550e94ed3775d2f4069884604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a450505050565b7f056264c94f28bb06c99d13f0446eb96c67c215d8d707bce2655a98ddf1c0b71f8282604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156116bd5781810151838201526020016116a5565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156116fc5781810151838201526020016116e4565b5050505090500194505050505060405180910390a15050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e3836760405160405180910390a4505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8316815290517f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa9181900360200190a150565b6040805183815273ffffffffffffffffffffffffffffffffffffffff83166020820152815185927ff3b5906e5672f3e524854103bcafbbdba80dbdfeca2c35e116127b1060a68318928290030190a2505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f9bf4a5b30267728df68663e14adb47e559863967c419dc6030638883408bed2e60405160405180910390a35050565b6000908152600860205260409020546bffffffffffffffffffffffff1690565b805161191a906001906020840190611ee0565b5050565b60035460045460055463ffffffff8084169468010000000000000000850462ffffff908116956b0100000000000000000000008104909316946f01000000000000000000000000000000840490911693720100000000000000000000000000000000000090930461ffff16929091565b60606000806000806000600960008981526020019081526020016000209050806000018160010154826002015483600301548460040154848054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611a5a5780601f10611a2f57610100808354040283529160200191611a5a565b820191906000526020600020905b815481529060010190602001808311611a3d57829003601f168201915b5050505050945095509550955095509550509295509295909350565b6000818152600660209081526040808320815160c081018352815473ffffffffffffffffffffffffffffffffffffffff8082168084527401000000000000000000000000000000000000000090920463ffffffff168387018190526001808601546bffffffffffffffffffffffff81168689019081526c010000000000000000000000009091048416606080880191825260029889015467ffffffffffffffff811660808a019081526801000000000000000090910490961660a089019081528d8d5260078c528a8d20935190519251965184548c5161010097821615979097027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01169a909a04601f81018d90048d0286018d01909b528a85528c9b919a8c9a8b9a8b9a8b9a91999098909796949591939091879190830182828015611bfe5780601f10611bd357610100808354040283529160200191611bfe565b820191906000526020600020905b815481529060010190602001808311611be157829003601f168201915b50505050509450975097509750975097509750975050919395979092949650565b6040805163ffffffff8416815273ffffffffffffffffffffffffffffffffffffffff83166020820152815185927fbae366358c023f887e791d7a62f2e4316f1026bd77f6fb49501a917b3bc5d012928290030190a2505050565b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff998a16177fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff16640100000000988a1698909802979097177fffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffffff166801000000000000000062ffffff97881602177fffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffff166b0100000000000000000000009590981694909402969096177fffffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffff166f010000000000000000000000000000009290941691909102929092177fffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffff16720100000000000000000000000000000000000061ffff939093169290920291909117909155600491909155600555565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127860405160405180910390a35050565b60005490565b805161191a906002906020840190611f1a565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282611e8a5760008555611ed0565b82601f10611ea357805160ff1916838001178555611ed0565b82800160010185558215611ed0579182015b82811115611ed0578251825591602001919060010190611eb5565b50611edc929150611f94565b5090565b828054828255906000526020600020908101928215611ed05791602002820182811115611ed0578251825591602001919060010190611eb5565b828054828255906000526020600020908101928215611ed0579160200282015b82811115611ed057825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190611f3a565b5b80821115611edc5760008155600101611f9556fea164736f6c6343000706000a", +} + +var KeeperRegistryMockABI = KeeperRegistryMockMetaData.ABI + +var KeeperRegistryMockBin = KeeperRegistryMockMetaData.Bin + +func DeployKeeperRegistryMock(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *KeeperRegistryMock, error) { + parsed, err := KeeperRegistryMockMetaData.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(KeeperRegistryMockBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &KeeperRegistryMock{KeeperRegistryMockCaller: KeeperRegistryMockCaller{contract: contract}, KeeperRegistryMockTransactor: KeeperRegistryMockTransactor{contract: contract}, KeeperRegistryMockFilterer: KeeperRegistryMockFilterer{contract: contract}}, nil +} + +type KeeperRegistryMock struct { + address common.Address + abi abi.ABI + KeeperRegistryMockCaller + KeeperRegistryMockTransactor + KeeperRegistryMockFilterer +} + +type KeeperRegistryMockCaller struct { + contract *bind.BoundContract +} + +type KeeperRegistryMockTransactor struct { + contract *bind.BoundContract +} + +type KeeperRegistryMockFilterer struct { + contract *bind.BoundContract +} + +type KeeperRegistryMockSession struct { + Contract *KeeperRegistryMock + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type KeeperRegistryMockCallerSession struct { + Contract *KeeperRegistryMockCaller + CallOpts bind.CallOpts +} + +type KeeperRegistryMockTransactorSession struct { + Contract *KeeperRegistryMockTransactor + TransactOpts bind.TransactOpts +} + +type KeeperRegistryMockRaw struct { + Contract *KeeperRegistryMock +} + +type KeeperRegistryMockCallerRaw struct { + Contract *KeeperRegistryMockCaller +} + +type KeeperRegistryMockTransactorRaw struct { + Contract *KeeperRegistryMockTransactor +} + +func NewKeeperRegistryMock(address common.Address, backend bind.ContractBackend) (*KeeperRegistryMock, error) { + abi, err := abi.JSON(strings.NewReader(KeeperRegistryMockABI)) + if err != nil { + return nil, err + } + contract, err := bindKeeperRegistryMock(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &KeeperRegistryMock{address: address, abi: abi, KeeperRegistryMockCaller: KeeperRegistryMockCaller{contract: contract}, KeeperRegistryMockTransactor: KeeperRegistryMockTransactor{contract: contract}, KeeperRegistryMockFilterer: KeeperRegistryMockFilterer{contract: contract}}, nil +} + +func NewKeeperRegistryMockCaller(address common.Address, caller bind.ContractCaller) (*KeeperRegistryMockCaller, error) { + contract, err := bindKeeperRegistryMock(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &KeeperRegistryMockCaller{contract: contract}, nil +} + +func NewKeeperRegistryMockTransactor(address common.Address, transactor bind.ContractTransactor) (*KeeperRegistryMockTransactor, error) { + contract, err := bindKeeperRegistryMock(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &KeeperRegistryMockTransactor{contract: contract}, nil +} + +func NewKeeperRegistryMockFilterer(address common.Address, filterer bind.ContractFilterer) (*KeeperRegistryMockFilterer, error) { + contract, err := bindKeeperRegistryMock(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &KeeperRegistryMockFilterer{contract: contract}, nil +} + +func bindKeeperRegistryMock(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := KeeperRegistryMockMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_KeeperRegistryMock *KeeperRegistryMockRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _KeeperRegistryMock.Contract.KeeperRegistryMockCaller.contract.Call(opts, result, method, params...) +} + +func (_KeeperRegistryMock *KeeperRegistryMockRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.KeeperRegistryMockTransactor.contract.Transfer(opts) +} + +func (_KeeperRegistryMock *KeeperRegistryMockRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.KeeperRegistryMockTransactor.contract.Transact(opts, method, params...) +} + +func (_KeeperRegistryMock *KeeperRegistryMockCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _KeeperRegistryMock.Contract.contract.Call(opts, result, method, params...) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.contract.Transfer(opts) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.contract.Transact(opts, method, params...) +} + +func (_KeeperRegistryMock *KeeperRegistryMockCaller) CheckUpkeep(opts *bind.CallOpts, id *big.Int, from common.Address) (CheckUpkeep, + + error) { + var out []interface{} + err := _KeeperRegistryMock.contract.Call(opts, &out, "checkUpkeep", id, from) + + outstruct := new(CheckUpkeep) + if err != nil { + return *outstruct, err + } + + outstruct.PerformData = *abi.ConvertType(out[0], new([]byte)).(*[]byte) + outstruct.MaxLinkPayment = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.GasLimit = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + outstruct.AdjustedGasWei = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.LinkEth = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) CheckUpkeep(id *big.Int, from common.Address) (CheckUpkeep, + + error) { + return _KeeperRegistryMock.Contract.CheckUpkeep(&_KeeperRegistryMock.CallOpts, id, from) +} + +func (_KeeperRegistryMock *KeeperRegistryMockCallerSession) CheckUpkeep(id *big.Int, from common.Address) (CheckUpkeep, + + error) { + return _KeeperRegistryMock.Contract.CheckUpkeep(&_KeeperRegistryMock.CallOpts, id, from) +} + +func (_KeeperRegistryMock *KeeperRegistryMockCaller) GetCanceledUpkeepList(opts *bind.CallOpts) ([]*big.Int, error) { + var out []interface{} + err := _KeeperRegistryMock.contract.Call(opts, &out, "getCanceledUpkeepList") + + if err != nil { + return *new([]*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) + + return out0, err + +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) GetCanceledUpkeepList() ([]*big.Int, error) { + return _KeeperRegistryMock.Contract.GetCanceledUpkeepList(&_KeeperRegistryMock.CallOpts) +} + +func (_KeeperRegistryMock *KeeperRegistryMockCallerSession) GetCanceledUpkeepList() ([]*big.Int, error) { + return _KeeperRegistryMock.Contract.GetCanceledUpkeepList(&_KeeperRegistryMock.CallOpts) +} + +func (_KeeperRegistryMock *KeeperRegistryMockCaller) GetConfig(opts *bind.CallOpts) (GetConfig, + + error) { + var out []interface{} + err := _KeeperRegistryMock.contract.Call(opts, &out, "getConfig") + + outstruct := new(GetConfig) + if err != nil { + return *outstruct, err + } + + outstruct.PaymentPremiumPPB = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.BlockCountPerTurn = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.CheckGasLimit = *abi.ConvertType(out[2], new(uint32)).(*uint32) + outstruct.StalenessSeconds = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.GasCeilingMultiplier = *abi.ConvertType(out[4], new(uint16)).(*uint16) + outstruct.FallbackGasPrice = *abi.ConvertType(out[5], new(*big.Int)).(**big.Int) + outstruct.FallbackLinkPrice = *abi.ConvertType(out[6], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) GetConfig() (GetConfig, + + error) { + return _KeeperRegistryMock.Contract.GetConfig(&_KeeperRegistryMock.CallOpts) +} + +func (_KeeperRegistryMock *KeeperRegistryMockCallerSession) GetConfig() (GetConfig, + + error) { + return _KeeperRegistryMock.Contract.GetConfig(&_KeeperRegistryMock.CallOpts) +} + +func (_KeeperRegistryMock *KeeperRegistryMockCaller) GetKeeperList(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _KeeperRegistryMock.contract.Call(opts, &out, "getKeeperList") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) GetKeeperList() ([]common.Address, error) { + return _KeeperRegistryMock.Contract.GetKeeperList(&_KeeperRegistryMock.CallOpts) +} + +func (_KeeperRegistryMock *KeeperRegistryMockCallerSession) GetKeeperList() ([]common.Address, error) { + return _KeeperRegistryMock.Contract.GetKeeperList(&_KeeperRegistryMock.CallOpts) +} + +func (_KeeperRegistryMock *KeeperRegistryMockCaller) GetMinBalanceForUpkeep(opts *bind.CallOpts, id *big.Int) (*big.Int, error) { + var out []interface{} + err := _KeeperRegistryMock.contract.Call(opts, &out, "getMinBalanceForUpkeep", id) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) GetMinBalanceForUpkeep(id *big.Int) (*big.Int, error) { + return _KeeperRegistryMock.Contract.GetMinBalanceForUpkeep(&_KeeperRegistryMock.CallOpts, id) +} + +func (_KeeperRegistryMock *KeeperRegistryMockCallerSession) GetMinBalanceForUpkeep(id *big.Int) (*big.Int, error) { + return _KeeperRegistryMock.Contract.GetMinBalanceForUpkeep(&_KeeperRegistryMock.CallOpts, id) +} + +func (_KeeperRegistryMock *KeeperRegistryMockCaller) GetUpkeep(opts *bind.CallOpts, id *big.Int) (GetUpkeep, + + error) { + var out []interface{} + err := _KeeperRegistryMock.contract.Call(opts, &out, "getUpkeep", id) + + outstruct := new(GetUpkeep) + if err != nil { + return *outstruct, err + } + + outstruct.Target = *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + outstruct.ExecuteGas = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.CheckData = *abi.ConvertType(out[2], new([]byte)).(*[]byte) + outstruct.Balance = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.LastKeeper = *abi.ConvertType(out[4], new(common.Address)).(*common.Address) + outstruct.Admin = *abi.ConvertType(out[5], new(common.Address)).(*common.Address) + outstruct.MaxValidBlocknumber = *abi.ConvertType(out[6], new(uint64)).(*uint64) + + return *outstruct, err + +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) GetUpkeep(id *big.Int) (GetUpkeep, + + error) { + return _KeeperRegistryMock.Contract.GetUpkeep(&_KeeperRegistryMock.CallOpts, id) +} + +func (_KeeperRegistryMock *KeeperRegistryMockCallerSession) GetUpkeep(id *big.Int) (GetUpkeep, + + error) { + return _KeeperRegistryMock.Contract.GetUpkeep(&_KeeperRegistryMock.CallOpts, id) +} + +func (_KeeperRegistryMock *KeeperRegistryMockCaller) GetUpkeepCount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _KeeperRegistryMock.contract.Call(opts, &out, "getUpkeepCount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) GetUpkeepCount() (*big.Int, error) { + return _KeeperRegistryMock.Contract.GetUpkeepCount(&_KeeperRegistryMock.CallOpts) +} + +func (_KeeperRegistryMock *KeeperRegistryMockCallerSession) GetUpkeepCount() (*big.Int, error) { + return _KeeperRegistryMock.Contract.GetUpkeepCount(&_KeeperRegistryMock.CallOpts) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) EmitConfigSet(opts *bind.TransactOpts, paymentPremiumPPB uint32, blockCountPerTurn *big.Int, checkGasLimit uint32, stalenessSeconds *big.Int, gasCeilingMultiplier uint16, fallbackGasPrice *big.Int, fallbackLinkPrice *big.Int) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "emitConfigSet", paymentPremiumPPB, blockCountPerTurn, checkGasLimit, stalenessSeconds, gasCeilingMultiplier, fallbackGasPrice, fallbackLinkPrice) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) EmitConfigSet(paymentPremiumPPB uint32, blockCountPerTurn *big.Int, checkGasLimit uint32, stalenessSeconds *big.Int, gasCeilingMultiplier uint16, fallbackGasPrice *big.Int, fallbackLinkPrice *big.Int) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitConfigSet(&_KeeperRegistryMock.TransactOpts, paymentPremiumPPB, blockCountPerTurn, checkGasLimit, stalenessSeconds, gasCeilingMultiplier, fallbackGasPrice, fallbackLinkPrice) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) EmitConfigSet(paymentPremiumPPB uint32, blockCountPerTurn *big.Int, checkGasLimit uint32, stalenessSeconds *big.Int, gasCeilingMultiplier uint16, fallbackGasPrice *big.Int, fallbackLinkPrice *big.Int) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitConfigSet(&_KeeperRegistryMock.TransactOpts, paymentPremiumPPB, blockCountPerTurn, checkGasLimit, stalenessSeconds, gasCeilingMultiplier, fallbackGasPrice, fallbackLinkPrice) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) EmitFlatFeeSet(opts *bind.TransactOpts, flatFeeMicroLink uint32) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "emitFlatFeeSet", flatFeeMicroLink) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) EmitFlatFeeSet(flatFeeMicroLink uint32) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitFlatFeeSet(&_KeeperRegistryMock.TransactOpts, flatFeeMicroLink) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) EmitFlatFeeSet(flatFeeMicroLink uint32) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitFlatFeeSet(&_KeeperRegistryMock.TransactOpts, flatFeeMicroLink) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) EmitFundsAdded(opts *bind.TransactOpts, id *big.Int, from common.Address, amount *big.Int) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "emitFundsAdded", id, from, amount) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) EmitFundsAdded(id *big.Int, from common.Address, amount *big.Int) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitFundsAdded(&_KeeperRegistryMock.TransactOpts, id, from, amount) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) EmitFundsAdded(id *big.Int, from common.Address, amount *big.Int) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitFundsAdded(&_KeeperRegistryMock.TransactOpts, id, from, amount) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) EmitFundsWithdrawn(opts *bind.TransactOpts, id *big.Int, amount *big.Int, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "emitFundsWithdrawn", id, amount, to) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) EmitFundsWithdrawn(id *big.Int, amount *big.Int, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitFundsWithdrawn(&_KeeperRegistryMock.TransactOpts, id, amount, to) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) EmitFundsWithdrawn(id *big.Int, amount *big.Int, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitFundsWithdrawn(&_KeeperRegistryMock.TransactOpts, id, amount, to) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) EmitKeepersUpdated(opts *bind.TransactOpts, keepers []common.Address, payees []common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "emitKeepersUpdated", keepers, payees) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) EmitKeepersUpdated(keepers []common.Address, payees []common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitKeepersUpdated(&_KeeperRegistryMock.TransactOpts, keepers, payees) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) EmitKeepersUpdated(keepers []common.Address, payees []common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitKeepersUpdated(&_KeeperRegistryMock.TransactOpts, keepers, payees) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) EmitOwnershipTransferRequested(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "emitOwnershipTransferRequested", from, to) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) EmitOwnershipTransferRequested(from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitOwnershipTransferRequested(&_KeeperRegistryMock.TransactOpts, from, to) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) EmitOwnershipTransferRequested(from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitOwnershipTransferRequested(&_KeeperRegistryMock.TransactOpts, from, to) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) EmitOwnershipTransferred(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "emitOwnershipTransferred", from, to) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) EmitOwnershipTransferred(from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitOwnershipTransferred(&_KeeperRegistryMock.TransactOpts, from, to) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) EmitOwnershipTransferred(from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitOwnershipTransferred(&_KeeperRegistryMock.TransactOpts, from, to) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) EmitPaused(opts *bind.TransactOpts, account common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "emitPaused", account) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) EmitPaused(account common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitPaused(&_KeeperRegistryMock.TransactOpts, account) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) EmitPaused(account common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitPaused(&_KeeperRegistryMock.TransactOpts, account) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) EmitPayeeshipTransferRequested(opts *bind.TransactOpts, keeper common.Address, from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "emitPayeeshipTransferRequested", keeper, from, to) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) EmitPayeeshipTransferRequested(keeper common.Address, from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitPayeeshipTransferRequested(&_KeeperRegistryMock.TransactOpts, keeper, from, to) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) EmitPayeeshipTransferRequested(keeper common.Address, from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitPayeeshipTransferRequested(&_KeeperRegistryMock.TransactOpts, keeper, from, to) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) EmitPayeeshipTransferred(opts *bind.TransactOpts, keeper common.Address, from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "emitPayeeshipTransferred", keeper, from, to) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) EmitPayeeshipTransferred(keeper common.Address, from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitPayeeshipTransferred(&_KeeperRegistryMock.TransactOpts, keeper, from, to) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) EmitPayeeshipTransferred(keeper common.Address, from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitPayeeshipTransferred(&_KeeperRegistryMock.TransactOpts, keeper, from, to) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) EmitPaymentWithdrawn(opts *bind.TransactOpts, keeper common.Address, amount *big.Int, to common.Address, payee common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "emitPaymentWithdrawn", keeper, amount, to, payee) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) EmitPaymentWithdrawn(keeper common.Address, amount *big.Int, to common.Address, payee common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitPaymentWithdrawn(&_KeeperRegistryMock.TransactOpts, keeper, amount, to, payee) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) EmitPaymentWithdrawn(keeper common.Address, amount *big.Int, to common.Address, payee common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitPaymentWithdrawn(&_KeeperRegistryMock.TransactOpts, keeper, amount, to, payee) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) EmitRegistrarChanged(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "emitRegistrarChanged", from, to) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) EmitRegistrarChanged(from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitRegistrarChanged(&_KeeperRegistryMock.TransactOpts, from, to) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) EmitRegistrarChanged(from common.Address, to common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitRegistrarChanged(&_KeeperRegistryMock.TransactOpts, from, to) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) EmitUnpaused(opts *bind.TransactOpts, account common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "emitUnpaused", account) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) EmitUnpaused(account common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitUnpaused(&_KeeperRegistryMock.TransactOpts, account) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) EmitUnpaused(account common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitUnpaused(&_KeeperRegistryMock.TransactOpts, account) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) EmitUpkeepCanceled(opts *bind.TransactOpts, id *big.Int, atBlockHeight uint64) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "emitUpkeepCanceled", id, atBlockHeight) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) EmitUpkeepCanceled(id *big.Int, atBlockHeight uint64) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitUpkeepCanceled(&_KeeperRegistryMock.TransactOpts, id, atBlockHeight) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) EmitUpkeepCanceled(id *big.Int, atBlockHeight uint64) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitUpkeepCanceled(&_KeeperRegistryMock.TransactOpts, id, atBlockHeight) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) EmitUpkeepPerformed(opts *bind.TransactOpts, id *big.Int, success bool, from common.Address, payment *big.Int, performData []byte) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "emitUpkeepPerformed", id, success, from, payment, performData) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) EmitUpkeepPerformed(id *big.Int, success bool, from common.Address, payment *big.Int, performData []byte) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitUpkeepPerformed(&_KeeperRegistryMock.TransactOpts, id, success, from, payment, performData) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) EmitUpkeepPerformed(id *big.Int, success bool, from common.Address, payment *big.Int, performData []byte) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitUpkeepPerformed(&_KeeperRegistryMock.TransactOpts, id, success, from, payment, performData) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) EmitUpkeepRegistered(opts *bind.TransactOpts, id *big.Int, executeGas uint32, admin common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "emitUpkeepRegistered", id, executeGas, admin) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) EmitUpkeepRegistered(id *big.Int, executeGas uint32, admin common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitUpkeepRegistered(&_KeeperRegistryMock.TransactOpts, id, executeGas, admin) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) EmitUpkeepRegistered(id *big.Int, executeGas uint32, admin common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.EmitUpkeepRegistered(&_KeeperRegistryMock.TransactOpts, id, executeGas, admin) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) PerformUpkeep(opts *bind.TransactOpts, id *big.Int, performData []byte) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "performUpkeep", id, performData) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) PerformUpkeep(id *big.Int, performData []byte) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.PerformUpkeep(&_KeeperRegistryMock.TransactOpts, id, performData) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) PerformUpkeep(id *big.Int, performData []byte) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.PerformUpkeep(&_KeeperRegistryMock.TransactOpts, id, performData) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) SetCanceledUpkeepList(opts *bind.TransactOpts, _canceledUpkeepList []*big.Int) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "setCanceledUpkeepList", _canceledUpkeepList) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) SetCanceledUpkeepList(_canceledUpkeepList []*big.Int) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.SetCanceledUpkeepList(&_KeeperRegistryMock.TransactOpts, _canceledUpkeepList) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) SetCanceledUpkeepList(_canceledUpkeepList []*big.Int) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.SetCanceledUpkeepList(&_KeeperRegistryMock.TransactOpts, _canceledUpkeepList) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) SetCheckUpkeepData(opts *bind.TransactOpts, id *big.Int, performData []byte, maxLinkPayment *big.Int, gasLimit *big.Int, adjustedGasWei *big.Int, linkEth *big.Int) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "setCheckUpkeepData", id, performData, maxLinkPayment, gasLimit, adjustedGasWei, linkEth) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) SetCheckUpkeepData(id *big.Int, performData []byte, maxLinkPayment *big.Int, gasLimit *big.Int, adjustedGasWei *big.Int, linkEth *big.Int) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.SetCheckUpkeepData(&_KeeperRegistryMock.TransactOpts, id, performData, maxLinkPayment, gasLimit, adjustedGasWei, linkEth) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) SetCheckUpkeepData(id *big.Int, performData []byte, maxLinkPayment *big.Int, gasLimit *big.Int, adjustedGasWei *big.Int, linkEth *big.Int) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.SetCheckUpkeepData(&_KeeperRegistryMock.TransactOpts, id, performData, maxLinkPayment, gasLimit, adjustedGasWei, linkEth) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) SetConfig(opts *bind.TransactOpts, _paymentPremiumPPB uint32, _flatFeeMicroLink uint32, _blockCountPerTurn *big.Int, _checkGasLimit uint32, _stalenessSeconds *big.Int, _gasCeilingMultiplier uint16, _fallbackGasPrice *big.Int, _fallbackLinkPrice *big.Int) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "setConfig", _paymentPremiumPPB, _flatFeeMicroLink, _blockCountPerTurn, _checkGasLimit, _stalenessSeconds, _gasCeilingMultiplier, _fallbackGasPrice, _fallbackLinkPrice) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) SetConfig(_paymentPremiumPPB uint32, _flatFeeMicroLink uint32, _blockCountPerTurn *big.Int, _checkGasLimit uint32, _stalenessSeconds *big.Int, _gasCeilingMultiplier uint16, _fallbackGasPrice *big.Int, _fallbackLinkPrice *big.Int) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.SetConfig(&_KeeperRegistryMock.TransactOpts, _paymentPremiumPPB, _flatFeeMicroLink, _blockCountPerTurn, _checkGasLimit, _stalenessSeconds, _gasCeilingMultiplier, _fallbackGasPrice, _fallbackLinkPrice) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) SetConfig(_paymentPremiumPPB uint32, _flatFeeMicroLink uint32, _blockCountPerTurn *big.Int, _checkGasLimit uint32, _stalenessSeconds *big.Int, _gasCeilingMultiplier uint16, _fallbackGasPrice *big.Int, _fallbackLinkPrice *big.Int) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.SetConfig(&_KeeperRegistryMock.TransactOpts, _paymentPremiumPPB, _flatFeeMicroLink, _blockCountPerTurn, _checkGasLimit, _stalenessSeconds, _gasCeilingMultiplier, _fallbackGasPrice, _fallbackLinkPrice) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) SetKeeperList(opts *bind.TransactOpts, _keepers []common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "setKeeperList", _keepers) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) SetKeeperList(_keepers []common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.SetKeeperList(&_KeeperRegistryMock.TransactOpts, _keepers) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) SetKeeperList(_keepers []common.Address) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.SetKeeperList(&_KeeperRegistryMock.TransactOpts, _keepers) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) SetMinBalance(opts *bind.TransactOpts, id *big.Int, minBalance *big.Int) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "setMinBalance", id, minBalance) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) SetMinBalance(id *big.Int, minBalance *big.Int) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.SetMinBalance(&_KeeperRegistryMock.TransactOpts, id, minBalance) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) SetMinBalance(id *big.Int, minBalance *big.Int) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.SetMinBalance(&_KeeperRegistryMock.TransactOpts, id, minBalance) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) SetPerformUpkeepSuccess(opts *bind.TransactOpts, id *big.Int, success bool) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "setPerformUpkeepSuccess", id, success) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) SetPerformUpkeepSuccess(id *big.Int, success bool) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.SetPerformUpkeepSuccess(&_KeeperRegistryMock.TransactOpts, id, success) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) SetPerformUpkeepSuccess(id *big.Int, success bool) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.SetPerformUpkeepSuccess(&_KeeperRegistryMock.TransactOpts, id, success) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) SetUpkeep(opts *bind.TransactOpts, id *big.Int, _target common.Address, _executeGas uint32, _balance *big.Int, _admin common.Address, _maxValidBlocknumber uint64, _lastKeeper common.Address, _checkData []byte) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "setUpkeep", id, _target, _executeGas, _balance, _admin, _maxValidBlocknumber, _lastKeeper, _checkData) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) SetUpkeep(id *big.Int, _target common.Address, _executeGas uint32, _balance *big.Int, _admin common.Address, _maxValidBlocknumber uint64, _lastKeeper common.Address, _checkData []byte) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.SetUpkeep(&_KeeperRegistryMock.TransactOpts, id, _target, _executeGas, _balance, _admin, _maxValidBlocknumber, _lastKeeper, _checkData) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) SetUpkeep(id *big.Int, _target common.Address, _executeGas uint32, _balance *big.Int, _admin common.Address, _maxValidBlocknumber uint64, _lastKeeper common.Address, _checkData []byte) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.SetUpkeep(&_KeeperRegistryMock.TransactOpts, id, _target, _executeGas, _balance, _admin, _maxValidBlocknumber, _lastKeeper, _checkData) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactor) SetUpkeepCount(opts *bind.TransactOpts, _upkeepCount *big.Int) (*types.Transaction, error) { + return _KeeperRegistryMock.contract.Transact(opts, "setUpkeepCount", _upkeepCount) +} + +func (_KeeperRegistryMock *KeeperRegistryMockSession) SetUpkeepCount(_upkeepCount *big.Int) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.SetUpkeepCount(&_KeeperRegistryMock.TransactOpts, _upkeepCount) +} + +func (_KeeperRegistryMock *KeeperRegistryMockTransactorSession) SetUpkeepCount(_upkeepCount *big.Int) (*types.Transaction, error) { + return _KeeperRegistryMock.Contract.SetUpkeepCount(&_KeeperRegistryMock.TransactOpts, _upkeepCount) +} + +type KeeperRegistryMockConfigSetIterator struct { + Event *KeeperRegistryMockConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistryMockConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistryMockConfigSet) + 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(KeeperRegistryMockConfigSet) + 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 *KeeperRegistryMockConfigSetIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistryMockConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistryMockConfigSet struct { + PaymentPremiumPPB uint32 + BlockCountPerTurn *big.Int + CheckGasLimit uint32 + StalenessSeconds *big.Int + GasCeilingMultiplier uint16 + FallbackGasPrice *big.Int + FallbackLinkPrice *big.Int + Raw types.Log +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) FilterConfigSet(opts *bind.FilterOpts) (*KeeperRegistryMockConfigSetIterator, error) { + + logs, sub, err := _KeeperRegistryMock.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &KeeperRegistryMockConfigSetIterator{contract: _KeeperRegistryMock.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockConfigSet) (event.Subscription, error) { + + logs, sub, err := _KeeperRegistryMock.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(KeeperRegistryMockConfigSet) + if err := _KeeperRegistryMock.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 (_KeeperRegistryMock *KeeperRegistryMockFilterer) ParseConfigSet(log types.Log) (*KeeperRegistryMockConfigSet, error) { + event := new(KeeperRegistryMockConfigSet) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistryMockFlatFeeSetIterator struct { + Event *KeeperRegistryMockFlatFeeSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistryMockFlatFeeSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistryMockFlatFeeSet) + 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(KeeperRegistryMockFlatFeeSet) + 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 *KeeperRegistryMockFlatFeeSetIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistryMockFlatFeeSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistryMockFlatFeeSet struct { + FlatFeeMicroLink uint32 + Raw types.Log +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) FilterFlatFeeSet(opts *bind.FilterOpts) (*KeeperRegistryMockFlatFeeSetIterator, error) { + + logs, sub, err := _KeeperRegistryMock.contract.FilterLogs(opts, "FlatFeeSet") + if err != nil { + return nil, err + } + return &KeeperRegistryMockFlatFeeSetIterator{contract: _KeeperRegistryMock.contract, event: "FlatFeeSet", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) WatchFlatFeeSet(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockFlatFeeSet) (event.Subscription, error) { + + logs, sub, err := _KeeperRegistryMock.contract.WatchLogs(opts, "FlatFeeSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(KeeperRegistryMockFlatFeeSet) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "FlatFeeSet", 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 (_KeeperRegistryMock *KeeperRegistryMockFilterer) ParseFlatFeeSet(log types.Log) (*KeeperRegistryMockFlatFeeSet, error) { + event := new(KeeperRegistryMockFlatFeeSet) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "FlatFeeSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistryMockFundsAddedIterator struct { + Event *KeeperRegistryMockFundsAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistryMockFundsAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistryMockFundsAdded) + 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(KeeperRegistryMockFundsAdded) + 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 *KeeperRegistryMockFundsAddedIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistryMockFundsAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistryMockFundsAdded struct { + Id *big.Int + From common.Address + Amount *big.Int + Raw types.Log +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) FilterFundsAdded(opts *bind.FilterOpts, id []*big.Int, from []common.Address) (*KeeperRegistryMockFundsAddedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _KeeperRegistryMock.contract.FilterLogs(opts, "FundsAdded", idRule, fromRule) + if err != nil { + return nil, err + } + return &KeeperRegistryMockFundsAddedIterator{contract: _KeeperRegistryMock.contract, event: "FundsAdded", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) WatchFundsAdded(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockFundsAdded, id []*big.Int, from []common.Address) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _KeeperRegistryMock.contract.WatchLogs(opts, "FundsAdded", idRule, fromRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(KeeperRegistryMockFundsAdded) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "FundsAdded", 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 (_KeeperRegistryMock *KeeperRegistryMockFilterer) ParseFundsAdded(log types.Log) (*KeeperRegistryMockFundsAdded, error) { + event := new(KeeperRegistryMockFundsAdded) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "FundsAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistryMockFundsWithdrawnIterator struct { + Event *KeeperRegistryMockFundsWithdrawn + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistryMockFundsWithdrawnIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistryMockFundsWithdrawn) + 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(KeeperRegistryMockFundsWithdrawn) + 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 *KeeperRegistryMockFundsWithdrawnIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistryMockFundsWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistryMockFundsWithdrawn struct { + Id *big.Int + Amount *big.Int + To common.Address + Raw types.Log +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) FilterFundsWithdrawn(opts *bind.FilterOpts, id []*big.Int) (*KeeperRegistryMockFundsWithdrawnIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _KeeperRegistryMock.contract.FilterLogs(opts, "FundsWithdrawn", idRule) + if err != nil { + return nil, err + } + return &KeeperRegistryMockFundsWithdrawnIterator{contract: _KeeperRegistryMock.contract, event: "FundsWithdrawn", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) WatchFundsWithdrawn(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockFundsWithdrawn, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _KeeperRegistryMock.contract.WatchLogs(opts, "FundsWithdrawn", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(KeeperRegistryMockFundsWithdrawn) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "FundsWithdrawn", 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 (_KeeperRegistryMock *KeeperRegistryMockFilterer) ParseFundsWithdrawn(log types.Log) (*KeeperRegistryMockFundsWithdrawn, error) { + event := new(KeeperRegistryMockFundsWithdrawn) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "FundsWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistryMockKeepersUpdatedIterator struct { + Event *KeeperRegistryMockKeepersUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistryMockKeepersUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistryMockKeepersUpdated) + 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(KeeperRegistryMockKeepersUpdated) + 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 *KeeperRegistryMockKeepersUpdatedIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistryMockKeepersUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistryMockKeepersUpdated struct { + Keepers []common.Address + Payees []common.Address + Raw types.Log +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) FilterKeepersUpdated(opts *bind.FilterOpts) (*KeeperRegistryMockKeepersUpdatedIterator, error) { + + logs, sub, err := _KeeperRegistryMock.contract.FilterLogs(opts, "KeepersUpdated") + if err != nil { + return nil, err + } + return &KeeperRegistryMockKeepersUpdatedIterator{contract: _KeeperRegistryMock.contract, event: "KeepersUpdated", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) WatchKeepersUpdated(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockKeepersUpdated) (event.Subscription, error) { + + logs, sub, err := _KeeperRegistryMock.contract.WatchLogs(opts, "KeepersUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(KeeperRegistryMockKeepersUpdated) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "KeepersUpdated", 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 (_KeeperRegistryMock *KeeperRegistryMockFilterer) ParseKeepersUpdated(log types.Log) (*KeeperRegistryMockKeepersUpdated, error) { + event := new(KeeperRegistryMockKeepersUpdated) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "KeepersUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistryMockOwnershipTransferRequestedIterator struct { + Event *KeeperRegistryMockOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistryMockOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistryMockOwnershipTransferRequested) + 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(KeeperRegistryMockOwnershipTransferRequested) + 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 *KeeperRegistryMockOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistryMockOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistryMockOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeeperRegistryMockOwnershipTransferRequestedIterator, 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 := _KeeperRegistryMock.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &KeeperRegistryMockOwnershipTransferRequestedIterator{contract: _KeeperRegistryMock.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockOwnershipTransferRequested, 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 := _KeeperRegistryMock.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(KeeperRegistryMockOwnershipTransferRequested) + if err := _KeeperRegistryMock.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 (_KeeperRegistryMock *KeeperRegistryMockFilterer) ParseOwnershipTransferRequested(log types.Log) (*KeeperRegistryMockOwnershipTransferRequested, error) { + event := new(KeeperRegistryMockOwnershipTransferRequested) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistryMockOwnershipTransferredIterator struct { + Event *KeeperRegistryMockOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistryMockOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistryMockOwnershipTransferred) + 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(KeeperRegistryMockOwnershipTransferred) + 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 *KeeperRegistryMockOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistryMockOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistryMockOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeeperRegistryMockOwnershipTransferredIterator, 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 := _KeeperRegistryMock.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &KeeperRegistryMockOwnershipTransferredIterator{contract: _KeeperRegistryMock.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockOwnershipTransferred, 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 := _KeeperRegistryMock.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(KeeperRegistryMockOwnershipTransferred) + if err := _KeeperRegistryMock.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 (_KeeperRegistryMock *KeeperRegistryMockFilterer) ParseOwnershipTransferred(log types.Log) (*KeeperRegistryMockOwnershipTransferred, error) { + event := new(KeeperRegistryMockOwnershipTransferred) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistryMockPausedIterator struct { + Event *KeeperRegistryMockPaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistryMockPausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistryMockPaused) + 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(KeeperRegistryMockPaused) + 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 *KeeperRegistryMockPausedIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistryMockPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistryMockPaused struct { + Account common.Address + Raw types.Log +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) FilterPaused(opts *bind.FilterOpts) (*KeeperRegistryMockPausedIterator, error) { + + logs, sub, err := _KeeperRegistryMock.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &KeeperRegistryMockPausedIterator{contract: _KeeperRegistryMock.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockPaused) (event.Subscription, error) { + + logs, sub, err := _KeeperRegistryMock.contract.WatchLogs(opts, "Paused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(KeeperRegistryMockPaused) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "Paused", 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 (_KeeperRegistryMock *KeeperRegistryMockFilterer) ParsePaused(log types.Log) (*KeeperRegistryMockPaused, error) { + event := new(KeeperRegistryMockPaused) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistryMockPayeeshipTransferRequestedIterator struct { + Event *KeeperRegistryMockPayeeshipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistryMockPayeeshipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistryMockPayeeshipTransferRequested) + 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(KeeperRegistryMockPayeeshipTransferRequested) + 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 *KeeperRegistryMockPayeeshipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistryMockPayeeshipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistryMockPayeeshipTransferRequested struct { + Keeper common.Address + From common.Address + To common.Address + Raw types.Log +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) FilterPayeeshipTransferRequested(opts *bind.FilterOpts, keeper []common.Address, from []common.Address, to []common.Address) (*KeeperRegistryMockPayeeshipTransferRequestedIterator, error) { + + var keeperRule []interface{} + for _, keeperItem := range keeper { + keeperRule = append(keeperRule, keeperItem) + } + 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 := _KeeperRegistryMock.contract.FilterLogs(opts, "PayeeshipTransferRequested", keeperRule, fromRule, toRule) + if err != nil { + return nil, err + } + return &KeeperRegistryMockPayeeshipTransferRequestedIterator{contract: _KeeperRegistryMock.contract, event: "PayeeshipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) WatchPayeeshipTransferRequested(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockPayeeshipTransferRequested, keeper []common.Address, from []common.Address, to []common.Address) (event.Subscription, error) { + + var keeperRule []interface{} + for _, keeperItem := range keeper { + keeperRule = append(keeperRule, keeperItem) + } + 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 := _KeeperRegistryMock.contract.WatchLogs(opts, "PayeeshipTransferRequested", keeperRule, 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(KeeperRegistryMockPayeeshipTransferRequested) + if err := _KeeperRegistryMock.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 (_KeeperRegistryMock *KeeperRegistryMockFilterer) ParsePayeeshipTransferRequested(log types.Log) (*KeeperRegistryMockPayeeshipTransferRequested, error) { + event := new(KeeperRegistryMockPayeeshipTransferRequested) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "PayeeshipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistryMockPayeeshipTransferredIterator struct { + Event *KeeperRegistryMockPayeeshipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistryMockPayeeshipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistryMockPayeeshipTransferred) + 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(KeeperRegistryMockPayeeshipTransferred) + 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 *KeeperRegistryMockPayeeshipTransferredIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistryMockPayeeshipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistryMockPayeeshipTransferred struct { + Keeper common.Address + From common.Address + To common.Address + Raw types.Log +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) FilterPayeeshipTransferred(opts *bind.FilterOpts, keeper []common.Address, from []common.Address, to []common.Address) (*KeeperRegistryMockPayeeshipTransferredIterator, error) { + + var keeperRule []interface{} + for _, keeperItem := range keeper { + keeperRule = append(keeperRule, keeperItem) + } + 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 := _KeeperRegistryMock.contract.FilterLogs(opts, "PayeeshipTransferred", keeperRule, fromRule, toRule) + if err != nil { + return nil, err + } + return &KeeperRegistryMockPayeeshipTransferredIterator{contract: _KeeperRegistryMock.contract, event: "PayeeshipTransferred", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) WatchPayeeshipTransferred(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockPayeeshipTransferred, keeper []common.Address, from []common.Address, to []common.Address) (event.Subscription, error) { + + var keeperRule []interface{} + for _, keeperItem := range keeper { + keeperRule = append(keeperRule, keeperItem) + } + 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 := _KeeperRegistryMock.contract.WatchLogs(opts, "PayeeshipTransferred", keeperRule, 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(KeeperRegistryMockPayeeshipTransferred) + if err := _KeeperRegistryMock.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 (_KeeperRegistryMock *KeeperRegistryMockFilterer) ParsePayeeshipTransferred(log types.Log) (*KeeperRegistryMockPayeeshipTransferred, error) { + event := new(KeeperRegistryMockPayeeshipTransferred) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "PayeeshipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistryMockPaymentWithdrawnIterator struct { + Event *KeeperRegistryMockPaymentWithdrawn + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistryMockPaymentWithdrawnIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistryMockPaymentWithdrawn) + 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(KeeperRegistryMockPaymentWithdrawn) + 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 *KeeperRegistryMockPaymentWithdrawnIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistryMockPaymentWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistryMockPaymentWithdrawn struct { + Keeper common.Address + Amount *big.Int + To common.Address + Payee common.Address + Raw types.Log +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) FilterPaymentWithdrawn(opts *bind.FilterOpts, keeper []common.Address, amount []*big.Int, to []common.Address) (*KeeperRegistryMockPaymentWithdrawnIterator, error) { + + var keeperRule []interface{} + for _, keeperItem := range keeper { + keeperRule = append(keeperRule, keeperItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _KeeperRegistryMock.contract.FilterLogs(opts, "PaymentWithdrawn", keeperRule, amountRule, toRule) + if err != nil { + return nil, err + } + return &KeeperRegistryMockPaymentWithdrawnIterator{contract: _KeeperRegistryMock.contract, event: "PaymentWithdrawn", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) WatchPaymentWithdrawn(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockPaymentWithdrawn, keeper []common.Address, amount []*big.Int, to []common.Address) (event.Subscription, error) { + + var keeperRule []interface{} + for _, keeperItem := range keeper { + keeperRule = append(keeperRule, keeperItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _KeeperRegistryMock.contract.WatchLogs(opts, "PaymentWithdrawn", keeperRule, amountRule, 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(KeeperRegistryMockPaymentWithdrawn) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "PaymentWithdrawn", 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 (_KeeperRegistryMock *KeeperRegistryMockFilterer) ParsePaymentWithdrawn(log types.Log) (*KeeperRegistryMockPaymentWithdrawn, error) { + event := new(KeeperRegistryMockPaymentWithdrawn) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "PaymentWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistryMockRegistrarChangedIterator struct { + Event *KeeperRegistryMockRegistrarChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistryMockRegistrarChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistryMockRegistrarChanged) + 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(KeeperRegistryMockRegistrarChanged) + 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 *KeeperRegistryMockRegistrarChangedIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistryMockRegistrarChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistryMockRegistrarChanged struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) FilterRegistrarChanged(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeeperRegistryMockRegistrarChangedIterator, 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 := _KeeperRegistryMock.contract.FilterLogs(opts, "RegistrarChanged", fromRule, toRule) + if err != nil { + return nil, err + } + return &KeeperRegistryMockRegistrarChangedIterator{contract: _KeeperRegistryMock.contract, event: "RegistrarChanged", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) WatchRegistrarChanged(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockRegistrarChanged, 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 := _KeeperRegistryMock.contract.WatchLogs(opts, "RegistrarChanged", 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(KeeperRegistryMockRegistrarChanged) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "RegistrarChanged", 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 (_KeeperRegistryMock *KeeperRegistryMockFilterer) ParseRegistrarChanged(log types.Log) (*KeeperRegistryMockRegistrarChanged, error) { + event := new(KeeperRegistryMockRegistrarChanged) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "RegistrarChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistryMockUnpausedIterator struct { + Event *KeeperRegistryMockUnpaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistryMockUnpausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistryMockUnpaused) + 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(KeeperRegistryMockUnpaused) + 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 *KeeperRegistryMockUnpausedIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistryMockUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistryMockUnpaused struct { + Account common.Address + Raw types.Log +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) FilterUnpaused(opts *bind.FilterOpts) (*KeeperRegistryMockUnpausedIterator, error) { + + logs, sub, err := _KeeperRegistryMock.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &KeeperRegistryMockUnpausedIterator{contract: _KeeperRegistryMock.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockUnpaused) (event.Subscription, error) { + + logs, sub, err := _KeeperRegistryMock.contract.WatchLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(KeeperRegistryMockUnpaused) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "Unpaused", 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 (_KeeperRegistryMock *KeeperRegistryMockFilterer) ParseUnpaused(log types.Log) (*KeeperRegistryMockUnpaused, error) { + event := new(KeeperRegistryMockUnpaused) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistryMockUpkeepCanceledIterator struct { + Event *KeeperRegistryMockUpkeepCanceled + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistryMockUpkeepCanceledIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistryMockUpkeepCanceled) + 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(KeeperRegistryMockUpkeepCanceled) + 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 *KeeperRegistryMockUpkeepCanceledIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistryMockUpkeepCanceledIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistryMockUpkeepCanceled struct { + Id *big.Int + AtBlockHeight uint64 + Raw types.Log +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) FilterUpkeepCanceled(opts *bind.FilterOpts, id []*big.Int, atBlockHeight []uint64) (*KeeperRegistryMockUpkeepCanceledIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var atBlockHeightRule []interface{} + for _, atBlockHeightItem := range atBlockHeight { + atBlockHeightRule = append(atBlockHeightRule, atBlockHeightItem) + } + + logs, sub, err := _KeeperRegistryMock.contract.FilterLogs(opts, "UpkeepCanceled", idRule, atBlockHeightRule) + if err != nil { + return nil, err + } + return &KeeperRegistryMockUpkeepCanceledIterator{contract: _KeeperRegistryMock.contract, event: "UpkeepCanceled", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) WatchUpkeepCanceled(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockUpkeepCanceled, id []*big.Int, atBlockHeight []uint64) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var atBlockHeightRule []interface{} + for _, atBlockHeightItem := range atBlockHeight { + atBlockHeightRule = append(atBlockHeightRule, atBlockHeightItem) + } + + logs, sub, err := _KeeperRegistryMock.contract.WatchLogs(opts, "UpkeepCanceled", idRule, atBlockHeightRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(KeeperRegistryMockUpkeepCanceled) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "UpkeepCanceled", 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 (_KeeperRegistryMock *KeeperRegistryMockFilterer) ParseUpkeepCanceled(log types.Log) (*KeeperRegistryMockUpkeepCanceled, error) { + event := new(KeeperRegistryMockUpkeepCanceled) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "UpkeepCanceled", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistryMockUpkeepPerformedIterator struct { + Event *KeeperRegistryMockUpkeepPerformed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistryMockUpkeepPerformedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistryMockUpkeepPerformed) + 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(KeeperRegistryMockUpkeepPerformed) + 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 *KeeperRegistryMockUpkeepPerformedIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistryMockUpkeepPerformedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistryMockUpkeepPerformed struct { + Id *big.Int + Success bool + From common.Address + Payment *big.Int + PerformData []byte + Raw types.Log +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) FilterUpkeepPerformed(opts *bind.FilterOpts, id []*big.Int, success []bool, from []common.Address) (*KeeperRegistryMockUpkeepPerformedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var successRule []interface{} + for _, successItem := range success { + successRule = append(successRule, successItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _KeeperRegistryMock.contract.FilterLogs(opts, "UpkeepPerformed", idRule, successRule, fromRule) + if err != nil { + return nil, err + } + return &KeeperRegistryMockUpkeepPerformedIterator{contract: _KeeperRegistryMock.contract, event: "UpkeepPerformed", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) WatchUpkeepPerformed(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockUpkeepPerformed, id []*big.Int, success []bool, from []common.Address) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var successRule []interface{} + for _, successItem := range success { + successRule = append(successRule, successItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _KeeperRegistryMock.contract.WatchLogs(opts, "UpkeepPerformed", idRule, successRule, fromRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(KeeperRegistryMockUpkeepPerformed) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "UpkeepPerformed", 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 (_KeeperRegistryMock *KeeperRegistryMockFilterer) ParseUpkeepPerformed(log types.Log) (*KeeperRegistryMockUpkeepPerformed, error) { + event := new(KeeperRegistryMockUpkeepPerformed) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "UpkeepPerformed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type KeeperRegistryMockUpkeepRegisteredIterator struct { + Event *KeeperRegistryMockUpkeepRegistered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistryMockUpkeepRegisteredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistryMockUpkeepRegistered) + 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(KeeperRegistryMockUpkeepRegistered) + 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 *KeeperRegistryMockUpkeepRegisteredIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistryMockUpkeepRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistryMockUpkeepRegistered struct { + Id *big.Int + ExecuteGas uint32 + Admin common.Address + Raw types.Log +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) FilterUpkeepRegistered(opts *bind.FilterOpts, id []*big.Int) (*KeeperRegistryMockUpkeepRegisteredIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _KeeperRegistryMock.contract.FilterLogs(opts, "UpkeepRegistered", idRule) + if err != nil { + return nil, err + } + return &KeeperRegistryMockUpkeepRegisteredIterator{contract: _KeeperRegistryMock.contract, event: "UpkeepRegistered", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistryMock *KeeperRegistryMockFilterer) WatchUpkeepRegistered(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockUpkeepRegistered, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _KeeperRegistryMock.contract.WatchLogs(opts, "UpkeepRegistered", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(KeeperRegistryMockUpkeepRegistered) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "UpkeepRegistered", 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 (_KeeperRegistryMock *KeeperRegistryMockFilterer) ParseUpkeepRegistered(log types.Log) (*KeeperRegistryMockUpkeepRegistered, error) { + event := new(KeeperRegistryMockUpkeepRegistered) + if err := _KeeperRegistryMock.contract.UnpackLog(event, "UpkeepRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CheckUpkeep struct { + PerformData []byte + MaxLinkPayment *big.Int + GasLimit *big.Int + AdjustedGasWei *big.Int + LinkEth *big.Int +} +type GetConfig struct { + PaymentPremiumPPB uint32 + BlockCountPerTurn *big.Int + CheckGasLimit uint32 + StalenessSeconds *big.Int + GasCeilingMultiplier uint16 + FallbackGasPrice *big.Int + FallbackLinkPrice *big.Int +} +type GetUpkeep struct { + Target common.Address + ExecuteGas uint32 + CheckData []byte + Balance *big.Int + LastKeeper common.Address + Admin common.Address + MaxValidBlocknumber uint64 +} + +func (_KeeperRegistryMock *KeeperRegistryMock) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _KeeperRegistryMock.abi.Events["ConfigSet"].ID: + return _KeeperRegistryMock.ParseConfigSet(log) + case _KeeperRegistryMock.abi.Events["FlatFeeSet"].ID: + return _KeeperRegistryMock.ParseFlatFeeSet(log) + case _KeeperRegistryMock.abi.Events["FundsAdded"].ID: + return _KeeperRegistryMock.ParseFundsAdded(log) + case _KeeperRegistryMock.abi.Events["FundsWithdrawn"].ID: + return _KeeperRegistryMock.ParseFundsWithdrawn(log) + case _KeeperRegistryMock.abi.Events["KeepersUpdated"].ID: + return _KeeperRegistryMock.ParseKeepersUpdated(log) + case _KeeperRegistryMock.abi.Events["OwnershipTransferRequested"].ID: + return _KeeperRegistryMock.ParseOwnershipTransferRequested(log) + case _KeeperRegistryMock.abi.Events["OwnershipTransferred"].ID: + return _KeeperRegistryMock.ParseOwnershipTransferred(log) + case _KeeperRegistryMock.abi.Events["Paused"].ID: + return _KeeperRegistryMock.ParsePaused(log) + case _KeeperRegistryMock.abi.Events["PayeeshipTransferRequested"].ID: + return _KeeperRegistryMock.ParsePayeeshipTransferRequested(log) + case _KeeperRegistryMock.abi.Events["PayeeshipTransferred"].ID: + return _KeeperRegistryMock.ParsePayeeshipTransferred(log) + case _KeeperRegistryMock.abi.Events["PaymentWithdrawn"].ID: + return _KeeperRegistryMock.ParsePaymentWithdrawn(log) + case _KeeperRegistryMock.abi.Events["RegistrarChanged"].ID: + return _KeeperRegistryMock.ParseRegistrarChanged(log) + case _KeeperRegistryMock.abi.Events["Unpaused"].ID: + return _KeeperRegistryMock.ParseUnpaused(log) + case _KeeperRegistryMock.abi.Events["UpkeepCanceled"].ID: + return _KeeperRegistryMock.ParseUpkeepCanceled(log) + case _KeeperRegistryMock.abi.Events["UpkeepPerformed"].ID: + return _KeeperRegistryMock.ParseUpkeepPerformed(log) + case _KeeperRegistryMock.abi.Events["UpkeepRegistered"].ID: + return _KeeperRegistryMock.ParseUpkeepRegistered(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (KeeperRegistryMockConfigSet) Topic() common.Hash { + return common.HexToHash("0xeb3c06937e6595fd80ec1add18a195026d5cf65f122cc3ffedbfb18a9ed80b39") +} + +func (KeeperRegistryMockFlatFeeSet) Topic() common.Hash { + return common.HexToHash("0x17b46a44a823646eef686b7824df2962de896bc9a012a60b67694c5cbf184d8b") +} + +func (KeeperRegistryMockFundsAdded) Topic() common.Hash { + return common.HexToHash("0xafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa734891506203") +} + +func (KeeperRegistryMockFundsWithdrawn) Topic() common.Hash { + return common.HexToHash("0xf3b5906e5672f3e524854103bcafbbdba80dbdfeca2c35e116127b1060a68318") +} + +func (KeeperRegistryMockKeepersUpdated) Topic() common.Hash { + return common.HexToHash("0x056264c94f28bb06c99d13f0446eb96c67c215d8d707bce2655a98ddf1c0b71f") +} + +func (KeeperRegistryMockOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (KeeperRegistryMockOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (KeeperRegistryMockPaused) Topic() common.Hash { + return common.HexToHash("0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258") +} + +func (KeeperRegistryMockPayeeshipTransferRequested) Topic() common.Hash { + return common.HexToHash("0x84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e38367") +} + +func (KeeperRegistryMockPayeeshipTransferred) Topic() common.Hash { + return common.HexToHash("0x78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b3") +} + +func (KeeperRegistryMockPaymentWithdrawn) Topic() common.Hash { + return common.HexToHash("0x9819093176a1851202c7bcfa46845809b4e47c261866550e94ed3775d2f40698") +} + +func (KeeperRegistryMockRegistrarChanged) Topic() common.Hash { + return common.HexToHash("0x9bf4a5b30267728df68663e14adb47e559863967c419dc6030638883408bed2e") +} + +func (KeeperRegistryMockUnpaused) Topic() common.Hash { + return common.HexToHash("0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa") +} + +func (KeeperRegistryMockUpkeepCanceled) Topic() common.Hash { + return common.HexToHash("0x91cb3bb75cfbd718bbfccc56b7f53d92d7048ef4ca39a3b7b7c6d4af1f791181") +} + +func (KeeperRegistryMockUpkeepPerformed) Topic() common.Hash { + return common.HexToHash("0xcaacad83e47cc45c280d487ec84184eee2fa3b54ebaa393bda7549f13da228f6") +} + +func (KeeperRegistryMockUpkeepRegistered) Topic() common.Hash { + return common.HexToHash("0xbae366358c023f887e791d7a62f2e4316f1026bd77f6fb49501a917b3bc5d012") +} + +func (_KeeperRegistryMock *KeeperRegistryMock) Address() common.Address { + return _KeeperRegistryMock.address +} + +type KeeperRegistryMockInterface interface { + CheckUpkeep(opts *bind.CallOpts, id *big.Int, from common.Address) (CheckUpkeep, + + error) + + GetCanceledUpkeepList(opts *bind.CallOpts) ([]*big.Int, error) + + GetConfig(opts *bind.CallOpts) (GetConfig, + + error) + + GetKeeperList(opts *bind.CallOpts) ([]common.Address, error) + + GetMinBalanceForUpkeep(opts *bind.CallOpts, id *big.Int) (*big.Int, error) + + GetUpkeep(opts *bind.CallOpts, id *big.Int) (GetUpkeep, + + error) + + GetUpkeepCount(opts *bind.CallOpts) (*big.Int, error) + + EmitConfigSet(opts *bind.TransactOpts, paymentPremiumPPB uint32, blockCountPerTurn *big.Int, checkGasLimit uint32, stalenessSeconds *big.Int, gasCeilingMultiplier uint16, fallbackGasPrice *big.Int, fallbackLinkPrice *big.Int) (*types.Transaction, error) + + EmitFlatFeeSet(opts *bind.TransactOpts, flatFeeMicroLink uint32) (*types.Transaction, error) + + EmitFundsAdded(opts *bind.TransactOpts, id *big.Int, from common.Address, amount *big.Int) (*types.Transaction, error) + + EmitFundsWithdrawn(opts *bind.TransactOpts, id *big.Int, amount *big.Int, to common.Address) (*types.Transaction, error) + + EmitKeepersUpdated(opts *bind.TransactOpts, keepers []common.Address, payees []common.Address) (*types.Transaction, error) + + EmitOwnershipTransferRequested(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) + + EmitOwnershipTransferred(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) + + EmitPaused(opts *bind.TransactOpts, account common.Address) (*types.Transaction, error) + + EmitPayeeshipTransferRequested(opts *bind.TransactOpts, keeper common.Address, from common.Address, to common.Address) (*types.Transaction, error) + + EmitPayeeshipTransferred(opts *bind.TransactOpts, keeper common.Address, from common.Address, to common.Address) (*types.Transaction, error) + + EmitPaymentWithdrawn(opts *bind.TransactOpts, keeper common.Address, amount *big.Int, to common.Address, payee common.Address) (*types.Transaction, error) + + EmitRegistrarChanged(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) + + EmitUnpaused(opts *bind.TransactOpts, account common.Address) (*types.Transaction, error) + + EmitUpkeepCanceled(opts *bind.TransactOpts, id *big.Int, atBlockHeight uint64) (*types.Transaction, error) + + EmitUpkeepPerformed(opts *bind.TransactOpts, id *big.Int, success bool, from common.Address, payment *big.Int, performData []byte) (*types.Transaction, error) + + EmitUpkeepRegistered(opts *bind.TransactOpts, id *big.Int, executeGas uint32, admin common.Address) (*types.Transaction, error) + + PerformUpkeep(opts *bind.TransactOpts, id *big.Int, performData []byte) (*types.Transaction, error) + + SetCanceledUpkeepList(opts *bind.TransactOpts, _canceledUpkeepList []*big.Int) (*types.Transaction, error) + + SetCheckUpkeepData(opts *bind.TransactOpts, id *big.Int, performData []byte, maxLinkPayment *big.Int, gasLimit *big.Int, adjustedGasWei *big.Int, linkEth *big.Int) (*types.Transaction, error) + + SetConfig(opts *bind.TransactOpts, _paymentPremiumPPB uint32, _flatFeeMicroLink uint32, _blockCountPerTurn *big.Int, _checkGasLimit uint32, _stalenessSeconds *big.Int, _gasCeilingMultiplier uint16, _fallbackGasPrice *big.Int, _fallbackLinkPrice *big.Int) (*types.Transaction, error) + + SetKeeperList(opts *bind.TransactOpts, _keepers []common.Address) (*types.Transaction, error) + + SetMinBalance(opts *bind.TransactOpts, id *big.Int, minBalance *big.Int) (*types.Transaction, error) + + SetPerformUpkeepSuccess(opts *bind.TransactOpts, id *big.Int, success bool) (*types.Transaction, error) + + SetUpkeep(opts *bind.TransactOpts, id *big.Int, _target common.Address, _executeGas uint32, _balance *big.Int, _admin common.Address, _maxValidBlocknumber uint64, _lastKeeper common.Address, _checkData []byte) (*types.Transaction, error) + + SetUpkeepCount(opts *bind.TransactOpts, _upkeepCount *big.Int) (*types.Transaction, error) + + FilterConfigSet(opts *bind.FilterOpts) (*KeeperRegistryMockConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*KeeperRegistryMockConfigSet, error) + + FilterFlatFeeSet(opts *bind.FilterOpts) (*KeeperRegistryMockFlatFeeSetIterator, error) + + WatchFlatFeeSet(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockFlatFeeSet) (event.Subscription, error) + + ParseFlatFeeSet(log types.Log) (*KeeperRegistryMockFlatFeeSet, error) + + FilterFundsAdded(opts *bind.FilterOpts, id []*big.Int, from []common.Address) (*KeeperRegistryMockFundsAddedIterator, error) + + WatchFundsAdded(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockFundsAdded, id []*big.Int, from []common.Address) (event.Subscription, error) + + ParseFundsAdded(log types.Log) (*KeeperRegistryMockFundsAdded, error) + + FilterFundsWithdrawn(opts *bind.FilterOpts, id []*big.Int) (*KeeperRegistryMockFundsWithdrawnIterator, error) + + WatchFundsWithdrawn(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockFundsWithdrawn, id []*big.Int) (event.Subscription, error) + + ParseFundsWithdrawn(log types.Log) (*KeeperRegistryMockFundsWithdrawn, error) + + FilterKeepersUpdated(opts *bind.FilterOpts) (*KeeperRegistryMockKeepersUpdatedIterator, error) + + WatchKeepersUpdated(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockKeepersUpdated) (event.Subscription, error) + + ParseKeepersUpdated(log types.Log) (*KeeperRegistryMockKeepersUpdated, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeeperRegistryMockOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*KeeperRegistryMockOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeeperRegistryMockOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*KeeperRegistryMockOwnershipTransferred, error) + + FilterPaused(opts *bind.FilterOpts) (*KeeperRegistryMockPausedIterator, error) + + WatchPaused(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockPaused) (event.Subscription, error) + + ParsePaused(log types.Log) (*KeeperRegistryMockPaused, error) + + FilterPayeeshipTransferRequested(opts *bind.FilterOpts, keeper []common.Address, from []common.Address, to []common.Address) (*KeeperRegistryMockPayeeshipTransferRequestedIterator, error) + + WatchPayeeshipTransferRequested(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockPayeeshipTransferRequested, keeper []common.Address, from []common.Address, to []common.Address) (event.Subscription, error) + + ParsePayeeshipTransferRequested(log types.Log) (*KeeperRegistryMockPayeeshipTransferRequested, error) + + FilterPayeeshipTransferred(opts *bind.FilterOpts, keeper []common.Address, from []common.Address, to []common.Address) (*KeeperRegistryMockPayeeshipTransferredIterator, error) + + WatchPayeeshipTransferred(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockPayeeshipTransferred, keeper []common.Address, from []common.Address, to []common.Address) (event.Subscription, error) + + ParsePayeeshipTransferred(log types.Log) (*KeeperRegistryMockPayeeshipTransferred, error) + + FilterPaymentWithdrawn(opts *bind.FilterOpts, keeper []common.Address, amount []*big.Int, to []common.Address) (*KeeperRegistryMockPaymentWithdrawnIterator, error) + + WatchPaymentWithdrawn(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockPaymentWithdrawn, keeper []common.Address, amount []*big.Int, to []common.Address) (event.Subscription, error) + + ParsePaymentWithdrawn(log types.Log) (*KeeperRegistryMockPaymentWithdrawn, error) + + FilterRegistrarChanged(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*KeeperRegistryMockRegistrarChangedIterator, error) + + WatchRegistrarChanged(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockRegistrarChanged, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseRegistrarChanged(log types.Log) (*KeeperRegistryMockRegistrarChanged, error) + + FilterUnpaused(opts *bind.FilterOpts) (*KeeperRegistryMockUnpausedIterator, error) + + WatchUnpaused(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockUnpaused) (event.Subscription, error) + + ParseUnpaused(log types.Log) (*KeeperRegistryMockUnpaused, error) + + FilterUpkeepCanceled(opts *bind.FilterOpts, id []*big.Int, atBlockHeight []uint64) (*KeeperRegistryMockUpkeepCanceledIterator, error) + + WatchUpkeepCanceled(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockUpkeepCanceled, id []*big.Int, atBlockHeight []uint64) (event.Subscription, error) + + ParseUpkeepCanceled(log types.Log) (*KeeperRegistryMockUpkeepCanceled, error) + + FilterUpkeepPerformed(opts *bind.FilterOpts, id []*big.Int, success []bool, from []common.Address) (*KeeperRegistryMockUpkeepPerformedIterator, error) + + WatchUpkeepPerformed(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockUpkeepPerformed, id []*big.Int, success []bool, from []common.Address) (event.Subscription, error) + + ParseUpkeepPerformed(log types.Log) (*KeeperRegistryMockUpkeepPerformed, error) + + FilterUpkeepRegistered(opts *bind.FilterOpts, id []*big.Int) (*KeeperRegistryMockUpkeepRegisteredIterator, error) + + WatchUpkeepRegistered(opts *bind.WatchOpts, sink chan<- *KeeperRegistryMockUpkeepRegistered, id []*big.Int) (event.Subscription, error) + + ParseUpkeepRegistered(log types.Log) (*KeeperRegistryMockUpkeepRegistered, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/keeper_registry_wrapper_2_1/keeper_registry_wrapper_2_1.go b/core/gethwrappers/generated/keeper_registry_wrapper_2_1/keeper_registry_wrapper_2_1.go index 7314e295e31..4bbd827dc52 100644 --- a/core/gethwrappers/generated/keeper_registry_wrapper_2_1/keeper_registry_wrapper_2_1.go +++ b/core/gethwrappers/generated/keeper_registry_wrapper_2_1/keeper_registry_wrapper_2_1.go @@ -49,8 +49,8 @@ type KeeperRegistryBase21OnchainConfig struct { } var KeeperRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractKeeperRegistryLogicB2_1\",\"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\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"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\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"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\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"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\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"upkeepTriggerID\",\"type\":\"bytes32\"}],\"name\":\"CancelledUpkeepReport\",\"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\":\"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\":\"bytes32\",\"name\":\"upkeepTriggerID\",\"type\":\"bytes32\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"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\":\"bytes32\",\"name\":\"upkeepTriggerID\",\"type\":\"bytes32\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"upkeepTriggerID\",\"type\":\"bytes32\"}],\"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\":\"bytes32\",\"name\":\"upkeepTriggerID\",\"type\":\"bytes32\"}],\"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\":\"nonpayable\",\"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\"},{\"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\":\"structKeeperRegistryBase2_1.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"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\"},{\"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\":\"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\":\"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: "0x6101206040523480156200001257600080fd5b506040516200543038038062005430833981016040819052620000359162000374565b80816001600160a01b0316634b4fd03b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b91906200039b565b826001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000100919062000374565b836001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000165919062000374565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca919062000374565b3380600081620002215760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b038481169190911790915581161562000254576200025481620002b0565b5050508360028111156200026c576200026c620003be565b60e0816002811115620002835762000283620003be565b9052506001600160a01b0392831660805290821660a052811660c052919091166101005250620003d49050565b336001600160a01b038216036200030a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000218565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200037157600080fd5b50565b6000602082840312156200038757600080fd5b815162000394816200035b565b9392505050565b600060208284031215620003ae57600080fd5b8151600381106200039457600080fd5b634e487b7160e01b600052602160045260246000fd5b60805160a05160c05160e051610100516150026200042e6000396000818160d6015261016f0152600081816124850152818161337c0152818161350f0152613a3f01526000505060005050600061043b01526150026000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c8063a931358d11610081578063b1dc65a41161005b578063b1dc65a4146102e8578063e3d0e712146102fb578063f2fde38b1461030e576100d4565b8063a931358d14610262578063aed2e92914610275578063afcb95d71461029f576100d4565b806381ff7048116100b257806381ff7048146101bc5780638da5cb5b14610231578063a4c0ed361461024f576100d4565b8063181f5a771461011b578063349e8cca1461016d57806379ba5097146101b4575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610114573d6000f35b3d6000fd5b005b6101576040518060400160405280601481526020017f4b6565706572526567697374727920322e312e3000000000000000000000000081525081565b6040516101649190613cbe565b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610164565b610119610321565b61020e60145460115463ffffffff780100000000000000000000000000000000000000000000000083048116937c01000000000000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610164565b60005473ffffffffffffffffffffffffffffffffffffffff1661018f565b61011961025d366004613d47565b610423565b610119610270366004614167565b61063f565b610288610283366004614234565b611456565b604080519215158352602083019190915201610164565b601154601254604080516000815260208101939093527c010000000000000000000000000000000000000000000000000000000090910463ffffffff1690820152606001610164565b6101196102f63660046142c5565b6115ce565b61011961030936600461437c565b6121b5565b61011961031c36600461440b565b6121de565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610492576040517fc8bad78d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081146104cc576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104da82840184614428565b60008181526004602052604090205490915065010000000000900463ffffffff90811614610534576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090206001015461056f9085906c0100000000000000000000000090046bffffffffffffffffffffffff16614470565b600082815260046020526040902060010180546bffffffffffffffffffffffff929092166c01000000000000000000000000027fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff9092169190911790556018546105da908590614495565b6018556040516bffffffffffffffffffffffff8516815273ffffffffffffffffffffffffffffffffffffffff86169082907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a35050505050565b6106476121f2565b601f86511115610683576040517f25d0209c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8360ff166000036106c0576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845186511415806106df57506106d78460036144a8565b60ff16865111155b15610716576040517f1d2d1c5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254600e547001000000000000000000000000000000009091046bffffffffffffffffffffffff169060005b816bffffffffffffffffffffffff168110156107ab57610798600e828154811061076f5761076f6144d1565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff168484612275565b50806107a381614500565b915050610743565b5060008060005b836bffffffffffffffffffffffff168110156108b457600d81815481106107db576107db6144d1565b600091825260209091200154600e805473ffffffffffffffffffffffffffffffffffffffff90921694509082908110610816576108166144d1565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff8681168452600c8352604080852080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690559116808452600b90925290912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690559150806108ac81614500565b9150506107b2565b506108c1600d6000613b93565b6108cd600e6000613b93565b604080516080810182526000808252602082018190529181018290526060810182905290805b8c51811015610c5157600c60008e8381518110610912576109126144d1565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff161561097d576040517f77cea0fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806001151581526020018260ff16815250600c60008f84815181106109ae576109ae6144d1565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909316929092171790558b518c9082908110610a5657610a566144d1565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff81166000908152600b83526040908190208151608081018352905460ff80821615801584526101008304909116958301959095526bffffffffffffffffffffffff6201000082048116938301939093526e0100000000000000000000000000009004909116606082015294509250610b1b576040517f6a7281ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001835260ff80821660208086019182526bffffffffffffffffffffffff808b166060880190815273ffffffffffffffffffffffffffffffffffffffff87166000908152600b909352604092839020885181549551948a0151925184166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff939094166201000002929092167fffffffffffff000000000000000000000000000000000000000000000000ffff94909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009095169490941717919091169290921791909117905580610c4981614500565b9150506108f3565b50508a51610c679150600d9060208d0190613bb1565b508851610c7b90600e9060208c0190613bb1565b506040518061012001604052808960ff168152602001886000015163ffffffff168152602001886020015163ffffffff168152602001886060015162ffffff168152602001886080015161ffff1681526020016012600001600e9054906101000a900460ff16151581526020016012600001600f9054906101000a900460ff1615158152602001856bffffffffffffffffffffffff168152602001600063ffffffff16815250601260008201518160000160006101000a81548160ff021916908360ff16021790555060208201518160000160016101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160056101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160096101000a81548162ffffff021916908362ffffff160217905550608082015181600001600c6101000a81548161ffff021916908361ffff16021790555060a082015181600001600e6101000a81548160ff02191690831515021790555060c082015181600001600f6101000a81548160ff02191690831515021790555060e08201518160000160106101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061010082015181600001601c6101000a81548163ffffffff021916908363ffffffff1602179055509050506040518061018001604052808860a001516bffffffffffffffffffffffff16815260200188610180015173ffffffffffffffffffffffffffffffffffffffff168152602001601360010160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152602001886040015163ffffffff1681526020018860c0015163ffffffff168152602001601360010160149054906101000a900463ffffffff1663ffffffff168152602001601360010160189054906101000a900463ffffffff1663ffffffff1681526020016013600101601c9054906101000a900463ffffffff1663ffffffff1681526020018860e0015163ffffffff16815260200188610100015163ffffffff16815260200188610120015163ffffffff168152602001886101c0015173ffffffffffffffffffffffffffffffffffffffff16815250601360008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550606082015181600101600c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160106101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548163ffffffff021916908363ffffffff1602179055506101208201518160020160046101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160086101000a81548163ffffffff021916908363ffffffff16021790555061016082015181600201600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505086610140015160168190555086610160015160178190555060006013600101601c9054906101000a900463ffffffff16905061123d61247f565b601480547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff93841602178082556001926018916112b89185917801000000000000000000000000000000000000000000000000900416614538565b92506101000a81548163ffffffff021916908363ffffffff1602179055506000886040516020016112e991906145a6565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905260145490915061135290469030907801000000000000000000000000000000000000000000000000900463ffffffff168f8f8f878f8f612534565b60115560005b61136260096125de565b8110156113925761137f6113776009836125ee565b6009906125fa565b508061138a81614500565b915050611358565b5060005b896101a00151518110156113e9576113d68a6101a0015182815181106113be576113be6144d1565b6020026020010151600961261c90919063ffffffff16565b50806113e181614500565b915050611396565b507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0582601154601360010160189054906101000a900463ffffffff168f8f8f878f8f6040516114409998979695949392919061470a565b60405180910390a1505050505050505050505050565b60008061146161263e565b6012546e010000000000000000000000000000900460ff16156114b0576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008581526004602090815260409182902082516101008082018552825460ff81161515835263ffffffff918104821683860181905265010000000000820483168488015273ffffffffffffffffffffffffffffffffffffffff690100000000000000000090920482166060850181905260018601546bffffffffffffffffffffffff80821660808801526c0100000000000000000000000082041660a08701527801000000000000000000000000000000000000000000000000900490931660c08501526002909401541660e08301528451601f890185900485028101850190955287855290936115bf93919291899089908190840183828082843760009201919091525061267692505050565b9093509150505b935093915050565b60005a604080516101208101825260125460ff808216835261010080830463ffffffff90811660208601526501000000000084048116958501959095526901000000000000000000830462ffffff1660608501526c01000000000000000000000000830461ffff1660808501526e0100000000000000000000000000008304821615801560a08601526f010000000000000000000000000000008404909216151560c085015270010000000000000000000000000000000083046bffffffffffffffffffffffff1660e08501527c0100000000000000000000000000000000000000000000000000000000909204909316908201529192506116fc576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604090205460ff16611745576040517f1099ed7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6011548a3514611781576040517fdfdcf8e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805161178e9060016147a0565b60ff168614158061179f5750858414155b156117d6576040517f0244f71a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6117e68a8a8a8a8a8a8a8a612881565b60006117f28a8a612aea565b9050600081604001515167ffffffffffffffff81111561181457611814613da3565b6040519080825280602002602001820160405280156118e857816020015b6040805161022081018252600061012082018181526101408301829052610160830182905261018083018290526101a083018290526101c083018290526101e08301829052610200830182905282526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e0820181905261010082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816118325790505b5090506000805b836040015151811015611da9576004600085604001518381518110611916576119166144d1565b602090810291909101810151825281810192909252604090810160002081516101008082018452825460ff81161515835263ffffffff91810482169583019590955265010000000000850481169382019390935273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009094048416606082015260018201546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490921660c08301526002015490911660e08201528351849083908110611a0857611a086144d1565b602002602001015160000181905250611a3d84604001518281518110611a3057611a306144d1565b6020026020010151612ba3565b838281518110611a4f57611a4f6144d1565b6020026020010151608001906001811115611a6c57611a6c6147b9565b90816001811115611a7f57611a7f6147b9565b81525050611af785848381518110611a9957611a996144d1565b602002602001015160800151858481518110611ab757611ab76144d1565b602002602001015160000151602001518760a001518581518110611add57611add6144d1565b602002602001015151886000015189602001516001612c4e565b838281518110611b0957611b096144d1565b6020026020010151604001906bffffffffffffffffffffffff1690816bffffffffffffffffffffffff1681525050611b7b84604001518281518110611b5057611b506144d1565b602002602001015185608001518381518110611b6e57611b6e6144d1565b6020026020010151612c99565b838281518110611b8d57611b8d6144d1565b602002602001015160e0018181525050611bfb84604001518281518110611bb657611bb66144d1565b602002602001015185608001518381518110611bd457611bd46144d1565b6020026020010151858481518110611bee57611bee6144d1565b6020026020010151612ccc565b848381518110611c0d57611c0d6144d1565b6020026020010151602001858481518110611c2a57611c2a6144d1565b6020026020010151610100018281525082151515158152505050828181518110611c5657611c566144d1565b60200260200101516020015115611c7957611c726001836147e8565b9150611c7e565b611d97565b611ce4838281518110611c9357611c936144d1565b6020026020010151600001516060015185606001518381518110611cb957611cb96144d1565b60200260200101518660a001518481518110611cd757611cd76144d1565b6020026020010151612676565b848381518110611cf657611cf66144d1565b6020026020010151606001858481518110611d1357611d136144d1565b602002602001015160a0018281525082151515158152505050828181518110611d3e57611d3e6144d1565b602002602001015160a0015186611d559190614803565b9550611d9784604001518281518110611d7057611d706144d1565b6020026020010151848381518110611d8a57611d8a6144d1565b6020026020010151612e57565b80611da181614500565b9150506118ef565b508061ffff16600003611dc05750505050506121ab565b8351611dcd9060016147a0565b611ddc9060ff1661044c614816565b616b6c611dea8d6010614816565b5a611df59089614803565b611dff9190614495565b611e099190614495565b611e139190614495565b9450611b58611e2661ffff831687614882565b611e309190614495565b945060008060008060005b87604001515181101561204d57868181518110611e5a57611e5a6144d1565b6020026020010151602001511561203b57611eb68a888381518110611e8157611e816144d1565b6020026020010151608001518a60a001518481518110611ea357611ea36144d1565b6020026020010151518c60000151612f40565b878281518110611ec857611ec86144d1565b602002602001015160c0018181525050611f248989604001518381518110611ef257611ef26144d1565b6020026020010151898481518110611f0c57611f0c6144d1565b60200260200101518b600001518c602001518b612f60565b9093509150611f338285614470565b9350611f3f8386614470565b9450868181518110611f5357611f536144d1565b602002602001015160600151151588604001518281518110611f7757611f776144d1565b60200260200101517fdacc0b3d36199a5f78afb27c76cd01bf100f605edf5ee0c0e23055b0553b68c68486611fac9190614470565b8a8581518110611fbe57611fbe6144d1565b602002602001015160a001518b8681518110611fdc57611fdc6144d1565b602002602001015160c001518c8781518110611ffa57611ffa6144d1565b60209081029190910181015160e00151604080516bffffffffffffffffffffffff909616865291850193909352830152606082015260800160405180910390a35b8061204581614500565b915050611e3b565b5050336000908152600b6020526040902080548492506002906120859084906201000090046bffffffffffffffffffffffff16614470565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080601260000160108282829054906101000a90046bffffffffffffffffffffffff166120df9190614470565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555060008f600160038110612122576121226144d1565b602002013560001c9050600060088264ffffffffff16901c905087610100015163ffffffff168163ffffffff1611156121a157601280547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff8416021790555b5050505050505050505b5050505050505050565b6121d6868686868060200190518101906121cf9190614931565b868661063f565b505050505050565b6121e66121f2565b6121ef81613053565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314612273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161039e565b565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e010000000000000000000000000000900490911660608201529061247157600081606001518561230d9190614a8b565b9050600061231b8583614ab0565b9050808360400181815161232f9190614470565b6bffffffffffffffffffffffff1690525061234a8582614adb565b8360600181815161235b9190614470565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b6040015190505b9392505050565b600060017f000000000000000000000000000000000000000000000000000000000000000060028111156124b5576124b56147b9565b0361252f57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612506573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061252a9190614b0f565b905090565b504390565b6000808a8a8a8a8a8a8a8a8a60405160200161255899989796959493929190614b28565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179b9a5050505050505050505050565b60006125e8825490565b92915050565b60006124788383613148565b60006124788373ffffffffffffffffffffffffffffffffffffffff8416613172565b60006124788373ffffffffffffffffffffffffffffffffffffffff841661326c565b3215612273576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60125460009081906f01000000000000000000000000000000900460ff16156126cb576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601280547fffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff166f010000000000000000000000000000001790556040517f4585e33b0000000000000000000000000000000000000000000000000000000090612738908590602401613cbe565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d169061280b9087908790600401614bbd565b60408051808303816000875af1158015612829573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061284d9190614bd6565b601280547fffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff16905590969095509350505050565b60008787604051612893929190614c09565b6040519081900381206128aa918b90602001614c19565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201208383019092526000808452908301819052909250906000805b88811015612a8157600185878360208110612916576129166144d1565b61292391901a601b6147a0565b8c8c85818110612935576129356144d1565b905060200201358b8b8681811061294e5761294e6144d1565b905060200201356040516000815260200160405260405161298b949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156129ad573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff81166000908152600c602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290955093509050612a5b576040517f0f4c073700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015160080260ff166001901b840193508080612a7990614500565b9150506128f9565b50827e01010101010101010101010101010101010101010101010101010101010101841614612adc576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050565b612b236040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b6000612b3183850185614d0a565b6040810151516060820151519192509081141580612b5457508082608001515114155b80612b645750808260a001515114155b15612b9b576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b509392505050565b6000818160045b600f811015612c30577fff000000000000000000000000000000000000000000000000000000000000008216838260208110612be857612be86144d1565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612c1e57506000949350505050565b80612c2881614500565b915050612baa565b5081600f1a6001811115612c4657612c466147b9565b949350505050565b600080612c6088878b600001516132bb565b9050600080612c7b8b8a63ffffffff16858a8a60018b613347565b9092509050612c8a8183614470565b9b9a5050505050505050505050565b60008282604051602001612cae929190614df7565b60405160208183030381529060405280519060200120905092915050565b600080808084608001516001811115612ce757612ce76147b9565b03612d0b57612cf78686866137a0565b612d06576000925090506115c6565b612d82565b600184608001516001811115612d2357612d236147b9565b03612d50576000612d358787876138a0565b9250905080612d4a57506000925090506115c6565b50612d82565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612d8a61247f565b84516040015163ffffffff1611612de457857f846af3fdde418e2757c00c4cf8c6827e65ac4179753128c454922ccd7963886d8560e00151604051612dd191815260200190565b60405180910390a26000925090506115c6565b83604001516bffffffffffffffffffffffff16846000015160a001516bffffffffffffffffffffffff161015612e4a57857ffcb5fa059ae0ddeeac53240ccaa0a8ad80993b33e18e8821f1e1cbc53481240e8560e00151604051612dd191815260200190565b6001969095509350505050565b600081608001516001811115612e6f57612e6f6147b9565b03612ee157612e7c61247f565b6000838152600460205260409020600101805463ffffffff929092167801000000000000000000000000000000000000000000000000027fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790555050565b600181608001516001811115612ef957612ef96147b9565b03612f3c57610100810151600090815260086020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555b5050565b6000612f4d8484846132bb565b905080851015612c465750929392505050565b600080612f7b888760a001518860c001518888886001613347565b90925090506000612f8c8284614470565b600089815260046020526040902060010180549192508291600c90612fd09084906c0100000000000000000000000090046bffffffffffffffffffffffff16614a8b565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008a81526004602052604081206001018054859450909261301991859116614470565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555050965096945050505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036130d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161039e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600082600001828154811061315f5761315f6144d1565b9060005260206000200154905092915050565b6000818152600183016020526040812054801561325b576000613196600183614803565b85549091506000906131aa90600190614803565b905081811461320f5760008660000182815481106131ca576131ca6144d1565b90600052602060002001549050808760000184815481106131ed576131ed6144d1565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061322057613220614e1d565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506125e8565b60009150506125e8565b5092915050565b60008181526001830160205260408120546132b3575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556125e8565b5060006125e8565b600080808560018111156132d1576132d16147b9565b036132e0575062015f906132ff565b60018560018111156132f4576132f46147b9565b03612d5057506201adb05b61331063ffffffff85166014614816565b61331b8460016147a0565b61332a9060ff16611d4c614816565b6133349083614495565b61333e9190614495565b95945050505050565b6000806000896080015161ffff16876133609190614816565b905083801561336e5750803a105b1561337657503a5b600060027f000000000000000000000000000000000000000000000000000000000000000060028111156133ac576133ac6147b9565b0361350b57604080516000815260208101909152851561340a57600036604051806080016040528060488152602001614fae604891396040516020016133f493929190614e4c565b6040516020818303038152906040529050613472565b60155461342690640100000000900463ffffffff166004614e73565b63ffffffff1667ffffffffffffffff81111561344457613444613da3565b6040519080825280601f01601f19166020018201604052801561346e576020820181803683370190505b5090505b6040517f49948e0e00000000000000000000000000000000000000000000000000000000815273420000000000000000000000000000000000000f906349948e0e906134c2908490600401613cbe565b602060405180830381865afa1580156134df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135039190614b0f565b915050613665565b60017f0000000000000000000000000000000000000000000000000000000000000000600281111561353f5761353f6147b9565b036136655784156135c157606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613596573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135ba9190614b0f565b9050613665565b6000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c060405180830381865afa15801561360f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136339190614e96565b505060155492945061365693505050640100000000900463ffffffff1682614816565b613661906010614816565b9150505b8461368157808b6080015161ffff1661367e9190614816565b90505b61368f61ffff871682614882565b90506000878261369f8c8e614495565b6136a99086614816565b6136b39190614495565b6136c590670de0b6b3a7640000614816565b6136cf9190614882565b905060008c6040015163ffffffff1664e8d4a510006136ee9190614816565b898e6020015163ffffffff16858f886137079190614816565b6137119190614495565b61371f90633b9aca00614816565b6137299190614816565b6137339190614882565b61373d9190614495565b90506b033b2e3c9fd0803ce80000006137568284614495565b111561378e576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909c909b509950505050505050505050565b600080838060200190518101906137b79190614ee0565b835160c00151815191925063ffffffff9081169116101561381a57847f909d8c7e883c6d2d53a5fb2dbb9ec57875a53c3769c099230027312ffb2a6b118460e0015160405161380891815260200190565b60405180910390a26000915050612478565b60208101511580159061384157506020810151815161383e9063ffffffff16613a39565b14155b8061385a575061384f61247f565b815163ffffffff1610155b1561389557847f07c4f19521a82d67071422fca888431cac8267935db8abe73e354791a3d388688460e0015160405161380891815260200190565b506001949350505050565b6000806000848060200190518101906138b99190614f38565b90506000868260000151836020015160405160200161391093929190928352602083019190915260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016604082015260440190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101206060830151909150158015906139725750816060015161396f836040015163ffffffff16613a39565b14155b8061398e575061398061247f565b826040015163ffffffff1610155b156139de57867f07c4f19521a82d67071422fca888431cac8267935db8abe73e354791a3d388688660e001516040516139c991815260200190565b60405180910390a26000935091506115c69050565b60008181526008602052604090205460ff1615613a2b57867f909d8c7e883c6d2d53a5fb2dbb9ec57875a53c3769c099230027312ffb2a6b118660e001516040516139c991815260200190565b600197909650945050505050565b600060017f00000000000000000000000000000000000000000000000000000000000000006002811115613a6f57613a6f6147b9565b03613b89576000606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613ac2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ae69190614b0f565b90508083101580613b015750610100613aff8483614803565b115b15613b0f5750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815260048101849052606490632b407a8290602401602060405180830381865afa158015613b65573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124789190614b0f565b504090565b919050565b50805460008255906000526020600020908101906121ef9190613c3b565b828054828255906000526020600020908101928215613c2b579160200282015b82811115613c2b57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190613bd1565b50613c37929150613c3b565b5090565b5b80821115613c375760008155600101613c3c565b60005b83811015613c6b578181015183820152602001613c53565b50506000910152565b60008151808452613c8c816020860160208601613c50565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006124786020830184613c74565b73ffffffffffffffffffffffffffffffffffffffff811681146121ef57600080fd5b8035613b8e81613cd1565b60008083601f840112613d1057600080fd5b50813567ffffffffffffffff811115613d2857600080fd5b602083019150836020828501011115613d4057600080fd5b9250929050565b60008060008060608587031215613d5d57600080fd5b8435613d6881613cd1565b935060208501359250604085013567ffffffffffffffff811115613d8b57600080fd5b613d9787828801613cfe565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516101e0810167ffffffffffffffff81118282101715613df657613df6613da3565b60405290565b60405160c0810167ffffffffffffffff81118282101715613df657613df6613da3565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613e6657613e66613da3565b604052919050565b600067ffffffffffffffff821115613e8857613e88613da3565b5060051b60200190565b600082601f830112613ea357600080fd5b81356020613eb8613eb383613e6e565b613e1f565b82815260059290921b84018101918181019086841115613ed757600080fd5b8286015b84811015613efb578035613eee81613cd1565b8352918301918301613edb565b509695505050505050565b803560ff81168114613b8e57600080fd5b63ffffffff811681146121ef57600080fd5b8035613b8e81613f17565b62ffffff811681146121ef57600080fd5b8035613b8e81613f34565b61ffff811681146121ef57600080fd5b8035613b8e81613f50565b6bffffffffffffffffffffffff811681146121ef57600080fd5b8035613b8e81613f6b565b60006101e08284031215613fa357600080fd5b613fab613dd2565b9050613fb682613f29565b8152613fc460208301613f29565b6020820152613fd560408301613f29565b6040820152613fe660608301613f45565b6060820152613ff760808301613f60565b608082015261400860a08301613f85565b60a082015261401960c08301613f29565b60c082015261402a60e08301613f29565b60e082015261010061403d818401613f29565b9082015261012061404f838201613f29565b9082015261014082810135908201526101608083013590820152610180614077818401613cf3565b908201526101a08281013567ffffffffffffffff81111561409757600080fd5b6140a385828601613e92565b8284015250506101c06140b7818401613cf3565b9082015292915050565b803567ffffffffffffffff81168114613b8e57600080fd5b600082601f8301126140ea57600080fd5b813567ffffffffffffffff81111561410457614104613da3565b61413560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613e1f565b81815284602083860101111561414a57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c0878903121561418057600080fd5b863567ffffffffffffffff8082111561419857600080fd5b6141a48a838b01613e92565b975060208901359150808211156141ba57600080fd5b6141c68a838b01613e92565b96506141d460408a01613f06565b955060608901359150808211156141ea57600080fd5b6141f68a838b01613f90565b945061420460808a016140c1565b935060a089013591508082111561421a57600080fd5b5061422789828a016140d9565b9150509295509295509295565b60008060006040848603121561424957600080fd5b83359250602084013567ffffffffffffffff81111561426757600080fd5b61427386828701613cfe565b9497909650939450505050565b60008083601f84011261429257600080fd5b50813567ffffffffffffffff8111156142aa57600080fd5b6020830191508360208260051b8501011115613d4057600080fd5b60008060008060008060008060e0898b0312156142e157600080fd5b606089018a8111156142f257600080fd5b8998503567ffffffffffffffff8082111561430c57600080fd5b6143188c838d01613cfe565b909950975060808b013591508082111561433157600080fd5b61433d8c838d01614280565b909750955060a08b013591508082111561435657600080fd5b506143638b828c01614280565b999c989b50969995989497949560c00135949350505050565b60008060008060008060c0878903121561439557600080fd5b863567ffffffffffffffff808211156143ad57600080fd5b6143b98a838b01613e92565b975060208901359150808211156143cf57600080fd5b6143db8a838b01613e92565b96506143e960408a01613f06565b955060608901359150808211156143ff57600080fd5b6141f68a838b016140d9565b60006020828403121561441d57600080fd5b813561247881613cd1565b60006020828403121561443a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff81811683821601908082111561326557613265614441565b808201808211156125e8576125e8614441565b600060ff821660ff84168160ff04811182151516156144c9576144c9614441565b029392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361453157614531614441565b5060010190565b63ffffffff81811683821601908082111561326557613265614441565b600081518084526020808501945080840160005b8381101561459b57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101614569565b509495945050505050565b602081526145bd60208201835163ffffffff169052565b600060208301516145d6604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015162ffffff8116608084015250608083015161ffff811660a08401525060a08301516bffffffffffffffffffffffff811660c08401525060c083015163ffffffff811660e08401525060e083015161010061464f8185018363ffffffff169052565b84015190506101206146688482018363ffffffff169052565b84015190506101406146818482018363ffffffff169052565b840151610160848101919091528401516101808085019190915284015190506101a06146c48185018373ffffffffffffffffffffffffffffffffffffffff169052565b808501519150506101e06101c081818601526146e4610200860184614555565b95015173ffffffffffffffffffffffffffffffffffffffff169301929092525090919050565b600061012063ffffffff808d1684528b6020850152808b1660408501525080606084015261473a8184018a614555565b9050828103608084015261474e8189614555565b905060ff871660a084015282810360c084015261476b8187613c74565b905067ffffffffffffffff851660e08401528281036101008401526147908185613c74565b9c9b505050505050505050505050565b60ff81811683821601908111156125e8576125e8614441565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b61ffff81811683821601908082111561326557613265614441565b818103818111156125e8576125e8614441565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561484e5761484e614441565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261489157614891614853565b500490565b8051613b8e81613f17565b8051613b8e81613f34565b8051613b8e81613f50565b8051613b8e81613f6b565b8051613b8e81613cd1565b600082601f8301126148de57600080fd5b815160206148ee613eb383613e6e565b82815260059290921b8401810191818101908684111561490d57600080fd5b8286015b84811015613efb57805161492481613cd1565b8352918301918301614911565b60006020828403121561494357600080fd5b815167ffffffffffffffff8082111561495b57600080fd5b908301906101e0828603121561497057600080fd5b614978613dd2565b61498183614896565b815261498f60208401614896565b60208201526149a060408401614896565b60408201526149b1606084016148a1565b60608201526149c2608084016148ac565b60808201526149d360a084016148b7565b60a08201526149e460c08401614896565b60c08201526149f560e08401614896565b60e0820152610100614a08818501614896565b90820152610120614a1a848201614896565b9082015261014083810151908201526101608084015190820152610180614a428185016148c2565b908201526101a08381015183811115614a5a57600080fd5b614a66888287016148cd565b8284015250506101c09150614a7c8284016148c2565b91810191909152949350505050565b6bffffffffffffffffffffffff82811682821603908082111561326557613265614441565b60006bffffffffffffffffffffffff80841680614acf57614acf614853565b92169190910492915050565b60006bffffffffffffffffffffffff80831681851681830481118215151615614b0657614b06614441565b02949350505050565b600060208284031215614b2157600080fd5b5051919050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614b6f8285018b614555565b91508382036080850152614b83828a614555565b915060ff881660a085015283820360c0850152614ba08288613c74565b90861660e085015283810361010085015290506147908185613c74565b828152604060208201526000612c466040830184613c74565b60008060408385031215614be957600080fd5b82518015158114614bf957600080fd5b6020939093015192949293505050565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b600082601f830112614c4057600080fd5b81356020614c50613eb383613e6e565b82815260059290921b84018101918181019086841115614c6f57600080fd5b8286015b84811015613efb5780358352918301918301614c73565b600082601f830112614c9b57600080fd5b81356020614cab613eb383613e6e565b82815260059290921b84018101918181019086841115614cca57600080fd5b8286015b84811015613efb57803567ffffffffffffffff811115614cee5760008081fd5b614cfc8986838b01016140d9565b845250918301918301614cce565b600060208284031215614d1c57600080fd5b813567ffffffffffffffff80821115614d3457600080fd5b9083019060c08286031215614d4857600080fd5b614d50613dfc565b8235815260208301356020820152604083013582811115614d7057600080fd5b614d7c87828601614c2f565b604083015250606083013582811115614d9457600080fd5b614da087828601614c2f565b606083015250608083013582811115614db857600080fd5b614dc487828601614c8a565b60808301525060a083013582811115614ddc57600080fd5b614de887828601614c8a565b60a08301525095945050505050565b82815260008251614e0f816020850160208701613c50565b919091016020019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b828482376000838201600081528351614e69818360208801613c50565b0195945050505050565b600063ffffffff80831681851681830481118215151615614b0657614b06614441565b60008060008060008060c08789031215614eaf57600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b600060408284031215614ef257600080fd5b6040516040810181811067ffffffffffffffff82111715614f1557614f15613da3565b6040528251614f2381613f17565b81526020928301519281019290925250919050565b600060808284031215614f4a57600080fd5b6040516080810181811067ffffffffffffffff82111715614f6d57614f6d613da3565b604052825181526020830151614f8281613f17565b60208201526040830151614f9581613f17565b6040820152606092830151928101929092525091905056fe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000810000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractKeeperRegistryLogicB2_1\",\"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\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"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\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"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\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"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\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"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\":\"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\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"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\":\"nonpayable\",\"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\":\"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\":\"structKeeperRegistryBase2_1.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfigTypeSafe\",\"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\":\"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: "0x6101406040523480156200001257600080fd5b50604051620054b9380380620054b98339810160408190526200003591620003df565b80816001600160a01b0316634b4fd03b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b919062000406565b826001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001009190620003df565b836001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001659190620003df565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca9190620003df565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f9190620003df565b3380600081620002865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620002b957620002b9816200031b565b505050846002811115620002d157620002d162000429565b60e0816002811115620002e857620002e862000429565b9052506001600160a01b0393841660805291831660a052821660c0528116610100529190911661012052506200043f9050565b336001600160a01b03821603620003755760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200027d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b0381168114620003dc57600080fd5b50565b600060208284031215620003f257600080fd5b8151620003ff81620003c6565b9392505050565b6000602082840312156200041957600080fd5b815160038110620003ff57600080fd5b634e487b7160e01b600052602160045260246000fd5b60805160a05160c05160e0516101005161012051615018620004a16000396000818160d6015261016f01526000505060008181612eb701528181613220015281816133b30152613a3e01526000505060005050600061043b01526150186000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c8063aed2e92911610081578063e29b753c1161005b578063e29b753c146102e8578063e3d0e712146102fb578063f2fde38b1461030e576100d4565b8063aed2e92914610262578063afcb95d71461028c578063b1dc65a4146102d5576100d4565b806381ff7048116100b257806381ff7048146101bc5780638da5cb5b14610231578063a4c0ed361461024f576100d4565b8063181f5a771461011b578063349e8cca1461016d57806379ba5097146101b4575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610114573d6000f35b3d6000fd5b005b6101576040518060400160405280601481526020017f4b6565706572526567697374727920322e312e3000000000000000000000000081525081565b6040516101649190613cbd565b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610164565b610119610321565b61020e60145460115463ffffffff780100000000000000000000000000000000000000000000000083048116937c01000000000000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610164565b60005473ffffffffffffffffffffffffffffffffffffffff1661018f565b61011961025d366004613d46565b610423565b610275610270366004613da2565b61063f565b604080519215158352602083019190915201610164565b601154601254604080516000815260208101939093527c010000000000000000000000000000000000000000000000000000000090910463ffffffff1690820152606001610164565b6101196102e3366004613e33565b6107a7565b6101196102f63660046142ae565b6112ea565b61011961030936600461437b565b6121e6565b61011961031c36600461440a565b61220f565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610492576040517fc8bad78d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081146104cc576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104da82840184614427565b60008181526004602052604090205490915065010000000000900463ffffffff90811614610534576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090206001015461056f9085906c0100000000000000000000000090046bffffffffffffffffffffffff1661446f565b600082815260046020526040902060010180546bffffffffffffffffffffffff929092166c01000000000000000000000000027fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff9092169190911790556018546105da908590614494565b6018556040516bffffffffffffffffffffffff8516815273ffffffffffffffffffffffffffffffffffffffff86169082907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a35050505050565b60008061064a612223565b6012546e010000000000000000000000000000900460ff1615610699576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260046020908152604091829020825160e081018452815460ff811615158252610100810463ffffffff908116838601819052650100000000008304821684880152690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff16606084018190526001909401546bffffffffffffffffffffffff80821660808601526c0100000000000000000000000082041660a0850152780100000000000000000000000000000000000000000000000090041660c08301528451601f8901859004850281018501909552878552909361079893899089908190840183828082843760009201919091525061225d92505050565b9093509150505b935093915050565b60005a604080516101208101825260125460ff808216835261010080830463ffffffff90811660208601526501000000000084048116958501959095526901000000000000000000830462ffffff1660608501526c01000000000000000000000000830461ffff1660808501526e0100000000000000000000000000008304821615801560a08601526f010000000000000000000000000000008404909216151560c085015270010000000000000000000000000000000083046bffffffffffffffffffffffff1660e08501527c0100000000000000000000000000000000000000000000000000000000909204909316908201529192506108d5576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604090205460ff1661091e576040517f1099ed7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6011548a351461095a576040517fdfdcf8e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516109679060016144d6565b60ff16861415806109785750858414155b156109af576040517f0244f71a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109bf8a8a8a8a8a8a8a8a612468565b60006109cb8a8a6126d1565b9050600081604001515167ffffffffffffffff8111156109ed576109ed613eea565b604051908082528060200260200182016040528015610ab157816020015b604080516101e0810182526000610100820181815261012083018290526101408301829052610160830182905261018083018290526101a083018290526101c0830182905282526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181610a0b5790505b5090506000805b836040015151811015610efa576004600085604001518381518110610adf57610adf6144a7565b6020908102919091018101518252818101929092526040908101600020815160e081018352815460ff811615158252610100810463ffffffff90811695830195909552650100000000008104851693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c08201528351849083908110610bc457610bc46144a7565b602002602001015160000181905250610bf984604001518281518110610bec57610bec6144a7565b602002602001015161278c565b838281518110610c0b57610c0b6144a7565b6020026020010151608001906001811115610c2857610c286144ef565b90816001811115610c3b57610c3b6144ef565b81525050610caf85848381518110610c5557610c556144a7565b60200260200101516080015186606001518481518110610c7757610c776144a7565b60200260200101518760a001518581518110610c9557610c956144a7565b602002602001015151886000015189602001516001612837565b838281518110610cc157610cc16144a7565b6020026020010151604001906bffffffffffffffffffffffff1690816bffffffffffffffffffffffff1681525050610d4d84604001518281518110610d0857610d086144a7565b602002602001015185608001518381518110610d2657610d266144a7565b6020026020010151858481518110610d4057610d406144a7565b6020026020010151612882565b848381518110610d5f57610d5f6144a7565b6020026020010151602001858481518110610d7c57610d7c6144a7565b602002602001015160e0018281525082151515158152505050828181518110610da757610da76144a7565b60200260200101516020015115610dca57610dc360018361451e565b9150610dcf565b610ee8565b610e35838281518110610de457610de46144a7565b6020026020010151600001516060015185606001518381518110610e0a57610e0a6144a7565b60200260200101518660a001518481518110610e2857610e286144a7565b602002602001015161225d565b848381518110610e4757610e476144a7565b6020026020010151606001858481518110610e6457610e646144a7565b602002602001015160a0018281525082151515158152505050828181518110610e8f57610e8f6144a7565b602002602001015160a0015186610ea69190614539565b9550610ee884604001518281518110610ec157610ec16144a7565b6020026020010151848381518110610edb57610edb6144a7565b6020026020010151612a01565b80610ef28161454c565b915050610ab8565b508061ffff16600003610f115750505050506112e0565b8351610f1e9060016144d6565b610f2d9060ff1661044c614584565b616b6c610f3b8d6010614584565b5a610f469089614539565b610f509190614494565b610f5a9190614494565b610f649190614494565b9450611b58610f7761ffff8316876145f0565b610f819190614494565b945060008060008060005b87604001515181101561118257868181518110610fab57610fab6144a7565b60200260200101516020015115611170576110078a888381518110610fd257610fd26144a7565b6020026020010151608001518a60a001518481518110610ff457610ff46144a7565b6020026020010151518c60000151612b13565b878281518110611019576110196144a7565b602002602001015160c00181815250506110758989604001518381518110611043576110436144a7565b602002602001015189848151811061105d5761105d6144a7565b60200260200101518b600001518c602001518b612b33565b9093509150611084828561446f565b9350611090838661446f565b94508681815181106110a4576110a46144a7565b6020026020010151606001511515886040015182815181106110c8576110c86144a7565b60200260200101517fad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b84866110fd919061446f565b8a858151811061110f5761110f6144a7565b602002602001015160a001518b868151811061112d5761112d6144a7565b602002602001015160c001518d60800151878151811061114f5761114f6144a7565b60200260200101516040516111679493929190614604565b60405180910390a35b8061117a8161454c565b915050610f8c565b5050336000908152600b6020526040902080548492506002906111ba9084906201000090046bffffffffffffffffffffffff1661446f565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080601260000160108282829054906101000a90046bffffffffffffffffffffffff16611214919061446f565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555060008f600160038110611257576112576144a7565b602002013560001c9050600060088264ffffffffff16901c905087610100015163ffffffff168163ffffffff1611156112d657601280547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff8416021790555b5050505050505050505b5050505050505050565b6112f2612c26565b601f8651111561132e576040517f25d0209c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8360ff1660000361136b576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451865114158061138a5750611382846003614641565b60ff16865111155b156113c1576040517f1d2d1c5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254600e547001000000000000000000000000000000009091046bffffffffffffffffffffffff169060005b816bffffffffffffffffffffffff1681101561145657611443600e828154811061141a5761141a6144a7565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff168484612ca7565b508061144e8161454c565b9150506113ee565b5060008060005b836bffffffffffffffffffffffff1681101561155f57600d8181548110611486576114866144a7565b600091825260209091200154600e805473ffffffffffffffffffffffffffffffffffffffff909216945090829081106114c1576114c16144a7565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff8681168452600c8352604080852080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690559116808452600b90925290912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690559150806115578161454c565b91505061145d565b5061156c600d6000613b92565b611578600e6000613b92565b604080516080810182526000808252602082018190529181018290526060810182905290805b8c518110156119e157600c60008e83815181106115bd576115bd6144a7565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615611628576040517f77cea0fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168d8281518110611652576116526144a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116a7576040517f815e1d6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806001151581526020018260ff16815250600c60008f84815181106116d8576116d86144a7565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909316929092171790558b518c9082908110611780576117806144a7565b60200260200101519150600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036117f0576040517f58a70a0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166000908152600b60209081526040918290208251608081018452905460ff80821615801584526101008304909116938301939093526bffffffffffffffffffffffff6201000082048116948301949094526e010000000000000000000000000000900490921660608301529093506118ab576040517f6a7281ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001835260ff80821660208086019182526bffffffffffffffffffffffff808b166060880190815273ffffffffffffffffffffffffffffffffffffffff87166000908152600b909352604092839020885181549551948a0151925184166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff939094166201000002929092167fffffffffffff000000000000000000000000000000000000000000000000ffff94909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090951694909417179190911692909217919091179055806119d98161454c565b91505061159e565b50508a516119f79150600d9060208d0190613bb0565b508851611a0b90600e9060208c0190613bb0565b506040518061012001604052808960ff168152602001886000015163ffffffff168152602001886020015163ffffffff168152602001886060015162ffffff168152602001886080015161ffff1681526020016012600001600e9054906101000a900460ff16151581526020016012600001600f9054906101000a900460ff1615158152602001856bffffffffffffffffffffffff168152602001600063ffffffff16815250601260008201518160000160006101000a81548160ff021916908360ff16021790555060208201518160000160016101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160056101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160096101000a81548162ffffff021916908362ffffff160217905550608082015181600001600c6101000a81548161ffff021916908361ffff16021790555060a082015181600001600e6101000a81548160ff02191690831515021790555060c082015181600001600f6101000a81548160ff02191690831515021790555060e08201518160000160106101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061010082015181600001601c6101000a81548163ffffffff021916908363ffffffff1602179055509050506040518061018001604052808860a001516bffffffffffffffffffffffff16815260200188610180015173ffffffffffffffffffffffffffffffffffffffff168152602001601360010160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152602001886040015163ffffffff1681526020018860c0015163ffffffff168152602001601360010160149054906101000a900463ffffffff1663ffffffff168152602001601360010160189054906101000a900463ffffffff1663ffffffff1681526020016013600101601c9054906101000a900463ffffffff1663ffffffff1681526020018860e0015163ffffffff16815260200188610100015163ffffffff16815260200188610120015163ffffffff168152602001886101c0015173ffffffffffffffffffffffffffffffffffffffff16815250601360008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550606082015181600101600c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160106101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548163ffffffff021916908363ffffffff1602179055506101208201518160020160046101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160086101000a81548163ffffffff021916908363ffffffff16021790555061016082015181600201600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505086610140015160168190555086610160015160178190555060006013600101601c9054906101000a900463ffffffff169050611fcd612eb1565b601480547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff9384160217808255600192601891612048918591780100000000000000000000000000000000000000000000000090041661466a565b92506101000a81548163ffffffff021916908363ffffffff16021790555060008860405160200161207991906146d8565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181529190526014549091506120e290469030907801000000000000000000000000000000000000000000000000900463ffffffff168f8f8f878f8f612f66565b60115560005b6120f26009613010565b8110156121225761210f61210760098361301a565b600990613026565b508061211a8161454c565b9150506120e8565b5060005b896101a0015151811015612179576121668a6101a00151828151811061214e5761214e6144a7565b6020026020010151600961304890919063ffffffff16565b50806121718161454c565b915050612126565b507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0582601154601360010160189054906101000a900463ffffffff168f8f8f878f8f6040516121d09998979695949392919061483c565b60405180910390a1505050505050505050505050565b61220786868686806020019051810190612200919061496d565b86866112ea565b505050505050565b612217612c26565b6122208161306a565b50565b321561225b576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60125460009081906f01000000000000000000000000000000900460ff16156122b2576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601280547fffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff166f010000000000000000000000000000001790556040517f4585e33b000000000000000000000000000000000000000000000000000000009061231f908590602401613cbd565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d16906123f29087908790600401614ac7565b60408051808303816000875af1158015612410573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124349190614ae0565b601280547fffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff16905590969095509350505050565b6000878760405161247a929190614b13565b604051908190038120612491918b90602001614b23565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201208383019092526000808452908301819052909250906000805b88811015612668576001858783602081106124fd576124fd6144a7565b61250a91901a601b6144d6565b8c8c8581811061251c5761251c6144a7565b905060200201358b8b86818110612535576125356144a7565b9050602002013560405160008152602001604052604051612572949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612594573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff81166000908152600c602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290955093509050612642576040517f0f4c073700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015160080260ff166001901b8401935080806126609061454c565b9150506124e0565b50827e010101010101010101010101010101010101010101010101010101010101018416146126c3576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050565b61270a6040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b600061271883850185614c14565b604081015151606082015151919250908114158061273b57508082608001515114155b8061274b5750808260a001515114155b15612782576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5090505b92915050565b6000818160045b600f811015612819577fff0000000000000000000000000000000000000000000000000000000000000082168382602081106127d1576127d16144a7565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461280757506000949350505050565b806128118161454c565b915050612793565b5081600f1a600181111561282f5761282f6144ef565b949350505050565b60008061284988878b6000015161315f565b90506000806128648b8a63ffffffff16858a8a60018b6131eb565b9092509050612873818361446f565b9b9a5050505050505050505050565b60008080808460800151600181111561289d5761289d6144ef565b036128c1576128ad868686613644565b6128bc5760009250905061079f565b612938565b6001846080015160018111156128d9576128d96144ef565b036129065760006128eb878787613738565b9250905080612900575060009250905061079f565b50612938565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612940612eb1565b84516040015163ffffffff161161299457857fc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636866040516129819190613cbd565b60405180910390a260009250905061079f565b83604001516bffffffffffffffffffffffff16846000015160a001516bffffffffffffffffffffffff1610156129f457857f377c8b0c126ae5248d27aca1c76fac4608aff85673ee3caf09747e1044549e02866040516129819190613cbd565b6001969095509350505050565b600081608001516001811115612a1957612a196144ef565b03612a8b57612a26612eb1565b6000838152600460205260409020600101805463ffffffff929092167801000000000000000000000000000000000000000000000000027fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790555050565b600181608001516001811115612aa357612aa36144ef565b03612b0f5760e08101805160009081526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055915191517fa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f29190a25b5050565b6000612b2084848461315f565b90508085101561282f5750929392505050565b600080612b4e888760a001518860c0015188888860016131eb565b90925090506000612b5f828461446f565b600089815260046020526040902060010180549192508291600c90612ba39084906c0100000000000000000000000090046bffffffffffffffffffffffff16614d01565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008a815260046020526040812060010180548594509092612bec9185911661446f565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555050965096945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461225b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161039e565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e0100000000000000000000000000009004909116606082015290612ea3576000816060015185612d3f9190614d01565b90506000612d4d8583614d26565b90508083604001818151612d61919061446f565b6bffffffffffffffffffffffff16905250612d7c8582614d51565b83606001818151612d8d919061446f565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b6040015190505b9392505050565b600060017f00000000000000000000000000000000000000000000000000000000000000006002811115612ee757612ee76144ef565b03612f6157606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f5c9190614d85565b905090565b504390565b6000808a8a8a8a8a8a8a8a8a604051602001612f8a99989796959493929190614d9e565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179b9a5050505050505050505050565b6000612786825490565b6000612eaa83836138c5565b6000612eaa8373ffffffffffffffffffffffffffffffffffffffff84166138ef565b6000612eaa8373ffffffffffffffffffffffffffffffffffffffff84166139e9565b3373ffffffffffffffffffffffffffffffffffffffff8216036130e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161039e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008080856001811115613175576131756144ef565b03613184575062015f906131a3565b6001856001811115613198576131986144ef565b0361290657506201adb05b6131b463ffffffff85166014614584565b6131bf8460016144d6565b6131ce9060ff16611d4c614584565b6131d89083614494565b6131e29190614494565b95945050505050565b6000806000896080015161ffff16876132049190614584565b90508380156132125750803a105b1561321a57503a5b600060027f00000000000000000000000000000000000000000000000000000000000000006002811115613250576132506144ef565b036133af5760408051600081526020810190915285156132ae57600036604051806080016040528060488152602001614fc46048913960405160200161329893929190614e33565b6040516020818303038152906040529050613316565b6015546132ca90640100000000900463ffffffff166004614e5a565b63ffffffff1667ffffffffffffffff8111156132e8576132e8613eea565b6040519080825280601f01601f191660200182016040528015613312576020820181803683370190505b5090505b6040517f49948e0e00000000000000000000000000000000000000000000000000000000815273420000000000000000000000000000000000000f906349948e0e90613366908490600401613cbd565b602060405180830381865afa158015613383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133a79190614d85565b915050613509565b60017f000000000000000000000000000000000000000000000000000000000000000060028111156133e3576133e36144ef565b0361350957841561346557606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561343a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061345e9190614d85565b9050613509565b6000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c060405180830381865afa1580156134b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134d79190614e7d565b50506015549294506134fa93505050640100000000900463ffffffff1682614584565b613505906010614584565b9150505b8461352557808b6080015161ffff166135229190614584565b90505b61353361ffff8716826145f0565b9050600087826135438c8e614494565b61354d9086614584565b6135579190614494565b61356990670de0b6b3a7640000614584565b61357391906145f0565b905060008c6040015163ffffffff1664e8d4a510006135929190614584565b898e6020015163ffffffff16858f886135ab9190614584565b6135b59190614494565b6135c390633b9aca00614584565b6135cd9190614584565b6135d791906145f0565b6135e19190614494565b90506b033b2e3c9fd0803ce80000006135fa8284614494565b1115613632576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909c909b509950505050505050505050565b6000808380602001905181019061365b9190614ec7565b835160c00151815191925063ffffffff908116911610156136b857847f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8856040516136a69190613cbd565b60405180910390a26000915050612eaa565b6020810151158015906136df5750602081015181516136dc9063ffffffff16613a38565b14155b806136f857506136ed612eb1565b815163ffffffff1610155b1561372d57847f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301856040516136a69190613cbd565b506001949350505050565b6000806000848060200190518101906137519190614f1f565b9050600086826000015183602001516040516020016137a893929190928352602083019190915260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016604082015260440190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012060608301519091501580159061380a57508160600151613807836040015163ffffffff16613a38565b14155b806138265750613818612eb1565b826040015163ffffffff1610155b1561387057867f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc3018760405161385b9190613cbd565b60405180910390a260009350915061079f9050565b60008181526008602052604090205460ff16156138b757867f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e88760405161385b9190613cbd565b600197909650945050505050565b60008260000182815481106138dc576138dc6144a7565b9060005260206000200154905092915050565b600081815260018301602052604081205480156139d8576000613913600183614539565b855490915060009061392790600190614539565b905081811461398c576000866000018281548110613947576139476144a7565b906000526020600020015490508087600001848154811061396a5761396a6144a7565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061399d5761399d614f94565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612786565b6000915050612786565b5092915050565b6000818152600183016020526040812054613a3057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155612786565b506000612786565b600060017f00000000000000000000000000000000000000000000000000000000000000006002811115613a6e57613a6e6144ef565b03613b88576000606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613ac1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ae59190614d85565b90508083101580613b005750610100613afe8483614539565b115b15613b0e5750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815260048101849052606490632b407a8290602401602060405180830381865afa158015613b64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eaa9190614d85565b504090565b919050565b50805460008255906000526020600020908101906122209190613c3a565b828054828255906000526020600020908101928215613c2a579160200282015b82811115613c2a57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190613bd0565b50613c36929150613c3a565b5090565b5b80821115613c365760008155600101613c3b565b60005b83811015613c6a578181015183820152602001613c52565b50506000910152565b60008151808452613c8b816020860160208601613c4f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612eaa6020830184613c73565b73ffffffffffffffffffffffffffffffffffffffff8116811461222057600080fd5b8035613b8d81613cd0565b60008083601f840112613d0f57600080fd5b50813567ffffffffffffffff811115613d2757600080fd5b602083019150836020828501011115613d3f57600080fd5b9250929050565b60008060008060608587031215613d5c57600080fd5b8435613d6781613cd0565b935060208501359250604085013567ffffffffffffffff811115613d8a57600080fd5b613d9687828801613cfd565b95989497509550505050565b600080600060408486031215613db757600080fd5b83359250602084013567ffffffffffffffff811115613dd557600080fd5b613de186828701613cfd565b9497909650939450505050565b60008083601f840112613e0057600080fd5b50813567ffffffffffffffff811115613e1857600080fd5b6020830191508360208260051b8501011115613d3f57600080fd5b60008060008060008060008060e0898b031215613e4f57600080fd5b606089018a811115613e6057600080fd5b8998503567ffffffffffffffff80821115613e7a57600080fd5b613e868c838d01613cfd565b909950975060808b0135915080821115613e9f57600080fd5b613eab8c838d01613dee565b909750955060a08b0135915080821115613ec457600080fd5b50613ed18b828c01613dee565b999c989b50969995989497949560c00135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516101e0810167ffffffffffffffff81118282101715613f3d57613f3d613eea565b60405290565b60405160c0810167ffffffffffffffff81118282101715613f3d57613f3d613eea565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613fad57613fad613eea565b604052919050565b600067ffffffffffffffff821115613fcf57613fcf613eea565b5060051b60200190565b600082601f830112613fea57600080fd5b81356020613fff613ffa83613fb5565b613f66565b82815260059290921b8401810191818101908684111561401e57600080fd5b8286015b8481101561404257803561403581613cd0565b8352918301918301614022565b509695505050505050565b803560ff81168114613b8d57600080fd5b63ffffffff8116811461222057600080fd5b8035613b8d8161405e565b62ffffff8116811461222057600080fd5b8035613b8d8161407b565b61ffff8116811461222057600080fd5b8035613b8d81614097565b6bffffffffffffffffffffffff8116811461222057600080fd5b8035613b8d816140b2565b60006101e082840312156140ea57600080fd5b6140f2613f19565b90506140fd82614070565b815261410b60208301614070565b602082015261411c60408301614070565b604082015261412d6060830161408c565b606082015261413e608083016140a7565b608082015261414f60a083016140cc565b60a082015261416060c08301614070565b60c082015261417160e08301614070565b60e0820152610100614184818401614070565b90820152610120614196838201614070565b90820152610140828101359082015261016080830135908201526101806141be818401613cf2565b908201526101a08281013567ffffffffffffffff8111156141de57600080fd5b6141ea85828601613fd9565b8284015250506101c06141fe818401613cf2565b9082015292915050565b803567ffffffffffffffff81168114613b8d57600080fd5b600082601f83011261423157600080fd5b813567ffffffffffffffff81111561424b5761424b613eea565b61427c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613f66565b81815284602083860101111561429157600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c087890312156142c757600080fd5b863567ffffffffffffffff808211156142df57600080fd5b6142eb8a838b01613fd9565b9750602089013591508082111561430157600080fd5b61430d8a838b01613fd9565b965061431b60408a0161404d565b9550606089013591508082111561433157600080fd5b61433d8a838b016140d7565b945061434b60808a01614208565b935060a089013591508082111561436157600080fd5b5061436e89828a01614220565b9150509295509295509295565b60008060008060008060c0878903121561439457600080fd5b863567ffffffffffffffff808211156143ac57600080fd5b6143b88a838b01613fd9565b975060208901359150808211156143ce57600080fd5b6143da8a838b01613fd9565b96506143e860408a0161404d565b955060608901359150808211156143fe57600080fd5b61433d8a838b01614220565b60006020828403121561441c57600080fd5b8135612eaa81613cd0565b60006020828403121561443957600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff8181168382160190808211156139e2576139e2614440565b8082018082111561278657612786614440565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60ff818116838216019081111561278657612786614440565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b61ffff8181168382160190808211156139e2576139e2614440565b8181038181111561278657612786614440565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361457d5761457d614440565b5060010190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156145bc576145bc614440565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826145ff576145ff6145c1565b500490565b6bffffffffffffffffffffffff851681528360208201528260408201526080606082015260006146376080830184613c73565b9695505050505050565b600060ff821660ff84168160ff048111821515161561466257614662614440565b029392505050565b63ffffffff8181168382160190808211156139e2576139e2614440565b600081518084526020808501945080840160005b838110156146cd57815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161469b565b509495945050505050565b602081526146ef60208201835163ffffffff169052565b60006020830151614708604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015162ffffff8116608084015250608083015161ffff811660a08401525060a08301516bffffffffffffffffffffffff811660c08401525060c083015163ffffffff811660e08401525060e08301516101006147818185018363ffffffff169052565b840151905061012061479a8482018363ffffffff169052565b84015190506101406147b38482018363ffffffff169052565b840151610160848101919091528401516101808085019190915284015190506101a06147f68185018373ffffffffffffffffffffffffffffffffffffffff169052565b808501519150506101e06101c08181860152614816610200860184614687565b95015173ffffffffffffffffffffffffffffffffffffffff169301929092525090919050565b600061012063ffffffff808d1684528b6020850152808b1660408501525080606084015261486c8184018a614687565b905082810360808401526148808189614687565b905060ff871660a084015282810360c084015261489d8187613c73565b905067ffffffffffffffff851660e08401528281036101008401526148c28185613c73565b9c9b505050505050505050505050565b8051613b8d8161405e565b8051613b8d8161407b565b8051613b8d81614097565b8051613b8d816140b2565b8051613b8d81613cd0565b600082601f83011261491a57600080fd5b8151602061492a613ffa83613fb5565b82815260059290921b8401810191818101908684111561494957600080fd5b8286015b8481101561404257805161496081613cd0565b835291830191830161494d565b60006020828403121561497f57600080fd5b815167ffffffffffffffff8082111561499757600080fd5b908301906101e082860312156149ac57600080fd5b6149b4613f19565b6149bd836148d2565b81526149cb602084016148d2565b60208201526149dc604084016148d2565b60408201526149ed606084016148dd565b60608201526149fe608084016148e8565b6080820152614a0f60a084016148f3565b60a0820152614a2060c084016148d2565b60c0820152614a3160e084016148d2565b60e0820152610100614a448185016148d2565b90820152610120614a568482016148d2565b9082015261014083810151908201526101608084015190820152610180614a7e8185016148fe565b908201526101a08381015183811115614a9657600080fd5b614aa288828701614909565b8284015250506101c09150614ab88284016148fe565b91810191909152949350505050565b82815260406020820152600061282f6040830184613c73565b60008060408385031215614af357600080fd5b82518015158114614b0357600080fd5b6020939093015192949293505050565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b600082601f830112614b4a57600080fd5b81356020614b5a613ffa83613fb5565b82815260059290921b84018101918181019086841115614b7957600080fd5b8286015b848110156140425780358352918301918301614b7d565b600082601f830112614ba557600080fd5b81356020614bb5613ffa83613fb5565b82815260059290921b84018101918181019086841115614bd457600080fd5b8286015b8481101561404257803567ffffffffffffffff811115614bf85760008081fd5b614c068986838b0101614220565b845250918301918301614bd8565b600060208284031215614c2657600080fd5b813567ffffffffffffffff80821115614c3e57600080fd5b9083019060c08286031215614c5257600080fd5b614c5a613f43565b8235815260208301356020820152604083013582811115614c7a57600080fd5b614c8687828601614b39565b604083015250606083013582811115614c9e57600080fd5b614caa87828601614b39565b606083015250608083013582811115614cc257600080fd5b614cce87828601614b94565b60808301525060a083013582811115614ce657600080fd5b614cf287828601614b94565b60a08301525095945050505050565b6bffffffffffffffffffffffff8281168282160390808211156139e2576139e2614440565b60006bffffffffffffffffffffffff80841680614d4557614d456145c1565b92169190910492915050565b60006bffffffffffffffffffffffff80831681851681830481118215151615614d7c57614d7c614440565b02949350505050565b600060208284031215614d9757600080fd5b5051919050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614de58285018b614687565b91508382036080850152614df9828a614687565b915060ff881660a085015283820360c0850152614e168288613c73565b90861660e085015283810361010085015290506148c28185613c73565b828482376000838201600081528351614e50818360208801613c4f565b0195945050505050565b600063ffffffff80831681851681830481118215151615614d7c57614d7c614440565b60008060008060008060c08789031215614e9657600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b600060408284031215614ed957600080fd5b6040516040810181811067ffffffffffffffff82111715614efc57614efc613eea565b6040528251614f0a8161405e565b81526020928301519281019290925250919050565b600060808284031215614f3157600080fd5b6040516080810181811067ffffffffffffffff82111715614f5457614f54613eea565b604052825181526020830151614f698161405e565b60208201526040830151614f7c8161405e565b60408201526060928301519281019290925250919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000810000a", } var KeeperRegistryABI = KeeperRegistryMetaData.ABI @@ -341,28 +341,28 @@ func (_KeeperRegistry *KeeperRegistryTransactorSession) OnTokenTransfer(sender c return _KeeperRegistry.Contract.OnTokenTransfer(&_KeeperRegistry.TransactOpts, sender, amount, data) } -func (_KeeperRegistry *KeeperRegistryTransactor) SetConfig(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig KeeperRegistryBase21OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { - return _KeeperRegistry.contract.Transact(opts, "setConfig", signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +func (_KeeperRegistry *KeeperRegistryTransactor) SetConfig(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _KeeperRegistry.contract.Transact(opts, "setConfig", signers, transmitters, f, onchainConfigBytes, offchainConfigVersion, offchainConfig) } -func (_KeeperRegistry *KeeperRegistrySession) SetConfig(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig KeeperRegistryBase21OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { - return _KeeperRegistry.Contract.SetConfig(&_KeeperRegistry.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +func (_KeeperRegistry *KeeperRegistrySession) SetConfig(signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _KeeperRegistry.Contract.SetConfig(&_KeeperRegistry.TransactOpts, signers, transmitters, f, onchainConfigBytes, offchainConfigVersion, offchainConfig) } -func (_KeeperRegistry *KeeperRegistryTransactorSession) SetConfig(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig KeeperRegistryBase21OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { - return _KeeperRegistry.Contract.SetConfig(&_KeeperRegistry.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +func (_KeeperRegistry *KeeperRegistryTransactorSession) SetConfig(signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _KeeperRegistry.Contract.SetConfig(&_KeeperRegistry.TransactOpts, signers, transmitters, f, onchainConfigBytes, offchainConfigVersion, offchainConfig) } -func (_KeeperRegistry *KeeperRegistryTransactor) SetConfig0(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { - return _KeeperRegistry.contract.Transact(opts, "setConfig0", signers, transmitters, f, onchainConfigBytes, offchainConfigVersion, offchainConfig) +func (_KeeperRegistry *KeeperRegistryTransactor) SetConfigTypeSafe(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig KeeperRegistryBase21OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _KeeperRegistry.contract.Transact(opts, "setConfigTypeSafe", signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) } -func (_KeeperRegistry *KeeperRegistrySession) SetConfig0(signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { - return _KeeperRegistry.Contract.SetConfig0(&_KeeperRegistry.TransactOpts, signers, transmitters, f, onchainConfigBytes, offchainConfigVersion, offchainConfig) +func (_KeeperRegistry *KeeperRegistrySession) SetConfigTypeSafe(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig KeeperRegistryBase21OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _KeeperRegistry.Contract.SetConfigTypeSafe(&_KeeperRegistry.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) } -func (_KeeperRegistry *KeeperRegistryTransactorSession) SetConfig0(signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { - return _KeeperRegistry.Contract.SetConfig0(&_KeeperRegistry.TransactOpts, signers, transmitters, f, onchainConfigBytes, offchainConfigVersion, offchainConfig) +func (_KeeperRegistry *KeeperRegistryTransactorSession) SetConfigTypeSafe(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig KeeperRegistryBase21OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _KeeperRegistry.Contract.SetConfigTypeSafe(&_KeeperRegistry.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) } func (_KeeperRegistry *KeeperRegistryTransactor) SimulatePerformUpkeep(opts *bind.TransactOpts, id *big.Int, performData []byte) (*types.Transaction, error) { @@ -602,9 +602,9 @@ func (it *KeeperRegistryCancelledUpkeepReportIterator) Close() error { } type KeeperRegistryCancelledUpkeepReport struct { - Id *big.Int - UpkeepTriggerID [32]byte - Raw types.Log + Id *big.Int + Trigger []byte + Raw types.Log } func (_KeeperRegistry *KeeperRegistryFilterer) FilterCancelledUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*KeeperRegistryCancelledUpkeepReportIterator, error) { @@ -794,6 +794,133 @@ func (_KeeperRegistry *KeeperRegistryFilterer) ParseConfigSet(log types.Log) (*K return event, nil } +type KeeperRegistryDedupKeyAddedIterator struct { + Event *KeeperRegistryDedupKeyAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *KeeperRegistryDedupKeyAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(KeeperRegistryDedupKeyAdded) + 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(KeeperRegistryDedupKeyAdded) + 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 *KeeperRegistryDedupKeyAddedIterator) Error() error { + return it.fail +} + +func (it *KeeperRegistryDedupKeyAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type KeeperRegistryDedupKeyAdded struct { + DedupKey [32]byte + Raw types.Log +} + +func (_KeeperRegistry *KeeperRegistryFilterer) FilterDedupKeyAdded(opts *bind.FilterOpts, dedupKey [][32]byte) (*KeeperRegistryDedupKeyAddedIterator, error) { + + var dedupKeyRule []interface{} + for _, dedupKeyItem := range dedupKey { + dedupKeyRule = append(dedupKeyRule, dedupKeyItem) + } + + logs, sub, err := _KeeperRegistry.contract.FilterLogs(opts, "DedupKeyAdded", dedupKeyRule) + if err != nil { + return nil, err + } + return &KeeperRegistryDedupKeyAddedIterator{contract: _KeeperRegistry.contract, event: "DedupKeyAdded", logs: logs, sub: sub}, nil +} + +func (_KeeperRegistry *KeeperRegistryFilterer) WatchDedupKeyAdded(opts *bind.WatchOpts, sink chan<- *KeeperRegistryDedupKeyAdded, dedupKey [][32]byte) (event.Subscription, error) { + + var dedupKeyRule []interface{} + for _, dedupKeyItem := range dedupKey { + dedupKeyRule = append(dedupKeyRule, dedupKeyItem) + } + + logs, sub, err := _KeeperRegistry.contract.WatchLogs(opts, "DedupKeyAdded", dedupKeyRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(KeeperRegistryDedupKeyAdded) + if err := _KeeperRegistry.contract.UnpackLog(event, "DedupKeyAdded", 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 (_KeeperRegistry *KeeperRegistryFilterer) ParseDedupKeyAdded(log types.Log) (*KeeperRegistryDedupKeyAdded, error) { + event := new(KeeperRegistryDedupKeyAdded) + if err := _KeeperRegistry.contract.UnpackLog(event, "DedupKeyAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type KeeperRegistryFundsAddedIterator struct { Event *KeeperRegistryFundsAdded @@ -1121,9 +1248,9 @@ func (it *KeeperRegistryInsufficientFundsUpkeepReportIterator) Close() error { } type KeeperRegistryInsufficientFundsUpkeepReport struct { - Id *big.Int - UpkeepTriggerID [32]byte - Raw types.Log + Id *big.Int + Trigger []byte + Raw types.Log } func (_KeeperRegistry *KeeperRegistryFilterer) FilterInsufficientFundsUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*KeeperRegistryInsufficientFundsUpkeepReportIterator, error) { @@ -2309,9 +2436,9 @@ func (it *KeeperRegistryReorgedUpkeepReportIterator) Close() error { } type KeeperRegistryReorgedUpkeepReport struct { - Id *big.Int - UpkeepTriggerID [32]byte - Raw types.Log + Id *big.Int + Trigger []byte + Raw types.Log } func (_KeeperRegistry *KeeperRegistryFilterer) FilterReorgedUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*KeeperRegistryReorgedUpkeepReportIterator, error) { @@ -2437,9 +2564,9 @@ func (it *KeeperRegistryStaleUpkeepReportIterator) Close() error { } type KeeperRegistryStaleUpkeepReport struct { - Id *big.Int - UpkeepTriggerID [32]byte - Raw types.Log + Id *big.Int + Trigger []byte + Raw types.Log } func (_KeeperRegistry *KeeperRegistryFilterer) FilterStaleUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*KeeperRegistryStaleUpkeepReportIterator, error) { @@ -3866,13 +3993,13 @@ func (it *KeeperRegistryUpkeepPerformedIterator) Close() error { } type KeeperRegistryUpkeepPerformed struct { - Id *big.Int - Success bool - TotalPayment *big.Int - GasUsed *big.Int - GasOverhead *big.Int - UpkeepTriggerID [32]byte - Raw types.Log + Id *big.Int + Success bool + TotalPayment *big.Int + GasUsed *big.Int + GasOverhead *big.Int + Trigger []byte + Raw types.Log } func (_KeeperRegistry *KeeperRegistryFilterer) FilterUpkeepPerformed(opts *bind.FilterOpts, id []*big.Int, success []bool) (*KeeperRegistryUpkeepPerformedIterator, error) { @@ -4605,6 +4732,8 @@ func (_KeeperRegistry *KeeperRegistry) ParseLog(log types.Log) (generated.Abigen return _KeeperRegistry.ParseCancelledUpkeepReport(log) case _KeeperRegistry.abi.Events["ConfigSet"].ID: return _KeeperRegistry.ParseConfigSet(log) + case _KeeperRegistry.abi.Events["DedupKeyAdded"].ID: + return _KeeperRegistry.ParseDedupKeyAdded(log) case _KeeperRegistry.abi.Events["FundsAdded"].ID: return _KeeperRegistry.ParseFundsAdded(log) case _KeeperRegistry.abi.Events["FundsWithdrawn"].ID: @@ -4674,13 +4803,17 @@ func (KeeperRegistryAdminPrivilegeConfigSet) Topic() common.Hash { } func (KeeperRegistryCancelledUpkeepReport) Topic() common.Hash { - return common.HexToHash("0x846af3fdde418e2757c00c4cf8c6827e65ac4179753128c454922ccd7963886d") + return common.HexToHash("0xc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636") } func (KeeperRegistryConfigSet) Topic() common.Hash { return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") } +func (KeeperRegistryDedupKeyAdded) Topic() common.Hash { + return common.HexToHash("0xa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f2") +} + func (KeeperRegistryFundsAdded) Topic() common.Hash { return common.HexToHash("0xafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa734891506203") } @@ -4690,7 +4823,7 @@ func (KeeperRegistryFundsWithdrawn) Topic() common.Hash { } func (KeeperRegistryInsufficientFundsUpkeepReport) Topic() common.Hash { - return common.HexToHash("0xfcb5fa059ae0ddeeac53240ccaa0a8ad80993b33e18e8821f1e1cbc53481240e") + return common.HexToHash("0x377c8b0c126ae5248d27aca1c76fac4608aff85673ee3caf09747e1044549e02") } func (KeeperRegistryOwnerFundsWithdrawn) Topic() common.Hash { @@ -4726,11 +4859,11 @@ func (KeeperRegistryPaymentWithdrawn) Topic() common.Hash { } func (KeeperRegistryReorgedUpkeepReport) Topic() common.Hash { - return common.HexToHash("0x07c4f19521a82d67071422fca888431cac8267935db8abe73e354791a3d38868") + return common.HexToHash("0x6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301") } func (KeeperRegistryStaleUpkeepReport) Topic() common.Hash { - return common.HexToHash("0x909d8c7e883c6d2d53a5fb2dbb9ec57875a53c3769c099230027312ffb2a6b11") + return common.HexToHash("0x405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8") } func (KeeperRegistryTransmitted) Topic() common.Hash { @@ -4774,7 +4907,7 @@ func (KeeperRegistryUpkeepPaused) Topic() common.Hash { } func (KeeperRegistryUpkeepPerformed) Topic() common.Hash { - return common.HexToHash("0xdacc0b3d36199a5f78afb27c76cd01bf100f605edf5ee0c0e23055b0553b68c6") + return common.HexToHash("0xad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b") } func (KeeperRegistryUpkeepPrivilegeConfigSet) Topic() common.Hash { @@ -4820,9 +4953,9 @@ type KeeperRegistryInterface interface { 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, onchainConfig KeeperRegistryBase21OnchainConfig, offchainConfigVersion uint64, offchainConfig []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) - SetConfig0(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) + SetConfigTypeSafe(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig KeeperRegistryBase21OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) SimulatePerformUpkeep(opts *bind.TransactOpts, id *big.Int, performData []byte) (*types.Transaction, error) @@ -4850,6 +4983,12 @@ type KeeperRegistryInterface interface { ParseConfigSet(log types.Log) (*KeeperRegistryConfigSet, error) + FilterDedupKeyAdded(opts *bind.FilterOpts, dedupKey [][32]byte) (*KeeperRegistryDedupKeyAddedIterator, error) + + WatchDedupKeyAdded(opts *bind.WatchOpts, sink chan<- *KeeperRegistryDedupKeyAdded, dedupKey [][32]byte) (event.Subscription, error) + + ParseDedupKeyAdded(log types.Log) (*KeeperRegistryDedupKeyAdded, error) + FilterFundsAdded(opts *bind.FilterOpts, id []*big.Int, from []common.Address) (*KeeperRegistryFundsAddedIterator, error) WatchFundsAdded(opts *bind.WatchOpts, sink chan<- *KeeperRegistryFundsAdded, id []*big.Int, from []common.Address) (event.Subscription, error) diff --git a/core/gethwrappers/generated/log_emitter/log_emitter.go b/core/gethwrappers/generated/log_emitter/log_emitter.go index 84fe5d5d6fe..4f0189dfdea 100644 --- a/core/gethwrappers/generated/log_emitter/log_emitter.go +++ b/core/gethwrappers/generated/log_emitter/log_emitter.go @@ -32,7 +32,7 @@ var ( var LogEmitterMetaData = &bind.MetaData{ ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"Log1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"Log2\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"name\":\"Log3\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"v\",\"type\":\"uint256[]\"}],\"name\":\"EmitLog1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"v\",\"type\":\"uint256[]\"}],\"name\":\"EmitLog2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"v\",\"type\":\"string[]\"}],\"name\":\"EmitLog3\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5061053e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063696933c914610046578063bc253bc01461005b578063d9c21f461461006e575b600080fd5b6100596100543660046102f5565b610081565b005b6100596100693660046102f5565b6100f5565b61005961007c3660046101c7565b610159565b60005b81518110156100f1577f46692c0e59ca9cd1ad8f984a9d11715ec83424398b7eed4e05c8ce84662415a88282815181106100c0576100c06104d3565b60200260200101516040516100d791815260200190565b60405180910390a1806100e981610473565b915050610084565b5050565b60005b81518110156100f157818181518110610113576101136104d3565b60200260200101517f624fb00c2ce79f34cb543884c3af64816dce0f4cec3d32661959e49d488a7a9360405160405180910390a28061015181610473565b9150506100f8565b60005b81518110156100f1577fb94ec34dfe32a8a7170992a093976368d1e63decf8f0bc0b38a8eb89cc9f95cf828281518110610198576101986104d3565b60200260200101516040516101ad919061038d565b60405180910390a1806101bf81610473565b91505061015c565b600060208083850312156101da57600080fd5b823567ffffffffffffffff808211156101f257600080fd5b8185019150601f868184011261020757600080fd5b823561021a6102158261044f565b610400565b8082825286820191508686018a888560051b890101111561023a57600080fd5b60005b848110156102e55781358781111561025457600080fd5b8801603f81018d1361026557600080fd5b8981013560408982111561027b5761027b610502565b6102aa8c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08b85011601610400565b8281528f828486010111156102be57600080fd5b828285018e83013760009281018d019290925250855250928801929088019060010161023d565b50909a9950505050505050505050565b6000602080838503121561030857600080fd5b823567ffffffffffffffff81111561031f57600080fd5b8301601f8101851361033057600080fd5b803561033e6102158261044f565b80828252848201915084840188868560051b870101111561035e57600080fd5b600094505b83851015610381578035835260019490940193918501918501610363565b50979650505050505050565b600060208083528351808285015260005b818110156103ba5785810183015185820160400152820161039e565b818111156103cc576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561044757610447610502565b604052919050565b600067ffffffffffffffff82111561046957610469610502565b5060051b60200190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156104cc577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", + Bin: "0x608060405234801561001057600080fd5b5061052b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063696933c914610046578063bc253bc01461005b578063d9c21f461461006e575b600080fd5b610059610054366004610269565b610081565b005b610059610069366004610269565b6100f5565b61005961007c3660046102ff565b610159565b60005b81518110156100f1577f46692c0e59ca9cd1ad8f984a9d11715ec83424398b7eed4e05c8ce84662415a88282815181106100c0576100c0610424565b60200260200101516040516100d791815260200190565b60405180910390a1806100e981610453565b915050610084565b5050565b60005b81518110156100f15781818151811061011357610113610424565b60200260200101517f624fb00c2ce79f34cb543884c3af64816dce0f4cec3d32661959e49d488a7a9360405160405180910390a28061015181610453565b9150506100f8565b60005b81518110156100f1577fb94ec34dfe32a8a7170992a093976368d1e63decf8f0bc0b38a8eb89cc9f95cf82828151811061019857610198610424565b60200260200101516040516101ad91906104b2565b60405180910390a1806101bf81610453565b91505061015c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561023d5761023d6101c7565b604052919050565b600067ffffffffffffffff82111561025f5761025f6101c7565b5060051b60200190565b6000602080838503121561027c57600080fd5b823567ffffffffffffffff81111561029357600080fd5b8301601f810185136102a457600080fd5b80356102b76102b282610245565b6101f6565b81815260059190911b820183019083810190878311156102d657600080fd5b928401925b828410156102f4578335825292840192908401906102db565b979650505050505050565b6000602080838503121561031257600080fd5b823567ffffffffffffffff8082111561032a57600080fd5b8185019150601f868184011261033f57600080fd5b823561034d6102b282610245565b81815260059190911b8401850190858101908983111561036c57600080fd5b8686015b83811015610416578035868111156103885760008081fd5b8701603f81018c1361039a5760008081fd5b888101356040888211156103b0576103b06101c7565b6103df8b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08a850116016101f6565b8281528e828486010111156103f45760008081fd5b828285018d83013760009281018c019290925250845250918701918701610370565b509998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036104ab577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b600060208083528351808285015260005b818110156104df578581018301518582016040015282016104c3565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116850101925050509291505056fea164736f6c6343000813000a", } var LogEmitterABI = LogEmitterMetaData.ABI diff --git a/core/gethwrappers/generated/log_triggered_feed_lookup_wrapper/log_triggered_feed_lookup_wrapper.go b/core/gethwrappers/generated/log_triggered_feed_lookup_wrapper/log_triggered_feed_lookup_wrapper.go index 4f9ae538bb9..21bc8fa80bf 100644 --- a/core/gethwrappers/generated/log_triggered_feed_lookup_wrapper/log_triggered_feed_lookup_wrapper.go +++ b/core/gethwrappers/generated/log_triggered_feed_lookup_wrapper/log_triggered_feed_lookup_wrapper.go @@ -42,15 +42,15 @@ type Log struct { } var LogTriggeredFeedLookupMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_useArbitrumBlockNum\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"feeds\",\"type\":\"string[]\"},{\"internalType\":\"string\",\"name\":\"timeParamKey\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"FeedLookup\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"orderId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"exchange\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"blob\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"verified\",\"type\":\"bytes\"}],\"name\":\"PerformingLogTriggerUpkeep\",\"type\":\"event\"},{\"inputs\":[{\"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\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"txIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"log\",\"type\":\"tuple\"}],\"name\":\"checkLog\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feedParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"feedsHex\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParam\",\"type\":\"string\"}],\"name\":\"setFeedParamKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"newFeeds\",\"type\":\"string[]\"}],\"name\":\"setFeedsHex\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"timeParam\",\"type\":\"string\"}],\"name\":\"setTimeParamKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timeParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useArbitrumBlockNum\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x610120604052604260a08181526080918291906200147560c03990526200002a9060019081620000d4565b506040805180820190915260098152680cccacac892c890caf60bb1b60208201526002906200005a908262000250565b5060408051808201909152600b81526a313637b1b5a73ab6b132b960a91b60208201526003906200008c908262000250565b503480156200009a57600080fd5b50604051620014b7380380620014b7833981016040819052620000bd916200031c565b6000805460ff191691151591909117905562000347565b8280548282559060005260206000209081019282156200011f579160200282015b828111156200011f57825182906200010e908262000250565b5091602001919060010190620000f5565b506200012d92915062000131565b5090565b808211156200012d57600062000148828262000152565b5060010162000131565b5080546200016090620001c1565b6000825580601f1062000171575050565b601f01602090049060005260206000209081019062000191919062000194565b50565b5b808211156200012d576000815560010162000195565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620001d657607f821691505b602082108103620001f757634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200024b57600081815260208120601f850160051c81016020861015620002265750805b601f850160051c820191505b81811015620002475782815560010162000232565b5050505b505050565b81516001600160401b038111156200026c576200026c620001ab565b62000284816200027d8454620001c1565b84620001fd565b602080601f831160018114620002bc5760008415620002a35750858301515b600019600386901b1c1916600185901b17855562000247565b600085815260208120601f198616915b82811015620002ed57888601518255948401946001909101908401620002cc565b50858210156200030c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602082840312156200032f57600080fd5b815180151581146200034057600080fd5b9392505050565b61111e80620003576000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c80639525d57411610076578063afb28d1f1161005b578063afb28d1f14610178578063be61b77514610180578063c98f10b01461019357600080fd5b80639525d574146101455780639d6f1cc71461015857600080fd5b80634b56a42e116100a75780634b56a42e146100eb578063601d5a7114610115578063642f6cef1461012857600080fd5b806305e25131146100c35780634585e33b146100d8575b600080fd5b6100d66100d13660046108b3565b61019b565b005b6100d66100e6366004610969565b6101b2565b6100fe6100f93660046109db565b610254565b60405161010c929190610b13565b60405180910390f35b6100d6610123366004610b36565b6102aa565b6000546101359060ff1681565b604051901515815260200161010c565b6100d6610153366004610b36565b6102b6565b61016b610166366004610b6b565b6102c2565b60405161010c9190610b84565b61016b61036e565b6100fe61018e366004610b9e565b61037b565b61016b61062b565b80516101ae9060019060208401906106be565b5050565b6000806101c1838501856109db565b915091506000806000838060200190518101906101de9190610c03565b919450925090506060327f299a03817e683a32b21e29e3ae3c31f1c9c773f7d532836d116b62a9281fbc9d858585610214610638565b8b60008151811061022757610227610c38565b60200260200101518760405161024296959493929190610c67565b60405180910390a25050505050505050565b600060606000848460405160200161026d929190610cc7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052600193509150505b9250929050565b60036101ae8282610dfd565b60026101ae8282610dfd565b600181815481106102d257600080fd5b9060005260206000200160009150905080546102ed90610d5b565b80601f016020809104026020016040519081016040528092919081815260200182805461031990610d5b565b80156103665780601f1061033b57610100808354040283529160200191610366565b820191906000526020600020905b81548152906001019060200180831161034957829003601f168201915b505050505081565b600280546102ed90610d5b565b600060606000610389610638565b90507fd1ffe9e45581c11d7d9f2ed5f75217cd4be9f8b7eee6af0f6d03f46de53956cd6103b960c0860186610f17565b60008181106103ca576103ca610c38565b90506020020135036105a35760006103e560c0860186610f17565b60018181106103f6576103f6610c38565b9050602002013560405160200161040f91815260200190565b60405160208183030381529060405290506000818060200190518101906104369190610f7f565b9050600061044760c0880188610f17565b600281811061045857610458610c38565b9050602002013560405160200161047191815260200190565b60405160208183030381529060405290506000818060200190518101906104989190610f7f565b905060006104a960c08a018a610f17565b60038181106104ba576104ba610c38565b905060200201356040516020016104d391815260200190565b60405160208183030381529060405290506000818060200190518101906104fa9190610f98565b604080516020810188905290810185905273ffffffffffffffffffffffffffffffffffffffff821660608201529091506002906001906003908a90608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f7ddd933e00000000000000000000000000000000000000000000000000000000825261059a959493929160040161104e565b60405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f636f756c64206e6f742066696e64206d61746368696e67206576656e7420736960448201527f6700000000000000000000000000000000000000000000000000000000000000606482015260840161059a565b600380546102ed90610d5b565b6000805460ff16156106b957606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610690573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106b49190610f7f565b905090565b504390565b828054828255906000526020600020908101928215610704579160200282015b8281111561070457825182906106f49082610dfd565b50916020019190600101906106de565b50610710929150610714565b5090565b808211156107105760006107288282610731565b50600101610714565b50805461073d90610d5b565b6000825580601f1061074d575050565b601f01602090049060005260206000209081019061076b919061076e565b50565b5b80821115610710576000815560010161076f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156107f9576107f9610783565b604052919050565b600067ffffffffffffffff82111561081b5761081b610783565b5060051b60200190565b600082601f83011261083657600080fd5b813567ffffffffffffffff81111561085057610850610783565b61088160207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016107b2565b81815284602083860101111561089657600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156108c657600080fd5b823567ffffffffffffffff808211156108de57600080fd5b818501915085601f8301126108f257600080fd5b813561090561090082610801565b6107b2565b81815260059190911b8301840190848101908883111561092457600080fd5b8585015b8381101561095c578035858111156109405760008081fd5b61094e8b89838a0101610825565b845250918601918601610928565b5098975050505050505050565b6000806020838503121561097c57600080fd5b823567ffffffffffffffff8082111561099457600080fd5b818501915085601f8301126109a857600080fd5b8135818111156109b757600080fd5b8660208285010111156109c957600080fd5b60209290920196919550909350505050565b600080604083850312156109ee57600080fd5b823567ffffffffffffffff80821115610a0657600080fd5b818501915085601f830112610a1a57600080fd5b81356020610a2a61090083610801565b82815260059290921b84018101918181019089841115610a4957600080fd5b8286015b84811015610a8157803586811115610a655760008081fd5b610a738c86838b0101610825565b845250918301918301610a4d565b5096505086013592505080821115610a9857600080fd5b50610aa585828601610825565b9150509250929050565b6000815180845260005b81811015610ad557602081850181015186830182015201610ab9565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b8215158152604060208201526000610b2e6040830184610aaf565b949350505050565b600060208284031215610b4857600080fd5b813567ffffffffffffffff811115610b5f57600080fd5b610b2e84828501610825565b600060208284031215610b7d57600080fd5b5035919050565b602081526000610b976020830184610aaf565b9392505050565b600060208284031215610bb057600080fd5b813567ffffffffffffffff811115610bc757600080fd5b82016101008185031215610b9757600080fd5b805173ffffffffffffffffffffffffffffffffffffffff81168114610bfe57600080fd5b919050565b600080600060608486031215610c1857600080fd5b8351925060208401519150610c2f60408501610bda565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b86815285602082015273ffffffffffffffffffffffffffffffffffffffff8516604082015283606082015260c060808201526000610ca860c0830185610aaf565b82810360a0840152610cba8185610aaf565b9998505050505050505050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015610d3c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018552610d2a868351610aaf565b95509382019390820190600101610cf0565b505085840381870152505050610d528185610aaf565b95945050505050565b600181811c90821680610d6f57607f821691505b602082108103610da8577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f821115610df857600081815260208120601f850160051c81016020861015610dd55750805b601f850160051c820191505b81811015610df457828155600101610de1565b5050505b505050565b815167ffffffffffffffff811115610e1757610e17610783565b610e2b81610e258454610d5b565b84610dae565b602080601f831160018114610e7e5760008415610e485750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610df4565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015610ecb57888601518255948401946001909101908401610eac565b5085821015610f0757878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610f4c57600080fd5b83018035915067ffffffffffffffff821115610f6757600080fd5b6020019150600581901b36038213156102a357600080fd5b600060208284031215610f9157600080fd5b5051919050565b600060208284031215610faa57600080fd5b610b9782610bda565b60008154610fc081610d5b565b808552602060018381168015610fdd576001811461101557611043565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b8901019550611043565b866000528260002060005b8581101561103b5781548a8201860152908301908401611020565b890184019650505b505050505092915050565b60a08152600061106160a0830188610fb3565b6020838203818501528188548084528284019150828160051b8501018a6000528360002060005b838110156110d3577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08784030185526110c18383610fb3565b94860194925060019182019101611088565b505086810360408801526110e7818b610fb3565b94505050505084606084015282810360808401526111058185610aaf565b9897505050505050505056fea164736f6c6343000810000a307834353534343832643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030", + ABI: "[{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_useArbitrumBlockNum\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_verify\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"feeds\",\"type\":\"string[]\"},{\"internalType\":\"string\",\"name\":\"timeParamKey\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"FeedLookup\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"orderId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"exchange\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"blob\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"verified\",\"type\":\"bytes\"}],\"name\":\"PerformingLogTriggerUpkeep\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"txIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"log\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"checkLog\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feedParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"feedsHex\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParam\",\"type\":\"string\"}],\"name\":\"setFeedParamKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"newFeeds\",\"type\":\"string[]\"}],\"name\":\"setFeedsHex\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"timeParam\",\"type\":\"string\"}],\"name\":\"setTimeParamKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timeParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useArbitrumBlockNum\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x610120604052604260a08181526080918291906200164e60c03990526200002a9060019081620000e5565b506040805180820190915260098152680cccacac892c890caf60bb1b60208201526002906200005a908262000261565b5060408051808201909152600b81526a313637b1b5a73ab6b132b960a91b60208201526003906200008c908262000261565b503480156200009a57600080fd5b506040516200169038038062001690833981016040819052620000bd9162000343565b6000805461ffff191692151561ff00191692909217610100911515919091021790556200037b565b82805482825590600052602060002090810192821562000130579160200282015b828111156200013057825182906200011f908262000261565b509160200191906001019062000106565b506200013e92915062000142565b5090565b808211156200013e57600062000159828262000163565b5060010162000142565b5080546200017190620001d2565b6000825580601f1062000182575050565b601f016020900490600052602060002090810190620001a29190620001a5565b50565b5b808211156200013e5760008155600101620001a6565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620001e757607f821691505b6020821081036200020857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200025c57600081815260208120601f850160051c81016020861015620002375750805b601f850160051c820191505b81811015620002585782815560010162000243565b5050505b505050565b81516001600160401b038111156200027d576200027d620001bc565b62000295816200028e8454620001d2565b846200020e565b602080601f831160018114620002cd5760008415620002b45750858301515b600019600386901b1c1916600185901b17855562000258565b600085815260208120601f198616915b82811015620002fe57888601518255948401946001909101908401620002dd565b50858210156200031d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b805180151581146200033e57600080fd5b919050565b600080604083850312156200035757600080fd5b62000362836200032d565b915062000372602084016200032d565b90509250929050565b6112c3806200038b6000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c8063642f6cef11610081578063afb28d1f1161005b578063afb28d1f14610196578063c98f10b01461019e578063fc735e99146101a657600080fd5b8063642f6cef146101465780639525d574146101635780639d6f1cc71461017657600080fd5b80634585e33b116100b25780634585e33b1461010d5780634b56a42e14610120578063601d5a711461013357600080fd5b806305e25131146100ce57806340691db4146100e3575b600080fd5b6100e16100dc3660046109cb565b6101b8565b005b6100f66100f1366004610a7c565b6101cf565b604051610104929190610b57565b60405180910390f35b6100e161011b366004610b7a565b61047f565b6100f661012e366004610bec565b61060e565b6100e1610141366004610ca9565b610664565b6000546101539060ff1681565b6040519015158152602001610104565b6100e1610171366004610ca9565b610670565b610189610184366004610cde565b61067c565b6040516101049190610cf7565b610189610728565b610189610735565b60005461015390610100900460ff1681565b80516101cb9060019060208401906107c8565b5050565b6000606060006101dd610742565b90507fd1ffe9e45581c11d7d9f2ed5f75217cd4be9f8b7eee6af0f6d03f46de53956cd61020d60c0870187610d11565b600081811061021e5761021e610d79565b90506020020135036103f757600061023960c0870187610d11565b600181811061024a5761024a610d79565b9050602002013560405160200161026391815260200190565b604051602081830303815290604052905060008180602001905181019061028a9190610da8565b9050600061029b60c0890189610d11565b60028181106102ac576102ac610d79565b905060200201356040516020016102c591815260200190565b60405160208183030381529060405290506000818060200190518101906102ec9190610da8565b905060006102fd60c08b018b610d11565b600381811061030e5761030e610d79565b9050602002013560405160200161032791815260200190565b604051602081830303815290604052905060008180602001905181019061034e9190610dea565b604080516020810188905290810185905273ffffffffffffffffffffffffffffffffffffffff821660608201529091506002906001906003908a90608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f7ddd933e0000000000000000000000000000000000000000000000000000000082526103ee9594939291600401610ef3565b60405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f636f756c64206e6f742066696e64206d61746368696e67206576656e7420736960448201527f670000000000000000000000000000000000000000000000000000000000000060648201526084016103ee565b60008061048e83850185610bec565b915091506000806000838060200190518101906104ab9190610fb6565b6040805160208101909152600080825254939650919450925090610100900460ff16156105a1577309dff56a4ff44e0f4436260a04f5cfa65636a48173ffffffffffffffffffffffffffffffffffffffff16638e760afe8760008151811061051557610515610d79565b60200260200101516040518263ffffffff1660e01b81526004016105399190610cf7565b6000604051808303816000875af1158015610558573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261059e9190810190610feb565b90505b327f299a03817e683a32b21e29e3ae3c31f1c9c773f7d532836d116b62a9281fbc9d8585856105ce610742565b8b6000815181106105e1576105e1610d79565b6020026020010151876040516105fc96959493929190611062565b60405180910390a25050505050505050565b60006060600084846040516020016106279291906110c2565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052600193509150505b9250929050565b60036101cb828261119c565b60026101cb828261119c565b6001818154811061068c57600080fd5b9060005260206000200160009150905080546106a790610e05565b80601f01602080910402602001604051908101604052809291908181526020018280546106d390610e05565b80156107205780601f106106f557610100808354040283529160200191610720565b820191906000526020600020905b81548152906001019060200180831161070357829003601f168201915b505050505081565b600280546106a790610e05565b600380546106a790610e05565b6000805460ff16156107c357606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561079a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107be9190610da8565b905090565b504390565b82805482825590600052602060002090810192821561080e579160200282015b8281111561080e57825182906107fe908261119c565b50916020019190600101906107e8565b5061081a92915061081e565b5090565b8082111561081a576000610832828261083b565b5060010161081e565b50805461084790610e05565b6000825580601f10610857575050565b601f0160209004906000526020600020908101906108759190610878565b50565b5b8082111561081a5760008155600101610879565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156109035761090361088d565b604052919050565b600067ffffffffffffffff8211156109255761092561088d565b5060051b60200190565b600067ffffffffffffffff8211156109495761094961088d565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261098657600080fd5b81356109996109948261092f565b6108bc565b8181528460208386010111156109ae57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156109de57600080fd5b823567ffffffffffffffff808211156109f657600080fd5b818501915085601f830112610a0a57600080fd5b8135610a186109948261090b565b81815260059190911b83018401908481019088831115610a3757600080fd5b8585015b83811015610a6f57803585811115610a535760008081fd5b610a618b89838a0101610975565b845250918601918601610a3b565b5098975050505050505050565b60008060408385031215610a8f57600080fd5b823567ffffffffffffffff80821115610aa757600080fd5b908401906101008287031215610abc57600080fd5b90925060208401359080821115610ad257600080fd5b50610adf85828601610975565b9150509250929050565b60005b83811015610b04578181015183820152602001610aec565b50506000910152565b60008151808452610b25816020860160208601610ae9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b8215158152604060208201526000610b726040830184610b0d565b949350505050565b60008060208385031215610b8d57600080fd5b823567ffffffffffffffff80821115610ba557600080fd5b818501915085601f830112610bb957600080fd5b813581811115610bc857600080fd5b866020828501011115610bda57600080fd5b60209290920196919550909350505050565b60008060408385031215610bff57600080fd5b823567ffffffffffffffff80821115610c1757600080fd5b818501915085601f830112610c2b57600080fd5b81356020610c3b6109948361090b565b82815260059290921b84018101918181019089841115610c5a57600080fd5b8286015b84811015610c9257803586811115610c765760008081fd5b610c848c86838b0101610975565b845250918301918301610c5e565b5096505086013592505080821115610ad257600080fd5b600060208284031215610cbb57600080fd5b813567ffffffffffffffff811115610cd257600080fd5b610b7284828501610975565b600060208284031215610cf057600080fd5b5035919050565b602081526000610d0a6020830184610b0d565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610d4657600080fd5b83018035915067ffffffffffffffff821115610d6157600080fd5b6020019150600581901b360382131561065d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215610dba57600080fd5b5051919050565b805173ffffffffffffffffffffffffffffffffffffffff81168114610de557600080fd5b919050565b600060208284031215610dfc57600080fd5b610d0a82610dc1565b600181811c90821680610e1957607f821691505b602082108103610e52577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60008154610e6581610e05565b808552602060018381168015610e825760018114610eba57610ee8565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b8901019550610ee8565b866000528260002060005b85811015610ee05781548a8201860152908301908401610ec5565b890184019650505b505050505092915050565b60a081526000610f0660a0830188610e58565b6020838203818501528188548084528284019150828160051b8501018a6000528360002060005b83811015610f78577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0878403018552610f668383610e58565b94860194925060019182019101610f2d565b50508681036040880152610f8c818b610e58565b9450505050508460608401528281036080840152610faa8185610b0d565b98975050505050505050565b600080600060608486031215610fcb57600080fd5b8351925060208401519150610fe260408501610dc1565b90509250925092565b600060208284031215610ffd57600080fd5b815167ffffffffffffffff81111561101457600080fd5b8201601f8101841361102557600080fd5b80516110336109948261092f565b81815285602083850101111561104857600080fd5b611059826020830160208601610ae9565b95945050505050565b86815285602082015273ffffffffffffffffffffffffffffffffffffffff8516604082015283606082015260c0608082015260006110a360c0830185610b0d565b82810360a08401526110b58185610b0d565b9998505050505050505050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015611137577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018552611125868351610b0d565b955093820193908201906001016110eb565b5050858403818701525050506110598185610b0d565b601f82111561119757600081815260208120601f850160051c810160208610156111745750805b601f850160051c820191505b8181101561119357828155600101611180565b5050505b505050565b815167ffffffffffffffff8111156111b6576111b661088d565b6111ca816111c48454610e05565b8461114d565b602080601f83116001811461121d57600084156111e75750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611193565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561126a5788860151825594840194600190910190840161124b565b50858210156112a657878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000810000a307834353534343832643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030", } var LogTriggeredFeedLookupABI = LogTriggeredFeedLookupMetaData.ABI var LogTriggeredFeedLookupBin = LogTriggeredFeedLookupMetaData.Bin -func DeployLogTriggeredFeedLookup(auth *bind.TransactOpts, backend bind.ContractBackend, _useArbitrumBlockNum bool) (common.Address, *types.Transaction, *LogTriggeredFeedLookup, error) { +func DeployLogTriggeredFeedLookup(auth *bind.TransactOpts, backend bind.ContractBackend, _useArbitrumBlockNum bool, _verify bool) (common.Address, *types.Transaction, *LogTriggeredFeedLookup, error) { parsed, err := LogTriggeredFeedLookupMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -59,7 +59,7 @@ func DeployLogTriggeredFeedLookup(auth *bind.TransactOpts, backend bind.Contract return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(LogTriggeredFeedLookupBin), backend, _useArbitrumBlockNum) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(LogTriggeredFeedLookupBin), backend, _useArbitrumBlockNum, _verify) if err != nil { return common.Address{}, nil, nil, err } @@ -182,33 +182,26 @@ func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupTransactorRaw) Transact(opt return _LogTriggeredFeedLookup.Contract.contract.Transact(opts, method, params...) } -func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupCaller) CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (CheckCallback, - - error) { +func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupCaller) CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (bool, []byte, error) { var out []interface{} err := _LogTriggeredFeedLookup.contract.Call(opts, &out, "checkCallback", values, extraData) - outstruct := new(CheckCallback) if err != nil { - return *outstruct, err + return *new(bool), *new([]byte), err } - outstruct.UpkeepNeeded = *abi.ConvertType(out[0], new(bool)).(*bool) - outstruct.PerformData = *abi.ConvertType(out[1], new([]byte)).(*[]byte) + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + out1 := *abi.ConvertType(out[1], new([]byte)).(*[]byte) - return *outstruct, err + return out0, out1, err } -func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupSession) CheckCallback(values [][]byte, extraData []byte) (CheckCallback, - - error) { +func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupSession) CheckCallback(values [][]byte, extraData []byte) (bool, []byte, error) { return _LogTriggeredFeedLookup.Contract.CheckCallback(&_LogTriggeredFeedLookup.CallOpts, values, extraData) } -func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupCallerSession) CheckCallback(values [][]byte, extraData []byte) (CheckCallback, - - error) { +func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupCallerSession) CheckCallback(values [][]byte, extraData []byte) (bool, []byte, error) { return _LogTriggeredFeedLookup.Contract.CheckCallback(&_LogTriggeredFeedLookup.CallOpts, values, extraData) } @@ -300,16 +293,38 @@ func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupCallerSession) UseArbitrumB return _LogTriggeredFeedLookup.Contract.UseArbitrumBlockNum(&_LogTriggeredFeedLookup.CallOpts) } -func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupTransactor) CheckLog(opts *bind.TransactOpts, log Log) (*types.Transaction, error) { - return _LogTriggeredFeedLookup.contract.Transact(opts, "checkLog", log) +func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupCaller) Verify(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _LogTriggeredFeedLookup.contract.Call(opts, &out, "verify") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupSession) Verify() (bool, error) { + return _LogTriggeredFeedLookup.Contract.Verify(&_LogTriggeredFeedLookup.CallOpts) +} + +func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupCallerSession) Verify() (bool, error) { + return _LogTriggeredFeedLookup.Contract.Verify(&_LogTriggeredFeedLookup.CallOpts) } -func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupSession) CheckLog(log Log) (*types.Transaction, error) { - return _LogTriggeredFeedLookup.Contract.CheckLog(&_LogTriggeredFeedLookup.TransactOpts, log) +func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupTransactor) CheckLog(opts *bind.TransactOpts, log Log, arg1 []byte) (*types.Transaction, error) { + return _LogTriggeredFeedLookup.contract.Transact(opts, "checkLog", log, arg1) } -func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupTransactorSession) CheckLog(log Log) (*types.Transaction, error) { - return _LogTriggeredFeedLookup.Contract.CheckLog(&_LogTriggeredFeedLookup.TransactOpts, log) +func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupSession) CheckLog(log Log, arg1 []byte) (*types.Transaction, error) { + return _LogTriggeredFeedLookup.Contract.CheckLog(&_LogTriggeredFeedLookup.TransactOpts, log, arg1) +} + +func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupTransactorSession) CheckLog(log Log, arg1 []byte) (*types.Transaction, error) { + return _LogTriggeredFeedLookup.Contract.CheckLog(&_LogTriggeredFeedLookup.TransactOpts, log, arg1) } func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupTransactor) PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error) { @@ -493,11 +508,6 @@ func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupFilterer) ParsePerformingLo return event, nil } -type CheckCallback struct { - UpkeepNeeded bool - PerformData []byte -} - func (_LogTriggeredFeedLookup *LogTriggeredFeedLookup) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { case _LogTriggeredFeedLookup.abi.Events["PerformingLogTriggerUpkeep"].ID: @@ -517,9 +527,7 @@ func (_LogTriggeredFeedLookup *LogTriggeredFeedLookup) Address() common.Address } type LogTriggeredFeedLookupInterface interface { - CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (CheckCallback, - - error) + CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (bool, []byte, error) FeedParamKey(opts *bind.CallOpts) (string, error) @@ -529,7 +537,9 @@ type LogTriggeredFeedLookupInterface interface { UseArbitrumBlockNum(opts *bind.CallOpts) (bool, error) - CheckLog(opts *bind.TransactOpts, log Log) (*types.Transaction, error) + Verify(opts *bind.CallOpts) (bool, error) + + CheckLog(opts *bind.TransactOpts, log Log, arg1 []byte) (*types.Transaction, error) PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error) diff --git a/core/gethwrappers/generated/log_upkeep_counter_wrapper/log_upkeep_counter_wrapper.go b/core/gethwrappers/generated/log_upkeep_counter_wrapper/log_upkeep_counter_wrapper.go index 46f1dc7bf64..1a6f58fe6b1 100644 --- a/core/gethwrappers/generated/log_upkeep_counter_wrapper/log_upkeep_counter_wrapper.go +++ b/core/gethwrappers/generated/log_upkeep_counter_wrapper/log_upkeep_counter_wrapper.go @@ -42,8 +42,8 @@ type Log struct { } var LogUpkeepCounterMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_testRange\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"initialBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"lastBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"counter\",\"type\":\"uint256\"}],\"name\":\"PerformingUpkeep\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Trigger\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"Trigger\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"b\",\"type\":\"uint256\"}],\"name\":\"Trigger\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"b\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"}],\"name\":\"Trigger\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"txIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"log\",\"type\":\"tuple\"}],\"name\":\"checkLog\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"counter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"previousPerformBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_testRange\",\"type\":\"uint256\"}],\"name\":\"setSpread\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"start\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"testRange\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60806040527f3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d6000557f57b1de35764b0939dde00771c7069cdf8d6a65d6a175623f19aa18784fd4c6da6001557f1da9f70fe932e73fba9374396c5c0b02dbd170f951874b7b4afabe4dd029a9c86002557f5121119bad45ca7e58e0bdadf39045f5111e93ba4304a0f6457a3e7bc9791e716003553480156100a057600080fd5b50604051610f17380380610f178339810160408190526100bf916100da565b600455600060068190554360055560078190556008556100f3565b6000602082840312156100ec57600080fd5b5051919050565b610e15806101026000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c8063917d895f11610076578063be61b7751161005b578063be61b77514610135578063be9a655514610156578063d832d92f1461015e57600080fd5b8063917d895f1461010f578063b66a261c1461011857600080fd5b806361bc221a116100a757806361bc221a146100f45780636250a13a146100fd578063806b984f1461010657600080fd5b80632cb15864146100c35780634585e33b146100df575b600080fd5b6100cc60075481565b6040519081526020015b60405180910390f35b6100f26100ed366004610810565b610176565b005b6100cc60085481565b6100cc60045481565b6100cc60055481565b6100cc60065481565b6100f261012636600461099a565b60045560006007819055600855565b610148610143366004610882565b6103ed565b6040516100d6929190610a4b565b6100f26105d0565b6101666106aa565b60405190151581526020016100d6565b60075461018257436007555b43600555600854610194906001610d4c565b60085560055460065560006101ab828401846108c5565b90506000548160c001516000815181106101c7576101c7610daa565b60200260200101511415610203576040517f3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d90600090a1610395565b6001548160c0015160008151811061021d5761021d610daa565b6020026020010151141561026557604051600181527f57b1de35764b0939dde00771c7069cdf8d6a65d6a175623f19aa18784fd4c6da906020015b60405180910390a1610395565b6002548160c0015160008151811061027f5761027f610daa565b602002602001015114156102c4576040805160018152600260208201527f1da9f70fe932e73fba9374396c5c0b02dbd170f951874b7b4afabe4dd029a9c89101610258565b6003548160c001516000815181106102de576102de610daa565b6020026020010151141561032e576040805160018152600260208201526003918101919091527f5121119bad45ca7e58e0bdadf39045f5111e93ba4304a0f6457a3e7bc9791e7190606001610258565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f636f756c64206e6f742066696e64206d61746368696e6720736967000000000060448201526064015b60405180910390fd5b60075460055460065460085460408051948552602085019390935291830152606082015232907f8e8112f20a2134e18e591d2cdd68cd86a95d06e6328ede501fc6314f4a5075fa9060800160405180910390a2505050565b600060606103f96106aa565b61045f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f6e6f7420656c696769626c650000000000000000000000000000000000000000604482015260640161038c565b60005461046f60c0850185610b99565b600081811061048057610480610daa565b9050602002013514806104b8575060015461049e60c0850185610b99565b60008181106104af576104af610daa565b90506020020135145b806104e857506002546104ce60c0850185610b99565b60008181106104df576104df610daa565b90506020020135145b8061051857506003546104fe60c0850185610b99565b600081811061050f5761050f610daa565b90506020020135145b15610548576001836040516020016105309190610ac8565b60405160208183030381529060405291509150915091565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f636f756c64206e6f742066696e64206d61746368696e67206576656e7420736960448201527f6700000000000000000000000000000000000000000000000000000000000000606482015260840161038c565b6040517f3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d90600090a1604051600181527f57b1de35764b0939dde00771c7069cdf8d6a65d6a175623f19aa18784fd4c6da9060200160405180910390a16040805160018152600260208201527f1da9f70fe932e73fba9374396c5c0b02dbd170f951874b7b4afabe4dd029a9c8910160405180910390a160408051600181526002602082015260038183015290517f5121119bad45ca7e58e0bdadf39045f5111e93ba4304a0f6457a3e7bc9791e719181900360600190a1565b6000600754600014156106bd5750600190565b6004546007546106cd9043610d64565b10905090565b803573ffffffffffffffffffffffffffffffffffffffff811681146106f757600080fd5b919050565b600082601f83011261070d57600080fd5b8135602067ffffffffffffffff82111561072957610729610dd9565b8160051b610738828201610c32565b83815282810190868401838801850189101561075357600080fd5b600093505b85841015610776578035835260019390930192918401918401610758565b50979650505050505050565b600082601f83011261079357600080fd5b813567ffffffffffffffff8111156107ad576107ad610dd9565b6107de60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610c32565b8181528460208386010111156107f357600080fd5b816020850160208301376000918101602001919091529392505050565b6000806020838503121561082357600080fd5b823567ffffffffffffffff8082111561083b57600080fd5b818501915085601f83011261084f57600080fd5b81358181111561085e57600080fd5b86602082850101111561087057600080fd5b60209290920196919550909350505050565b60006020828403121561089457600080fd5b813567ffffffffffffffff8111156108ab57600080fd5b820161010081850312156108be57600080fd5b9392505050565b6000602082840312156108d757600080fd5b813567ffffffffffffffff808211156108ef57600080fd5b90830190610100828603121561090457600080fd5b61090c610c08565b823581526020830135602082015260408301356040820152606083013560608201526080830135608082015261094460a084016106d3565b60a082015260c08301358281111561095b57600080fd5b610967878286016106fc565b60c08301525060e08301358281111561097f57600080fd5b61098b87828601610782565b60e08301525095945050505050565b6000602082840312156109ac57600080fd5b5035919050565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156109e557600080fd5b8260051b8083602087013760009401602001938452509192915050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b821515815260006020604081840152835180604085015260005b81811015610a8157858101830151858201606001528201610a65565b81811115610a93576000606083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201606001949350505050565b6020815281356020820152602082013560408201526040820135606082015260608201356080820152608082013560a082015273ffffffffffffffffffffffffffffffffffffffff610b1c60a084016106d3565b1660c08201526000610b3160c0840184610c81565b6101008060e0860152610b49610120860183856109b3565b9250610b5860e0870187610ce8565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08685030182870152610b8e848483610a02565b979650505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610bce57600080fd5b83018035915067ffffffffffffffff821115610be957600080fd5b6020019150600581901b3603821315610c0157600080fd5b9250929050565b604051610100810167ffffffffffffffff81118282101715610c2c57610c2c610dd9565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610c7957610c79610dd9565b604052919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610cb657600080fd5b830160208101925035905067ffffffffffffffff811115610cd657600080fd5b8060051b3603831315610c0157600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610d1d57600080fd5b830160208101925035905067ffffffffffffffff811115610d3d57600080fd5b803603831315610c0157600080fd5b60008219821115610d5f57610d5f610d7b565b500190565b600082821015610d7657610d76610d7b565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_testRange\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"initialBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"lastBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"counter\",\"type\":\"uint256\"}],\"name\":\"PerformingUpkeep\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Trigger\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"Trigger\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"b\",\"type\":\"uint256\"}],\"name\":\"Trigger\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"b\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"}],\"name\":\"Trigger\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"txIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"log\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"checkLog\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"counter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"previousPerformBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_testRange\",\"type\":\"uint256\"}],\"name\":\"setSpread\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"start\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"testRange\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60806040527f3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d6000557f57b1de35764b0939dde00771c7069cdf8d6a65d6a175623f19aa18784fd4c6da6001557f1da9f70fe932e73fba9374396c5c0b02dbd170f951874b7b4afabe4dd029a9c86002557f5121119bad45ca7e58e0bdadf39045f5111e93ba4304a0f6457a3e7bc9791e716003553480156100a057600080fd5b50604051610f41380380610f418339810160408190526100bf916100da565b600455600060068190554360055560078190556008556100f3565b6000602082840312156100ec57600080fd5b5051919050565b610e3f806101026000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c8063806b984f11610076578063b66a261c1161005b578063b66a261c14610139578063be9a655514610156578063d832d92f1461015e57600080fd5b8063806b984f14610127578063917d895f1461013057600080fd5b80634585e33b116100a75780634585e33b1461010057806361bc221a146101155780636250a13a1461011e57600080fd5b80632cb15864146100c357806340691db4146100df575b600080fd5b6100cc60075481565b6040519081526020015b60405180910390f35b6100f26100ed366004610889565b610176565b6040516100d6929190610a7c565b61011361010e366004610817565b610365565b005b6100cc60085481565b6100cc60045481565b6100cc60055481565b6100cc60065481565b6101136101473660046109cb565b60045560006007819055600855565b6101136105d7565b6101666106b1565b60405190151581526020016100d6565b600060606101826106b1565b6101ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f6e6f7420656c696769626c65000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6000546101fd60c0860186610bca565b600081811061020e5761020e610dd4565b905060200201351480610246575060015461022c60c0860186610bca565b600081811061023d5761023d610dd4565b90506020020135145b80610276575060025461025c60c0860186610bca565b600081811061026d5761026d610dd4565b90506020020135145b806102a6575060035461028c60c0860186610bca565b600081811061029d5761029d610dd4565b90506020020135145b156102d6576001846040516020016102be9190610af9565b6040516020818303038152906040529150915061035e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f636f756c64206e6f742066696e64206d61746368696e67206576656e7420736960448201527f670000000000000000000000000000000000000000000000000000000000000060648201526084016101e4565b9250929050565b60075461037157436007555b43600555600854610383906001610d76565b600855600554600655600061039a828401846108f6565b90506000548160c001516000815181106103b6576103b6610dd4565b602002602001015114156103f2576040517f3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d90600090a161057f565b6001548160c0015160008151811061040c5761040c610dd4565b6020026020010151141561045457604051600181527f57b1de35764b0939dde00771c7069cdf8d6a65d6a175623f19aa18784fd4c6da906020015b60405180910390a161057f565b6002548160c0015160008151811061046e5761046e610dd4565b602002602001015114156104b3576040805160018152600260208201527f1da9f70fe932e73fba9374396c5c0b02dbd170f951874b7b4afabe4dd029a9c89101610447565b6003548160c001516000815181106104cd576104cd610dd4565b6020026020010151141561051d576040805160018152600260208201526003918101919091527f5121119bad45ca7e58e0bdadf39045f5111e93ba4304a0f6457a3e7bc9791e7190606001610447565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f636f756c64206e6f742066696e64206d61746368696e6720736967000000000060448201526064016101e4565b60075460055460065460085460408051948552602085019390935291830152606082015232907f8e8112f20a2134e18e591d2cdd68cd86a95d06e6328ede501fc6314f4a5075fa9060800160405180910390a2505050565b6040517f3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d90600090a1604051600181527f57b1de35764b0939dde00771c7069cdf8d6a65d6a175623f19aa18784fd4c6da9060200160405180910390a16040805160018152600260208201527f1da9f70fe932e73fba9374396c5c0b02dbd170f951874b7b4afabe4dd029a9c8910160405180910390a160408051600181526002602082015260038183015290517f5121119bad45ca7e58e0bdadf39045f5111e93ba4304a0f6457a3e7bc9791e719181900360600190a1565b6000600754600014156106c45750600190565b6004546007546106d49043610d8e565b10905090565b803573ffffffffffffffffffffffffffffffffffffffff811681146106fe57600080fd5b919050565b600082601f83011261071457600080fd5b8135602067ffffffffffffffff82111561073057610730610e03565b8160051b61073f828201610c5c565b83815282810190868401838801850189101561075a57600080fd5b600093505b8584101561077d57803583526001939093019291840191840161075f565b50979650505050505050565b600082601f83011261079a57600080fd5b813567ffffffffffffffff8111156107b4576107b4610e03565b6107e560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610c5c565b8181528460208386010111156107fa57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806020838503121561082a57600080fd5b823567ffffffffffffffff8082111561084257600080fd5b818501915085601f83011261085657600080fd5b81358181111561086557600080fd5b86602082850101111561087757600080fd5b60209290920196919550909350505050565b6000806040838503121561089c57600080fd5b823567ffffffffffffffff808211156108b457600080fd5b9084019061010082870312156108c957600080fd5b909250602084013590808211156108df57600080fd5b506108ec85828601610789565b9150509250929050565b60006020828403121561090857600080fd5b813567ffffffffffffffff8082111561092057600080fd5b90830190610100828603121561093557600080fd5b61093d610c32565b823581526020830135602082015260408301356040820152606083013560608201526080830135608082015261097560a084016106da565b60a082015260c08301358281111561098c57600080fd5b61099887828601610703565b60c08301525060e0830135828111156109b057600080fd5b6109bc87828601610789565b60e08301525095945050505050565b6000602082840312156109dd57600080fd5b5035919050565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115610a1657600080fd5b8260051b8083602087013760009401602001938452509192915050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b821515815260006020604081840152835180604085015260005b81811015610ab257858101830151858201606001528201610a96565b81811115610ac4576000606083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201606001949350505050565b6020815281356020820152602082013560408201526040820135606082015260608201356080820152608082013560a082015273ffffffffffffffffffffffffffffffffffffffff610b4d60a084016106da565b1660c08201526000610b6260c0840184610cab565b6101008060e0860152610b7a610120860183856109e4565b9250610b8960e0870187610d12565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08685030182870152610bbf848483610a33565b979650505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610bff57600080fd5b83018035915067ffffffffffffffff821115610c1a57600080fd5b6020019150600581901b360382131561035e57600080fd5b604051610100810167ffffffffffffffff81118282101715610c5657610c56610e03565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610ca357610ca3610e03565b604052919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610ce057600080fd5b830160208101925035905067ffffffffffffffff811115610d0057600080fd5b8060051b360383131561035e57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610d4757600080fd5b830160208101925035905067ffffffffffffffff811115610d6757600080fd5b80360383131561035e57600080fd5b60008219821115610d8957610d89610da5565b500190565b600082821015610da057610da0610da5565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", } var LogUpkeepCounterABI = LogUpkeepCounterMetaData.ABI @@ -182,9 +182,9 @@ func (_LogUpkeepCounter *LogUpkeepCounterTransactorRaw) Transact(opts *bind.Tran return _LogUpkeepCounter.Contract.contract.Transact(opts, method, params...) } -func (_LogUpkeepCounter *LogUpkeepCounterCaller) CheckLog(opts *bind.CallOpts, log Log) (bool, []byte, error) { +func (_LogUpkeepCounter *LogUpkeepCounterCaller) CheckLog(opts *bind.CallOpts, log Log, arg1 []byte) (bool, []byte, error) { var out []interface{} - err := _LogUpkeepCounter.contract.Call(opts, &out, "checkLog", log) + err := _LogUpkeepCounter.contract.Call(opts, &out, "checkLog", log, arg1) if err != nil { return *new(bool), *new([]byte), err @@ -197,12 +197,12 @@ func (_LogUpkeepCounter *LogUpkeepCounterCaller) CheckLog(opts *bind.CallOpts, l } -func (_LogUpkeepCounter *LogUpkeepCounterSession) CheckLog(log Log) (bool, []byte, error) { - return _LogUpkeepCounter.Contract.CheckLog(&_LogUpkeepCounter.CallOpts, log) +func (_LogUpkeepCounter *LogUpkeepCounterSession) CheckLog(log Log, arg1 []byte) (bool, []byte, error) { + return _LogUpkeepCounter.Contract.CheckLog(&_LogUpkeepCounter.CallOpts, log, arg1) } -func (_LogUpkeepCounter *LogUpkeepCounterCallerSession) CheckLog(log Log) (bool, []byte, error) { - return _LogUpkeepCounter.Contract.CheckLog(&_LogUpkeepCounter.CallOpts, log) +func (_LogUpkeepCounter *LogUpkeepCounterCallerSession) CheckLog(log Log, arg1 []byte) (bool, []byte, error) { + return _LogUpkeepCounter.Contract.CheckLog(&_LogUpkeepCounter.CallOpts, log, arg1) } func (_LogUpkeepCounter *LogUpkeepCounterCaller) Counter(opts *bind.CallOpts) (*big.Int, error) { @@ -1017,7 +1017,7 @@ func (_LogUpkeepCounter *LogUpkeepCounter) Address() common.Address { } type LogUpkeepCounterInterface interface { - CheckLog(opts *bind.CallOpts, log Log) (bool, []byte, error) + CheckLog(opts *bind.CallOpts, log Log, arg1 []byte) (bool, []byte, error) Counter(opts *bind.CallOpts) (*big.Int, error) diff --git a/core/gethwrappers/generated/mercury_upkeep_wrapper/mercury_upkeep_wrapper.go b/core/gethwrappers/generated/mercury_upkeep_wrapper/mercury_upkeep_wrapper.go index 86dab6cf1b4..3233012fb7c 100644 --- a/core/gethwrappers/generated/mercury_upkeep_wrapper/mercury_upkeep_wrapper.go +++ b/core/gethwrappers/generated/mercury_upkeep_wrapper/mercury_upkeep_wrapper.go @@ -32,7 +32,7 @@ var ( var MercuryUpkeepMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_testRange\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_interval\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"_useL1BlockNumber\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"feeds\",\"type\":\"string[]\"},{\"internalType\":\"string\",\"name\":\"timeParamKey\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"FeedLookup\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"origin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"v0\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"v1\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"ed\",\"type\":\"bytes\"}],\"name\":\"MercuryPerformEvent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"callbackReturnBool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"counter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feedParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"feeds\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"interval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"previousPerformBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"value\",\"type\":\"bool\"}],\"name\":\"setCallbackReturnBool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"value\",\"type\":\"bool\"}],\"name\":\"setShouldRevertCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"shouldRevertCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"testRange\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timeParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useL1BlockNumber\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b5060405162001312380380620013128339810160408190526200003491620001f7565b60008381556001839055600281905560038190556004556040805180820190915260098152680cccacac8928890caf60bb1b60208201526006906200007a9082620002dc565b5060405180604001604052806040518060800160405280604281526020016200128e604291398152602001604051806080016040528060428152602001620012d0604291399052620000d190600590600262000120565b5060408051808201909152600b81526a313637b1b5a73ab6b132b960a91b6020820152600790620001039082620002dc565b50151560805250506008805461ff001916610100179055620003a8565b8280548282559060005260206000209081019282156200016b579160200282015b828111156200016b57825182906200015a9082620002dc565b509160200191906001019062000141565b50620001799291506200017d565b5090565b80821115620001795760006200019482826200019e565b506001016200017d565b508054620001ac906200024d565b6000825580601f10620001bd575050565b601f016020900490600052602060002090810190620001dd9190620001e0565b50565b5b80821115620001795760008155600101620001e1565b6000806000606084860312156200020d57600080fd5b8351925060208401519150604084015180151581146200022c57600080fd5b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200026257607f821691505b6020821081036200028357634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002d757600081815260208120601f850160051c81016020861015620002b25750805b601f850160051c820191505b81811015620002d357828155600101620002be565b5050505b505050565b81516001600160401b03811115620002f857620002f862000237565b62000310816200030984546200024d565b8462000289565b602080601f8311600181146200034857600084156200032f5750858301515b600019600386901b1c1916600185901b178555620002d3565b600085815260208120601f198616915b82811015620003795788860151825594840194600190910190840162000358565b5085821015620003985787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b608051610eb5620003d960003960008181610170015281816102bf015281816105ef01526107220152610eb56000f3fe608060405234801561001057600080fd5b506004361061011b5760003560e01c80635b48391a116100b2578063917d895f11610081578063afb28d1f11610066578063afb28d1f146102a3578063c98f10b0146102ab578063d832d92f146102b357600080fd5b8063917d895f14610291578063947a36fb1461029a57600080fd5b80635b48391a1461022757806361bc221a1461026c5780636250a13a146102755780636e04ff0d1461027e57600080fd5b80634585e33b116100ee5780634585e33b146101925780634a5479f3146101a75780634b56a42e146101c75780634bdb3862146101e857600080fd5b806302be021f14610120578063102d538b146101425780632cb15864146101545780632d02b93b1461016b575b600080fd5b60085461012d9060ff1681565b60405190151581526020015b60405180910390f35b60085461012d90610100900460ff1681565b61015d60035481565b604051908152602001610139565b61012d7f000000000000000000000000000000000000000000000000000000000000000081565b6101a56101a03660046107f1565b6102bb565b005b6101ba6101b5366004610863565b610414565b60405161013991906108e7565b6101da6101d5366004610a0d565b6104c0565b604051610139929190610af3565b6101a56101f6366004610b16565b600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b6101a5610235366004610b16565b60088054911515610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909216919091179055565b61015d60045481565b61015d60005481565b6101da61028c3660046107f1565b610593565b61015d60025481565b61015d60015481565b6101ba6106f2565b6101ba6106ff565b61012d61070c565b60007f0000000000000000000000000000000000000000000000000000000000000000156102ea57504361035d565b606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610336573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035a9190610b38565b90505b60035460000361036d5760038190555b60008061037c84860186610a0d565b60028590556004549193509150610394906001610b80565b60045581518390339032907fec3208363089f292bf230caa1cd39f9dc25d98a341b935d9ebd7a95e2ec82af19086906000906103d2576103d2610b98565b6020026020010151866001815181106103ed576103ed610b98565b60200260200101518660405161040593929190610bc7565b60405180910390a45050505050565b6005818154811061042457600080fd5b90600052602060002001600091509050805461043f90610c0a565b80601f016020809104026020016040519081016040528092919081815260200182805461046b90610c0a565b80156104b85780601f1061048d576101008083540402835291602001916104b8565b820191906000526020600020905b81548152906001019060200180831161049b57829003601f168201915b505050505081565b60085460009060609060ff1615610538576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f73686f756c6452657665727443616c6c6261636b20697320747275650000000060448201526064015b60405180910390fd5b6000848460405160200161054d929190610c5d565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018152919052600854610100900460ff1693509150505b9250929050565b6000606061059f61070c565b6105eb576000848481818080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525095975091955061058c945050505050565b60007f00000000000000000000000000000000000000000000000000000000000000001561061a57504361068d565b606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610666573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068a9190610b38565b90505b604080516c6400000000000000000000000060208201528151601481830301815260348201928390527f7ddd933e0000000000000000000000000000000000000000000000000000000090925261052f91600691600591600791869190603801610dce565b6006805461043f90610c0a565b6007805461043f90610c0a565b600060035460000361071e5750600190565b60007f00000000000000000000000000000000000000000000000000000000000000001561074d5750436107c0565b606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610799573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107bd9190610b38565b90505b6000546003546107d09083610e91565b1080156107eb57506001546002546107e89083610e91565b10155b91505090565b6000806020838503121561080457600080fd5b823567ffffffffffffffff8082111561081c57600080fd5b818501915085601f83011261083057600080fd5b81358181111561083f57600080fd5b86602082850101111561085157600080fd5b60209290920196919550909350505050565b60006020828403121561087557600080fd5b5035919050565b6000815180845260005b818110156108a257602081850181015186830182015201610886565b818111156108b4576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006108fa602083018461087c565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561097757610977610901565b604052919050565b600082601f83011261099057600080fd5b813567ffffffffffffffff8111156109aa576109aa610901565b6109db60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610930565b8181528460208386010111156109f057600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215610a2057600080fd5b823567ffffffffffffffff80821115610a3857600080fd5b818501915085601f830112610a4c57600080fd5b8135602082821115610a6057610a60610901565b8160051b610a6f828201610930565b928352848101820192828101908a851115610a8957600080fd5b83870192505b84831015610ac557823586811115610aa75760008081fd5b610ab58c86838b010161097f565b8352509183019190830190610a8f565b9750505086013592505080821115610adc57600080fd5b50610ae98582860161097f565b9150509250929050565b8215158152604060208201526000610b0e604083018461087c565b949350505050565b600060208284031215610b2857600080fd5b813580151581146108fa57600080fd5b600060208284031215610b4a57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610b9357610b93610b51565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b606081526000610bda606083018661087c565b8281036020840152610bec818661087c565b90508281036040840152610c00818561087c565b9695505050505050565b600181811c90821680610c1e57607f821691505b602082108103610c57577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015610cd2577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018552610cc086835161087c565b95509382019390820190600101610c86565b505085840381870152505050610ce8818561087c565b95945050505050565b8054600090600181811c9080831680610d0b57607f831692505b60208084108203610d45577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b838852818015610d5c5760018114610d9457610dc2565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008616828a01528185151560051b8a01019650610dc2565b876000528160002060005b86811015610dba5781548b8201850152908501908301610d9f565b8a0183019750505b50505050505092915050565b60a081526000610de160a0830188610cf1565b6020838203818501528188548084528284019150828160051b8501018a6000528360002060005b83811015610e53577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0878403018552610e418383610cf1565b94860194925060019182019101610e08565b50508681036040880152610e67818b610cf1565b9450505050508460608401528281036080840152610e85818561087c565b98975050505050505050565b600082821015610ea357610ea3610b51565b50039056fea164736f6c634300080f000a307834353534343832643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030307834323534343332643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030", + Bin: "0x60a06040523480156200001157600080fd5b5060405162001308380380620013088339810160408190526200003491620001f7565b60008381556001839055600281905560038190556004556040805180820190915260098152680cccacac892c890caf60bb1b60208201526006906200007a9082620002dc565b50604051806040016040528060405180608001604052806042815260200162001284604291398152602001604051806080016040528060428152602001620012c6604291399052620000d190600590600262000120565b5060408051808201909152600b81526a313637b1b5a73ab6b132b960a91b6020820152600790620001039082620002dc565b50151560805250506008805461ff001916610100179055620003a8565b8280548282559060005260206000209081019282156200016b579160200282015b828111156200016b57825182906200015a9082620002dc565b509160200191906001019062000141565b50620001799291506200017d565b5090565b80821115620001795760006200019482826200019e565b506001016200017d565b508054620001ac906200024d565b6000825580601f10620001bd575050565b601f016020900490600052602060002090810190620001dd9190620001e0565b50565b5b80821115620001795760008155600101620001e1565b6000806000606084860312156200020d57600080fd5b8351925060208401519150604084015180151581146200022c57600080fd5b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200026257607f821691505b6020821081036200028357634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002d757600081815260208120601f850160051c81016020861015620002b25750805b601f850160051c820191505b81811015620002d357828155600101620002be565b5050505b505050565b81516001600160401b03811115620002f857620002f862000237565b62000310816200030984546200024d565b8462000289565b602080601f8311600181146200034857600084156200032f5750858301515b600019600386901b1c1916600185901b178555620002d3565b600085815260208120601f198616915b82811015620003795788860151825594840194600190910190840162000358565b5085821015620003985787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b608051610eab620003d960003960008181610170015281816102bf015281816105ef01526107220152610eab6000f3fe608060405234801561001057600080fd5b506004361061011b5760003560e01c80635b48391a116100b2578063917d895f11610081578063afb28d1f11610066578063afb28d1f146102a3578063c98f10b0146102ab578063d832d92f146102b357600080fd5b8063917d895f14610291578063947a36fb1461029a57600080fd5b80635b48391a1461022757806361bc221a1461026c5780636250a13a146102755780636e04ff0d1461027e57600080fd5b80634585e33b116100ee5780634585e33b146101925780634a5479f3146101a75780634b56a42e146101c75780634bdb3862146101e857600080fd5b806302be021f14610120578063102d538b146101425780632cb15864146101545780632d02b93b1461016b575b600080fd5b60085461012d9060ff1681565b60405190151581526020015b60405180910390f35b60085461012d90610100900460ff1681565b61015d60035481565b604051908152602001610139565b61012d7f000000000000000000000000000000000000000000000000000000000000000081565b6101a56101a03660046107f1565b6102bb565b005b6101ba6101b5366004610863565b610414565b60405161013991906108e0565b6101da6101d5366004610a06565b6104c0565b604051610139929190610aec565b6101a56101f6366004610b0f565b600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b6101a5610235366004610b0f565b60088054911515610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909216919091179055565b61015d60045481565b61015d60005481565b6101da61028c3660046107f1565b610593565b61015d60025481565b61015d60015481565b6101ba6106f2565b6101ba6106ff565b61012d61070c565b60007f0000000000000000000000000000000000000000000000000000000000000000156102ea57504361035d565b606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610336573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035a9190610b31565b90505b60035460000361036d5760038190555b60008061037c84860186610a06565b60028590556004549193509150610394906001610b79565b60045581518390339032907fec3208363089f292bf230caa1cd39f9dc25d98a341b935d9ebd7a95e2ec82af19086906000906103d2576103d2610b92565b6020026020010151866001815181106103ed576103ed610b92565b60200260200101518660405161040593929190610bc1565b60405180910390a45050505050565b6005818154811061042457600080fd5b90600052602060002001600091509050805461043f90610c04565b80601f016020809104026020016040519081016040528092919081815260200182805461046b90610c04565b80156104b85780601f1061048d576101008083540402835291602001916104b8565b820191906000526020600020905b81548152906001019060200180831161049b57829003601f168201915b505050505081565b60085460009060609060ff1615610538576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f73686f756c6452657665727443616c6c6261636b20697320747275650000000060448201526064015b60405180910390fd5b6000848460405160200161054d929190610c57565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018152919052600854610100900460ff1693509150505b9250929050565b6000606061059f61070c565b6105eb576000848481818080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525095975091955061058c945050505050565b60007f00000000000000000000000000000000000000000000000000000000000000001561061a57504361068d565b606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610666573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068a9190610b31565b90505b604080516c6400000000000000000000000060208201528151601481830301815260348201928390527f7ddd933e0000000000000000000000000000000000000000000000000000000090925261052f91600691600591600791869190603801610dc8565b6006805461043f90610c04565b6007805461043f90610c04565b600060035460000361071e5750600190565b60007f00000000000000000000000000000000000000000000000000000000000000001561074d5750436107c0565b606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610799573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107bd9190610b31565b90505b6000546003546107d09083610e8b565b1080156107eb57506001546002546107e89083610e8b565b10155b91505090565b6000806020838503121561080457600080fd5b823567ffffffffffffffff8082111561081c57600080fd5b818501915085601f83011261083057600080fd5b81358181111561083f57600080fd5b86602082850101111561085157600080fd5b60209290920196919550909350505050565b60006020828403121561087557600080fd5b5035919050565b6000815180845260005b818110156108a257602081850181015186830182015201610886565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006108f3602083018461087c565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610970576109706108fa565b604052919050565b600082601f83011261098957600080fd5b813567ffffffffffffffff8111156109a3576109a36108fa565b6109d460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610929565b8181528460208386010111156109e957600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215610a1957600080fd5b823567ffffffffffffffff80821115610a3157600080fd5b818501915085601f830112610a4557600080fd5b8135602082821115610a5957610a596108fa565b8160051b610a68828201610929565b928352848101820192828101908a851115610a8257600080fd5b83870192505b84831015610abe57823586811115610aa05760008081fd5b610aae8c86838b0101610978565b8352509183019190830190610a88565b9750505086013592505080821115610ad557600080fd5b50610ae285828601610978565b9150509250929050565b8215158152604060208201526000610b07604083018461087c565b949350505050565b600060208284031215610b2157600080fd5b813580151581146108f357600080fd5b600060208284031215610b4357600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610b8c57610b8c610b4a565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b606081526000610bd4606083018661087c565b8281036020840152610be6818661087c565b90508281036040840152610bfa818561087c565b9695505050505050565b600181811c90821680610c1857607f821691505b602082108103610c51577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015610ccc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018552610cba86835161087c565b95509382019390820190600101610c80565b505085840381870152505050610ce2818561087c565b95945050505050565b8054600090600181811c9080831680610d0557607f831692505b60208084108203610d3f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b838852818015610d565760018114610d8e57610dbc565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008616828a01528185151560051b8a01019650610dbc565b876000528160002060005b86811015610db45781548b8201850152908501908301610d99565b8a0183019750505b50505050505092915050565b60a081526000610ddb60a0830188610ceb565b6020838203818501528188548084528284019150828160051b8501018a6000528360002060005b83811015610e4d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0878403018552610e3b8383610ceb565b94860194925060019182019101610e02565b50508681036040880152610e61818b610ceb565b9450505050508460608401528281036080840152610e7f818561087c565b98975050505050505050565b81810381811115610b8c57610b8c610b4a56fea164736f6c6343000810000a307834353534343832643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030307834323534343332643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030", } var MercuryUpkeepABI = MercuryUpkeepMetaData.ABI diff --git a/core/gethwrappers/generated/mercury_verifier/mercury_verifier.go b/core/gethwrappers/generated/mercury_verifier/mercury_verifier.go deleted file mode 100644 index b4b449f0530..00000000000 --- a/core/gethwrappers/generated/mercury_verifier/mercury_verifier.go +++ /dev/null @@ -1,1597 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package mercury_verifier - -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 MercuryVerifierMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierProxyAddr\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"CannotDeactivateLatestConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DigestEmpty\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"DigestInactive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"DigestNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSigners\",\"type\":\"uint256\"}],\"name\":\"ExcessSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FaultToleranceMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FeedIdEmpty\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"InactiveFeed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expectedNumSigners\",\"type\":\"uint256\"}],\"name\":\"IncorrectSignatureCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minSigners\",\"type\":\"uint256\"}],\"name\":\"InsufficientSigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"rsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ssLength\",\"type\":\"uint256\"}],\"name\":\"MismatchedSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigDeactivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"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\":\"bytes32[]\",\"name\":\"offchainTransmitters\",\"type\":\"bytes32[]\"},{\"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\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"FeedActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"FeedDeactivated\",\"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\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"name\":\"ReportVerified\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"activateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"activateFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"deactivateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"deactivateFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"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\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"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\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"offchainTransmitters\",\"type\":\"bytes32[]\"},{\"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\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isVerifier\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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\":\"bytes\",\"name\":\"signedReport\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b506040516200200c3803806200200c8339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e95760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b608051611e11620001fb6000396000818161031d01526109180152611e116000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c806379ba50971161008c578063b70d929d11610066578063b70d929d14610221578063ded6307c14610280578063e84f128e14610293578063f2fde38b146102f057600080fd5b806379ba5097146101de5780638da5cb5b146101e657806394d959801461020e57600080fd5b80633dd86430116100bd5780633dd86430146101a357806344a0b2ad146101b8578063564a0a7a146101cb57600080fd5b806301ffc9a7146100e4578063181f5a771461014e5780633d3ac1b514610190575b600080fd5b6101396100f2366004611487565b7fffffffff00000000000000000000000000000000000000000000000000000000167f3d3ac1b5000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b60408051808201909152600e81527f566572696669657220312e302e3000000000000000000000000000000000000060208201525b6040516101459190611534565b61018361019e366004611570565b610303565b6101b66101b13660046115f1565b61049d565b005b6101b66101c6366004611859565b61054f565b6101b66101d93660046115f1565b610a3f565b6101b6610b00565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610145565b6101b661021c366004611931565b610bfd565b61025d61022f3660046115f1565b6000908152600260205260408120600181015490549192909168010000000000000000900463ffffffff1690565b604080519315158452602084019290925263ffffffff1690820152606001610145565b6101b661028e366004611931565b610d5e565b6102cd6102a13660046115f1565b6000908152600260205260409020805460019091015463ffffffff808316936401000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610145565b6101b66102fe366004611953565b610e6f565b60603373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610374576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080808080610386888a018a61196e565b9450945094509450945060008461039c90611a49565b60008181526002602052604090208054919250906c01000000000000000000000000900460ff1615610402576040517f36dbe748000000000000000000000000000000000000000000000000000000008152600481018390526024015b60405180910390fd5b8651600081815260028301602052604090206104218483898985610e83565b61042b8984610f7f565b87516020890120610440818b8a8a8a87610fe7565b60405173ffffffffffffffffffffffffffffffffffffffff8d16815285907f58ca9502e98a536e06e72d680fcc251e5d10b72291a281665a2c2dc0ac30fcc59060200160405180910390a250969c9b505050505050505050505050565b6104a5611263565b60008181526002602052604081208054909163ffffffff90911690036104fa576040517fa25b0b96000000000000000000000000000000000000000000000000000000008152600481018390526024016103f9565b80547fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff16815560405182907ff438564f793525caa89c6e3a26d41e16aa39d1e589747595751e3f3df75cb2b490600090a25050565b85518460ff168060000361058f576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f8211156105d4576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f60248201526044016103f9565b6105df816003611aec565b821161063757816105f1826003611aec565b6105fc906001611b29565b6040517f9dd9e6d8000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016103f9565b61063f611263565b60008981526002602052604081208054909163ffffffff90911690829061066583611b42565b82546101009290920a63ffffffff81810219909316918316021790915582546000925061069a918d91168c8c8c8c8c8c6112e6565b6000818152600284016020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8c16176101001790559091505b8a518160ff1610156108db5760008b8260ff168151811061070057610700611a8e565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610770576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000858152600287016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452600190810190925290912054610100900460ff16908111156107c3576107c3611b65565b14801591506107fe576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff8416815260208101600190526000858152600287016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684526001908101835292208351815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00821681178355928501519193919284927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090921617906101009084908111156108c0576108c0611b65565b02179055509050505050806108d490611b94565b90506106dd565b5060018201546040517f2cc994770000000000000000000000000000000000000000000000000000000081526004810191909152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cc9947790604401600060405180830381600087803b15801561097157600080fd5b505af1158015610985573d6000803e3d6000fd5b505050508a7fa23a88453230b183877098801ff5a8f771a120e2573eea559ce6c4c2e305a4da8360000160049054906101000a900463ffffffff16838560000160009054906101000a900463ffffffff168e8e8e8e8e8e6040516109f199989796959493929190611c34565b60405180910390a281547fffffffffffffffffffffffffffffffffffffffff0000000000000000ffffffff1664010000000063ffffffff431602178255600190910155505050505050505050565b610a47611263565b60008181526002602052604081208054909163ffffffff9091169003610a9c576040517fa25b0b96000000000000000000000000000000000000000000000000000000008152600481018390526024016103f9565b80547fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff166c0100000000000000000000000017815560405182907ffc4f79b8c65b6be1773063461984c0974400d1e99654c79477a092ace83fd06190600090a25050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b81576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016103f9565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610c05611263565b600082815260026020526040902081610c4a576040517fe332262700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260028201602052604081205460ff169003610ca0576040517f8bca631100000000000000000000000000000000000000000000000000000000815260048101849052602481018390526044016103f9565b80600101548203610ce7576040517fa403c01600000000000000000000000000000000000000000000000000000000815260048101849052602481018390526044016103f9565b60008281526002820160205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555183907f0e173bea63a8c59ec70bf87043f2a729693790183f16a1a54b705de9e989cc4c90610d519085815260200190565b60405180910390a2505050565b610d66611263565b600082815260026020526040902081610dab576040517fe332262700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260028201602052604081205460ff169003610e01576040517f8bca631100000000000000000000000000000000000000000000000000000000815260048101849052602481018390526044016103f9565b60008281526002820160205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555183907f54f8872b9b94ebea6577f33576d55847bd8ea22641ccc886b965f6e50bfe774690610d519085815260200190565b610e77611263565b610e8081611392565b50565b8054600090610e969060ff166001611cca565b8254909150610100900460ff16610ee3576040517ffc10a28300000000000000000000000000000000000000000000000000000000815260048101879052602481018690526044016103f9565b8060ff16845114610f2f5783516040517f5348a282000000000000000000000000000000000000000000000000000000008152600481019190915260ff821660248201526044016103f9565b8251845114610f7757835183516040517ff0d31408000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016103f9565b505050505050565b6020820151815463ffffffff600883901c81169168010000000000000000900416811115610fe15782547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff166801000000000000000063ffffffff8316021783555b50505050565b60008686604051602001610ffc929190611ce3565b6040516020818303038152906040528051906020012090506000611030604080518082019091526000808252602082015290565b8651600090815b818110156111fb5760018689836020811061105457611054611a8e565b61106191901a601b611cca565b8c848151811061107357611073611a8e565b60200260200101518c858151811061108d5761108d611a8e565b6020026020010151604051600081526020016040526040516110cb949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156110ed573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526001808d01602090815291859020848601909552845460ff80821686529399509395509085019261010090049091169081111561117257611172611b65565b600181111561118357611183611b65565b90525093506001846020015160018111156111a0576111a0611b65565b146111d7576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836000015160080260ff166001901b85019450806111f490611d1f565b9050611037565b50837e01010101010101010101010101010101010101010101010101010101010101851614611256576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146112e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103f9565b565b6000808946308b8b8b8b8b8b8b60405160200161130c9a99989796959493929190611d57565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e060000000000000000000000000000000000000000000000000000000000001791505098975050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603611411576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103f9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006020828403121561149957600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146114c957600080fd5b9392505050565b6000815180845260005b818110156114f6576020818501810151868301820152016114da565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006114c960208301846114d0565b803573ffffffffffffffffffffffffffffffffffffffff8116811461156b57600080fd5b919050565b60008060006040848603121561158557600080fd5b833567ffffffffffffffff8082111561159d57600080fd5b818601915086601f8301126115b157600080fd5b8135818111156115c057600080fd5b8760208285010111156115d257600080fd5b6020928301955093506115e89186019050611547565b90509250925092565b60006020828403121561160357600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561165c5761165c61160a565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156116a9576116a961160a565b604052919050565b600067ffffffffffffffff8211156116cb576116cb61160a565b5060051b60200190565b600082601f8301126116e657600080fd5b813560206116fb6116f6836116b1565b611662565b82815260059290921b8401810191818101908684111561171a57600080fd5b8286015b8481101561173c5761172f81611547565b835291830191830161171e565b509695505050505050565b600082601f83011261175857600080fd5b813560206117686116f6836116b1565b82815260059290921b8401810191818101908684111561178757600080fd5b8286015b8481101561173c578035835291830191830161178b565b803560ff8116811461156b57600080fd5b600082601f8301126117c457600080fd5b813567ffffffffffffffff8111156117de576117de61160a565b61180f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611662565b81815284602083860101111561182457600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff8116811461156b57600080fd5b600080600080600080600060e0888a03121561187457600080fd5b87359650602088013567ffffffffffffffff8082111561189357600080fd5b61189f8b838c016116d5565b975060408a01359150808211156118b557600080fd5b6118c18b838c01611747565b96506118cf60608b016117a2565b955060808a01359150808211156118e557600080fd5b6118f18b838c016117b3565b94506118ff60a08b01611841565b935060c08a013591508082111561191557600080fd5b506119228a828b016117b3565b91505092959891949750929550565b6000806040838503121561194457600080fd5b50508035926020909101359150565b60006020828403121561196557600080fd5b6114c982611547565b600080600080600060e0868803121561198657600080fd5b86601f87011261199557600080fd5b61199d611639565b8060608801898111156119af57600080fd5b885b818110156119c95780358452602093840193016119b1565b5090965035905067ffffffffffffffff808211156119e657600080fd5b6119f289838a016117b3565b95506080880135915080821115611a0857600080fd5b611a1489838a01611747565b945060a0880135915080821115611a2a57600080fd5b50611a3788828901611747565b9598949750929560c001359392505050565b80516020808301519190811015611a88577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611b2457611b24611abd565b500290565b80820180821115611b3c57611b3c611abd565b92915050565b600063ffffffff808316818103611b5b57611b5b611abd565b6001019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060ff821660ff8103611baa57611baa611abd565b60010192915050565b600081518084526020808501945080840160005b83811015611bf957815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101611bc7565b509495945050505050565b600081518084526020808501945080840160005b83811015611bf957815187529582019590820190600101611c18565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152611c648184018a611bb3565b90508281036080840152611c788189611c04565b905060ff871660a084015282810360c0840152611c9581876114d0565b905067ffffffffffffffff851660e0840152828103610100840152611cba81856114d0565b9c9b505050505050505050505050565b60ff8181168382160190811115611b3c57611b3c611abd565b828152600060208083018460005b6003811015611d0e57815183529183019190830190600101611cf1565b505050506080820190509392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611d5057611d50611abd565b5060010190565b60006101408c83528b602084015273ffffffffffffffffffffffffffffffffffffffff8b16604084015267ffffffffffffffff808b166060850152816080850152611da48285018b611bb3565b915083820360a0850152611db8828a611c04565b915060ff881660c085015283820360e0850152611dd582886114d0565b9086166101008501528381036101208501529050611df381856114d0565b9d9c5050505050505050505050505056fea164736f6c6343000810000a", -} - -var MercuryVerifierABI = MercuryVerifierMetaData.ABI - -var MercuryVerifierBin = MercuryVerifierMetaData.Bin - -func DeployMercuryVerifier(auth *bind.TransactOpts, backend bind.ContractBackend, verifierProxyAddr common.Address) (common.Address, *types.Transaction, *MercuryVerifier, error) { - parsed, err := MercuryVerifierMetaData.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(MercuryVerifierBin), backend, verifierProxyAddr) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &MercuryVerifier{MercuryVerifierCaller: MercuryVerifierCaller{contract: contract}, MercuryVerifierTransactor: MercuryVerifierTransactor{contract: contract}, MercuryVerifierFilterer: MercuryVerifierFilterer{contract: contract}}, nil -} - -type MercuryVerifier struct { - address common.Address - abi abi.ABI - MercuryVerifierCaller - MercuryVerifierTransactor - MercuryVerifierFilterer -} - -type MercuryVerifierCaller struct { - contract *bind.BoundContract -} - -type MercuryVerifierTransactor struct { - contract *bind.BoundContract -} - -type MercuryVerifierFilterer struct { - contract *bind.BoundContract -} - -type MercuryVerifierSession struct { - Contract *MercuryVerifier - CallOpts bind.CallOpts - TransactOpts bind.TransactOpts -} - -type MercuryVerifierCallerSession struct { - Contract *MercuryVerifierCaller - CallOpts bind.CallOpts -} - -type MercuryVerifierTransactorSession struct { - Contract *MercuryVerifierTransactor - TransactOpts bind.TransactOpts -} - -type MercuryVerifierRaw struct { - Contract *MercuryVerifier -} - -type MercuryVerifierCallerRaw struct { - Contract *MercuryVerifierCaller -} - -type MercuryVerifierTransactorRaw struct { - Contract *MercuryVerifierTransactor -} - -func NewMercuryVerifier(address common.Address, backend bind.ContractBackend) (*MercuryVerifier, error) { - abi, err := abi.JSON(strings.NewReader(MercuryVerifierABI)) - if err != nil { - return nil, err - } - contract, err := bindMercuryVerifier(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &MercuryVerifier{address: address, abi: abi, MercuryVerifierCaller: MercuryVerifierCaller{contract: contract}, MercuryVerifierTransactor: MercuryVerifierTransactor{contract: contract}, MercuryVerifierFilterer: MercuryVerifierFilterer{contract: contract}}, nil -} - -func NewMercuryVerifierCaller(address common.Address, caller bind.ContractCaller) (*MercuryVerifierCaller, error) { - contract, err := bindMercuryVerifier(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &MercuryVerifierCaller{contract: contract}, nil -} - -func NewMercuryVerifierTransactor(address common.Address, transactor bind.ContractTransactor) (*MercuryVerifierTransactor, error) { - contract, err := bindMercuryVerifier(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &MercuryVerifierTransactor{contract: contract}, nil -} - -func NewMercuryVerifierFilterer(address common.Address, filterer bind.ContractFilterer) (*MercuryVerifierFilterer, error) { - contract, err := bindMercuryVerifier(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &MercuryVerifierFilterer{contract: contract}, nil -} - -func bindMercuryVerifier(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := MercuryVerifierMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -func (_MercuryVerifier *MercuryVerifierRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _MercuryVerifier.Contract.MercuryVerifierCaller.contract.Call(opts, result, method, params...) -} - -func (_MercuryVerifier *MercuryVerifierRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _MercuryVerifier.Contract.MercuryVerifierTransactor.contract.Transfer(opts) -} - -func (_MercuryVerifier *MercuryVerifierRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _MercuryVerifier.Contract.MercuryVerifierTransactor.contract.Transact(opts, method, params...) -} - -func (_MercuryVerifier *MercuryVerifierCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _MercuryVerifier.Contract.contract.Call(opts, result, method, params...) -} - -func (_MercuryVerifier *MercuryVerifierTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _MercuryVerifier.Contract.contract.Transfer(opts) -} - -func (_MercuryVerifier *MercuryVerifierTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _MercuryVerifier.Contract.contract.Transact(opts, method, params...) -} - -func (_MercuryVerifier *MercuryVerifierCaller) LatestConfigDetails(opts *bind.CallOpts, feedId [32]byte) (LatestConfigDetails, - - error) { - var out []interface{} - err := _MercuryVerifier.contract.Call(opts, &out, "latestConfigDetails", feedId) - - 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 (_MercuryVerifier *MercuryVerifierSession) LatestConfigDetails(feedId [32]byte) (LatestConfigDetails, - - error) { - return _MercuryVerifier.Contract.LatestConfigDetails(&_MercuryVerifier.CallOpts, feedId) -} - -func (_MercuryVerifier *MercuryVerifierCallerSession) LatestConfigDetails(feedId [32]byte) (LatestConfigDetails, - - error) { - return _MercuryVerifier.Contract.LatestConfigDetails(&_MercuryVerifier.CallOpts, feedId) -} - -func (_MercuryVerifier *MercuryVerifierCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts, feedId [32]byte) (LatestConfigDigestAndEpoch, - - error) { - var out []interface{} - err := _MercuryVerifier.contract.Call(opts, &out, "latestConfigDigestAndEpoch", feedId) - - 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 (_MercuryVerifier *MercuryVerifierSession) LatestConfigDigestAndEpoch(feedId [32]byte) (LatestConfigDigestAndEpoch, - - error) { - return _MercuryVerifier.Contract.LatestConfigDigestAndEpoch(&_MercuryVerifier.CallOpts, feedId) -} - -func (_MercuryVerifier *MercuryVerifierCallerSession) LatestConfigDigestAndEpoch(feedId [32]byte) (LatestConfigDigestAndEpoch, - - error) { - return _MercuryVerifier.Contract.LatestConfigDigestAndEpoch(&_MercuryVerifier.CallOpts, feedId) -} - -func (_MercuryVerifier *MercuryVerifierCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _MercuryVerifier.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 (_MercuryVerifier *MercuryVerifierSession) Owner() (common.Address, error) { - return _MercuryVerifier.Contract.Owner(&_MercuryVerifier.CallOpts) -} - -func (_MercuryVerifier *MercuryVerifierCallerSession) Owner() (common.Address, error) { - return _MercuryVerifier.Contract.Owner(&_MercuryVerifier.CallOpts) -} - -func (_MercuryVerifier *MercuryVerifierCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { - var out []interface{} - err := _MercuryVerifier.contract.Call(opts, &out, "supportsInterface", interfaceId) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -func (_MercuryVerifier *MercuryVerifierSession) SupportsInterface(interfaceId [4]byte) (bool, error) { - return _MercuryVerifier.Contract.SupportsInterface(&_MercuryVerifier.CallOpts, interfaceId) -} - -func (_MercuryVerifier *MercuryVerifierCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { - return _MercuryVerifier.Contract.SupportsInterface(&_MercuryVerifier.CallOpts, interfaceId) -} - -func (_MercuryVerifier *MercuryVerifierCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { - var out []interface{} - err := _MercuryVerifier.contract.Call(opts, &out, "typeAndVersion") - - if err != nil { - return *new(string), err - } - - out0 := *abi.ConvertType(out[0], new(string)).(*string) - - return out0, err - -} - -func (_MercuryVerifier *MercuryVerifierSession) TypeAndVersion() (string, error) { - return _MercuryVerifier.Contract.TypeAndVersion(&_MercuryVerifier.CallOpts) -} - -func (_MercuryVerifier *MercuryVerifierCallerSession) TypeAndVersion() (string, error) { - return _MercuryVerifier.Contract.TypeAndVersion(&_MercuryVerifier.CallOpts) -} - -func (_MercuryVerifier *MercuryVerifierTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _MercuryVerifier.contract.Transact(opts, "acceptOwnership") -} - -func (_MercuryVerifier *MercuryVerifierSession) AcceptOwnership() (*types.Transaction, error) { - return _MercuryVerifier.Contract.AcceptOwnership(&_MercuryVerifier.TransactOpts) -} - -func (_MercuryVerifier *MercuryVerifierTransactorSession) AcceptOwnership() (*types.Transaction, error) { - return _MercuryVerifier.Contract.AcceptOwnership(&_MercuryVerifier.TransactOpts) -} - -func (_MercuryVerifier *MercuryVerifierTransactor) ActivateConfig(opts *bind.TransactOpts, feedId [32]byte, configDigest [32]byte) (*types.Transaction, error) { - return _MercuryVerifier.contract.Transact(opts, "activateConfig", feedId, configDigest) -} - -func (_MercuryVerifier *MercuryVerifierSession) ActivateConfig(feedId [32]byte, configDigest [32]byte) (*types.Transaction, error) { - return _MercuryVerifier.Contract.ActivateConfig(&_MercuryVerifier.TransactOpts, feedId, configDigest) -} - -func (_MercuryVerifier *MercuryVerifierTransactorSession) ActivateConfig(feedId [32]byte, configDigest [32]byte) (*types.Transaction, error) { - return _MercuryVerifier.Contract.ActivateConfig(&_MercuryVerifier.TransactOpts, feedId, configDigest) -} - -func (_MercuryVerifier *MercuryVerifierTransactor) ActivateFeed(opts *bind.TransactOpts, feedId [32]byte) (*types.Transaction, error) { - return _MercuryVerifier.contract.Transact(opts, "activateFeed", feedId) -} - -func (_MercuryVerifier *MercuryVerifierSession) ActivateFeed(feedId [32]byte) (*types.Transaction, error) { - return _MercuryVerifier.Contract.ActivateFeed(&_MercuryVerifier.TransactOpts, feedId) -} - -func (_MercuryVerifier *MercuryVerifierTransactorSession) ActivateFeed(feedId [32]byte) (*types.Transaction, error) { - return _MercuryVerifier.Contract.ActivateFeed(&_MercuryVerifier.TransactOpts, feedId) -} - -func (_MercuryVerifier *MercuryVerifierTransactor) DeactivateConfig(opts *bind.TransactOpts, feedId [32]byte, configDigest [32]byte) (*types.Transaction, error) { - return _MercuryVerifier.contract.Transact(opts, "deactivateConfig", feedId, configDigest) -} - -func (_MercuryVerifier *MercuryVerifierSession) DeactivateConfig(feedId [32]byte, configDigest [32]byte) (*types.Transaction, error) { - return _MercuryVerifier.Contract.DeactivateConfig(&_MercuryVerifier.TransactOpts, feedId, configDigest) -} - -func (_MercuryVerifier *MercuryVerifierTransactorSession) DeactivateConfig(feedId [32]byte, configDigest [32]byte) (*types.Transaction, error) { - return _MercuryVerifier.Contract.DeactivateConfig(&_MercuryVerifier.TransactOpts, feedId, configDigest) -} - -func (_MercuryVerifier *MercuryVerifierTransactor) DeactivateFeed(opts *bind.TransactOpts, feedId [32]byte) (*types.Transaction, error) { - return _MercuryVerifier.contract.Transact(opts, "deactivateFeed", feedId) -} - -func (_MercuryVerifier *MercuryVerifierSession) DeactivateFeed(feedId [32]byte) (*types.Transaction, error) { - return _MercuryVerifier.Contract.DeactivateFeed(&_MercuryVerifier.TransactOpts, feedId) -} - -func (_MercuryVerifier *MercuryVerifierTransactorSession) DeactivateFeed(feedId [32]byte) (*types.Transaction, error) { - return _MercuryVerifier.Contract.DeactivateFeed(&_MercuryVerifier.TransactOpts, feedId) -} - -func (_MercuryVerifier *MercuryVerifierTransactor) SetConfig(opts *bind.TransactOpts, feedId [32]byte, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { - return _MercuryVerifier.contract.Transact(opts, "setConfig", feedId, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) -} - -func (_MercuryVerifier *MercuryVerifierSession) SetConfig(feedId [32]byte, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { - return _MercuryVerifier.Contract.SetConfig(&_MercuryVerifier.TransactOpts, feedId, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) -} - -func (_MercuryVerifier *MercuryVerifierTransactorSession) SetConfig(feedId [32]byte, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { - return _MercuryVerifier.Contract.SetConfig(&_MercuryVerifier.TransactOpts, feedId, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) -} - -func (_MercuryVerifier *MercuryVerifierTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _MercuryVerifier.contract.Transact(opts, "transferOwnership", to) -} - -func (_MercuryVerifier *MercuryVerifierSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _MercuryVerifier.Contract.TransferOwnership(&_MercuryVerifier.TransactOpts, to) -} - -func (_MercuryVerifier *MercuryVerifierTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _MercuryVerifier.Contract.TransferOwnership(&_MercuryVerifier.TransactOpts, to) -} - -func (_MercuryVerifier *MercuryVerifierTransactor) Verify(opts *bind.TransactOpts, signedReport []byte, sender common.Address) (*types.Transaction, error) { - return _MercuryVerifier.contract.Transact(opts, "verify", signedReport, sender) -} - -func (_MercuryVerifier *MercuryVerifierSession) Verify(signedReport []byte, sender common.Address) (*types.Transaction, error) { - return _MercuryVerifier.Contract.Verify(&_MercuryVerifier.TransactOpts, signedReport, sender) -} - -func (_MercuryVerifier *MercuryVerifierTransactorSession) Verify(signedReport []byte, sender common.Address) (*types.Transaction, error) { - return _MercuryVerifier.Contract.Verify(&_MercuryVerifier.TransactOpts, signedReport, sender) -} - -type MercuryVerifierConfigActivatedIterator struct { - Event *MercuryVerifierConfigActivated - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *MercuryVerifierConfigActivatedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(MercuryVerifierConfigActivated) - 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(MercuryVerifierConfigActivated) - 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 *MercuryVerifierConfigActivatedIterator) Error() error { - return it.fail -} - -func (it *MercuryVerifierConfigActivatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type MercuryVerifierConfigActivated struct { - FeedId [32]byte - ConfigDigest [32]byte - Raw types.Log -} - -func (_MercuryVerifier *MercuryVerifierFilterer) FilterConfigActivated(opts *bind.FilterOpts, feedId [][32]byte) (*MercuryVerifierConfigActivatedIterator, error) { - - var feedIdRule []interface{} - for _, feedIdItem := range feedId { - feedIdRule = append(feedIdRule, feedIdItem) - } - - logs, sub, err := _MercuryVerifier.contract.FilterLogs(opts, "ConfigActivated", feedIdRule) - if err != nil { - return nil, err - } - return &MercuryVerifierConfigActivatedIterator{contract: _MercuryVerifier.contract, event: "ConfigActivated", logs: logs, sub: sub}, nil -} - -func (_MercuryVerifier *MercuryVerifierFilterer) WatchConfigActivated(opts *bind.WatchOpts, sink chan<- *MercuryVerifierConfigActivated, feedId [][32]byte) (event.Subscription, error) { - - var feedIdRule []interface{} - for _, feedIdItem := range feedId { - feedIdRule = append(feedIdRule, feedIdItem) - } - - logs, sub, err := _MercuryVerifier.contract.WatchLogs(opts, "ConfigActivated", feedIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(MercuryVerifierConfigActivated) - if err := _MercuryVerifier.contract.UnpackLog(event, "ConfigActivated", 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 (_MercuryVerifier *MercuryVerifierFilterer) ParseConfigActivated(log types.Log) (*MercuryVerifierConfigActivated, error) { - event := new(MercuryVerifierConfigActivated) - if err := _MercuryVerifier.contract.UnpackLog(event, "ConfigActivated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type MercuryVerifierConfigDeactivatedIterator struct { - Event *MercuryVerifierConfigDeactivated - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *MercuryVerifierConfigDeactivatedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(MercuryVerifierConfigDeactivated) - 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(MercuryVerifierConfigDeactivated) - 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 *MercuryVerifierConfigDeactivatedIterator) Error() error { - return it.fail -} - -func (it *MercuryVerifierConfigDeactivatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type MercuryVerifierConfigDeactivated struct { - FeedId [32]byte - ConfigDigest [32]byte - Raw types.Log -} - -func (_MercuryVerifier *MercuryVerifierFilterer) FilterConfigDeactivated(opts *bind.FilterOpts, feedId [][32]byte) (*MercuryVerifierConfigDeactivatedIterator, error) { - - var feedIdRule []interface{} - for _, feedIdItem := range feedId { - feedIdRule = append(feedIdRule, feedIdItem) - } - - logs, sub, err := _MercuryVerifier.contract.FilterLogs(opts, "ConfigDeactivated", feedIdRule) - if err != nil { - return nil, err - } - return &MercuryVerifierConfigDeactivatedIterator{contract: _MercuryVerifier.contract, event: "ConfigDeactivated", logs: logs, sub: sub}, nil -} - -func (_MercuryVerifier *MercuryVerifierFilterer) WatchConfigDeactivated(opts *bind.WatchOpts, sink chan<- *MercuryVerifierConfigDeactivated, feedId [][32]byte) (event.Subscription, error) { - - var feedIdRule []interface{} - for _, feedIdItem := range feedId { - feedIdRule = append(feedIdRule, feedIdItem) - } - - logs, sub, err := _MercuryVerifier.contract.WatchLogs(opts, "ConfigDeactivated", feedIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(MercuryVerifierConfigDeactivated) - if err := _MercuryVerifier.contract.UnpackLog(event, "ConfigDeactivated", 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 (_MercuryVerifier *MercuryVerifierFilterer) ParseConfigDeactivated(log types.Log) (*MercuryVerifierConfigDeactivated, error) { - event := new(MercuryVerifierConfigDeactivated) - if err := _MercuryVerifier.contract.UnpackLog(event, "ConfigDeactivated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type MercuryVerifierConfigSetIterator struct { - Event *MercuryVerifierConfigSet - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *MercuryVerifierConfigSetIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(MercuryVerifierConfigSet) - 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(MercuryVerifierConfigSet) - 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 *MercuryVerifierConfigSetIterator) Error() error { - return it.fail -} - -func (it *MercuryVerifierConfigSetIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type MercuryVerifierConfigSet struct { - FeedId [32]byte - PreviousConfigBlockNumber uint32 - ConfigDigest [32]byte - ConfigCount uint64 - Signers []common.Address - OffchainTransmitters [][32]byte - F uint8 - OnchainConfig []byte - OffchainConfigVersion uint64 - OffchainConfig []byte - Raw types.Log -} - -func (_MercuryVerifier *MercuryVerifierFilterer) FilterConfigSet(opts *bind.FilterOpts, feedId [][32]byte) (*MercuryVerifierConfigSetIterator, error) { - - var feedIdRule []interface{} - for _, feedIdItem := range feedId { - feedIdRule = append(feedIdRule, feedIdItem) - } - - logs, sub, err := _MercuryVerifier.contract.FilterLogs(opts, "ConfigSet", feedIdRule) - if err != nil { - return nil, err - } - return &MercuryVerifierConfigSetIterator{contract: _MercuryVerifier.contract, event: "ConfigSet", logs: logs, sub: sub}, nil -} - -func (_MercuryVerifier *MercuryVerifierFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *MercuryVerifierConfigSet, feedId [][32]byte) (event.Subscription, error) { - - var feedIdRule []interface{} - for _, feedIdItem := range feedId { - feedIdRule = append(feedIdRule, feedIdItem) - } - - logs, sub, err := _MercuryVerifier.contract.WatchLogs(opts, "ConfigSet", feedIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(MercuryVerifierConfigSet) - if err := _MercuryVerifier.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 (_MercuryVerifier *MercuryVerifierFilterer) ParseConfigSet(log types.Log) (*MercuryVerifierConfigSet, error) { - event := new(MercuryVerifierConfigSet) - if err := _MercuryVerifier.contract.UnpackLog(event, "ConfigSet", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type MercuryVerifierFeedActivatedIterator struct { - Event *MercuryVerifierFeedActivated - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *MercuryVerifierFeedActivatedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(MercuryVerifierFeedActivated) - 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(MercuryVerifierFeedActivated) - 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 *MercuryVerifierFeedActivatedIterator) Error() error { - return it.fail -} - -func (it *MercuryVerifierFeedActivatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type MercuryVerifierFeedActivated struct { - FeedId [32]byte - Raw types.Log -} - -func (_MercuryVerifier *MercuryVerifierFilterer) FilterFeedActivated(opts *bind.FilterOpts, feedId [][32]byte) (*MercuryVerifierFeedActivatedIterator, error) { - - var feedIdRule []interface{} - for _, feedIdItem := range feedId { - feedIdRule = append(feedIdRule, feedIdItem) - } - - logs, sub, err := _MercuryVerifier.contract.FilterLogs(opts, "FeedActivated", feedIdRule) - if err != nil { - return nil, err - } - return &MercuryVerifierFeedActivatedIterator{contract: _MercuryVerifier.contract, event: "FeedActivated", logs: logs, sub: sub}, nil -} - -func (_MercuryVerifier *MercuryVerifierFilterer) WatchFeedActivated(opts *bind.WatchOpts, sink chan<- *MercuryVerifierFeedActivated, feedId [][32]byte) (event.Subscription, error) { - - var feedIdRule []interface{} - for _, feedIdItem := range feedId { - feedIdRule = append(feedIdRule, feedIdItem) - } - - logs, sub, err := _MercuryVerifier.contract.WatchLogs(opts, "FeedActivated", feedIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(MercuryVerifierFeedActivated) - if err := _MercuryVerifier.contract.UnpackLog(event, "FeedActivated", 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 (_MercuryVerifier *MercuryVerifierFilterer) ParseFeedActivated(log types.Log) (*MercuryVerifierFeedActivated, error) { - event := new(MercuryVerifierFeedActivated) - if err := _MercuryVerifier.contract.UnpackLog(event, "FeedActivated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type MercuryVerifierFeedDeactivatedIterator struct { - Event *MercuryVerifierFeedDeactivated - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *MercuryVerifierFeedDeactivatedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(MercuryVerifierFeedDeactivated) - 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(MercuryVerifierFeedDeactivated) - 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 *MercuryVerifierFeedDeactivatedIterator) Error() error { - return it.fail -} - -func (it *MercuryVerifierFeedDeactivatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type MercuryVerifierFeedDeactivated struct { - FeedId [32]byte - Raw types.Log -} - -func (_MercuryVerifier *MercuryVerifierFilterer) FilterFeedDeactivated(opts *bind.FilterOpts, feedId [][32]byte) (*MercuryVerifierFeedDeactivatedIterator, error) { - - var feedIdRule []interface{} - for _, feedIdItem := range feedId { - feedIdRule = append(feedIdRule, feedIdItem) - } - - logs, sub, err := _MercuryVerifier.contract.FilterLogs(opts, "FeedDeactivated", feedIdRule) - if err != nil { - return nil, err - } - return &MercuryVerifierFeedDeactivatedIterator{contract: _MercuryVerifier.contract, event: "FeedDeactivated", logs: logs, sub: sub}, nil -} - -func (_MercuryVerifier *MercuryVerifierFilterer) WatchFeedDeactivated(opts *bind.WatchOpts, sink chan<- *MercuryVerifierFeedDeactivated, feedId [][32]byte) (event.Subscription, error) { - - var feedIdRule []interface{} - for _, feedIdItem := range feedId { - feedIdRule = append(feedIdRule, feedIdItem) - } - - logs, sub, err := _MercuryVerifier.contract.WatchLogs(opts, "FeedDeactivated", feedIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(MercuryVerifierFeedDeactivated) - if err := _MercuryVerifier.contract.UnpackLog(event, "FeedDeactivated", 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 (_MercuryVerifier *MercuryVerifierFilterer) ParseFeedDeactivated(log types.Log) (*MercuryVerifierFeedDeactivated, error) { - event := new(MercuryVerifierFeedDeactivated) - if err := _MercuryVerifier.contract.UnpackLog(event, "FeedDeactivated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type MercuryVerifierOwnershipTransferRequestedIterator struct { - Event *MercuryVerifierOwnershipTransferRequested - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *MercuryVerifierOwnershipTransferRequestedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(MercuryVerifierOwnershipTransferRequested) - 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(MercuryVerifierOwnershipTransferRequested) - 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 *MercuryVerifierOwnershipTransferRequestedIterator) Error() error { - return it.fail -} - -func (it *MercuryVerifierOwnershipTransferRequestedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type MercuryVerifierOwnershipTransferRequested struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_MercuryVerifier *MercuryVerifierFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MercuryVerifierOwnershipTransferRequestedIterator, 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 := _MercuryVerifier.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) - if err != nil { - return nil, err - } - return &MercuryVerifierOwnershipTransferRequestedIterator{contract: _MercuryVerifier.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil -} - -func (_MercuryVerifier *MercuryVerifierFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *MercuryVerifierOwnershipTransferRequested, 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 := _MercuryVerifier.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(MercuryVerifierOwnershipTransferRequested) - if err := _MercuryVerifier.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 (_MercuryVerifier *MercuryVerifierFilterer) ParseOwnershipTransferRequested(log types.Log) (*MercuryVerifierOwnershipTransferRequested, error) { - event := new(MercuryVerifierOwnershipTransferRequested) - if err := _MercuryVerifier.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type MercuryVerifierOwnershipTransferredIterator struct { - Event *MercuryVerifierOwnershipTransferred - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *MercuryVerifierOwnershipTransferredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(MercuryVerifierOwnershipTransferred) - 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(MercuryVerifierOwnershipTransferred) - 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 *MercuryVerifierOwnershipTransferredIterator) Error() error { - return it.fail -} - -func (it *MercuryVerifierOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type MercuryVerifierOwnershipTransferred struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_MercuryVerifier *MercuryVerifierFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MercuryVerifierOwnershipTransferredIterator, 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 := _MercuryVerifier.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) - if err != nil { - return nil, err - } - return &MercuryVerifierOwnershipTransferredIterator{contract: _MercuryVerifier.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil -} - -func (_MercuryVerifier *MercuryVerifierFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *MercuryVerifierOwnershipTransferred, 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 := _MercuryVerifier.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(MercuryVerifierOwnershipTransferred) - if err := _MercuryVerifier.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 (_MercuryVerifier *MercuryVerifierFilterer) ParseOwnershipTransferred(log types.Log) (*MercuryVerifierOwnershipTransferred, error) { - event := new(MercuryVerifierOwnershipTransferred) - if err := _MercuryVerifier.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type MercuryVerifierReportVerifiedIterator struct { - Event *MercuryVerifierReportVerified - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *MercuryVerifierReportVerifiedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(MercuryVerifierReportVerified) - 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(MercuryVerifierReportVerified) - 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 *MercuryVerifierReportVerifiedIterator) Error() error { - return it.fail -} - -func (it *MercuryVerifierReportVerifiedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type MercuryVerifierReportVerified struct { - FeedId [32]byte - Requester common.Address - Raw types.Log -} - -func (_MercuryVerifier *MercuryVerifierFilterer) FilterReportVerified(opts *bind.FilterOpts, feedId [][32]byte) (*MercuryVerifierReportVerifiedIterator, error) { - - var feedIdRule []interface{} - for _, feedIdItem := range feedId { - feedIdRule = append(feedIdRule, feedIdItem) - } - - logs, sub, err := _MercuryVerifier.contract.FilterLogs(opts, "ReportVerified", feedIdRule) - if err != nil { - return nil, err - } - return &MercuryVerifierReportVerifiedIterator{contract: _MercuryVerifier.contract, event: "ReportVerified", logs: logs, sub: sub}, nil -} - -func (_MercuryVerifier *MercuryVerifierFilterer) WatchReportVerified(opts *bind.WatchOpts, sink chan<- *MercuryVerifierReportVerified, feedId [][32]byte) (event.Subscription, error) { - - var feedIdRule []interface{} - for _, feedIdItem := range feedId { - feedIdRule = append(feedIdRule, feedIdItem) - } - - logs, sub, err := _MercuryVerifier.contract.WatchLogs(opts, "ReportVerified", feedIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(MercuryVerifierReportVerified) - if err := _MercuryVerifier.contract.UnpackLog(event, "ReportVerified", 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 (_MercuryVerifier *MercuryVerifierFilterer) ParseReportVerified(log types.Log) (*MercuryVerifierReportVerified, error) { - event := new(MercuryVerifierReportVerified) - if err := _MercuryVerifier.contract.UnpackLog(event, "ReportVerified", 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 (_MercuryVerifier *MercuryVerifier) ParseLog(log types.Log) (generated.AbigenLog, error) { - switch log.Topics[0] { - case _MercuryVerifier.abi.Events["ConfigActivated"].ID: - return _MercuryVerifier.ParseConfigActivated(log) - case _MercuryVerifier.abi.Events["ConfigDeactivated"].ID: - return _MercuryVerifier.ParseConfigDeactivated(log) - case _MercuryVerifier.abi.Events["ConfigSet"].ID: - return _MercuryVerifier.ParseConfigSet(log) - case _MercuryVerifier.abi.Events["FeedActivated"].ID: - return _MercuryVerifier.ParseFeedActivated(log) - case _MercuryVerifier.abi.Events["FeedDeactivated"].ID: - return _MercuryVerifier.ParseFeedDeactivated(log) - case _MercuryVerifier.abi.Events["OwnershipTransferRequested"].ID: - return _MercuryVerifier.ParseOwnershipTransferRequested(log) - case _MercuryVerifier.abi.Events["OwnershipTransferred"].ID: - return _MercuryVerifier.ParseOwnershipTransferred(log) - case _MercuryVerifier.abi.Events["ReportVerified"].ID: - return _MercuryVerifier.ParseReportVerified(log) - - default: - return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) - } -} - -func (MercuryVerifierConfigActivated) Topic() common.Hash { - return common.HexToHash("0x54f8872b9b94ebea6577f33576d55847bd8ea22641ccc886b965f6e50bfe7746") -} - -func (MercuryVerifierConfigDeactivated) Topic() common.Hash { - return common.HexToHash("0x0e173bea63a8c59ec70bf87043f2a729693790183f16a1a54b705de9e989cc4c") -} - -func (MercuryVerifierConfigSet) Topic() common.Hash { - return common.HexToHash("0xa23a88453230b183877098801ff5a8f771a120e2573eea559ce6c4c2e305a4da") -} - -func (MercuryVerifierFeedActivated) Topic() common.Hash { - return common.HexToHash("0xf438564f793525caa89c6e3a26d41e16aa39d1e589747595751e3f3df75cb2b4") -} - -func (MercuryVerifierFeedDeactivated) Topic() common.Hash { - return common.HexToHash("0xfc4f79b8c65b6be1773063461984c0974400d1e99654c79477a092ace83fd061") -} - -func (MercuryVerifierOwnershipTransferRequested) Topic() common.Hash { - return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") -} - -func (MercuryVerifierOwnershipTransferred) Topic() common.Hash { - return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") -} - -func (MercuryVerifierReportVerified) Topic() common.Hash { - return common.HexToHash("0x58ca9502e98a536e06e72d680fcc251e5d10b72291a281665a2c2dc0ac30fcc5") -} - -func (_MercuryVerifier *MercuryVerifier) Address() common.Address { - return _MercuryVerifier.address -} - -type MercuryVerifierInterface interface { - LatestConfigDetails(opts *bind.CallOpts, feedId [32]byte) (LatestConfigDetails, - - error) - - LatestConfigDigestAndEpoch(opts *bind.CallOpts, feedId [32]byte) (LatestConfigDigestAndEpoch, - - error) - - Owner(opts *bind.CallOpts) (common.Address, error) - - SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) - - TypeAndVersion(opts *bind.CallOpts) (string, error) - - AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) - - ActivateConfig(opts *bind.TransactOpts, feedId [32]byte, configDigest [32]byte) (*types.Transaction, error) - - ActivateFeed(opts *bind.TransactOpts, feedId [32]byte) (*types.Transaction, error) - - DeactivateConfig(opts *bind.TransactOpts, feedId [32]byte, configDigest [32]byte) (*types.Transaction, error) - - DeactivateFeed(opts *bind.TransactOpts, feedId [32]byte) (*types.Transaction, error) - - SetConfig(opts *bind.TransactOpts, feedId [32]byte, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) - - TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) - - Verify(opts *bind.TransactOpts, signedReport []byte, sender common.Address) (*types.Transaction, error) - - FilterConfigActivated(opts *bind.FilterOpts, feedId [][32]byte) (*MercuryVerifierConfigActivatedIterator, error) - - WatchConfigActivated(opts *bind.WatchOpts, sink chan<- *MercuryVerifierConfigActivated, feedId [][32]byte) (event.Subscription, error) - - ParseConfigActivated(log types.Log) (*MercuryVerifierConfigActivated, error) - - FilterConfigDeactivated(opts *bind.FilterOpts, feedId [][32]byte) (*MercuryVerifierConfigDeactivatedIterator, error) - - WatchConfigDeactivated(opts *bind.WatchOpts, sink chan<- *MercuryVerifierConfigDeactivated, feedId [][32]byte) (event.Subscription, error) - - ParseConfigDeactivated(log types.Log) (*MercuryVerifierConfigDeactivated, error) - - FilterConfigSet(opts *bind.FilterOpts, feedId [][32]byte) (*MercuryVerifierConfigSetIterator, error) - - WatchConfigSet(opts *bind.WatchOpts, sink chan<- *MercuryVerifierConfigSet, feedId [][32]byte) (event.Subscription, error) - - ParseConfigSet(log types.Log) (*MercuryVerifierConfigSet, error) - - FilterFeedActivated(opts *bind.FilterOpts, feedId [][32]byte) (*MercuryVerifierFeedActivatedIterator, error) - - WatchFeedActivated(opts *bind.WatchOpts, sink chan<- *MercuryVerifierFeedActivated, feedId [][32]byte) (event.Subscription, error) - - ParseFeedActivated(log types.Log) (*MercuryVerifierFeedActivated, error) - - FilterFeedDeactivated(opts *bind.FilterOpts, feedId [][32]byte) (*MercuryVerifierFeedDeactivatedIterator, error) - - WatchFeedDeactivated(opts *bind.WatchOpts, sink chan<- *MercuryVerifierFeedDeactivated, feedId [][32]byte) (event.Subscription, error) - - ParseFeedDeactivated(log types.Log) (*MercuryVerifierFeedDeactivated, error) - - FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MercuryVerifierOwnershipTransferRequestedIterator, error) - - WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *MercuryVerifierOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) - - ParseOwnershipTransferRequested(log types.Log) (*MercuryVerifierOwnershipTransferRequested, error) - - FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MercuryVerifierOwnershipTransferredIterator, error) - - WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *MercuryVerifierOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) - - ParseOwnershipTransferred(log types.Log) (*MercuryVerifierOwnershipTransferred, error) - - FilterReportVerified(opts *bind.FilterOpts, feedId [][32]byte) (*MercuryVerifierReportVerifiedIterator, error) - - WatchReportVerified(opts *bind.WatchOpts, sink chan<- *MercuryVerifierReportVerified, feedId [][32]byte) (event.Subscription, error) - - ParseReportVerified(log types.Log) (*MercuryVerifierReportVerified, error) - - ParseLog(log types.Log) (generated.AbigenLog, error) - - Address() common.Address -} diff --git a/core/gethwrappers/generated/mercury_verifier_proxy/mercury_verifier_proxy.go b/core/gethwrappers/generated/mercury_verifier_proxy/mercury_verifier_proxy.go deleted file mode 100644 index af82aa4e15b..00000000000 --- a/core/gethwrappers/generated/mercury_verifier_proxy/mercury_verifier_proxy.go +++ /dev/null @@ -1,1200 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package mercury_verifier_proxy - -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 MercuryVerifierProxyMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"accessController\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"verifier\",\"type\":\"address\"}],\"name\":\"ConfigDigestAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifier\",\"type\":\"address\"}],\"name\":\"VerifierAlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerifierInvalid\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"VerifierNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessController\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessController\",\"type\":\"address\"}],\"name\":\"AccessControllerSet\",\"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\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"oldConfigDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"newConfigDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierUnset\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAccessController\",\"outputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"accessController\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"getVerifier\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"initializeVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"accessController\",\"type\":\"address\"}],\"name\":\"setAccessController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"currentConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"newConfigDigest\",\"type\":\"bytes32\"}],\"name\":\"setVerifier\",\"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\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"unsetVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signedReport\",\"type\":\"bytes\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"verifierResponse\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5060405161112e38038061112e83398101604081905261002f91610187565b33806000816100855760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156100b5576100b5816100de565b5050600480546001600160a01b0319166001600160a01b039390931692909217909155506101b7565b336001600160a01b038216036101365760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161007c565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006020828403121561019957600080fd5b81516001600160a01b03811681146101b057600080fd5b9392505050565b610f68806101c66000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80638c2a4d5311610081578063eeb7b2481161005b578063eeb7b248146101c8578063f08391d8146101fe578063f2fde38b1461021157600080fd5b80638c2a4d53146101845780638da5cb5b146101975780638e760afe146101b557600080fd5b80632cc99477116100b25780632cc99477146101545780636e9140941461016957806379ba50971461017c57600080fd5b806316d6b5f6146100ce578063181f5a7714610112575b600080fd5b60045473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b60408051808201909152601381527f566572696669657250726f787920312e302e300000000000000000000000000060208201525b6040516101099190610c40565b610167610162366004610c5a565b610224565b005b610167610177366004610c7c565b61036f565b610167610467565b610167610192366004610cb7565b610564565b60005473ffffffffffffffffffffffffffffffffffffffff166100e8565b6101476101c3366004610cd4565b610795565b6100e86101d6366004610c7c565b60009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b61016761020c366004610cb7565b6109bf565b61016761021f366004610cb7565b610a46565b600081815260036020526040902054819073ffffffffffffffffffffffffffffffffffffffff1680156102a7576040517f375d1fe60000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff821660248201526044015b60405180910390fd5b3360009081526002602052604090205460ff166102f0576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152600360209081526040918290208054337fffffffffffffffffffffffff0000000000000000000000000000000000000000909116811790915582518781529182018690528183015290517fbeb513e532542a562ac35699e7cd9ae7d198dcd3eee15bada6c857d28ceaddcf9181900360600190a150505050565b610377610a5a565b60008181526003602052604090205473ffffffffffffffffffffffffffffffffffffffff16806103d6576040517fb151802b0000000000000000000000000000000000000000000000000000000081526004810183905260240161029e565b6000828152600360205260409081902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055517f11dc15c4b8ac2b183166cc8427e5385a5ece8308217a4217338c6a7614845c4c9061045b908490849091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a15050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146104e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161029e565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61056c610a5a565b8073ffffffffffffffffffffffffffffffffffffffff81166105ba576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f3d3ac1b500000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015610644573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106689190610d46565b61069e576040517f75b0527a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090205460ff1615610716576040517f4e01ccfd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015260240161029e565b73ffffffffffffffffffffffffffffffffffffffff821660008181526002602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590519182527f1f2cd7c97f4d801b5efe26cc409617c1fd6c5ef786e79aacb90af40923e4e8e9910161045b565b60045460609073ffffffffffffffffffffffffffffffffffffffff16801580159061085557506040517f6b14daf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690636b14daf8906108129033906000903690600401610db1565b602060405180830381865afa15801561082f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108539190610d46565b155b1561088c576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006108988486610dea565b60008181526003602052604090205490915073ffffffffffffffffffffffffffffffffffffffff16806108fa576040517fb151802b0000000000000000000000000000000000000000000000000000000081526004810183905260240161029e565b6040517f3d3ac1b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690633d3ac1b59061095090899089903390600401610e27565b6000604051808303816000875af115801561096f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526109b59190810190610e90565b9695505050505050565b6109c7610a5a565b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f953e92b1a6442e9c3242531154a3f6f6eb00b4e9c719ba8118fa6235e4ce89b6910161045b565b610a4e610a5a565b610a5781610add565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610adb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161029e565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610b5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161029e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b83811015610bed578181015183820152602001610bd5565b50506000910152565b60008151808452610c0e816020860160208601610bd2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610c536020830184610bf6565b9392505050565b60008060408385031215610c6d57600080fd5b50508035926020909101359150565b600060208284031215610c8e57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610a5757600080fd5b600060208284031215610cc957600080fd5b8135610c5381610c95565b60008060208385031215610ce757600080fd5b823567ffffffffffffffff80821115610cff57600080fd5b818501915085601f830112610d1357600080fd5b813581811115610d2257600080fd5b866020828501011115610d3457600080fd5b60209290920196919550909350505050565b600060208284031215610d5857600080fd5b81518015158114610c5357600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff84168152604060208201526000610de1604083018486610d68565b95945050505050565b80356020831015610e21577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b165b92915050565b604081526000610e3b604083018587610d68565b905073ffffffffffffffffffffffffffffffffffffffff83166020830152949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610ea257600080fd5b815167ffffffffffffffff80821115610eba57600080fd5b818401915084601f830112610ece57600080fd5b815181811115610ee057610ee0610e61565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610f2657610f26610e61565b81604052828152876020848701011115610f3f57600080fd5b610f50836020830160208801610bd2565b97965050505050505056fea164736f6c6343000810000a", -} - -var MercuryVerifierProxyABI = MercuryVerifierProxyMetaData.ABI - -var MercuryVerifierProxyBin = MercuryVerifierProxyMetaData.Bin - -func DeployMercuryVerifierProxy(auth *bind.TransactOpts, backend bind.ContractBackend, accessController common.Address) (common.Address, *types.Transaction, *MercuryVerifierProxy, error) { - parsed, err := MercuryVerifierProxyMetaData.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(MercuryVerifierProxyBin), backend, accessController) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &MercuryVerifierProxy{MercuryVerifierProxyCaller: MercuryVerifierProxyCaller{contract: contract}, MercuryVerifierProxyTransactor: MercuryVerifierProxyTransactor{contract: contract}, MercuryVerifierProxyFilterer: MercuryVerifierProxyFilterer{contract: contract}}, nil -} - -type MercuryVerifierProxy struct { - address common.Address - abi abi.ABI - MercuryVerifierProxyCaller - MercuryVerifierProxyTransactor - MercuryVerifierProxyFilterer -} - -type MercuryVerifierProxyCaller struct { - contract *bind.BoundContract -} - -type MercuryVerifierProxyTransactor struct { - contract *bind.BoundContract -} - -type MercuryVerifierProxyFilterer struct { - contract *bind.BoundContract -} - -type MercuryVerifierProxySession struct { - Contract *MercuryVerifierProxy - CallOpts bind.CallOpts - TransactOpts bind.TransactOpts -} - -type MercuryVerifierProxyCallerSession struct { - Contract *MercuryVerifierProxyCaller - CallOpts bind.CallOpts -} - -type MercuryVerifierProxyTransactorSession struct { - Contract *MercuryVerifierProxyTransactor - TransactOpts bind.TransactOpts -} - -type MercuryVerifierProxyRaw struct { - Contract *MercuryVerifierProxy -} - -type MercuryVerifierProxyCallerRaw struct { - Contract *MercuryVerifierProxyCaller -} - -type MercuryVerifierProxyTransactorRaw struct { - Contract *MercuryVerifierProxyTransactor -} - -func NewMercuryVerifierProxy(address common.Address, backend bind.ContractBackend) (*MercuryVerifierProxy, error) { - abi, err := abi.JSON(strings.NewReader(MercuryVerifierProxyABI)) - if err != nil { - return nil, err - } - contract, err := bindMercuryVerifierProxy(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &MercuryVerifierProxy{address: address, abi: abi, MercuryVerifierProxyCaller: MercuryVerifierProxyCaller{contract: contract}, MercuryVerifierProxyTransactor: MercuryVerifierProxyTransactor{contract: contract}, MercuryVerifierProxyFilterer: MercuryVerifierProxyFilterer{contract: contract}}, nil -} - -func NewMercuryVerifierProxyCaller(address common.Address, caller bind.ContractCaller) (*MercuryVerifierProxyCaller, error) { - contract, err := bindMercuryVerifierProxy(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &MercuryVerifierProxyCaller{contract: contract}, nil -} - -func NewMercuryVerifierProxyTransactor(address common.Address, transactor bind.ContractTransactor) (*MercuryVerifierProxyTransactor, error) { - contract, err := bindMercuryVerifierProxy(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &MercuryVerifierProxyTransactor{contract: contract}, nil -} - -func NewMercuryVerifierProxyFilterer(address common.Address, filterer bind.ContractFilterer) (*MercuryVerifierProxyFilterer, error) { - contract, err := bindMercuryVerifierProxy(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &MercuryVerifierProxyFilterer{contract: contract}, nil -} - -func bindMercuryVerifierProxy(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := MercuryVerifierProxyMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _MercuryVerifierProxy.Contract.MercuryVerifierProxyCaller.contract.Call(opts, result, method, params...) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _MercuryVerifierProxy.Contract.MercuryVerifierProxyTransactor.contract.Transfer(opts) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _MercuryVerifierProxy.Contract.MercuryVerifierProxyTransactor.contract.Transact(opts, method, params...) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _MercuryVerifierProxy.Contract.contract.Call(opts, result, method, params...) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _MercuryVerifierProxy.Contract.contract.Transfer(opts) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _MercuryVerifierProxy.Contract.contract.Transact(opts, method, params...) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyCaller) GetAccessController(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _MercuryVerifierProxy.contract.Call(opts, &out, "getAccessController") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -func (_MercuryVerifierProxy *MercuryVerifierProxySession) GetAccessController() (common.Address, error) { - return _MercuryVerifierProxy.Contract.GetAccessController(&_MercuryVerifierProxy.CallOpts) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyCallerSession) GetAccessController() (common.Address, error) { - return _MercuryVerifierProxy.Contract.GetAccessController(&_MercuryVerifierProxy.CallOpts) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyCaller) GetVerifier(opts *bind.CallOpts, configDigest [32]byte) (common.Address, error) { - var out []interface{} - err := _MercuryVerifierProxy.contract.Call(opts, &out, "getVerifier", configDigest) - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -func (_MercuryVerifierProxy *MercuryVerifierProxySession) GetVerifier(configDigest [32]byte) (common.Address, error) { - return _MercuryVerifierProxy.Contract.GetVerifier(&_MercuryVerifierProxy.CallOpts, configDigest) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyCallerSession) GetVerifier(configDigest [32]byte) (common.Address, error) { - return _MercuryVerifierProxy.Contract.GetVerifier(&_MercuryVerifierProxy.CallOpts, configDigest) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _MercuryVerifierProxy.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 (_MercuryVerifierProxy *MercuryVerifierProxySession) Owner() (common.Address, error) { - return _MercuryVerifierProxy.Contract.Owner(&_MercuryVerifierProxy.CallOpts) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyCallerSession) Owner() (common.Address, error) { - return _MercuryVerifierProxy.Contract.Owner(&_MercuryVerifierProxy.CallOpts) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { - var out []interface{} - err := _MercuryVerifierProxy.contract.Call(opts, &out, "typeAndVersion") - - if err != nil { - return *new(string), err - } - - out0 := *abi.ConvertType(out[0], new(string)).(*string) - - return out0, err - -} - -func (_MercuryVerifierProxy *MercuryVerifierProxySession) TypeAndVersion() (string, error) { - return _MercuryVerifierProxy.Contract.TypeAndVersion(&_MercuryVerifierProxy.CallOpts) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyCallerSession) TypeAndVersion() (string, error) { - return _MercuryVerifierProxy.Contract.TypeAndVersion(&_MercuryVerifierProxy.CallOpts) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _MercuryVerifierProxy.contract.Transact(opts, "acceptOwnership") -} - -func (_MercuryVerifierProxy *MercuryVerifierProxySession) AcceptOwnership() (*types.Transaction, error) { - return _MercuryVerifierProxy.Contract.AcceptOwnership(&_MercuryVerifierProxy.TransactOpts) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyTransactorSession) AcceptOwnership() (*types.Transaction, error) { - return _MercuryVerifierProxy.Contract.AcceptOwnership(&_MercuryVerifierProxy.TransactOpts) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyTransactor) InitializeVerifier(opts *bind.TransactOpts, verifierAddress common.Address) (*types.Transaction, error) { - return _MercuryVerifierProxy.contract.Transact(opts, "initializeVerifier", verifierAddress) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxySession) InitializeVerifier(verifierAddress common.Address) (*types.Transaction, error) { - return _MercuryVerifierProxy.Contract.InitializeVerifier(&_MercuryVerifierProxy.TransactOpts, verifierAddress) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyTransactorSession) InitializeVerifier(verifierAddress common.Address) (*types.Transaction, error) { - return _MercuryVerifierProxy.Contract.InitializeVerifier(&_MercuryVerifierProxy.TransactOpts, verifierAddress) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyTransactor) SetAccessController(opts *bind.TransactOpts, accessController common.Address) (*types.Transaction, error) { - return _MercuryVerifierProxy.contract.Transact(opts, "setAccessController", accessController) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxySession) SetAccessController(accessController common.Address) (*types.Transaction, error) { - return _MercuryVerifierProxy.Contract.SetAccessController(&_MercuryVerifierProxy.TransactOpts, accessController) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyTransactorSession) SetAccessController(accessController common.Address) (*types.Transaction, error) { - return _MercuryVerifierProxy.Contract.SetAccessController(&_MercuryVerifierProxy.TransactOpts, accessController) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyTransactor) SetVerifier(opts *bind.TransactOpts, currentConfigDigest [32]byte, newConfigDigest [32]byte) (*types.Transaction, error) { - return _MercuryVerifierProxy.contract.Transact(opts, "setVerifier", currentConfigDigest, newConfigDigest) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxySession) SetVerifier(currentConfigDigest [32]byte, newConfigDigest [32]byte) (*types.Transaction, error) { - return _MercuryVerifierProxy.Contract.SetVerifier(&_MercuryVerifierProxy.TransactOpts, currentConfigDigest, newConfigDigest) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyTransactorSession) SetVerifier(currentConfigDigest [32]byte, newConfigDigest [32]byte) (*types.Transaction, error) { - return _MercuryVerifierProxy.Contract.SetVerifier(&_MercuryVerifierProxy.TransactOpts, currentConfigDigest, newConfigDigest) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _MercuryVerifierProxy.contract.Transact(opts, "transferOwnership", to) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxySession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _MercuryVerifierProxy.Contract.TransferOwnership(&_MercuryVerifierProxy.TransactOpts, to) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _MercuryVerifierProxy.Contract.TransferOwnership(&_MercuryVerifierProxy.TransactOpts, to) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyTransactor) UnsetVerifier(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) { - return _MercuryVerifierProxy.contract.Transact(opts, "unsetVerifier", configDigest) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxySession) UnsetVerifier(configDigest [32]byte) (*types.Transaction, error) { - return _MercuryVerifierProxy.Contract.UnsetVerifier(&_MercuryVerifierProxy.TransactOpts, configDigest) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyTransactorSession) UnsetVerifier(configDigest [32]byte) (*types.Transaction, error) { - return _MercuryVerifierProxy.Contract.UnsetVerifier(&_MercuryVerifierProxy.TransactOpts, configDigest) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyTransactor) Verify(opts *bind.TransactOpts, signedReport []byte) (*types.Transaction, error) { - return _MercuryVerifierProxy.contract.Transact(opts, "verify", signedReport) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxySession) Verify(signedReport []byte) (*types.Transaction, error) { - return _MercuryVerifierProxy.Contract.Verify(&_MercuryVerifierProxy.TransactOpts, signedReport) -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyTransactorSession) Verify(signedReport []byte) (*types.Transaction, error) { - return _MercuryVerifierProxy.Contract.Verify(&_MercuryVerifierProxy.TransactOpts, signedReport) -} - -type MercuryVerifierProxyAccessControllerSetIterator struct { - Event *MercuryVerifierProxyAccessControllerSet - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *MercuryVerifierProxyAccessControllerSetIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(MercuryVerifierProxyAccessControllerSet) - 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(MercuryVerifierProxyAccessControllerSet) - 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 *MercuryVerifierProxyAccessControllerSetIterator) Error() error { - return it.fail -} - -func (it *MercuryVerifierProxyAccessControllerSetIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type MercuryVerifierProxyAccessControllerSet struct { - OldAccessController common.Address - NewAccessController common.Address - Raw types.Log -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyFilterer) FilterAccessControllerSet(opts *bind.FilterOpts) (*MercuryVerifierProxyAccessControllerSetIterator, error) { - - logs, sub, err := _MercuryVerifierProxy.contract.FilterLogs(opts, "AccessControllerSet") - if err != nil { - return nil, err - } - return &MercuryVerifierProxyAccessControllerSetIterator{contract: _MercuryVerifierProxy.contract, event: "AccessControllerSet", logs: logs, sub: sub}, nil -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyFilterer) WatchAccessControllerSet(opts *bind.WatchOpts, sink chan<- *MercuryVerifierProxyAccessControllerSet) (event.Subscription, error) { - - logs, sub, err := _MercuryVerifierProxy.contract.WatchLogs(opts, "AccessControllerSet") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(MercuryVerifierProxyAccessControllerSet) - if err := _MercuryVerifierProxy.contract.UnpackLog(event, "AccessControllerSet", 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 (_MercuryVerifierProxy *MercuryVerifierProxyFilterer) ParseAccessControllerSet(log types.Log) (*MercuryVerifierProxyAccessControllerSet, error) { - event := new(MercuryVerifierProxyAccessControllerSet) - if err := _MercuryVerifierProxy.contract.UnpackLog(event, "AccessControllerSet", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type MercuryVerifierProxyOwnershipTransferRequestedIterator struct { - Event *MercuryVerifierProxyOwnershipTransferRequested - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *MercuryVerifierProxyOwnershipTransferRequestedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(MercuryVerifierProxyOwnershipTransferRequested) - 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(MercuryVerifierProxyOwnershipTransferRequested) - 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 *MercuryVerifierProxyOwnershipTransferRequestedIterator) Error() error { - return it.fail -} - -func (it *MercuryVerifierProxyOwnershipTransferRequestedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type MercuryVerifierProxyOwnershipTransferRequested struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MercuryVerifierProxyOwnershipTransferRequestedIterator, 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 := _MercuryVerifierProxy.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) - if err != nil { - return nil, err - } - return &MercuryVerifierProxyOwnershipTransferRequestedIterator{contract: _MercuryVerifierProxy.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *MercuryVerifierProxyOwnershipTransferRequested, 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 := _MercuryVerifierProxy.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(MercuryVerifierProxyOwnershipTransferRequested) - if err := _MercuryVerifierProxy.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 (_MercuryVerifierProxy *MercuryVerifierProxyFilterer) ParseOwnershipTransferRequested(log types.Log) (*MercuryVerifierProxyOwnershipTransferRequested, error) { - event := new(MercuryVerifierProxyOwnershipTransferRequested) - if err := _MercuryVerifierProxy.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type MercuryVerifierProxyOwnershipTransferredIterator struct { - Event *MercuryVerifierProxyOwnershipTransferred - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *MercuryVerifierProxyOwnershipTransferredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(MercuryVerifierProxyOwnershipTransferred) - 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(MercuryVerifierProxyOwnershipTransferred) - 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 *MercuryVerifierProxyOwnershipTransferredIterator) Error() error { - return it.fail -} - -func (it *MercuryVerifierProxyOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type MercuryVerifierProxyOwnershipTransferred struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MercuryVerifierProxyOwnershipTransferredIterator, 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 := _MercuryVerifierProxy.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) - if err != nil { - return nil, err - } - return &MercuryVerifierProxyOwnershipTransferredIterator{contract: _MercuryVerifierProxy.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *MercuryVerifierProxyOwnershipTransferred, 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 := _MercuryVerifierProxy.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(MercuryVerifierProxyOwnershipTransferred) - if err := _MercuryVerifierProxy.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 (_MercuryVerifierProxy *MercuryVerifierProxyFilterer) ParseOwnershipTransferred(log types.Log) (*MercuryVerifierProxyOwnershipTransferred, error) { - event := new(MercuryVerifierProxyOwnershipTransferred) - if err := _MercuryVerifierProxy.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type MercuryVerifierProxyVerifierInitializedIterator struct { - Event *MercuryVerifierProxyVerifierInitialized - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *MercuryVerifierProxyVerifierInitializedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(MercuryVerifierProxyVerifierInitialized) - 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(MercuryVerifierProxyVerifierInitialized) - 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 *MercuryVerifierProxyVerifierInitializedIterator) Error() error { - return it.fail -} - -func (it *MercuryVerifierProxyVerifierInitializedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type MercuryVerifierProxyVerifierInitialized struct { - VerifierAddress common.Address - Raw types.Log -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyFilterer) FilterVerifierInitialized(opts *bind.FilterOpts) (*MercuryVerifierProxyVerifierInitializedIterator, error) { - - logs, sub, err := _MercuryVerifierProxy.contract.FilterLogs(opts, "VerifierInitialized") - if err != nil { - return nil, err - } - return &MercuryVerifierProxyVerifierInitializedIterator{contract: _MercuryVerifierProxy.contract, event: "VerifierInitialized", logs: logs, sub: sub}, nil -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyFilterer) WatchVerifierInitialized(opts *bind.WatchOpts, sink chan<- *MercuryVerifierProxyVerifierInitialized) (event.Subscription, error) { - - logs, sub, err := _MercuryVerifierProxy.contract.WatchLogs(opts, "VerifierInitialized") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(MercuryVerifierProxyVerifierInitialized) - if err := _MercuryVerifierProxy.contract.UnpackLog(event, "VerifierInitialized", 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 (_MercuryVerifierProxy *MercuryVerifierProxyFilterer) ParseVerifierInitialized(log types.Log) (*MercuryVerifierProxyVerifierInitialized, error) { - event := new(MercuryVerifierProxyVerifierInitialized) - if err := _MercuryVerifierProxy.contract.UnpackLog(event, "VerifierInitialized", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type MercuryVerifierProxyVerifierSetIterator struct { - Event *MercuryVerifierProxyVerifierSet - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *MercuryVerifierProxyVerifierSetIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(MercuryVerifierProxyVerifierSet) - 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(MercuryVerifierProxyVerifierSet) - 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 *MercuryVerifierProxyVerifierSetIterator) Error() error { - return it.fail -} - -func (it *MercuryVerifierProxyVerifierSetIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type MercuryVerifierProxyVerifierSet struct { - OldConfigDigest [32]byte - NewConfigDigest [32]byte - VerifierAddress common.Address - Raw types.Log -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyFilterer) FilterVerifierSet(opts *bind.FilterOpts) (*MercuryVerifierProxyVerifierSetIterator, error) { - - logs, sub, err := _MercuryVerifierProxy.contract.FilterLogs(opts, "VerifierSet") - if err != nil { - return nil, err - } - return &MercuryVerifierProxyVerifierSetIterator{contract: _MercuryVerifierProxy.contract, event: "VerifierSet", logs: logs, sub: sub}, nil -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyFilterer) WatchVerifierSet(opts *bind.WatchOpts, sink chan<- *MercuryVerifierProxyVerifierSet) (event.Subscription, error) { - - logs, sub, err := _MercuryVerifierProxy.contract.WatchLogs(opts, "VerifierSet") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(MercuryVerifierProxyVerifierSet) - if err := _MercuryVerifierProxy.contract.UnpackLog(event, "VerifierSet", 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 (_MercuryVerifierProxy *MercuryVerifierProxyFilterer) ParseVerifierSet(log types.Log) (*MercuryVerifierProxyVerifierSet, error) { - event := new(MercuryVerifierProxyVerifierSet) - if err := _MercuryVerifierProxy.contract.UnpackLog(event, "VerifierSet", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type MercuryVerifierProxyVerifierUnsetIterator struct { - Event *MercuryVerifierProxyVerifierUnset - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *MercuryVerifierProxyVerifierUnsetIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(MercuryVerifierProxyVerifierUnset) - 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(MercuryVerifierProxyVerifierUnset) - 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 *MercuryVerifierProxyVerifierUnsetIterator) Error() error { - return it.fail -} - -func (it *MercuryVerifierProxyVerifierUnsetIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type MercuryVerifierProxyVerifierUnset struct { - ConfigDigest [32]byte - VerifierAddress common.Address - Raw types.Log -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyFilterer) FilterVerifierUnset(opts *bind.FilterOpts) (*MercuryVerifierProxyVerifierUnsetIterator, error) { - - logs, sub, err := _MercuryVerifierProxy.contract.FilterLogs(opts, "VerifierUnset") - if err != nil { - return nil, err - } - return &MercuryVerifierProxyVerifierUnsetIterator{contract: _MercuryVerifierProxy.contract, event: "VerifierUnset", logs: logs, sub: sub}, nil -} - -func (_MercuryVerifierProxy *MercuryVerifierProxyFilterer) WatchVerifierUnset(opts *bind.WatchOpts, sink chan<- *MercuryVerifierProxyVerifierUnset) (event.Subscription, error) { - - logs, sub, err := _MercuryVerifierProxy.contract.WatchLogs(opts, "VerifierUnset") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(MercuryVerifierProxyVerifierUnset) - if err := _MercuryVerifierProxy.contract.UnpackLog(event, "VerifierUnset", 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 (_MercuryVerifierProxy *MercuryVerifierProxyFilterer) ParseVerifierUnset(log types.Log) (*MercuryVerifierProxyVerifierUnset, error) { - event := new(MercuryVerifierProxyVerifierUnset) - if err := _MercuryVerifierProxy.contract.UnpackLog(event, "VerifierUnset", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -func (_MercuryVerifierProxy *MercuryVerifierProxy) ParseLog(log types.Log) (generated.AbigenLog, error) { - switch log.Topics[0] { - case _MercuryVerifierProxy.abi.Events["AccessControllerSet"].ID: - return _MercuryVerifierProxy.ParseAccessControllerSet(log) - case _MercuryVerifierProxy.abi.Events["OwnershipTransferRequested"].ID: - return _MercuryVerifierProxy.ParseOwnershipTransferRequested(log) - case _MercuryVerifierProxy.abi.Events["OwnershipTransferred"].ID: - return _MercuryVerifierProxy.ParseOwnershipTransferred(log) - case _MercuryVerifierProxy.abi.Events["VerifierInitialized"].ID: - return _MercuryVerifierProxy.ParseVerifierInitialized(log) - case _MercuryVerifierProxy.abi.Events["VerifierSet"].ID: - return _MercuryVerifierProxy.ParseVerifierSet(log) - case _MercuryVerifierProxy.abi.Events["VerifierUnset"].ID: - return _MercuryVerifierProxy.ParseVerifierUnset(log) - - default: - return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) - } -} - -func (MercuryVerifierProxyAccessControllerSet) Topic() common.Hash { - return common.HexToHash("0x953e92b1a6442e9c3242531154a3f6f6eb00b4e9c719ba8118fa6235e4ce89b6") -} - -func (MercuryVerifierProxyOwnershipTransferRequested) Topic() common.Hash { - return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") -} - -func (MercuryVerifierProxyOwnershipTransferred) Topic() common.Hash { - return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") -} - -func (MercuryVerifierProxyVerifierInitialized) Topic() common.Hash { - return common.HexToHash("0x1f2cd7c97f4d801b5efe26cc409617c1fd6c5ef786e79aacb90af40923e4e8e9") -} - -func (MercuryVerifierProxyVerifierSet) Topic() common.Hash { - return common.HexToHash("0xbeb513e532542a562ac35699e7cd9ae7d198dcd3eee15bada6c857d28ceaddcf") -} - -func (MercuryVerifierProxyVerifierUnset) Topic() common.Hash { - return common.HexToHash("0x11dc15c4b8ac2b183166cc8427e5385a5ece8308217a4217338c6a7614845c4c") -} - -func (_MercuryVerifierProxy *MercuryVerifierProxy) Address() common.Address { - return _MercuryVerifierProxy.address -} - -type MercuryVerifierProxyInterface interface { - GetAccessController(opts *bind.CallOpts) (common.Address, error) - - GetVerifier(opts *bind.CallOpts, configDigest [32]byte) (common.Address, error) - - Owner(opts *bind.CallOpts) (common.Address, error) - - TypeAndVersion(opts *bind.CallOpts) (string, error) - - AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) - - InitializeVerifier(opts *bind.TransactOpts, verifierAddress common.Address) (*types.Transaction, error) - - SetAccessController(opts *bind.TransactOpts, accessController common.Address) (*types.Transaction, error) - - SetVerifier(opts *bind.TransactOpts, currentConfigDigest [32]byte, newConfigDigest [32]byte) (*types.Transaction, error) - - TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) - - UnsetVerifier(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) - - Verify(opts *bind.TransactOpts, signedReport []byte) (*types.Transaction, error) - - FilterAccessControllerSet(opts *bind.FilterOpts) (*MercuryVerifierProxyAccessControllerSetIterator, error) - - WatchAccessControllerSet(opts *bind.WatchOpts, sink chan<- *MercuryVerifierProxyAccessControllerSet) (event.Subscription, error) - - ParseAccessControllerSet(log types.Log) (*MercuryVerifierProxyAccessControllerSet, error) - - FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MercuryVerifierProxyOwnershipTransferRequestedIterator, error) - - WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *MercuryVerifierProxyOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) - - ParseOwnershipTransferRequested(log types.Log) (*MercuryVerifierProxyOwnershipTransferRequested, error) - - FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*MercuryVerifierProxyOwnershipTransferredIterator, error) - - WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *MercuryVerifierProxyOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) - - ParseOwnershipTransferred(log types.Log) (*MercuryVerifierProxyOwnershipTransferred, error) - - FilterVerifierInitialized(opts *bind.FilterOpts) (*MercuryVerifierProxyVerifierInitializedIterator, error) - - WatchVerifierInitialized(opts *bind.WatchOpts, sink chan<- *MercuryVerifierProxyVerifierInitialized) (event.Subscription, error) - - ParseVerifierInitialized(log types.Log) (*MercuryVerifierProxyVerifierInitialized, error) - - FilterVerifierSet(opts *bind.FilterOpts) (*MercuryVerifierProxyVerifierSetIterator, error) - - WatchVerifierSet(opts *bind.WatchOpts, sink chan<- *MercuryVerifierProxyVerifierSet) (event.Subscription, error) - - ParseVerifierSet(log types.Log) (*MercuryVerifierProxyVerifierSet, error) - - FilterVerifierUnset(opts *bind.FilterOpts) (*MercuryVerifierProxyVerifierUnsetIterator, error) - - WatchVerifierUnset(opts *bind.WatchOpts, sink chan<- *MercuryVerifierProxyVerifierUnset) (event.Subscription, error) - - ParseVerifierUnset(log types.Log) (*MercuryVerifierProxyVerifierUnset, error) - - ParseLog(log types.Log) (generated.AbigenLog, error) - - Address() common.Address -} diff --git a/core/gethwrappers/generated/trusted_blockhash_store/trusted_blockhash_store.go b/core/gethwrappers/generated/trusted_blockhash_store/trusted_blockhash_store.go new file mode 100644 index 00000000000..0ddddead4bd --- /dev/null +++ b/core/gethwrappers/generated/trusted_blockhash_store/trusted_blockhash_store.go @@ -0,0 +1,680 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package trusted_blockhash_store + +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 TrustedBlockhashStoreMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"whitelist\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidRecentBlockhash\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrustedBlockhashes\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInWhitelist\",\"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\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getBlockhash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_whitelist\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_whitelistStatus\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"whitelist\",\"type\":\"address[]\"}],\"name\":\"setWhitelist\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"store\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"storeEarliest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"blockNums\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"blockhashes\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"recentBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"recentBlockhash\",\"type\":\"bytes32\"}],\"name\":\"storeTrusted\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"header\",\"type\":\"bytes\"}],\"name\":\"storeVerifyHeader\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b50604051620014db380380620014db8339810160408190526200003491620003e8565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d9565b505050620000d2816200018560201b60201c565b5062000517565b6001600160a01b038116331415620001345760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200018f620002ec565b60006004805480602002602001604051908101604052809291908181526020018280548015620001e957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620001ca575b5050855193945062000207936004935060208701925090506200034a565b5060005b81518110156200027757600060036000848481518110620002305762000230620004eb565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055806200026e81620004c1565b9150506200020b565b5060005b8251811015620002e757600160036000858481518110620002a057620002a0620004eb565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905580620002de81620004c1565b9150506200027b565b505050565b6000546001600160a01b03163314620003485760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b828054828255906000526020600020908101928215620003a2579160200282015b82811115620003a257825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906200036b565b50620003b0929150620003b4565b5090565b5b80821115620003b05760008155600101620003b5565b80516001600160a01b0381168114620003e357600080fd5b919050565b60006020808385031215620003fc57600080fd5b82516001600160401b03808211156200041457600080fd5b818501915085601f8301126200042957600080fd5b8151818111156200043e576200043e62000501565b8060051b604051601f19603f8301168101818110858211171562000466576200046662000501565b604052828152858101935084860182860187018a10156200048657600080fd5b600095505b83861015620004b4576200049f81620003cb565b8552600195909501949386019386016200048b565b5098975050505050505050565b6000600019821415620004e457634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b610fb480620005276000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b5578063f4217648146101c8578063fadff0e1146101db57600080fd5b80638da5cb5b14610143578063e9413d3814610161578063e9ecc1541461018257600080fd5b80636057361d116100b25780636057361d1461012057806379ba50971461013357806383b6d6b71461013b57600080fd5b80633b69ad60146100ce5780635c7de309146100e3575b600080fd5b6100e16100dc366004610cf6565b6101ee565b005b6100f66100f1366004610d8d565b610326565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100e161012e366004610d8d565b61035d565b6100e16103e8565b6100e16104e5565b60005473ffffffffffffffffffffffffffffffffffffffff166100f6565b61017461016f366004610d8d565b6104ff565b604051908152602001610117565b6101a5610190366004610c27565b60036020526000908152604090205460ff1681565b6040519015158152602001610117565b6100e16101c3366004610c27565b61057b565b6100e16101d6366004610c42565b61058f565b6100e16101e9366004610da6565b610745565b60006101f9836107e8565b9050818114610234576040517fd2f69c9500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526003602052604090205460ff1661027d576040517f5b0aa2ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8584146102b6576040517fbd75093300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8681101561031c578585828181106102d3576102d3610f49565b90506020020135600260008a8a858181106102f0576102f0610f49565b90506020020135815260200190815260200160002081905550808061031490610ee1565b9150506102b9565b5050505050505050565b6004818154811061033657600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6000610368826107e8565b9050806103d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f626c6f636b68617368286e29206661696c65640000000000000000000000000060448201526064015b60405180910390fd5b60009182526002602052604090912055565b60015473ffffffffffffffffffffffffffffffffffffffff163314610469576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016103cd565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6104fd6101006104f36108f6565b61012e9190610eca565b565b60008181526002602052604081205480610575576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f626c6f636b68617368206e6f7420666f756e6420696e2073746f72650000000060448201526064016103cd565b92915050565b61058361099c565b61058c81610a1d565b50565b61059761099c565b600060048054806020026020016040519081016040528092919081815260200182805480156105fc57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116105d1575b5050855193945061061893600493506020870192509050610b13565b5060005b81518110156106ac5760006003600084848151811061063d5761063d610f49565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055806106a481610ee1565b91505061061c565b5060005b8251811015610740576001600360008584815181106106d1576106d1610f49565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790558061073881610ee1565b9150506106b0565b505050565b60026000610754846001610eb2565b8152602001908152602001600020548180519060200120146107d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6865616465722068617320756e6b6e6f776e20626c6f636b686173680000000060448201526064016103cd565b6024015160009182526002602052604090912055565b60004661a4b18114806107fd575062066eed81145b156108e6576101008367ffffffffffffffff166108186108f6565b6108229190610eca565b118061083f57506108316108f6565b8367ffffffffffffffff1610155b1561084d5750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152606490632b407a829060240160206040518083038186803b1580156108a757600080fd5b505afa1580156108bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108df9190610d74565b9392505050565b505067ffffffffffffffff164090565b60004661a4b181148061090b575062066eed81145b1561099557606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561095757600080fd5b505afa15801561096b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098f9190610d74565b91505090565b4391505090565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103cd565b73ffffffffffffffffffffffffffffffffffffffff8116331415610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103cd565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610b8d579160200282015b82811115610b8d57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190610b33565b50610b99929150610b9d565b5090565b5b80821115610b995760008155600101610b9e565b803573ffffffffffffffffffffffffffffffffffffffff81168114610bd657600080fd5b919050565b60008083601f840112610bed57600080fd5b50813567ffffffffffffffff811115610c0557600080fd5b6020830191508360208260051b8501011115610c2057600080fd5b9250929050565b600060208284031215610c3957600080fd5b6108df82610bb2565b60006020808385031215610c5557600080fd5b823567ffffffffffffffff80821115610c6d57600080fd5b818501915085601f830112610c8157600080fd5b813581811115610c9357610c93610f78565b8060051b9150610ca4848301610e63565b8181528481019084860184860187018a1015610cbf57600080fd5b600095505b83861015610ce957610cd581610bb2565b835260019590950194918601918601610cc4565b5098975050505050505050565b60008060008060008060808789031215610d0f57600080fd5b863567ffffffffffffffff80821115610d2757600080fd5b610d338a838b01610bdb565b90985096506020890135915080821115610d4c57600080fd5b50610d5989828a01610bdb565b979a9699509760408101359660609091013595509350505050565b600060208284031215610d8657600080fd5b5051919050565b600060208284031215610d9f57600080fd5b5035919050565b60008060408385031215610db957600080fd5b8235915060208084013567ffffffffffffffff80821115610dd957600080fd5b818601915086601f830112610ded57600080fd5b813581811115610dff57610dff610f78565b610e2f847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610e63565b91508082528784828501011115610e4557600080fd5b80848401858401376000848284010152508093505050509250929050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610eaa57610eaa610f78565b604052919050565b60008219821115610ec557610ec5610f1a565b500190565b600082821015610edc57610edc610f1a565b500390565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610f1357610f13610f1a565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", +} + +var TrustedBlockhashStoreABI = TrustedBlockhashStoreMetaData.ABI + +var TrustedBlockhashStoreBin = TrustedBlockhashStoreMetaData.Bin + +func DeployTrustedBlockhashStore(auth *bind.TransactOpts, backend bind.ContractBackend, whitelist []common.Address) (common.Address, *types.Transaction, *TrustedBlockhashStore, error) { + parsed, err := TrustedBlockhashStoreMetaData.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(TrustedBlockhashStoreBin), backend, whitelist) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &TrustedBlockhashStore{TrustedBlockhashStoreCaller: TrustedBlockhashStoreCaller{contract: contract}, TrustedBlockhashStoreTransactor: TrustedBlockhashStoreTransactor{contract: contract}, TrustedBlockhashStoreFilterer: TrustedBlockhashStoreFilterer{contract: contract}}, nil +} + +type TrustedBlockhashStore struct { + address common.Address + abi abi.ABI + TrustedBlockhashStoreCaller + TrustedBlockhashStoreTransactor + TrustedBlockhashStoreFilterer +} + +type TrustedBlockhashStoreCaller struct { + contract *bind.BoundContract +} + +type TrustedBlockhashStoreTransactor struct { + contract *bind.BoundContract +} + +type TrustedBlockhashStoreFilterer struct { + contract *bind.BoundContract +} + +type TrustedBlockhashStoreSession struct { + Contract *TrustedBlockhashStore + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type TrustedBlockhashStoreCallerSession struct { + Contract *TrustedBlockhashStoreCaller + CallOpts bind.CallOpts +} + +type TrustedBlockhashStoreTransactorSession struct { + Contract *TrustedBlockhashStoreTransactor + TransactOpts bind.TransactOpts +} + +type TrustedBlockhashStoreRaw struct { + Contract *TrustedBlockhashStore +} + +type TrustedBlockhashStoreCallerRaw struct { + Contract *TrustedBlockhashStoreCaller +} + +type TrustedBlockhashStoreTransactorRaw struct { + Contract *TrustedBlockhashStoreTransactor +} + +func NewTrustedBlockhashStore(address common.Address, backend bind.ContractBackend) (*TrustedBlockhashStore, error) { + abi, err := abi.JSON(strings.NewReader(TrustedBlockhashStoreABI)) + if err != nil { + return nil, err + } + contract, err := bindTrustedBlockhashStore(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &TrustedBlockhashStore{address: address, abi: abi, TrustedBlockhashStoreCaller: TrustedBlockhashStoreCaller{contract: contract}, TrustedBlockhashStoreTransactor: TrustedBlockhashStoreTransactor{contract: contract}, TrustedBlockhashStoreFilterer: TrustedBlockhashStoreFilterer{contract: contract}}, nil +} + +func NewTrustedBlockhashStoreCaller(address common.Address, caller bind.ContractCaller) (*TrustedBlockhashStoreCaller, error) { + contract, err := bindTrustedBlockhashStore(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TrustedBlockhashStoreCaller{contract: contract}, nil +} + +func NewTrustedBlockhashStoreTransactor(address common.Address, transactor bind.ContractTransactor) (*TrustedBlockhashStoreTransactor, error) { + contract, err := bindTrustedBlockhashStore(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TrustedBlockhashStoreTransactor{contract: contract}, nil +} + +func NewTrustedBlockhashStoreFilterer(address common.Address, filterer bind.ContractFilterer) (*TrustedBlockhashStoreFilterer, error) { + contract, err := bindTrustedBlockhashStore(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TrustedBlockhashStoreFilterer{contract: contract}, nil +} + +func bindTrustedBlockhashStore(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TrustedBlockhashStoreMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TrustedBlockhashStore.Contract.TrustedBlockhashStoreCaller.contract.Call(opts, result, method, params...) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TrustedBlockhashStore.Contract.TrustedBlockhashStoreTransactor.contract.Transfer(opts) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TrustedBlockhashStore.Contract.TrustedBlockhashStoreTransactor.contract.Transact(opts, method, params...) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TrustedBlockhashStore.Contract.contract.Call(opts, result, method, params...) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TrustedBlockhashStore.Contract.contract.Transfer(opts) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TrustedBlockhashStore.Contract.contract.Transact(opts, method, params...) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreCaller) GetBlockhash(opts *bind.CallOpts, n *big.Int) ([32]byte, error) { + var out []interface{} + err := _TrustedBlockhashStore.contract.Call(opts, &out, "getBlockhash", n) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreSession) GetBlockhash(n *big.Int) ([32]byte, error) { + return _TrustedBlockhashStore.Contract.GetBlockhash(&_TrustedBlockhashStore.CallOpts, n) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreCallerSession) GetBlockhash(n *big.Int) ([32]byte, error) { + return _TrustedBlockhashStore.Contract.GetBlockhash(&_TrustedBlockhashStore.CallOpts, n) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TrustedBlockhashStore.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 (_TrustedBlockhashStore *TrustedBlockhashStoreSession) Owner() (common.Address, error) { + return _TrustedBlockhashStore.Contract.Owner(&_TrustedBlockhashStore.CallOpts) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreCallerSession) Owner() (common.Address, error) { + return _TrustedBlockhashStore.Contract.Owner(&_TrustedBlockhashStore.CallOpts) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreCaller) SWhitelist(opts *bind.CallOpts, arg0 *big.Int) (common.Address, error) { + var out []interface{} + err := _TrustedBlockhashStore.contract.Call(opts, &out, "s_whitelist", arg0) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreSession) SWhitelist(arg0 *big.Int) (common.Address, error) { + return _TrustedBlockhashStore.Contract.SWhitelist(&_TrustedBlockhashStore.CallOpts, arg0) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreCallerSession) SWhitelist(arg0 *big.Int) (common.Address, error) { + return _TrustedBlockhashStore.Contract.SWhitelist(&_TrustedBlockhashStore.CallOpts, arg0) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreCaller) SWhitelistStatus(opts *bind.CallOpts, arg0 common.Address) (bool, error) { + var out []interface{} + err := _TrustedBlockhashStore.contract.Call(opts, &out, "s_whitelistStatus", arg0) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreSession) SWhitelistStatus(arg0 common.Address) (bool, error) { + return _TrustedBlockhashStore.Contract.SWhitelistStatus(&_TrustedBlockhashStore.CallOpts, arg0) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreCallerSession) SWhitelistStatus(arg0 common.Address) (bool, error) { + return _TrustedBlockhashStore.Contract.SWhitelistStatus(&_TrustedBlockhashStore.CallOpts, arg0) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TrustedBlockhashStore.contract.Transact(opts, "acceptOwnership") +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreSession) AcceptOwnership() (*types.Transaction, error) { + return _TrustedBlockhashStore.Contract.AcceptOwnership(&_TrustedBlockhashStore.TransactOpts) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _TrustedBlockhashStore.Contract.AcceptOwnership(&_TrustedBlockhashStore.TransactOpts) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreTransactor) SetWhitelist(opts *bind.TransactOpts, whitelist []common.Address) (*types.Transaction, error) { + return _TrustedBlockhashStore.contract.Transact(opts, "setWhitelist", whitelist) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreSession) SetWhitelist(whitelist []common.Address) (*types.Transaction, error) { + return _TrustedBlockhashStore.Contract.SetWhitelist(&_TrustedBlockhashStore.TransactOpts, whitelist) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreTransactorSession) SetWhitelist(whitelist []common.Address) (*types.Transaction, error) { + return _TrustedBlockhashStore.Contract.SetWhitelist(&_TrustedBlockhashStore.TransactOpts, whitelist) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreTransactor) Store(opts *bind.TransactOpts, n *big.Int) (*types.Transaction, error) { + return _TrustedBlockhashStore.contract.Transact(opts, "store", n) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreSession) Store(n *big.Int) (*types.Transaction, error) { + return _TrustedBlockhashStore.Contract.Store(&_TrustedBlockhashStore.TransactOpts, n) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreTransactorSession) Store(n *big.Int) (*types.Transaction, error) { + return _TrustedBlockhashStore.Contract.Store(&_TrustedBlockhashStore.TransactOpts, n) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreTransactor) StoreEarliest(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TrustedBlockhashStore.contract.Transact(opts, "storeEarliest") +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreSession) StoreEarliest() (*types.Transaction, error) { + return _TrustedBlockhashStore.Contract.StoreEarliest(&_TrustedBlockhashStore.TransactOpts) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreTransactorSession) StoreEarliest() (*types.Transaction, error) { + return _TrustedBlockhashStore.Contract.StoreEarliest(&_TrustedBlockhashStore.TransactOpts) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreTransactor) StoreTrusted(opts *bind.TransactOpts, blockNums []*big.Int, blockhashes [][32]byte, recentBlockNumber *big.Int, recentBlockhash [32]byte) (*types.Transaction, error) { + return _TrustedBlockhashStore.contract.Transact(opts, "storeTrusted", blockNums, blockhashes, recentBlockNumber, recentBlockhash) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreSession) StoreTrusted(blockNums []*big.Int, blockhashes [][32]byte, recentBlockNumber *big.Int, recentBlockhash [32]byte) (*types.Transaction, error) { + return _TrustedBlockhashStore.Contract.StoreTrusted(&_TrustedBlockhashStore.TransactOpts, blockNums, blockhashes, recentBlockNumber, recentBlockhash) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreTransactorSession) StoreTrusted(blockNums []*big.Int, blockhashes [][32]byte, recentBlockNumber *big.Int, recentBlockhash [32]byte) (*types.Transaction, error) { + return _TrustedBlockhashStore.Contract.StoreTrusted(&_TrustedBlockhashStore.TransactOpts, blockNums, blockhashes, recentBlockNumber, recentBlockhash) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreTransactor) StoreVerifyHeader(opts *bind.TransactOpts, n *big.Int, header []byte) (*types.Transaction, error) { + return _TrustedBlockhashStore.contract.Transact(opts, "storeVerifyHeader", n, header) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreSession) StoreVerifyHeader(n *big.Int, header []byte) (*types.Transaction, error) { + return _TrustedBlockhashStore.Contract.StoreVerifyHeader(&_TrustedBlockhashStore.TransactOpts, n, header) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreTransactorSession) StoreVerifyHeader(n *big.Int, header []byte) (*types.Transaction, error) { + return _TrustedBlockhashStore.Contract.StoreVerifyHeader(&_TrustedBlockhashStore.TransactOpts, n, header) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _TrustedBlockhashStore.contract.Transact(opts, "transferOwnership", to) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _TrustedBlockhashStore.Contract.TransferOwnership(&_TrustedBlockhashStore.TransactOpts, to) +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _TrustedBlockhashStore.Contract.TransferOwnership(&_TrustedBlockhashStore.TransactOpts, to) +} + +type TrustedBlockhashStoreOwnershipTransferRequestedIterator struct { + Event *TrustedBlockhashStoreOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TrustedBlockhashStoreOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TrustedBlockhashStoreOwnershipTransferRequested) + 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(TrustedBlockhashStoreOwnershipTransferRequested) + 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 *TrustedBlockhashStoreOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *TrustedBlockhashStoreOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TrustedBlockhashStoreOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TrustedBlockhashStoreOwnershipTransferRequestedIterator, 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 := _TrustedBlockhashStore.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &TrustedBlockhashStoreOwnershipTransferRequestedIterator{contract: _TrustedBlockhashStore.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *TrustedBlockhashStoreOwnershipTransferRequested, 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 := _TrustedBlockhashStore.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(TrustedBlockhashStoreOwnershipTransferRequested) + if err := _TrustedBlockhashStore.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 (_TrustedBlockhashStore *TrustedBlockhashStoreFilterer) ParseOwnershipTransferRequested(log types.Log) (*TrustedBlockhashStoreOwnershipTransferRequested, error) { + event := new(TrustedBlockhashStoreOwnershipTransferRequested) + if err := _TrustedBlockhashStore.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TrustedBlockhashStoreOwnershipTransferredIterator struct { + Event *TrustedBlockhashStoreOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TrustedBlockhashStoreOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TrustedBlockhashStoreOwnershipTransferred) + 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(TrustedBlockhashStoreOwnershipTransferred) + 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 *TrustedBlockhashStoreOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *TrustedBlockhashStoreOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TrustedBlockhashStoreOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TrustedBlockhashStoreOwnershipTransferredIterator, 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 := _TrustedBlockhashStore.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &TrustedBlockhashStoreOwnershipTransferredIterator{contract: _TrustedBlockhashStore.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_TrustedBlockhashStore *TrustedBlockhashStoreFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *TrustedBlockhashStoreOwnershipTransferred, 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 := _TrustedBlockhashStore.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(TrustedBlockhashStoreOwnershipTransferred) + if err := _TrustedBlockhashStore.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 (_TrustedBlockhashStore *TrustedBlockhashStoreFilterer) ParseOwnershipTransferred(log types.Log) (*TrustedBlockhashStoreOwnershipTransferred, error) { + event := new(TrustedBlockhashStoreOwnershipTransferred) + if err := _TrustedBlockhashStore.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_TrustedBlockhashStore *TrustedBlockhashStore) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _TrustedBlockhashStore.abi.Events["OwnershipTransferRequested"].ID: + return _TrustedBlockhashStore.ParseOwnershipTransferRequested(log) + case _TrustedBlockhashStore.abi.Events["OwnershipTransferred"].ID: + return _TrustedBlockhashStore.ParseOwnershipTransferred(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (TrustedBlockhashStoreOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (TrustedBlockhashStoreOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (_TrustedBlockhashStore *TrustedBlockhashStore) Address() common.Address { + return _TrustedBlockhashStore.address +} + +type TrustedBlockhashStoreInterface interface { + GetBlockhash(opts *bind.CallOpts, n *big.Int) ([32]byte, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SWhitelist(opts *bind.CallOpts, arg0 *big.Int) (common.Address, error) + + SWhitelistStatus(opts *bind.CallOpts, arg0 common.Address) (bool, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + SetWhitelist(opts *bind.TransactOpts, whitelist []common.Address) (*types.Transaction, error) + + Store(opts *bind.TransactOpts, n *big.Int) (*types.Transaction, error) + + StoreEarliest(opts *bind.TransactOpts) (*types.Transaction, error) + + StoreTrusted(opts *bind.TransactOpts, blockNums []*big.Int, blockhashes [][32]byte, recentBlockNumber *big.Int, recentBlockhash [32]byte) (*types.Transaction, error) + + StoreVerifyHeader(opts *bind.TransactOpts, n *big.Int, header []byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TrustedBlockhashStoreOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *TrustedBlockhashStoreOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*TrustedBlockhashStoreOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TrustedBlockhashStoreOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *TrustedBlockhashStoreOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*TrustedBlockhashStoreOwnershipTransferred, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/verifiable_load_log_trigger_upkeep_wrapper/verifiable_load_log_trigger_upkeep_wrapper.go b/core/gethwrappers/generated/verifiable_load_log_trigger_upkeep_wrapper/verifiable_load_log_trigger_upkeep_wrapper.go new file mode 100644 index 00000000000..4840897e022 --- /dev/null +++ b/core/gethwrappers/generated/verifiable_load_log_trigger_upkeep_wrapper/verifiable_load_log_trigger_upkeep_wrapper.go @@ -0,0 +1,2409 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package verifiable_load_log_trigger_upkeep_wrapper + +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 Log struct { + Index *big.Int + TxIndex *big.Int + TxHash [32]byte + BlockNumber *big.Int + BlockHash [32]byte + Source common.Address + Topics [][32]byte + Data []byte +} + +var VerifiableLoadLogTriggerUpkeepMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"_registrar\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useArb\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_autoLog\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_useMercury\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"feeds\",\"type\":\"string[]\"},{\"internalType\":\"string\",\"name\":\"timeParamKey\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"FeedLookup\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"LogEmitted\",\"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\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Received\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"UpkeepTopUp\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"UpkeepsRegistered\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BUCKET_SIZE\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"addLinkAmount\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"autoLog\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchCancelUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"number\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"checkGasToBurn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"performGasToBurn\",\"type\":\"uint256\"}],\"name\":\"batchRegisterUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"batchSendLogs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint32\",\"name\":\"interval\",\"type\":\"uint32\"}],\"name\":\"batchSetIntervals\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchUpdatePipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchWithdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bucketedDelays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"buckets\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"startGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"burnPerformGas\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"checkGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"txIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"log\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"}],\"name\":\"checkLog\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"counters\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"delays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"dummyMap\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emittedSig\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feedParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"feedsHex\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"firstPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"gasLimits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"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\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getBucketedDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getBucketedDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getLogTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"logTrigger\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"p\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getPxDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getSumDelayInBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getSumDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"intervals\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"lastTopUpBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkToken\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBalanceThresholdMultiplier\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performDataSizes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"previousPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registrar\",\"outputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contractIKeeperRegistryMaster\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"sendLog\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"setAddLinkAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_autoLog\",\"type\":\"bool\"}],\"name\":\"setAutoLog\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setCheckGasToBurn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"newRegistrar\",\"type\":\"address\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"newFeeds\",\"type\":\"string[]\"}],\"name\":\"setFeedsHex\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_interval\",\"type\":\"uint256\"}],\"name\":\"setInterval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"newMinBalanceThresholdMultiplier\",\"type\":\"uint8\"}],\"name\":\"setMinBalanceThresholdMultiplier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setPerformDataSize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setPerformGasToBurn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newInterval\",\"type\":\"uint256\"}],\"name\":\"setUpkeepTopUpCheckInterval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_useMercury\",\"type\":\"bool\"}],\"name\":\"setUseMercury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timeParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"topUpFund\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pipelineData\",\"type\":\"bytes\"}],\"name\":\"updateUpkeepPipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTopUpCheckInterval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useArbitrumBlockNum\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useMercury\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x7f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf086080526005601455601580546001600160681b0319166c140000000002c68af0bb140000179055606460c0526101a0604052604261012081815260e091829190620054fe6101403981526020016040518060800160405280604281526020016200554060429139905262000099906016906002620003c4565b506040805180820190915260098152680cccacac892c890caf60bb1b6020820152601790620000c9908262000540565b5060408051808201909152600b81526a313637b1b5a73ab6b132b960a91b6020820152601890620000fb908262000540565b503480156200010957600080fd5b5060405162005582380380620055828339810160408190526200012c9162000638565b83833380600081620001855760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620001b857620001b88162000319565b5050601180546001600160a01b0319166001600160a01b038516908117909155604080516330fe427560e21b815281516000945063c3f909d4926004808401939192918290030181865afa15801562000215573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200023b919062000697565b50601380546001600160a01b0319166001600160a01b038381169190911790915560115460408051631b6b6d2360e01b81529051939450911691631b6b6d23916004808201926020929091908290030181865afa158015620002a1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002c79190620006c8565b601280546001600160a01b0319166001600160a01b039290921691909117905550151560a052506019805461ffff191692151561ff001916929092176101009115159190910217905550620006ef9050565b336001600160a01b03821603620003735760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200017c565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b8280548282559060005260206000209081019282156200040f579160200282015b828111156200040f5782518290620003fe908262000540565b5091602001919060010190620003e5565b506200041d92915062000421565b5090565b808211156200041d57600062000438828262000442565b5060010162000421565b5080546200045090620004b1565b6000825580601f1062000461575050565b601f01602090049060005260206000209081019062000481919062000484565b50565b5b808211156200041d576000815560010162000485565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620004c657607f821691505b602082108103620004e757634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200053b57600081815260208120601f850160051c81016020861015620005165750805b601f850160051c820191505b81811015620005375782815560010162000522565b5050505b505050565b81516001600160401b038111156200055c576200055c6200049b565b62000574816200056d8454620004b1565b84620004ed565b602080601f831160018114620005ac5760008415620005935750858301515b600019600386901b1c1916600185901b17855562000537565b600085815260208120601f198616915b82811015620005dd57888601518255948401946001909101908401620005bc565b5085821015620005fc5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b03811681146200048157600080fd5b805180151581146200063357600080fd5b919050565b600080600080608085870312156200064f57600080fd5b84516200065c816200060c565b93506200066c6020860162000622565b92506200067c6040860162000622565b91506200068c6060860162000622565b905092959194509250565b60008060408385031215620006ab57600080fd5b8251620006b8816200060c565b6020939093015192949293505050565b600060208284031215620006db57600080fd5b8151620006e8816200060c565b9392505050565b60805160a05160c051614dc36200073b600039600081816105970152611e3e0152600081816108d301526130b3015260008181610c410152818161151c0152611a1c0152614dc36000f3fe60806040526004361061044e5760003560e01c806379ba509711610243578063af953a4a11610143578063d90c4a68116100bb578063e15e1b341161008a578063f2fde38b1161006f578063f2fde38b14610f5b578063fba7ffa314610f7b578063fcdc1f6314610fa857600080fd5b8063e15e1b3414610ef9578063e455308314610f4557600080fd5b8063d90c4a6814610e72578063daee1aeb14610e8c578063dbef701e14610eac578063e0114adb14610ecc57600080fd5b8063c41c815b11610112578063c98f10b0116100f7578063c98f10b014610dde578063d355852814610df3578063d6051a7214610e5257600080fd5b8063c41c815b14610d9f578063c804802214610dbe57600080fd5b8063af953a4a14610cf0578063afb28d1f14610d10578063becde0e114610d25578063c357f1f314610d4557600080fd5b80639b429354116101d6578063a6548248116101a5578063a6c60d891161018a578063a6c60d8914610c83578063a72aa27e14610ca3578063a79c404314610cc357600080fd5b8063a654824814610c2f578063a6b5947514610c6357600080fd5b80639b42935414610b915780639b51fb0d14610bbe5780639d385eaa14610bef5780639d6f1cc714610c0f57600080fd5b80638fcb3fba116102125780638fcb3fba14610ae8578063924ca57814610b15578063948108f714610b355780639ac542eb14610b5557600080fd5b806379ba509714610a5b5780637b10399914610a705780637e7a46dc14610a9d5780638da5cb5b14610abd57600080fd5b806346e7a63e1161034e578063636092e8116102e15780636b2120c6116102b057806373644cce1161029557806373644cce146109e15780637672130314610a0e578063776898c814610a3b57600080fd5b80636b2120c61461095f5780637145f11b146109b157600080fd5b8063636092e81461087f578063642f6cef146108c157806369cdbadb1461090557806369e9b7731461093257600080fd5b8063597109921161031d57806359710992146108085780635d4ee7f31461081d5780635f17e6161461083257806360457ff51461085257600080fd5b806346e7a63e1461076e5780634b56a42e1461079b57806351c98be3146107bb57806357970e93146107db57600080fd5b806320e3dbd4116103e1578063328ffd11116103b057806340691db41161039557806340691db4146107005780634585e33b1461072e57806345d2ec171461074e57600080fd5b8063328ffd11146106b35780633ebe8d6c146106e057600080fd5b806320e3dbd41461060157806328c4b57b146106215780632a9032d3146106415780632b20e3971461066157600080fd5b80630d4a4fb11161041d5780630d4a4fb1146105385780630e577d421461056557806312c5502714610585578063206c32e8146105cc57600080fd5b806305e251311461049257806306c1cc00146104b457806306e3b632146104d4578063077ac6211461050a57600080fd5b3661048d57604080513381523460208201527f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f88525874910160405180910390a1005b600080fd5b34801561049e57600080fd5b506104b26104ad3660046139e0565b610fd5565b005b3480156104c057600080fd5b506104b26104cf366004613b01565b610fec565b3480156104e057600080fd5b506104f46104ef366004613b9d565b6113a8565b6040516105019190613bbf565b60405180910390f35b34801561051657600080fd5b5061052a610525366004613c1a565b6114a7565b604051908152602001610501565b34801561054457600080fd5b50610558610553366004613c4f565b6114e5565b6040516105019190613cd6565b34801561057157600080fd5b506104b2610580366004613c4f565b611602565b34801561059157600080fd5b506105b97f000000000000000000000000000000000000000000000000000000000000000081565b60405161ffff9091168152602001610501565b3480156105d857600080fd5b506105ec6105e7366004613ce9565b61164a565b60408051928352602083019190915201610501565b34801561060d57600080fd5b506104b261061c366004613d37565b6116cd565b34801561062d57600080fd5b5061052a61063c366004613d54565b611897565b34801561064d57600080fd5b506104b261065c366004613dc5565b611902565b34801561066d57600080fd5b5060115461068e9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610501565b3480156106bf57600080fd5b5061052a6106ce366004613c4f565b60036020526000908152604090205481565b3480156106ec57600080fd5b5061052a6106fb366004613c4f565b61199c565b34801561070c57600080fd5b5061072061071b366004613e07565b611a05565b604051610501929190613e74565b34801561073a57600080fd5b506104b2610749366004613ed1565b611d3d565b34801561075a57600080fd5b506104f4610769366004613ce9565b611f9a565b34801561077a57600080fd5b5061052a610789366004613c4f565b600a6020526000908152604090205481565b3480156107a757600080fd5b506107206107b6366004613f07565b612009565b3480156107c757600080fd5b506104b26107d6366004613fc4565b61205d565b3480156107e757600080fd5b5060125461068e9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561081457600080fd5b506104b2612101565b34801561082957600080fd5b506104b26122ec565b34801561083e57600080fd5b506104b261084d366004613b9d565b612423565b34801561085e57600080fd5b5061052a61086d366004613c4f565b60076020526000908152604090205481565b34801561088b57600080fd5b506015546108a4906bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff9091168152602001610501565b3480156108cd57600080fd5b506108f57f000000000000000000000000000000000000000000000000000000000000000081565b6040519015158152602001610501565b34801561091157600080fd5b5061052a610920366004613c4f565b60086020526000908152604090205481565b34801561093e57600080fd5b506104b261094d366004613b9d565b60009182526008602052604090912055565b34801561096b57600080fd5b506104b261097a366004614029565b60198054911515610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909216919091179055565b3480156109bd57600080fd5b506108f56109cc366004613c4f565b600b6020526000908152604090205460ff1681565b3480156109ed57600080fd5b5061052a6109fc366004613c4f565b6000908152600c602052604090205490565b348015610a1a57600080fd5b5061052a610a29366004613c4f565b60046020526000908152604090205481565b348015610a4757600080fd5b506108f5610a56366004613c4f565b6124f0565b348015610a6757600080fd5b506104b2612542565b348015610a7c57600080fd5b5060135461068e9073ffffffffffffffffffffffffffffffffffffffff1681565b348015610aa957600080fd5b506104b2610ab8366004614046565b61263f565b348015610ac957600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff1661068e565b348015610af457600080fd5b5061052a610b03366004613c4f565b60056020526000908152604090205481565b348015610b2157600080fd5b506104b2610b30366004613b9d565b6126d0565b348015610b4157600080fd5b506104b2610b50366004614092565b612915565b348015610b6157600080fd5b50601554610b7f906c01000000000000000000000000900460ff1681565b60405160ff9091168152602001610501565b348015610b9d57600080fd5b506104b2610bac366004613b9d565b60009182526009602052604090912055565b348015610bca57600080fd5b506105b9610bd9366004613c4f565b600e6020526000908152604090205461ffff1681565b348015610bfb57600080fd5b506104f4610c0a366004613c4f565b612a5e565b348015610c1b57600080fd5b50610558610c2a366004613c4f565b612ac0565b348015610c3b57600080fd5b5061052a7f000000000000000000000000000000000000000000000000000000000000000081565b348015610c6f57600080fd5b506104b2610c7e366004613d54565b612b6c565b348015610c8f57600080fd5b506104b2610c9e366004613c4f565b601455565b348015610caf57600080fd5b506104b2610cbe3660046140c2565b612bd5565b348015610ccf57600080fd5b506104b2610cde366004613b9d565b60009182526007602052604090912055565b348015610cfc57600080fd5b506104b2610d0b366004613c4f565b612c80565b348015610d1c57600080fd5b50610558612d06565b348015610d3157600080fd5b506104b2610d40366004613dc5565b612d13565b348015610d5157600080fd5b506104b2610d603660046140e7565b601580547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff92909216919091179055565b348015610dab57600080fd5b506019546108f590610100900460ff1681565b348015610dca57600080fd5b506104b2610dd9366004613c4f565b612dad565b348015610dea57600080fd5b50610558612e45565b348015610dff57600080fd5b506104b2610e0e366004614104565b6015805460ff9092166c01000000000000000000000000027fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff909216919091179055565b348015610e5e57600080fd5b506105ec610e6d366004613b9d565b612e52565b348015610e7e57600080fd5b506019546108f59060ff1681565b348015610e9857600080fd5b506104b2610ea7366004613dc5565b612ebb565b348015610eb857600080fd5b5061052a610ec7366004613b9d565b612f86565b348015610ed857600080fd5b5061052a610ee7366004613c4f565b60096020526000908152604090205481565b348015610f0557600080fd5b506104b2610f14366004614029565b601980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b348015610f5157600080fd5b5061052a60145481565b348015610f6757600080fd5b506104b2610f76366004613d37565b612fb7565b348015610f8757600080fd5b5061052a610f96366004613c4f565b60066020526000908152604090205481565b348015610fb457600080fd5b5061052a610fc3366004613c4f565b60026020526000908152604090205481565b8051610fe89060169060208401906137b0565b5050565b6040805161018081018252600461014082019081527f746573740000000000000000000000000000000000000000000000000000000061016083015281528151602081810184526000808352818401929092523083850181905263ffffffff8b166060850152608084015260ff808a1660a08501528451808301865283815260c085015260e0840189905284519182019094529081526101008201526bffffffffffffffffffffffff8516610120820152601254601154919273ffffffffffffffffffffffffffffffffffffffff9182169263095ea7b39216906110d2908c1688614150565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526bffffffffffffffffffffffff1660248201526044016020604051808303816000875af1158015611150573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611174919061418f565b5060008860ff1667ffffffffffffffff81111561119357611193613890565b6040519080825280602002602001820160405280156111bc578160200160208202803683370190505b50905060005b8960ff168160ff1610156113655760006111db84612fcb565b90508860ff16600103611313576040517f0d4a4fb1000000000000000000000000000000000000000000000000000000008152600481018290526000903090630d4a4fb190602401600060405180830381865afa158015611240573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261128691908101906141f9565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634ee88d35906112df908590859060040161422e565b600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b50505050505b80838360ff168151811061132957611329614247565b6020908102919091018101919091526000918252600881526040808320889055600790915290208490558061135d81614276565b9150506111c2565b507f2ee10f7eb180441fb9fbba75b10c0162b5390b557712c93426243ca8f383c711816040516113959190613bbf565b60405180910390a1505050505050505050565b606060006113b6600f613099565b90508084106113f1576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611406576114038482614295565b92505b60008367ffffffffffffffff81111561142157611421613890565b60405190808252806020026020018201604052801561144a578160200160208202803683370190505b50905060005b8481101561149c5761146d61146582886142a8565b600f906130a3565b82828151811061147f5761147f614247565b602090810291909101015280611494816142bb565b915050611450565b509150505b92915050565b600d60205282600052604060002060205281600052604060002081815481106114cf57600080fd5b9060005260206000200160009250925050505481565b606060006040518060c001604052803073ffffffffffffffffffffffffffffffffffffffff168152602001600160ff1681526020017f000000000000000000000000000000000000000000000000000000000000000081526020018460405160200161155391815260200190565b60405160208183030381529060405261156b906142f3565b81526020016000801b81526020016000801b8152509050806040516020016115eb9190600060c08201905073ffffffffffffffffffffffffffffffffffffffff835116825260ff602084015116602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015292915050565b604051602081830303815290604052915050919050565b600061160c6130af565b604051308152909150819083907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf089060200160405180910390a35050565b6000828152600d6020908152604080832061ffff8516845282528083208054825181850281018501909352808352849384939291908301828280156116ae57602002820191906000526020600020905b81548152602001906001019080831161169a575b505050505090506116c0818251613151565b92509250505b9250929050565b601180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117909155604080517fc3f909d400000000000000000000000000000000000000000000000000000000815281516000939263c3f909d492600480820193918290030181865afa158015611763573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117879190614343565b50601380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691909117909155601154604080517f1b6b6d230000000000000000000000000000000000000000000000000000000081529051939450911691631b6b6d23916004808201926020929091908290030181865afa15801561182a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184e9190614371565b601280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555050565b6000838152600c6020908152604080832080548251818502810185019093528083526118f8938301828280156118ec57602002820191906000526020600020905b8154815260200190600101908083116118d8575b505050505084846131d6565b90505b9392505050565b8060005b818160ff161015611996573063c8048022858560ff851681811061192c5761192c614247565b905060200201356040518263ffffffff1660e01b815260040161195191815260200190565b600060405180830381600087803b15801561196b57600080fd5b505af115801561197f573d6000803e3d6000fd5b50505050808061198e90614276565b915050611906565b50505050565b6000818152600e602052604081205461ffff1681805b8261ffff168161ffff16116119fd576000858152600d6020908152604080832061ffff851684529091529020546119e990836142a8565b9150806119f58161438e565b9150506119b2565b509392505050565b6000606060005a90506000611a186130af565b90507f0000000000000000000000000000000000000000000000000000000000000000611a4860c08801886143af565b6000818110611a5957611a59614247565b9050602002013503611cb5576000611a7460c08801886143af565b6001818110611a8557611a85614247565b90506020020135604051602001611a9e91815260200190565b6040516020818303038152906040529050600081806020019051810190611ac59190614417565b90506000611ad660c08a018a6143af565b6002818110611ae757611ae7614247565b90506020020135604051602001611b0091815260200190565b6040516020818303038152906040529050600081806020019051810190611b279190614417565b6000848152600860205260409020549091505b805a611b469089614295565b611b5290613a986142a8565b1015611b935781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055611b3a565b601954610100900460ff1615611c3157601760166018848786604051602001611bc6929190918252602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f7ddd933e000000000000000000000000000000000000000000000000000000008252611c289594939291600401614518565b60405180910390fd5b604080516001808252818301909252600091816020015b6060815260200190600190039081611c4857505060408051602081018890528082018690528151808203830181526060820190925291925090600190611c9490849084906080016145db565b6040516020818303038152906040529a509a505050505050505050506116c6565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f636f756c64206e6f742066696e64206d61746368696e67206576656e7420736960448201527f67000000000000000000000000000000000000000000000000000000000000006064820152608401611c28565b60005a9050600080611d5184860186613f07565b9150915060008082806020019051810190611d6c919061466f565b6000828152600560209081526040808320546004909252822054939550919350909190611d976130af565b905082600003611db7576000858152600560205260409020819055611efb565b6000611dc38583614295565b6000878152600e6020908152604080832054600d835281842061ffff909116808552908352818420805483518186028101860190945280845295965090949192909190830182828015611e3557602002820191906000526020600020905b815481526020019060010190808311611e21575b505050505090507f000000000000000000000000000000000000000000000000000000000000000061ffff16815103611eb05781611e728161438e565b60008a8152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff83161790559250505b506000878152600d6020908152604080832061ffff909416835292815282822080546001818101835591845282842001859055898352600c8252928220805493840181558252902001555b600085815260066020526040812054611f159060016142a8565b6000878152600660209081526040808320849055600490915290208390559050611f3f86836126d0565b60195460ff1615611f8257604051308152829087907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf089060200160405180910390a35b611f8d868a84612b6c565b5050505050505050505050565b6000828152600d6020908152604080832061ffff85168452825291829020805483518184028101840190945280845260609392830182828015611ffc57602002820191906000526020600020905b815481526020019060010190808311611fe8575b5050505050905092915050565b60006060600084846040516020016120229291906145db565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181529190526001969095509350505050565b8160005b818110156120fa5730635f17e61686868481811061208157612081614247565b90506020020135856040518363ffffffff1660e01b81526004016120b592919091825263ffffffff16602082015260400190565b600060405180830381600087803b1580156120cf57600080fd5b505af11580156120e3573d6000803e3d6000fd5b5050505080806120f2906142bb565b915050612061565b5050505050565b6013546040517f06e3b632000000000000000000000000000000000000000000000000000000008152600060048201819052602482018190529173ffffffffffffffffffffffffffffffffffffffff16906306e3b63290604401600060405180830381865afa158015612178573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526121be9190810190614693565b805190915060006121cd6130af565b905060005b828110156119965760008482815181106121ee576121ee614247565b60209081029190910101516013546040517f5147cd590000000000000000000000000000000000000000000000000000000081526004810183905291925060009173ffffffffffffffffffffffffffffffffffffffff90911690635147cd5990602401602060405180830381865afa15801561226e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122929190614724565b90508060ff166001036122d757604051308152849083907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf089060200160405180910390a35b505080806122e4906142bb565b9150506121d2565b6122f4613335565b6012546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612363573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123879190614417565b6012546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810183905291925073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb906044016020604051808303816000875af11580156123ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe8919061418f565b60008281526003602090815260408083208490556005825280832083905560068252808320839055600c909152812061245b91613806565b6000828152600e602052604081205461ffff16905b8161ffff168161ffff16116124b7576000848152600d6020908152604080832061ffff8516845290915281206124a591613806565b806124af8161438e565b915050612470565b5050506000908152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055565b600081815260056020526040812054810361250d57506001919050565b6000828152600360209081526040808320546004909252909120546125306130af565b61253a9190614295565b101592915050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146125c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401611c28565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6013546040517fcd7f71b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063cd7f71b59061269990869086908690600401614741565b600060405180830381600087803b1580156126b357600080fd5b505af11580156126c7573d6000803e3d6000fd5b50505050505050565b6014546000838152600260205260409020546126ec9083614295565b1115610fe8576013546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810184905260009173ffffffffffffffffffffffffffffffffffffffff169063c7c3a19a90602401600060405180830381865afa158015612762573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526127a891908101906147c3565b6013546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810186905291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063b657bc9c90602401602060405180830381865afa15801561281d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061284191906148e2565b6015549091506128659082906c01000000000000000000000000900460ff16614150565b6bffffffffffffffffffffffff1682606001516bffffffffffffffffffffffff161015611996576015546128a89085906bffffffffffffffffffffffff16612915565b60008481526002602090815260409182902085905560155482518781526bffffffffffffffffffffffff909116918101919091529081018490527f49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c09060600160405180910390a150505050565b6012546013546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526bffffffffffffffffffffffff8416602482015291169063095ea7b3906044016020604051808303816000875af115801561299d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c1919061418f565b506013546040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063948108f790604401600060405180830381600087803b158015612a4257600080fd5b505af1158015612a56573d6000803e3d6000fd5b505050505050565b6000818152600c6020908152604091829020805483518184028101840190945280845260609392830182828015612ab457602002820191906000526020600020905b815481526020019060010190808311612aa0575b50505050509050919050565b60168181548110612ad057600080fd5b906000526020600020016000915090508054612aeb90614430565b80601f0160208091040260200160405190810160405280929190818152602001828054612b1790614430565b8015612b645780601f10612b3957610100808354040283529160200191612b64565b820191906000526020600020905b815481529060010190602001808311612b4757829003601f168201915b505050505081565b6000838152600760205260409020545b805a612b889085614295565b612b94906127106142a8565b10156119965781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055612b7c565b6013546040517fa72aa27e0000000000000000000000000000000000000000000000000000000081526004810184905263ffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063a72aa27e90604401600060405180830381600087803b158015612c4d57600080fd5b505af1158015612c61573d6000803e3d6000fd5b505050600092835250600a602052604090912063ffffffff9091169055565b6013546040517f744bfe610000000000000000000000000000000000000000000000000000000081526004810183905230602482015273ffffffffffffffffffffffffffffffffffffffff9091169063744bfe6190604401600060405180830381600087803b158015612cf257600080fd5b505af11580156120fa573d6000803e3d6000fd5b60178054612aeb90614430565b8060005b818163ffffffff161015611996573063af953a4a858563ffffffff8516818110612d4357612d43614247565b905060200201356040518263ffffffff1660e01b8152600401612d6891815260200190565b600060405180830381600087803b158015612d8257600080fd5b505af1158015612d96573d6000803e3d6000fd5b505050508080612da5906148ff565b915050612d17565b6013546040517fc80480220000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff9091169063c804802290602401600060405180830381600087803b158015612e1957600080fd5b505af1158015612e2d573d6000803e3d6000fd5b50505050610fe881600f6133b890919063ffffffff16565b60188054612aeb90614430565b6000828152600c60209081526040808320805482518185028101850190935280835284938493929190830182828015612eaa57602002820191906000526020600020905b815481526020019060010190808311612e96575b505050505090506116c08185613151565b8060005b81811015611996576000848483818110612edb57612edb614247565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc8283604051602001612f1491815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401612f4092919061422e565b600060405180830381600087803b158015612f5a57600080fd5b505af1158015612f6e573d6000803e3d6000fd5b50505050508080612f7e906142bb565b915050612ebf565b600c6020528160005260406000208181548110612fa257600080fd5b90600052602060002001600091509150505481565b612fbf613335565b612fc8816133c4565b50565b6011546040517f3f678e11000000000000000000000000000000000000000000000000000000008152600091829173ffffffffffffffffffffffffffffffffffffffff90911690633f678e1190613026908690600401614918565b6020604051808303816000875af1158015613045573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130699190614417565b9050613076600f826134b9565b506060909201516000838152600a6020526040902063ffffffff90911690555090565b60006114a1825490565b60006118fb83836134c5565b60007f00000000000000000000000000000000000000000000000000000000000000001561314c57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613123573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131479190614417565b905090565b504390565b8151600090819081908415806131675750808510155b15613170578094505b60008092505b858310156131cc5786600161318b8585614295565b6131959190614295565b815181106131a5576131a5614247565b6020026020010151816131b891906142a8565b9050826131c4816142bb565b935050613176565b9694955050505050565b825160009081908315806131ea5750808410155b156131f3578093505b60008467ffffffffffffffff81111561320e5761320e613890565b604051908082528060200260200182016040528015613237578160200160208202803683370190505b509050600092505b848310156132a5578660016132548585614295565b61325e9190614295565b8151811061326e5761326e614247565b602002602001015181848151811061328857613288614247565b60209081029190910101528261329d816142bb565b93505061323f565b6132be816000600184516132b99190614295565b6134ef565b856064036132f75780600182516132d59190614295565b815181106132e5576132e5614247565b602002602001015193505050506118fb565b8060648251886133079190614a6a565b6133119190614ad6565b8151811061332157613321614247565b602002602001015193505050509392505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146133b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401611c28565b565b60006118fb8383613667565b3373ffffffffffffffffffffffffffffffffffffffff821603613443576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401611c28565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006118fb8383613761565b60008260000182815481106134dc576134dc614247565b9060005260206000200154905092915050565b81818082036134ff575050505050565b600085600261350e8787614aea565b6135189190614b0a565b6135229087614b72565b8151811061353257613532614247565b602002602001015190505b818313613641575b8086848151811061355857613558614247565b60200260200101511015613578578261357081614b9a565b935050613545565b85828151811061358a5761358a614247565b60200260200101518110156135ab57816135a381614bcb565b925050613578565b81831361363c578582815181106135c4576135c4614247565b60200260200101518684815181106135de576135de614247565b60200260200101518785815181106135f8576135f8614247565b6020026020010188858151811061361157613611614247565b6020908102919091010191909152528261362a81614b9a565b935050818061363890614bcb565b9250505b61353d565b81851215613654576136548686846134ef565b83831215612a5657612a568684866134ef565b6000818152600183016020526040812054801561375057600061368b600183614295565b855490915060009061369f90600190614295565b90508181146137045760008660000182815481106136bf576136bf614247565b90600052602060002001549050808760000184815481106136e2576136e2614247565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061371557613715614c22565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506114a1565b60009150506114a1565b5092915050565b60008181526001830160205260408120546137a8575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556114a1565b5060006114a1565b8280548282559060005260206000209081019282156137f6579160200282015b828111156137f657825182906137e69082614c9c565b50916020019190600101906137d0565b50613802929150613824565b5090565b5080546000825590600052602060002090810190612fc89190613841565b808211156138025760006138388282613856565b50600101613824565b5b808211156138025760008155600101613842565b50805461386290614430565b6000825580601f10613872575050565b601f016020900490600052602060002090810190612fc89190613841565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff811182821017156138e3576138e3613890565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561393057613930613890565b604052919050565b600067ffffffffffffffff82111561395257613952613890565b5060051b60200190565b600067ffffffffffffffff82111561397657613976613890565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60006139b56139b08461395c565b6138e9565b90508281528383830111156139c957600080fd5b828260208301376000602084830101529392505050565b600060208083850312156139f357600080fd5b823567ffffffffffffffff80821115613a0b57600080fd5b818501915085601f830112613a1f57600080fd5b8135613a2d6139b082613938565b81815260059190911b83018401908481019088831115613a4c57600080fd5b8585015b83811015613a9957803585811115613a685760008081fd5b8601603f81018b13613a7a5760008081fd5b613a8b8b89830135604084016139a2565b845250918601918601613a50565b5098975050505050505050565b60ff81168114612fc857600080fd5b63ffffffff81168114612fc857600080fd5b600082601f830112613ad857600080fd5b6118fb838335602085016139a2565b6bffffffffffffffffffffffff81168114612fc857600080fd5b600080600080600080600060e0888a031215613b1c57600080fd5b8735613b2781613aa6565b96506020880135613b3781613ab5565b95506040880135613b4781613aa6565b9450606088013567ffffffffffffffff811115613b6357600080fd5b613b6f8a828b01613ac7565b9450506080880135613b8081613ae7565b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215613bb057600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b81811015613bf757835183529284019291840191600101613bdb565b50909695505050505050565b803561ffff81168114613c1557600080fd5b919050565b600080600060608486031215613c2f57600080fd5b83359250613c3f60208501613c03565b9150604084013590509250925092565b600060208284031215613c6157600080fd5b5035919050565b60005b83811015613c83578181015183820152602001613c6b565b50506000910152565b60008151808452613ca4816020860160208601613c68565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006118fb6020830184613c8c565b60008060408385031215613cfc57600080fd5b82359150613d0c60208401613c03565b90509250929050565b73ffffffffffffffffffffffffffffffffffffffff81168114612fc857600080fd5b600060208284031215613d4957600080fd5b81356118fb81613d15565b600080600060608486031215613d6957600080fd5b505081359360208301359350604090920135919050565b60008083601f840112613d9257600080fd5b50813567ffffffffffffffff811115613daa57600080fd5b6020830191508360208260051b85010111156116c657600080fd5b60008060208385031215613dd857600080fd5b823567ffffffffffffffff811115613def57600080fd5b613dfb85828601613d80565b90969095509350505050565b60008060408385031215613e1a57600080fd5b823567ffffffffffffffff80821115613e3257600080fd5b908401906101008287031215613e4757600080fd5b90925060208401359080821115613e5d57600080fd5b50613e6a85828601613ac7565b9150509250929050565b82151581526040602082015260006118f86040830184613c8c565b60008083601f840112613ea157600080fd5b50813567ffffffffffffffff811115613eb957600080fd5b6020830191508360208285010111156116c657600080fd5b60008060208385031215613ee457600080fd5b823567ffffffffffffffff811115613efb57600080fd5b613dfb85828601613e8f565b60008060408385031215613f1a57600080fd5b823567ffffffffffffffff80821115613f3257600080fd5b818501915085601f830112613f4657600080fd5b81356020613f566139b083613938565b82815260059290921b84018101918181019089841115613f7557600080fd5b8286015b84811015613fad57803586811115613f915760008081fd5b613f9f8c86838b0101613ac7565b845250918301918301613f79565b5096505086013592505080821115613e5d57600080fd5b600080600060408486031215613fd957600080fd5b833567ffffffffffffffff811115613ff057600080fd5b613ffc86828701613d80565b909450925050602084013561401081613ab5565b809150509250925092565b8015158114612fc857600080fd5b60006020828403121561403b57600080fd5b81356118fb8161401b565b60008060006040848603121561405b57600080fd5b83359250602084013567ffffffffffffffff81111561407957600080fd5b61408586828701613e8f565b9497909650939450505050565b600080604083850312156140a557600080fd5b8235915060208301356140b781613ae7565b809150509250929050565b600080604083850312156140d557600080fd5b8235915060208301356140b781613ab5565b6000602082840312156140f957600080fd5b81356118fb81613ae7565b60006020828403121561411657600080fd5b81356118fb81613aa6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006bffffffffffffffffffffffff8083168185168183048111821515161561417b5761417b614121565b02949350505050565b8051613c158161401b565b6000602082840312156141a157600080fd5b81516118fb8161401b565b600082601f8301126141bd57600080fd5b81516141cb6139b08261395c565b8181528460208386010111156141e057600080fd5b6141f1826020830160208701613c68565b949350505050565b60006020828403121561420b57600080fd5b815167ffffffffffffffff81111561422257600080fd5b6141f1848285016141ac565b8281526040602082015260006118f86040830184613c8c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff821660ff810361428c5761428c614121565b60010192915050565b818103818111156114a1576114a1614121565b808201808211156114a1576114a1614121565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036142ec576142ec614121565b5060010190565b80516020808301519190811015614332577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8051613c1581613d15565b6000806040838503121561435657600080fd5b825161436181613d15565b6020939093015192949293505050565b60006020828403121561438357600080fd5b81516118fb81613d15565b600061ffff8083168181036143a5576143a5614121565b6001019392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126143e457600080fd5b83018035915067ffffffffffffffff8211156143ff57600080fd5b6020019150600581901b36038213156116c657600080fd5b60006020828403121561442957600080fd5b5051919050565b600181811c9082168061444457607f821691505b602082108103614332577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000815461448a81614430565b8085526020600183811680156144a757600181146144df5761450d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b890101955061450d565b866000528260002060005b858110156145055781548a82018601529083019084016144ea565b890184019650505b505050505092915050565b60a08152600061452b60a083018861447d565b6020838203818501528188548084528284019150828160051b8501018a6000528360002060005b8381101561459d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe087840301855261458b838361447d565b94860194925060019182019101614552565b505086810360408801526145b1818b61447d565b94505050505084606084015282810360808401526145cf8185613c8c565b98975050505050505050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015614650577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa088870301855261463e868351613c8c565b95509382019390820190600101614604565b5050858403818701525050506146668185613c8c565b95945050505050565b6000806040838503121561468257600080fd5b505080516020909101519092909150565b600060208083850312156146a657600080fd5b825167ffffffffffffffff8111156146bd57600080fd5b8301601f810185136146ce57600080fd5b80516146dc6139b082613938565b81815260059190911b820183019083810190878311156146fb57600080fd5b928401925b8284101561471957835182529284019290840190614700565b979650505050505050565b60006020828403121561473657600080fd5b81516118fb81613aa6565b83815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b8051613c1581613ab5565b8051613c1581613ae7565b805167ffffffffffffffff81168114613c1557600080fd5b6000602082840312156147d557600080fd5b815167ffffffffffffffff808211156147ed57600080fd5b90830190610140828603121561480257600080fd5b61480a6138bf565b61481383614338565b815261482160208401614795565b602082015260408301518281111561483857600080fd5b614844878286016141ac565b604083015250614856606084016147a0565b606082015261486760808401614338565b608082015261487860a084016147ab565b60a082015261488960c08401614795565b60c082015261489a60e084016147a0565b60e08201526101006148ad818501614184565b9082015261012083810151838111156148c557600080fd5b6148d1888287016141ac565b918301919091525095945050505050565b6000602082840312156148f457600080fd5b81516118fb81613ae7565b600063ffffffff8083168181036143a5576143a5614121565b6020815260008251610140806020850152614937610160850183613c8c565b915060208501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808685030160408701526149738483613c8c565b93506040870151915061499e606087018373ffffffffffffffffffffffffffffffffffffffff169052565b606087015163ffffffff811660808801529150608087015173ffffffffffffffffffffffffffffffffffffffff811660a0880152915060a087015160ff811660c0880152915060c08701519150808685030160e08701526149ff8483613c8c565b935060e08701519150610100818786030181880152614a1e8584613c8c565b945080880151925050610120818786030181880152614a3d8584613c8c565b94508088015192505050614a60828601826bffffffffffffffffffffffff169052565b5090949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614aa257614aa2614121565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614ae557614ae5614aa7565b500490565b818103600083128015838313168383128216171561375a5761375a614121565b600082614b1957614b19614aa7565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615614b6d57614b6d614121565b500590565b8082018281126000831280158216821582161715614b9257614b92614121565b505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036142ec576142ec614121565b60007f80000000000000000000000000000000000000000000000000000000000000008203614bfc57614bfc614121565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b601f821115614c9757600081815260208120601f850160051c81016020861015614c785750805b601f850160051c820191505b81811015612a5657828155600101614c84565b505050565b815167ffffffffffffffff811115614cb657614cb6613890565b614cca81614cc48454614430565b84614c51565b602080601f831160018114614d1d5760008415614ce75750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555612a56565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015614d6a57888601518255948401946001909101908401614d4b565b5085821015614da657878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000810000a307834353534343832643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030307834323534343332643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030", +} + +var VerifiableLoadLogTriggerUpkeepABI = VerifiableLoadLogTriggerUpkeepMetaData.ABI + +var VerifiableLoadLogTriggerUpkeepBin = VerifiableLoadLogTriggerUpkeepMetaData.Bin + +func DeployVerifiableLoadLogTriggerUpkeep(auth *bind.TransactOpts, backend bind.ContractBackend, _registrar common.Address, _useArb bool, _autoLog bool, _useMercury bool) (common.Address, *types.Transaction, *VerifiableLoadLogTriggerUpkeep, error) { + parsed, err := VerifiableLoadLogTriggerUpkeepMetaData.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(VerifiableLoadLogTriggerUpkeepBin), backend, _registrar, _useArb, _autoLog, _useMercury) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &VerifiableLoadLogTriggerUpkeep{VerifiableLoadLogTriggerUpkeepCaller: VerifiableLoadLogTriggerUpkeepCaller{contract: contract}, VerifiableLoadLogTriggerUpkeepTransactor: VerifiableLoadLogTriggerUpkeepTransactor{contract: contract}, VerifiableLoadLogTriggerUpkeepFilterer: VerifiableLoadLogTriggerUpkeepFilterer{contract: contract}}, nil +} + +type VerifiableLoadLogTriggerUpkeep struct { + address common.Address + abi abi.ABI + VerifiableLoadLogTriggerUpkeepCaller + VerifiableLoadLogTriggerUpkeepTransactor + VerifiableLoadLogTriggerUpkeepFilterer +} + +type VerifiableLoadLogTriggerUpkeepCaller struct { + contract *bind.BoundContract +} + +type VerifiableLoadLogTriggerUpkeepTransactor struct { + contract *bind.BoundContract +} + +type VerifiableLoadLogTriggerUpkeepFilterer struct { + contract *bind.BoundContract +} + +type VerifiableLoadLogTriggerUpkeepSession struct { + Contract *VerifiableLoadLogTriggerUpkeep + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type VerifiableLoadLogTriggerUpkeepCallerSession struct { + Contract *VerifiableLoadLogTriggerUpkeepCaller + CallOpts bind.CallOpts +} + +type VerifiableLoadLogTriggerUpkeepTransactorSession struct { + Contract *VerifiableLoadLogTriggerUpkeepTransactor + TransactOpts bind.TransactOpts +} + +type VerifiableLoadLogTriggerUpkeepRaw struct { + Contract *VerifiableLoadLogTriggerUpkeep +} + +type VerifiableLoadLogTriggerUpkeepCallerRaw struct { + Contract *VerifiableLoadLogTriggerUpkeepCaller +} + +type VerifiableLoadLogTriggerUpkeepTransactorRaw struct { + Contract *VerifiableLoadLogTriggerUpkeepTransactor +} + +func NewVerifiableLoadLogTriggerUpkeep(address common.Address, backend bind.ContractBackend) (*VerifiableLoadLogTriggerUpkeep, error) { + abi, err := abi.JSON(strings.NewReader(VerifiableLoadLogTriggerUpkeepABI)) + if err != nil { + return nil, err + } + contract, err := bindVerifiableLoadLogTriggerUpkeep(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &VerifiableLoadLogTriggerUpkeep{address: address, abi: abi, VerifiableLoadLogTriggerUpkeepCaller: VerifiableLoadLogTriggerUpkeepCaller{contract: contract}, VerifiableLoadLogTriggerUpkeepTransactor: VerifiableLoadLogTriggerUpkeepTransactor{contract: contract}, VerifiableLoadLogTriggerUpkeepFilterer: VerifiableLoadLogTriggerUpkeepFilterer{contract: contract}}, nil +} + +func NewVerifiableLoadLogTriggerUpkeepCaller(address common.Address, caller bind.ContractCaller) (*VerifiableLoadLogTriggerUpkeepCaller, error) { + contract, err := bindVerifiableLoadLogTriggerUpkeep(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &VerifiableLoadLogTriggerUpkeepCaller{contract: contract}, nil +} + +func NewVerifiableLoadLogTriggerUpkeepTransactor(address common.Address, transactor bind.ContractTransactor) (*VerifiableLoadLogTriggerUpkeepTransactor, error) { + contract, err := bindVerifiableLoadLogTriggerUpkeep(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &VerifiableLoadLogTriggerUpkeepTransactor{contract: contract}, nil +} + +func NewVerifiableLoadLogTriggerUpkeepFilterer(address common.Address, filterer bind.ContractFilterer) (*VerifiableLoadLogTriggerUpkeepFilterer, error) { + contract, err := bindVerifiableLoadLogTriggerUpkeep(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &VerifiableLoadLogTriggerUpkeepFilterer{contract: contract}, nil +} + +func bindVerifiableLoadLogTriggerUpkeep(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := VerifiableLoadLogTriggerUpkeepMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VerifiableLoadLogTriggerUpkeep.Contract.VerifiableLoadLogTriggerUpkeepCaller.contract.Call(opts, result, method, params...) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.VerifiableLoadLogTriggerUpkeepTransactor.contract.Transfer(opts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.VerifiableLoadLogTriggerUpkeepTransactor.contract.Transact(opts, method, params...) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VerifiableLoadLogTriggerUpkeep.Contract.contract.Call(opts, result, method, params...) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.contract.Transfer(opts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.contract.Transact(opts, method, params...) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) BUCKETSIZE(opts *bind.CallOpts) (uint16, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "BUCKET_SIZE") + + if err != nil { + return *new(uint16), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) BUCKETSIZE() (uint16, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.BUCKETSIZE(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) BUCKETSIZE() (uint16, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.BUCKETSIZE(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) AddLinkAmount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "addLinkAmount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) AddLinkAmount() (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.AddLinkAmount(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) AddLinkAmount() (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.AddLinkAmount(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) AutoLog(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "autoLog") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) AutoLog() (bool, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.AutoLog(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) AutoLog() (bool, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.AutoLog(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) BucketedDelays(opts *bind.CallOpts, arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "bucketedDelays", arg0, arg1, arg2) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) BucketedDelays(arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.BucketedDelays(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0, arg1, arg2) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) BucketedDelays(arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.BucketedDelays(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0, arg1, arg2) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) Buckets(opts *bind.CallOpts, arg0 *big.Int) (uint16, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "buckets", arg0) + + if err != nil { + return *new(uint16), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) Buckets(arg0 *big.Int) (uint16, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.Buckets(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) Buckets(arg0 *big.Int) (uint16, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.Buckets(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (bool, []byte, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "checkCallback", values, extraData) + + if err != nil { + return *new(bool), *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + out1 := *abi.ConvertType(out[1], new([]byte)).(*[]byte) + + return out0, out1, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) CheckCallback(values [][]byte, extraData []byte) (bool, []byte, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.CheckCallback(&_VerifiableLoadLogTriggerUpkeep.CallOpts, values, extraData) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) CheckCallback(values [][]byte, extraData []byte) (bool, []byte, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.CheckCallback(&_VerifiableLoadLogTriggerUpkeep.CallOpts, values, extraData) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) CheckGasToBurns(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "checkGasToBurns", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) CheckGasToBurns(arg0 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.CheckGasToBurns(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) CheckGasToBurns(arg0 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.CheckGasToBurns(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) Counters(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "counters", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) Counters(arg0 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.Counters(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) Counters(arg0 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.Counters(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) Delays(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "delays", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) Delays(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.Delays(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0, arg1) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) Delays(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.Delays(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0, arg1) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) DummyMap(opts *bind.CallOpts, arg0 [32]byte) (bool, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "dummyMap", arg0) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) DummyMap(arg0 [32]byte) (bool, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.DummyMap(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) DummyMap(arg0 [32]byte) (bool, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.DummyMap(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) Eligible(opts *bind.CallOpts, upkeepId *big.Int) (bool, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "eligible", upkeepId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) Eligible(upkeepId *big.Int) (bool, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.Eligible(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) Eligible(upkeepId *big.Int) (bool, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.Eligible(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) EmittedSig(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "emittedSig") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) EmittedSig() ([32]byte, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.EmittedSig(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) EmittedSig() ([32]byte, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.EmittedSig(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) FeedParamKey(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "feedParamKey") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) FeedParamKey() (string, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.FeedParamKey(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) FeedParamKey() (string, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.FeedParamKey(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) FeedsHex(opts *bind.CallOpts, arg0 *big.Int) (string, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "feedsHex", arg0) + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) FeedsHex(arg0 *big.Int) (string, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.FeedsHex(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) FeedsHex(arg0 *big.Int) (string, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.FeedsHex(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) FirstPerformBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "firstPerformBlocks", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) FirstPerformBlocks(arg0 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.FirstPerformBlocks(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) FirstPerformBlocks(arg0 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.FirstPerformBlocks(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GasLimits(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "gasLimits", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GasLimits(arg0 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.GasLimits(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GasLimits(arg0 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.GasLimits(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetActiveUpkeepIDs(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "getActiveUpkeepIDs", startIndex, maxCount) + + if err != nil { + return *new([]*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GetActiveUpkeepIDs(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.GetActiveUpkeepIDs(&_VerifiableLoadLogTriggerUpkeep.CallOpts, startIndex, maxCount) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GetActiveUpkeepIDs(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.GetActiveUpkeepIDs(&_VerifiableLoadLogTriggerUpkeep.CallOpts, startIndex, maxCount) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetBucketedDelays(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) ([]*big.Int, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "getBucketedDelays", upkeepId, bucket) + + if err != nil { + return *new([]*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GetBucketedDelays(upkeepId *big.Int, bucket uint16) ([]*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.GetBucketedDelays(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId, bucket) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GetBucketedDelays(upkeepId *big.Int, bucket uint16) ([]*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.GetBucketedDelays(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId, bucket) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetBucketedDelaysLength(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "getBucketedDelaysLength", upkeepId) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GetBucketedDelaysLength(upkeepId *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.GetBucketedDelaysLength(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GetBucketedDelaysLength(upkeepId *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.GetBucketedDelaysLength(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetDelays(opts *bind.CallOpts, upkeepId *big.Int) ([]*big.Int, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "getDelays", upkeepId) + + if err != nil { + return *new([]*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GetDelays(upkeepId *big.Int) ([]*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.GetDelays(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GetDelays(upkeepId *big.Int) ([]*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.GetDelays(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetDelaysLength(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "getDelaysLength", upkeepId) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GetDelaysLength(upkeepId *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.GetDelaysLength(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GetDelaysLength(upkeepId *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.GetDelaysLength(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetLogTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "getLogTriggerConfig", upkeepId) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GetLogTriggerConfig(upkeepId *big.Int) ([]byte, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.GetLogTriggerConfig(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GetLogTriggerConfig(upkeepId *big.Int) ([]byte, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.GetLogTriggerConfig(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetPxDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, n *big.Int) (*big.Int, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "getPxDelayLastNPerforms", upkeepId, p, n) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GetPxDelayLastNPerforms(upkeepId *big.Int, p *big.Int, n *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.GetPxDelayLastNPerforms(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId, p, n) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GetPxDelayLastNPerforms(upkeepId *big.Int, p *big.Int, n *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.GetPxDelayLastNPerforms(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId, p, n) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetSumDelayInBucket(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) (*big.Int, *big.Int, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "getSumDelayInBucket", upkeepId, bucket) + + if err != nil { + return *new(*big.Int), *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return out0, out1, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GetSumDelayInBucket(upkeepId *big.Int, bucket uint16) (*big.Int, *big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.GetSumDelayInBucket(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId, bucket) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GetSumDelayInBucket(upkeepId *big.Int, bucket uint16) (*big.Int, *big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.GetSumDelayInBucket(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId, bucket) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetSumDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "getSumDelayLastNPerforms", upkeepId, n) + + if err != nil { + return *new(*big.Int), *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return out0, out1, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GetSumDelayLastNPerforms(upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.GetSumDelayLastNPerforms(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId, n) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GetSumDelayLastNPerforms(upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.GetSumDelayLastNPerforms(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId, n) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) Intervals(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "intervals", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) Intervals(arg0 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.Intervals(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) Intervals(arg0 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.Intervals(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) LastTopUpBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "lastTopUpBlocks", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) LastTopUpBlocks(arg0 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.LastTopUpBlocks(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) LastTopUpBlocks(arg0 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.LastTopUpBlocks(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) LinkToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "linkToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) LinkToken() (common.Address, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.LinkToken(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) LinkToken() (common.Address, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.LinkToken(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) MinBalanceThresholdMultiplier(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "minBalanceThresholdMultiplier") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) MinBalanceThresholdMultiplier() (uint8, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.MinBalanceThresholdMultiplier(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) MinBalanceThresholdMultiplier() (uint8, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.MinBalanceThresholdMultiplier(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.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 (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) Owner() (common.Address, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.Owner(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) Owner() (common.Address, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.Owner(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) PerformDataSizes(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "performDataSizes", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) PerformDataSizes(arg0 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.PerformDataSizes(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) PerformDataSizes(arg0 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.PerformDataSizes(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) PerformGasToBurns(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "performGasToBurns", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) PerformGasToBurns(arg0 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.PerformGasToBurns(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) PerformGasToBurns(arg0 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.PerformGasToBurns(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) PreviousPerformBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "previousPerformBlocks", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) PreviousPerformBlocks(arg0 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.PreviousPerformBlocks(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) PreviousPerformBlocks(arg0 *big.Int) (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.PreviousPerformBlocks(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) Registrar(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "registrar") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) Registrar() (common.Address, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.Registrar(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) Registrar() (common.Address, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.Registrar(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) Registry(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "registry") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) Registry() (common.Address, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.Registry(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) Registry() (common.Address, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.Registry(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) TimeParamKey(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "timeParamKey") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) TimeParamKey() (string, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.TimeParamKey(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) TimeParamKey() (string, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.TimeParamKey(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) UpkeepTopUpCheckInterval(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "upkeepTopUpCheckInterval") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) UpkeepTopUpCheckInterval() (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.UpkeepTopUpCheckInterval(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) UpkeepTopUpCheckInterval() (*big.Int, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.UpkeepTopUpCheckInterval(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) UseArbitrumBlockNum(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "useArbitrumBlockNum") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) UseArbitrumBlockNum() (bool, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.UseArbitrumBlockNum(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) UseArbitrumBlockNum() (bool, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.UseArbitrumBlockNum(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) UseMercury(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "useMercury") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) UseMercury() (bool, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.UseMercury(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) UseMercury() (bool, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.UseMercury(&_VerifiableLoadLogTriggerUpkeep.CallOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "acceptOwnership") +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) AcceptOwnership() (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.AcceptOwnership(&_VerifiableLoadLogTriggerUpkeep.TransactOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.AcceptOwnership(&_VerifiableLoadLogTriggerUpkeep.TransactOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) AddFunds(opts *bind.TransactOpts, upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "addFunds", upkeepId, amount) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) AddFunds(upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.AddFunds(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, amount) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) AddFunds(upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.AddFunds(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, amount) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) BatchCancelUpkeeps(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "batchCancelUpkeeps", upkeepIds) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) BatchCancelUpkeeps(upkeepIds []*big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.BatchCancelUpkeeps(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepIds) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) BatchCancelUpkeeps(upkeepIds []*big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.BatchCancelUpkeeps(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepIds) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) BatchRegisterUpkeeps(opts *bind.TransactOpts, number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "batchRegisterUpkeeps", number, gasLimit, triggerType, triggerConfig, amount, checkGasToBurn, performGasToBurn) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) BatchRegisterUpkeeps(number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.BatchRegisterUpkeeps(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, number, gasLimit, triggerType, triggerConfig, amount, checkGasToBurn, performGasToBurn) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) BatchRegisterUpkeeps(number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.BatchRegisterUpkeeps(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, number, gasLimit, triggerType, triggerConfig, amount, checkGasToBurn, performGasToBurn) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) BatchSendLogs(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "batchSendLogs") +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) BatchSendLogs() (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.BatchSendLogs(&_VerifiableLoadLogTriggerUpkeep.TransactOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) BatchSendLogs() (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.BatchSendLogs(&_VerifiableLoadLogTriggerUpkeep.TransactOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) BatchSetIntervals(opts *bind.TransactOpts, upkeepIds []*big.Int, interval uint32) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "batchSetIntervals", upkeepIds, interval) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) BatchSetIntervals(upkeepIds []*big.Int, interval uint32) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.BatchSetIntervals(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepIds, interval) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) BatchSetIntervals(upkeepIds []*big.Int, interval uint32) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.BatchSetIntervals(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepIds, interval) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) BatchUpdatePipelineData(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "batchUpdatePipelineData", upkeepIds) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) BatchUpdatePipelineData(upkeepIds []*big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.BatchUpdatePipelineData(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepIds) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) BatchUpdatePipelineData(upkeepIds []*big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.BatchUpdatePipelineData(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepIds) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) BatchWithdrawLinks(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "batchWithdrawLinks", upkeepIds) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) BatchWithdrawLinks(upkeepIds []*big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.BatchWithdrawLinks(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepIds) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) BatchWithdrawLinks(upkeepIds []*big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.BatchWithdrawLinks(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepIds) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) BurnPerformGas(opts *bind.TransactOpts, upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "burnPerformGas", upkeepId, startGas, blockNum) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) BurnPerformGas(upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.BurnPerformGas(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, startGas, blockNum) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) BurnPerformGas(upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.BurnPerformGas(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, startGas, blockNum) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) CancelUpkeep(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "cancelUpkeep", upkeepId) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) CancelUpkeep(upkeepId *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.CancelUpkeep(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) CancelUpkeep(upkeepId *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.CancelUpkeep(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) CheckLog(opts *bind.TransactOpts, log Log, checkData []byte) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "checkLog", log, checkData) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) CheckLog(log Log, checkData []byte) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.CheckLog(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, log, checkData) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) CheckLog(log Log, checkData []byte) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.CheckLog(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, log, checkData) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "performUpkeep", performData) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) PerformUpkeep(performData []byte) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.PerformUpkeep(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, performData) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) PerformUpkeep(performData []byte) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.PerformUpkeep(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, performData) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SendLog(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "sendLog", upkeepId) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SendLog(upkeepId *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SendLog(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SendLog(upkeepId *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SendLog(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetAddLinkAmount(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setAddLinkAmount", amount) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetAddLinkAmount(amount *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetAddLinkAmount(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, amount) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetAddLinkAmount(amount *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetAddLinkAmount(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, amount) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetAutoLog(opts *bind.TransactOpts, _autoLog bool) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setAutoLog", _autoLog) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetAutoLog(_autoLog bool) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetAutoLog(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, _autoLog) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetAutoLog(_autoLog bool) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetAutoLog(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, _autoLog) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetCheckGasToBurn(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setCheckGasToBurn", upkeepId, value) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetCheckGasToBurn(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetCheckGasToBurn(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, value) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetCheckGasToBurn(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetCheckGasToBurn(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, value) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetConfig(opts *bind.TransactOpts, newRegistrar common.Address) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setConfig", newRegistrar) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetConfig(newRegistrar common.Address) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetConfig(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, newRegistrar) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetConfig(newRegistrar common.Address) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetConfig(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, newRegistrar) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetFeedsHex(opts *bind.TransactOpts, newFeeds []string) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setFeedsHex", newFeeds) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetFeedsHex(newFeeds []string) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetFeedsHex(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, newFeeds) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetFeedsHex(newFeeds []string) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetFeedsHex(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, newFeeds) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetInterval(opts *bind.TransactOpts, upkeepId *big.Int, _interval *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setInterval", upkeepId, _interval) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetInterval(upkeepId *big.Int, _interval *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetInterval(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, _interval) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetInterval(upkeepId *big.Int, _interval *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetInterval(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, _interval) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetMinBalanceThresholdMultiplier(opts *bind.TransactOpts, newMinBalanceThresholdMultiplier uint8) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setMinBalanceThresholdMultiplier", newMinBalanceThresholdMultiplier) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetMinBalanceThresholdMultiplier(newMinBalanceThresholdMultiplier uint8) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetMinBalanceThresholdMultiplier(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, newMinBalanceThresholdMultiplier) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetMinBalanceThresholdMultiplier(newMinBalanceThresholdMultiplier uint8) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetMinBalanceThresholdMultiplier(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, newMinBalanceThresholdMultiplier) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetPerformDataSize(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setPerformDataSize", upkeepId, value) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetPerformDataSize(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetPerformDataSize(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, value) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetPerformDataSize(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetPerformDataSize(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, value) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetPerformGasToBurn(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setPerformGasToBurn", upkeepId, value) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetPerformGasToBurn(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetPerformGasToBurn(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, value) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetPerformGasToBurn(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetPerformGasToBurn(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, value) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetUpkeepGasLimit(opts *bind.TransactOpts, upkeepId *big.Int, gasLimit uint32) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setUpkeepGasLimit", upkeepId, gasLimit) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetUpkeepGasLimit(upkeepId *big.Int, gasLimit uint32) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetUpkeepGasLimit(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, gasLimit) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetUpkeepGasLimit(upkeepId *big.Int, gasLimit uint32) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetUpkeepGasLimit(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, gasLimit) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetUpkeepTopUpCheckInterval(opts *bind.TransactOpts, newInterval *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setUpkeepTopUpCheckInterval", newInterval) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetUpkeepTopUpCheckInterval(newInterval *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetUpkeepTopUpCheckInterval(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, newInterval) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetUpkeepTopUpCheckInterval(newInterval *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetUpkeepTopUpCheckInterval(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, newInterval) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetUseMercury(opts *bind.TransactOpts, _useMercury bool) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setUseMercury", _useMercury) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetUseMercury(_useMercury bool) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetUseMercury(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, _useMercury) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetUseMercury(_useMercury bool) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.SetUseMercury(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, _useMercury) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) TopUpFund(opts *bind.TransactOpts, upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "topUpFund", upkeepId, blockNum) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) TopUpFund(upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.TopUpFund(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, blockNum) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) TopUpFund(upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.TopUpFund(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, blockNum) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "transferOwnership", to) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.TransferOwnership(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, to) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.TransferOwnership(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, to) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) UpdateUpkeepPipelineData(opts *bind.TransactOpts, upkeepId *big.Int, pipelineData []byte) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "updateUpkeepPipelineData", upkeepId, pipelineData) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) UpdateUpkeepPipelineData(upkeepId *big.Int, pipelineData []byte) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.UpdateUpkeepPipelineData(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, pipelineData) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) UpdateUpkeepPipelineData(upkeepId *big.Int, pipelineData []byte) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.UpdateUpkeepPipelineData(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, pipelineData) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) WithdrawLinks(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "withdrawLinks") +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) WithdrawLinks() (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.WithdrawLinks(&_VerifiableLoadLogTriggerUpkeep.TransactOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) WithdrawLinks() (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.WithdrawLinks(&_VerifiableLoadLogTriggerUpkeep.TransactOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) WithdrawLinks0(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "withdrawLinks0", upkeepId) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) WithdrawLinks0(upkeepId *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.WithdrawLinks0(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) WithdrawLinks0(upkeepId *big.Int) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.WithdrawLinks0(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.contract.RawTransact(opts, nil) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) Receive() (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.Receive(&_VerifiableLoadLogTriggerUpkeep.TransactOpts) +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) Receive() (*types.Transaction, error) { + return _VerifiableLoadLogTriggerUpkeep.Contract.Receive(&_VerifiableLoadLogTriggerUpkeep.TransactOpts) +} + +type VerifiableLoadLogTriggerUpkeepLogEmittedIterator struct { + Event *VerifiableLoadLogTriggerUpkeepLogEmitted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifiableLoadLogTriggerUpkeepLogEmittedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifiableLoadLogTriggerUpkeepLogEmitted) + 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(VerifiableLoadLogTriggerUpkeepLogEmitted) + 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 *VerifiableLoadLogTriggerUpkeepLogEmittedIterator) Error() error { + return it.fail +} + +func (it *VerifiableLoadLogTriggerUpkeepLogEmittedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifiableLoadLogTriggerUpkeepLogEmitted struct { + UpkeepId *big.Int + BlockNum *big.Int + Addr common.Address + Raw types.Log +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) FilterLogEmitted(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int) (*VerifiableLoadLogTriggerUpkeepLogEmittedIterator, error) { + + var upkeepIdRule []interface{} + for _, upkeepIdItem := range upkeepId { + upkeepIdRule = append(upkeepIdRule, upkeepIdItem) + } + var blockNumRule []interface{} + for _, blockNumItem := range blockNum { + blockNumRule = append(blockNumRule, blockNumItem) + } + + logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.FilterLogs(opts, "LogEmitted", upkeepIdRule, blockNumRule) + if err != nil { + return nil, err + } + return &VerifiableLoadLogTriggerUpkeepLogEmittedIterator{contract: _VerifiableLoadLogTriggerUpkeep.contract, event: "LogEmitted", logs: logs, sub: sub}, nil +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) WatchLogEmitted(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepLogEmitted, upkeepId []*big.Int, blockNum []*big.Int) (event.Subscription, error) { + + var upkeepIdRule []interface{} + for _, upkeepIdItem := range upkeepId { + upkeepIdRule = append(upkeepIdRule, upkeepIdItem) + } + var blockNumRule []interface{} + for _, blockNumItem := range blockNum { + blockNumRule = append(blockNumRule, blockNumItem) + } + + logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.WatchLogs(opts, "LogEmitted", upkeepIdRule, blockNumRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifiableLoadLogTriggerUpkeepLogEmitted) + if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "LogEmitted", 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 (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) ParseLogEmitted(log types.Log) (*VerifiableLoadLogTriggerUpkeepLogEmitted, error) { + event := new(VerifiableLoadLogTriggerUpkeepLogEmitted) + if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "LogEmitted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator struct { + Event *VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested) + 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(VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested) + 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 *VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator, 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 := _VerifiableLoadLogTriggerUpkeep.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator{contract: _VerifiableLoadLogTriggerUpkeep.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested, 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 := _VerifiableLoadLogTriggerUpkeep.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(VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested) + if err := _VerifiableLoadLogTriggerUpkeep.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 (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) ParseOwnershipTransferRequested(log types.Log) (*VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested, error) { + event := new(VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested) + if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator struct { + Event *VerifiableLoadLogTriggerUpkeepOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifiableLoadLogTriggerUpkeepOwnershipTransferred) + 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(VerifiableLoadLogTriggerUpkeepOwnershipTransferred) + 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 *VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifiableLoadLogTriggerUpkeepOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator, 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 := _VerifiableLoadLogTriggerUpkeep.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator{contract: _VerifiableLoadLogTriggerUpkeep.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepOwnershipTransferred, 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 := _VerifiableLoadLogTriggerUpkeep.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(VerifiableLoadLogTriggerUpkeepOwnershipTransferred) + if err := _VerifiableLoadLogTriggerUpkeep.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 (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) ParseOwnershipTransferred(log types.Log) (*VerifiableLoadLogTriggerUpkeepOwnershipTransferred, error) { + event := new(VerifiableLoadLogTriggerUpkeepOwnershipTransferred) + if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifiableLoadLogTriggerUpkeepReceivedIterator struct { + Event *VerifiableLoadLogTriggerUpkeepReceived + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifiableLoadLogTriggerUpkeepReceivedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifiableLoadLogTriggerUpkeepReceived) + 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(VerifiableLoadLogTriggerUpkeepReceived) + 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 *VerifiableLoadLogTriggerUpkeepReceivedIterator) Error() error { + return it.fail +} + +func (it *VerifiableLoadLogTriggerUpkeepReceivedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifiableLoadLogTriggerUpkeepReceived struct { + Sender common.Address + Value *big.Int + Raw types.Log +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) FilterReceived(opts *bind.FilterOpts) (*VerifiableLoadLogTriggerUpkeepReceivedIterator, error) { + + logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.FilterLogs(opts, "Received") + if err != nil { + return nil, err + } + return &VerifiableLoadLogTriggerUpkeepReceivedIterator{contract: _VerifiableLoadLogTriggerUpkeep.contract, event: "Received", logs: logs, sub: sub}, nil +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) WatchReceived(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepReceived) (event.Subscription, error) { + + logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.WatchLogs(opts, "Received") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifiableLoadLogTriggerUpkeepReceived) + if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "Received", 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 (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) ParseReceived(log types.Log) (*VerifiableLoadLogTriggerUpkeepReceived, error) { + event := new(VerifiableLoadLogTriggerUpkeepReceived) + if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "Received", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifiableLoadLogTriggerUpkeepUpkeepTopUpIterator struct { + Event *VerifiableLoadLogTriggerUpkeepUpkeepTopUp + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifiableLoadLogTriggerUpkeepUpkeepTopUpIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifiableLoadLogTriggerUpkeepUpkeepTopUp) + 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(VerifiableLoadLogTriggerUpkeepUpkeepTopUp) + 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 *VerifiableLoadLogTriggerUpkeepUpkeepTopUpIterator) Error() error { + return it.fail +} + +func (it *VerifiableLoadLogTriggerUpkeepUpkeepTopUpIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifiableLoadLogTriggerUpkeepUpkeepTopUp struct { + UpkeepId *big.Int + Amount *big.Int + BlockNum *big.Int + Raw types.Log +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) FilterUpkeepTopUp(opts *bind.FilterOpts) (*VerifiableLoadLogTriggerUpkeepUpkeepTopUpIterator, error) { + + logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.FilterLogs(opts, "UpkeepTopUp") + if err != nil { + return nil, err + } + return &VerifiableLoadLogTriggerUpkeepUpkeepTopUpIterator{contract: _VerifiableLoadLogTriggerUpkeep.contract, event: "UpkeepTopUp", logs: logs, sub: sub}, nil +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) WatchUpkeepTopUp(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepUpkeepTopUp) (event.Subscription, error) { + + logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.WatchLogs(opts, "UpkeepTopUp") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifiableLoadLogTriggerUpkeepUpkeepTopUp) + if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "UpkeepTopUp", 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 (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) ParseUpkeepTopUp(log types.Log) (*VerifiableLoadLogTriggerUpkeepUpkeepTopUp, error) { + event := new(VerifiableLoadLogTriggerUpkeepUpkeepTopUp) + if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "UpkeepTopUp", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifiableLoadLogTriggerUpkeepUpkeepsRegisteredIterator struct { + Event *VerifiableLoadLogTriggerUpkeepUpkeepsRegistered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifiableLoadLogTriggerUpkeepUpkeepsRegisteredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifiableLoadLogTriggerUpkeepUpkeepsRegistered) + 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(VerifiableLoadLogTriggerUpkeepUpkeepsRegistered) + 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 *VerifiableLoadLogTriggerUpkeepUpkeepsRegisteredIterator) Error() error { + return it.fail +} + +func (it *VerifiableLoadLogTriggerUpkeepUpkeepsRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifiableLoadLogTriggerUpkeepUpkeepsRegistered struct { + UpkeepIds []*big.Int + Raw types.Log +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) FilterUpkeepsRegistered(opts *bind.FilterOpts) (*VerifiableLoadLogTriggerUpkeepUpkeepsRegisteredIterator, error) { + + logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.FilterLogs(opts, "UpkeepsRegistered") + if err != nil { + return nil, err + } + return &VerifiableLoadLogTriggerUpkeepUpkeepsRegisteredIterator{contract: _VerifiableLoadLogTriggerUpkeep.contract, event: "UpkeepsRegistered", logs: logs, sub: sub}, nil +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) WatchUpkeepsRegistered(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepUpkeepsRegistered) (event.Subscription, error) { + + logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.WatchLogs(opts, "UpkeepsRegistered") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifiableLoadLogTriggerUpkeepUpkeepsRegistered) + if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "UpkeepsRegistered", 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 (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) ParseUpkeepsRegistered(log types.Log) (*VerifiableLoadLogTriggerUpkeepUpkeepsRegistered, error) { + event := new(VerifiableLoadLogTriggerUpkeepUpkeepsRegistered) + if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "UpkeepsRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeep) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _VerifiableLoadLogTriggerUpkeep.abi.Events["LogEmitted"].ID: + return _VerifiableLoadLogTriggerUpkeep.ParseLogEmitted(log) + case _VerifiableLoadLogTriggerUpkeep.abi.Events["OwnershipTransferRequested"].ID: + return _VerifiableLoadLogTriggerUpkeep.ParseOwnershipTransferRequested(log) + case _VerifiableLoadLogTriggerUpkeep.abi.Events["OwnershipTransferred"].ID: + return _VerifiableLoadLogTriggerUpkeep.ParseOwnershipTransferred(log) + case _VerifiableLoadLogTriggerUpkeep.abi.Events["Received"].ID: + return _VerifiableLoadLogTriggerUpkeep.ParseReceived(log) + case _VerifiableLoadLogTriggerUpkeep.abi.Events["UpkeepTopUp"].ID: + return _VerifiableLoadLogTriggerUpkeep.ParseUpkeepTopUp(log) + case _VerifiableLoadLogTriggerUpkeep.abi.Events["UpkeepsRegistered"].ID: + return _VerifiableLoadLogTriggerUpkeep.ParseUpkeepsRegistered(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (VerifiableLoadLogTriggerUpkeepLogEmitted) Topic() common.Hash { + return common.HexToHash("0x97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf08") +} + +func (VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (VerifiableLoadLogTriggerUpkeepOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (VerifiableLoadLogTriggerUpkeepReceived) Topic() common.Hash { + return common.HexToHash("0x88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f88525874") +} + +func (VerifiableLoadLogTriggerUpkeepUpkeepTopUp) Topic() common.Hash { + return common.HexToHash("0x49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c0") +} + +func (VerifiableLoadLogTriggerUpkeepUpkeepsRegistered) Topic() common.Hash { + return common.HexToHash("0x2ee10f7eb180441fb9fbba75b10c0162b5390b557712c93426243ca8f383c711") +} + +func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeep) Address() common.Address { + return _VerifiableLoadLogTriggerUpkeep.address +} + +type VerifiableLoadLogTriggerUpkeepInterface interface { + BUCKETSIZE(opts *bind.CallOpts) (uint16, error) + + AddLinkAmount(opts *bind.CallOpts) (*big.Int, error) + + AutoLog(opts *bind.CallOpts) (bool, error) + + BucketedDelays(opts *bind.CallOpts, arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error) + + Buckets(opts *bind.CallOpts, arg0 *big.Int) (uint16, error) + + CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (bool, []byte, error) + + CheckGasToBurns(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) + + Counters(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) + + Delays(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) + + DummyMap(opts *bind.CallOpts, arg0 [32]byte) (bool, error) + + Eligible(opts *bind.CallOpts, upkeepId *big.Int) (bool, error) + + EmittedSig(opts *bind.CallOpts) ([32]byte, error) + + FeedParamKey(opts *bind.CallOpts) (string, error) + + FeedsHex(opts *bind.CallOpts, arg0 *big.Int) (string, error) + + FirstPerformBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) + + GasLimits(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) + + GetActiveUpkeepIDs(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) + + GetBucketedDelays(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) ([]*big.Int, error) + + GetBucketedDelaysLength(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error) + + GetDelays(opts *bind.CallOpts, upkeepId *big.Int) ([]*big.Int, error) + + GetDelaysLength(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error) + + GetLogTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) + + GetPxDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, n *big.Int) (*big.Int, error) + + GetSumDelayInBucket(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) (*big.Int, *big.Int, error) + + GetSumDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) + + Intervals(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) + + LastTopUpBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) + + LinkToken(opts *bind.CallOpts) (common.Address, error) + + MinBalanceThresholdMultiplier(opts *bind.CallOpts) (uint8, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + PerformDataSizes(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) + + PerformGasToBurns(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) + + PreviousPerformBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) + + Registrar(opts *bind.CallOpts) (common.Address, error) + + Registry(opts *bind.CallOpts) (common.Address, error) + + TimeParamKey(opts *bind.CallOpts) (string, error) + + UpkeepTopUpCheckInterval(opts *bind.CallOpts) (*big.Int, error) + + UseArbitrumBlockNum(opts *bind.CallOpts) (bool, error) + + UseMercury(opts *bind.CallOpts) (bool, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + AddFunds(opts *bind.TransactOpts, upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) + + BatchCancelUpkeeps(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error) + + BatchRegisterUpkeeps(opts *bind.TransactOpts, number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) + + BatchSendLogs(opts *bind.TransactOpts) (*types.Transaction, error) + + BatchSetIntervals(opts *bind.TransactOpts, upkeepIds []*big.Int, interval uint32) (*types.Transaction, error) + + BatchUpdatePipelineData(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error) + + BatchWithdrawLinks(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error) + + BurnPerformGas(opts *bind.TransactOpts, upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error) + + CancelUpkeep(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) + + CheckLog(opts *bind.TransactOpts, log Log, checkData []byte) (*types.Transaction, error) + + PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error) + + SendLog(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) + + SetAddLinkAmount(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) + + SetAutoLog(opts *bind.TransactOpts, _autoLog bool) (*types.Transaction, error) + + SetCheckGasToBurn(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error) + + SetConfig(opts *bind.TransactOpts, newRegistrar common.Address) (*types.Transaction, error) + + SetFeedsHex(opts *bind.TransactOpts, newFeeds []string) (*types.Transaction, error) + + SetInterval(opts *bind.TransactOpts, upkeepId *big.Int, _interval *big.Int) (*types.Transaction, error) + + SetMinBalanceThresholdMultiplier(opts *bind.TransactOpts, newMinBalanceThresholdMultiplier uint8) (*types.Transaction, error) + + SetPerformDataSize(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error) + + SetPerformGasToBurn(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error) + + SetUpkeepGasLimit(opts *bind.TransactOpts, upkeepId *big.Int, gasLimit uint32) (*types.Transaction, error) + + SetUpkeepTopUpCheckInterval(opts *bind.TransactOpts, newInterval *big.Int) (*types.Transaction, error) + + SetUseMercury(opts *bind.TransactOpts, _useMercury bool) (*types.Transaction, error) + + TopUpFund(opts *bind.TransactOpts, upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + UpdateUpkeepPipelineData(opts *bind.TransactOpts, upkeepId *big.Int, pipelineData []byte) (*types.Transaction, error) + + WithdrawLinks(opts *bind.TransactOpts) (*types.Transaction, error) + + WithdrawLinks0(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) + + Receive(opts *bind.TransactOpts) (*types.Transaction, error) + + FilterLogEmitted(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int) (*VerifiableLoadLogTriggerUpkeepLogEmittedIterator, error) + + WatchLogEmitted(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepLogEmitted, upkeepId []*big.Int, blockNum []*big.Int) (event.Subscription, error) + + ParseLogEmitted(log types.Log) (*VerifiableLoadLogTriggerUpkeepLogEmitted, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*VerifiableLoadLogTriggerUpkeepOwnershipTransferred, error) + + FilterReceived(opts *bind.FilterOpts) (*VerifiableLoadLogTriggerUpkeepReceivedIterator, error) + + WatchReceived(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepReceived) (event.Subscription, error) + + ParseReceived(log types.Log) (*VerifiableLoadLogTriggerUpkeepReceived, error) + + FilterUpkeepTopUp(opts *bind.FilterOpts) (*VerifiableLoadLogTriggerUpkeepUpkeepTopUpIterator, error) + + WatchUpkeepTopUp(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepUpkeepTopUp) (event.Subscription, error) + + ParseUpkeepTopUp(log types.Log) (*VerifiableLoadLogTriggerUpkeepUpkeepTopUp, error) + + FilterUpkeepsRegistered(opts *bind.FilterOpts) (*VerifiableLoadLogTriggerUpkeepUpkeepsRegisteredIterator, error) + + WatchUpkeepsRegistered(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepUpkeepsRegistered) (event.Subscription, error) + + ParseUpkeepsRegistered(log types.Log) (*VerifiableLoadLogTriggerUpkeepUpkeepsRegistered, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/verifiable_load_mercury_upkeep_wrapper/verifiable_load_mercury_upkeep_wrapper.go b/core/gethwrappers/generated/verifiable_load_mercury_upkeep_wrapper/verifiable_load_mercury_upkeep_wrapper.go index dcaf739c1bb..2d84e4c98b7 100644 --- a/core/gethwrappers/generated/verifiable_load_mercury_upkeep_wrapper/verifiable_load_mercury_upkeep_wrapper.go +++ b/core/gethwrappers/generated/verifiable_load_mercury_upkeep_wrapper/verifiable_load_mercury_upkeep_wrapper.go @@ -31,15 +31,15 @@ var ( ) var VerifiableLoadMercuryUpkeepMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"registrarAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"useArb\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"feeds\",\"type\":\"string[]\"},{\"internalType\":\"string\",\"name\":\"timeParamKey\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"FeedLookup\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"InsufficientFunds\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"origin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"v0\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"ed\",\"type\":\"bytes\"}],\"name\":\"MercuryPerformEvent\",\"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\":\"uint256\",\"name\":\"firstPerformBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"lastBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"counter\",\"type\":\"uint256\"}],\"name\":\"PerformingUpkeep\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Received\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRegistrar\",\"type\":\"address\"}],\"name\":\"RegistrarSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"UpkeepTopUp\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"UpkeepsCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"UpkeepsRegistered\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BUCKET_SIZE\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TIMESTAMP_INTERVAL\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"addLinkAmount\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchCancelUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"number\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"checkGasToBurn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"performGasToBurn\",\"type\":\"uint256\"}],\"name\":\"batchRegisterUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint32\",\"name\":\"interval\",\"type\":\"uint32\"}],\"name\":\"batchSetIntervals\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchUpdatePipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchWithdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bucketedDelays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"buckets\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"checkDatas\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"checkGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"counters\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"delays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"dummyMap\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feedParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"feedsHex\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"firstPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"gasLimits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"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\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getBucketedDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getBucketedDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getDelaysLengthAtBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"timestampBucket\",\"type\":\"uint16\"}],\"name\":\"getDelaysLengthAtTimestampBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"p\",\"type\":\"uint256\"}],\"name\":\"getPxBucketedDelaysForAllUpkeeps\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"p\",\"type\":\"uint256\"}],\"name\":\"getPxDelayForAllUpkeeps\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"p\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getPxDelayInBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"p\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"timestampBucket\",\"type\":\"uint16\"}],\"name\":\"getPxDelayInTimestampBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"p\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getPxDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getSumBucketedDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getSumDelayInBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"timestampBucket\",\"type\":\"uint16\"}],\"name\":\"getSumDelayInTimestampBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getSumDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getSumTimestampBucketedDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTimestampBucketedDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"timestampBucket\",\"type\":\"uint16\"}],\"name\":\"getTimestampDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"intervals\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"lastTopUpBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkToken\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBalanceThresholdMultiplier\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performDataSizes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"previousPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registrar\",\"outputs\":[{\"internalType\":\"contractKeeperRegistrar2_0\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contractIKeeperRegistryMaster\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"setAddLinkAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setCheckGasToBurn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractKeeperRegistrar2_0\",\"name\":\"newRegistrar\",\"type\":\"address\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"newFeeds\",\"type\":\"string[]\"}],\"name\":\"setFeedsHex\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_interval\",\"type\":\"uint256\"}],\"name\":\"setInterval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"newMinBalanceThresholdMultiplier\",\"type\":\"uint8\"}],\"name\":\"setMinBalanceThresholdMultiplier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setPerformDataSize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setPerformGasToBurn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newInterval\",\"type\":\"uint256\"}],\"name\":\"setUpkeepTopUpCheckInterval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timeParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"timestampBuckets\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"timestampDelays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"timestamps\",\"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\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pipelineData\",\"type\":\"bytes\"}],\"name\":\"updateUpkeepPipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTopUpCheckInterval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useArbitrumBlockNum\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", - Bin: "0x6005601855601980546001600160681b0319166c140000000002c68af0bb140000179055601960f21b60a05260e160f41b60c0526101c0604052604261014081815260e09182919062005da261016039815260200160405180608001604052806042815260200162005de460429139815260200160405180608001604052806042815260200162005e266042913990526200009f90601a9060036200036e565b50348015620000ad57600080fd5b5060405162005e6838038062005e68833981016040819052620000d091620004f1565b81813380600081620001295760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156200015c576200015c81620002c2565b5050601580546001600160a01b0319166001600160a01b0385169081179091556040805163850af0cb60e01b815290516000935063850af0cb9160048082019260a092909190829003018186803b158015620001b757600080fd5b505afa158015620001cc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001f291906200055b565b50601780546001600160a01b0319166001600160a01b038381169190911790915560155460408051631b6b6d2360e01b8152905193975091169450631b6b6d2393506004808201935060209291829003018186803b1580156200025457600080fd5b505afa15801562000269573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200028f919062000534565b601680546001600160a01b0319166001600160a01b039290921691909117905550151560f81b608052506200061e915050565b6001600160a01b0381163314156200031d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000120565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215620003c0579160200282015b82811115620003c05782518051620003af918491602090910190620003d2565b50916020019190600101906200038f565b50620003ce9291506200045d565b5090565b828054620003e090620005cb565b90600052602060002090601f0160209004810192826200040457600085556200044f565b82601f106200041f57805160ff19168380011785556200044f565b828001600101855582156200044f579182015b828111156200044f57825182559160200191906001019062000432565b50620003ce9291506200047e565b80821115620003ce57600062000474828262000495565b506001016200045d565b5b80821115620003ce57600081556001016200047f565b508054620004a390620005cb565b6000825580601f10620004b4575050565b601f016020900490600052602060002090810190620004d491906200047e565b50565b805163ffffffff81168114620004ec57600080fd5b919050565b600080604083850312156200050557600080fd5b8251620005128162000608565b602084015190925080151581146200052957600080fd5b809150509250929050565b6000602082840312156200054757600080fd5b8151620005548162000608565b9392505050565b600080600080600060a086880312156200057457600080fd5b8551600381106200058457600080fd5b94506200059460208701620004d7565b9350620005a460408701620004d7565b92506060860151620005b68162000608565b80925050608086015190509295509295909350565b600181811c90821680620005e057607f821691505b602082108114156200060257634e487b7160e01b600052602260045260246000fd5b50919050565b6001600160a01b0381168114620004d457600080fd5b60805160f81c60a05160f01c60c05160f01c6157366200066c600039600081816106f40152611b480152600081816105cc0152611c5c0152600081816109d10152613ba801526157366000f3fe6080604052600436106104f05760003560e01c80637b10399911610294578063a79c40431161015e578063d6051a72116100d6578063f2fde38b1161008a578063fba7ffa31161006f578063fba7ffa314611134578063fbfb4f7614611161578063fcdc1f631461118157600080fd5b8063f2fde38b146110f4578063fb0ceb041461111457600080fd5b8063dbef701e116100bb578063dbef701e14611091578063e0114adb146110b1578063e4553083146110de57600080fd5b8063d6051a7214611051578063daee1aeb1461107157600080fd5b8063becde0e11161012d578063c804802211610112578063c804802214610f89578063c98f10b014610fa9578063d355852814610ff257600080fd5b8063becde0e114610f0f578063c357f1f314610f2f57600080fd5b8063a79c404314610e3b578063af953a4a14610e68578063afb28d1f14610e88578063b0971e1a14610ed157600080fd5b8063948108f71161020c5780639d385eaa116101c0578063a5f58934116101a5578063a5f5893414610ddb578063a6c60d8914610dfb578063a72aa27e14610e1b57600080fd5b80639d385eaa14610d9b5780639d6f1cc714610dbb57600080fd5b80639ac542eb116101f15780639ac542eb14610d015780639b42935414610d3d5780639b51fb0d14610d6a57600080fd5b8063948108f714610cc157806399cc6b0b14610ce157600080fd5b806387dfa900116102635780638da5cb5b116102485780638da5cb5b14610c495780638fcb3fba14610c745780639095aa3514610ca157600080fd5b806387dfa90014610c095780638bc7b77214610c2957600080fd5b80637b10399914610b7c5780637e4087b814610ba95780637e7a46dc14610bc95780638237831714610be957600080fd5b80634b56a42e116103d5578063643b34e91161034d5780637145f11b1161030157806376721303116102e65780637672130314610b1a578063776898c814610b4757806379ba509714610b6757600080fd5b80637145f11b14610abd57806373644cce14610aed57600080fd5b806369e9b7731161033257806369e9b77314610a505780636e04ff0d14610a7d5780637137a70214610a9d57600080fd5b8063643b34e914610a0357806369cdbadb14610a2357600080fd5b80635d4ee7f3116103a457806360457ff51161038957806360457ff514610950578063636092e81461097d578063642f6cef146109bf57600080fd5b80635d4ee7f31461091b5780635f17e6161461093057600080fd5b80634b56a42e1461087357806351c98be3146108a157806357970e93146108c157806358c52c04146108ee57600080fd5b806329f0e4961161046857806333774d1c116104375780634585e33b1161041c5780634585e33b1461080657806345d2ec171461082657806346e7a63e1461084657600080fd5b806333774d1c146107b55780633ebe8d6c146107e657600080fd5b806329f0e496146106e25780632a9032d3146107165780632b20e39714610736578063328ffd111461078857600080fd5b8063177b0eb9116104bf578063206c32e8116104a4578063206c32e81461066d57806320e3dbd4146106a257806328c4b57b146106c257600080fd5b8063177b0eb9146106015780631bee00801461063f57600080fd5b806305e251311461053457806306e3b63214610556578063077ac6211461058c57806312c55027146105ba57600080fd5b3661052f57604080513381523460208201527f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f88525874910160405180910390a1005b600080fd5b34801561054057600080fd5b5061055461054f366004614668565b6111ae565b005b34801561056257600080fd5b50610576610571366004614aa7565b6111c5565b6040516105839190614d92565b60405180910390f35b34801561059857600080fd5b506105ac6105a7366004614a72565b6112c1565b604051908152602001610583565b3480156105c657600080fd5b506105ee7f000000000000000000000000000000000000000000000000000000000000000081565b60405161ffff9091168152602001610583565b34801561060d57600080fd5b506105ac61061c366004614a46565b6000918252600f6020908152604080842061ffff93909316845291905290205490565b34801561064b57600080fd5b5061065f61065a3660046147e7565b6112ff565b604051610583929190614da5565b34801561067957600080fd5b5061068d610688366004614a46565b611608565b60408051928352602083019190915201610583565b3480156106ae57600080fd5b506105546106bd366004614571565b61168b565b3480156106ce57600080fd5b506105ac6106dd366004614afe565b6118ac565b3480156106ee57600080fd5b506105ee7f000000000000000000000000000000000000000000000000000000000000000081565b34801561072257600080fd5b50610554610731366004614733565b611917565b34801561074257600080fd5b506015546107639073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610583565b34801561079457600080fd5b506105ac6107a33660046147e7565b60036020526000908152604090205481565b3480156107c157600080fd5b506105ee6107d03660046147e7565b60116020526000908152604090205461ffff1681565b3480156107f257600080fd5b506105ac6108013660046147e7565b6119ea565b34801561081257600080fd5b50610554610821366004614800565b611a53565b34801561083257600080fd5b50610576610841366004614a46565b612170565b34801561085257600080fd5b506105ac6108613660046147e7565b600a6020526000908152604090205481565b34801561087f57600080fd5b5061089361088e36600461458e565b6121df565b604051610583929190614dca565b3480156108ad57600080fd5b506105546108bc366004614775565b612233565b3480156108cd57600080fd5b506016546107639073ffffffffffffffffffffffffffffffffffffffff1681565b3480156108fa57600080fd5b5061090e6109093660046147e7565b6122d7565b6040516105839190614de5565b34801561092757600080fd5b50610554612371565b34801561093c57600080fd5b5061055461094b366004614aa7565b6124c6565b34801561095c57600080fd5b506105ac61096b3660046147e7565b60076020526000908152604090205481565b34801561098957600080fd5b506019546109a2906bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff9091168152602001610583565b3480156109cb57600080fd5b506109f37f000000000000000000000000000000000000000000000000000000000000000081565b6040519015158152602001610583565b348015610a0f57600080fd5b5061068d610a1e366004614aa7565b612638565b348015610a2f57600080fd5b506105ac610a3e3660046147e7565b60086020526000908152604090205481565b348015610a5c57600080fd5b50610554610a6b366004614aa7565b60009182526008602052604090912055565b348015610a8957600080fd5b50610893610a98366004614800565b6127bd565b348015610aa957600080fd5b506105ac610ab8366004614a72565b6129d2565b348015610ac957600080fd5b506109f3610ad83660046147e7565b600c6020526000908152604090205460ff1681565b348015610af957600080fd5b506105ac610b083660046147e7565b6000908152600d602052604090205490565b348015610b2657600080fd5b506105ac610b353660046147e7565b60046020526000908152604090205481565b348015610b5357600080fd5b506109f3610b623660046147e7565b6129fa565b348015610b7357600080fd5b50610554612a4a565b348015610b8857600080fd5b506017546107639073ffffffffffffffffffffffffffffffffffffffff1681565b348015610bb557600080fd5b5061068d610bc4366004614aa7565b612b47565b348015610bd557600080fd5b50610554610be43660046149fa565b612cbf565b348015610bf557600080fd5b506105ac610c04366004614ac9565b612d6a565b348015610c1557600080fd5b506105ac610c24366004614ac9565b612de5565b348015610c3557600080fd5b5061065f610c443660046147e7565b612e55565b348015610c5557600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610763565b348015610c8057600080fd5b506105ac610c8f3660046147e7565b60056020526000908152604090205481565b348015610cad57600080fd5b50610554610cbc366004614b9a565b612fca565b348015610ccd57600080fd5b50610554610cdc366004614b5a565b61324a565b348015610ced57600080fd5b50610576610cfc366004614a46565b6133e2565b348015610d0d57600080fd5b50601954610d2b906c01000000000000000000000000900460ff1681565b60405160ff9091168152602001610583565b348015610d4957600080fd5b50610554610d58366004614aa7565b60009182526009602052604090912055565b348015610d7657600080fd5b506105ee610d853660046147e7565b60126020526000908152604090205461ffff1681565b348015610da757600080fd5b50610576610db63660046147e7565b61344f565b348015610dc757600080fd5b5061090e610dd63660046147e7565b6134b1565b348015610de757600080fd5b506105ac610df63660046147e7565b6134dc565b348015610e0757600080fd5b50610554610e163660046147e7565b601855565b348015610e2757600080fd5b50610554610e36366004614b2a565b61353d565b348015610e4757600080fd5b50610554610e56366004614aa7565b60009182526007602052604090912055565b348015610e7457600080fd5b50610554610e833660046147e7565b6135e8565b348015610e9457600080fd5b5061090e6040518060400160405280600981526020017f666565644944486578000000000000000000000000000000000000000000000081525081565b348015610edd57600080fd5b506105ac610eec366004614a46565b6000918252600e6020908152604080842061ffff93909316845291905290205490565b348015610f1b57600080fd5b50610554610f2a366004614733565b61366e565b348015610f3b57600080fd5b50610554610f4a366004614bf3565b601980547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff92909216919091179055565b348015610f9557600080fd5b50610554610fa43660046147e7565b613708565b348015610fb557600080fd5b5061090e6040518060400160405280600b81526020017f626c6f636b4e756d62657200000000000000000000000000000000000000000081525081565b348015610ffe57600080fd5b5061055461100d366004614b7f565b6019805460ff9092166c01000000000000000000000000027fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff909216919091179055565b34801561105d57600080fd5b5061068d61106c366004614aa7565b6137a0565b34801561107d57600080fd5b5061055461108c366004614733565b613809565b34801561109d57600080fd5b506105ac6110ac366004614aa7565b6138d4565b3480156110bd57600080fd5b506105ac6110cc3660046147e7565b60096020526000908152604090205481565b3480156110ea57600080fd5b506105ac60185481565b34801561110057600080fd5b5061055461110f366004614571565b613905565b34801561112057600080fd5b506105ac61112f366004614aa7565b613919565b34801561114057600080fd5b506105ac61114f3660046147e7565b60066020526000908152604090205481565b34801561116d57600080fd5b5061068d61117c366004614a46565b613935565b34801561118d57600080fd5b506105ac61119c3660046147e7565b60026020526000908152604090205481565b80516111c190601a9060208401906141d5565b5050565b606060006111d360136139a9565b905080841061120e576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826112205761121d84826153fe565b92505b60008367ffffffffffffffff81111561123b5761123b6156ac565b604051908082528060200260200182016040528015611264578160200160208202803683370190505b50905060005b848110156112b65761128761127f8288615285565b6013906139b3565b8282815181106112995761129961567d565b6020908102919091010152806112ae81615584565b91505061126a565b509150505b92915050565b600e60205282600052604060002060205281600052604060002081815481106112e957600080fd5b9060005260206000200160009250925050505481565b606080600061130e60136139a9565b905060008167ffffffffffffffff81111561132b5761132b6156ac565b604051908082528060200260200182016040528015611354578160200160208202803683370190505b50905060008267ffffffffffffffff811115611372576113726156ac565b60405190808252806020026020018201604052801561139b578160200160208202803683370190505b50905060005b838110156115fc5760006113b66013836139b3565b9050808483815181106113cb576113cb61567d565b6020908102919091018101919091526000828152601290915260408082205490517f3ebe8d6c0000000000000000000000000000000000000000000000000000000081526004810184905261ffff90911691903090633ebe8d6c9060240160206040518083038186803b15801561144157600080fd5b505afa158015611455573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147991906149e1565b905060008167ffffffffffffffff811115611496576114966156ac565b6040519080825280602002602001820160405280156114bf578160200160208202803683370190505b506000858152600e6020526040812091925090815b8561ffff168161ffff16116115b95761ffff81166000908152602083815260408083208054825181850281018501909352808352919290919083018282801561153c57602002820191906000526020600020905b815481526020019060010190808311611528575b5050505050905060005b81518110156115a4578181815181106115615761156161567d565b602002602001015186868061157590615584565b9750815181106115875761158761567d565b60209081029190910101528061159c81615584565b915050611546565b505080806115b190615562565b9150506114d4565b506115c5838e866139bf565b8888815181106115d7576115d761567d565b60200260200101818152505050505050505080806115f490615584565b9150506113a1565b50909590945092505050565b6000828152600e6020908152604080832061ffff85168452825280832080548251818502810185019093528083528493849392919083018282801561166c57602002820191906000526020600020905b815481526020019060010190808311611658575b5050505050905061167e818251613b1f565b92509250505b9250929050565b601580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117909155604080517f850af0cb00000000000000000000000000000000000000000000000000000000815290516000929163850af0cb9160048083019260a0929190829003018186803b15801561172057600080fd5b505afa158015611734573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117589190614853565b50601780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691909117909155601554604080517f1b6b6d23000000000000000000000000000000000000000000000000000000008152905193975091169450631b6b6d2393506004808201935060209291829003018186803b1580156117f757600080fd5b505afa15801561180b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061182f9190614836565b601680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055601554604051911681527f6263309d5d4d1cfececd45a387cda7f14dccde21cf7a1bee1be6561075e61014906020015b60405180910390a15050565b6000838152600d60209081526040808320805482518185028101850190935280835261190d9383018282801561190157602002820191906000526020600020905b8154815260200190600101908083116118ed575b505050505084846139bf565b90505b9392505050565b8060005b818160ff1610156119ab573063c8048022858560ff85168181106119415761194161567d565b905060200201356040518263ffffffff1660e01b815260040161196691815260200190565b600060405180830381600087803b15801561198057600080fd5b505af1158015611994573d6000803e3d6000fd5b5050505080806119a3906155d0565b91505061191b565b507fbeac20a03a6674e40498fac4356bc86e356c0d761a8d35d436712dc93bc7c74b83836040516119dd929190614d3d565b60405180910390a1505050565b60008181526012602052604081205461ffff1681805b8261ffff168161ffff1611611a4b576000858152600e6020908152604080832061ffff85168452909152902054611a379083615285565b915080611a4381615562565b915050611a00565b509392505050565b60005a9050600080611a678486018661458e565b91509150600081806020019051810190611a8191906149e1565b60008181526005602090815260408083205460049092528220549293509190611aa8613ba4565b905082611ae25760008481526005602090815260408083208490556010825282208054600181018255908352912042910155915081611d42565b600084815260036020526040812054611afb84846153fe565b611b0591906153fe565b6000868152601160209081526040808320546010909252909120805492935061ffff9091169182908110611b3b57611b3b61567d565b90600052602060002001547f000000000000000000000000000000000000000000000000000000000000000061ffff1642611b7691906153fe565b1115611be55760008681526010602090815260408220805460018101825590835291204291015580611ba781615562565b600088815260116020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff83161790559150505b600086815260126020908152604080832054600e835281842061ffff9091168085529083528184208054835181860281018601909452808452919493909190830182828015611c5357602002820191906000526020600020905b815481526020019060010190808311611c3f575b505050505090507f000000000000000000000000000000000000000000000000000000000000000061ffff1681511415611ccf5781611c9181615562565b60008a815260126020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff83161790559250505b506000878152600e6020908152604080832061ffff94851684528252808320805460018181018355918552838520018790558a8452600f83528184209590941683529381528382208054808501825590835281832001859055888252600d81529281208054928301815581529190912001555b600084815260066020526040812054611d5c906001615285565b6000868152600660209081526040918290208390558151878152908101859052908101859052606081018290529091507f6b6b3eeaaf107627513e76a81662118e7b1d8c78866f70760262115ddcfeede39060800160405180910390a16000858152600460209081526040808320859055601854600290925290912054611de390846153fe565b111561208e576017546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810187905260009173ffffffffffffffffffffffffffffffffffffffff169063c7c3a19a9060240160006040518083038186803b158015611e5457600080fd5b505afa158015611e68573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611eae91908101906148c2565b6017546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810189905291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063b657bc9c9060240160206040518083038186803b158015611f1e57600080fd5b505afa158015611f32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f569190614c10565b601954909150611f7a9082906c01000000000000000000000000900460ff16615356565b6bffffffffffffffffffffffff1682606001516bffffffffffffffffffffffff16101561208b576019546040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018990526bffffffffffffffffffffffff9091166024820152309063948108f790604401600060405180830381600087803b15801561200b57600080fd5b505af115801561201f573d6000803e3d6000fd5b50505060008881526002602090815260409182902087905560195482518b81526bffffffffffffffffffffffff909116918101919091529081018690527f49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c0915060600160405180910390a15b50505b6000858152600760205260409020545b805a6120aa908b6153fe565b6120b690612710615285565b10156120f75782406000908152600c6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905561209e565b82863273ffffffffffffffffffffffffffffffffffffffff167fcad583be2d908a590c81c7e332cf11c7a4ea41ecf1e059efac3ea7e83e34f1a58b6000815181106121445761214461567d565b60200260200101518b60405161215b929190614df8565b60405180910390a45050505050505050505050565b6000828152600e6020908152604080832061ffff851684528252918290208054835181840281018401909452808452606093928301828280156121d257602002820191906000526020600020905b8154815260200190600101908083116121be575b5050505050905092915050565b60006060600084846040516020016121f8929190614cb2565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181529190526001969095509350505050565b8160005b818110156122d05730635f17e6168686848181106122575761225761567d565b90506020020135856040518363ffffffff1660e01b815260040161228b92919091825263ffffffff16602082015260400190565b600060405180830381600087803b1580156122a557600080fd5b505af11580156122b9573d6000803e3d6000fd5b5050505080806122c890615584565b915050612237565b5050505050565b600b60205260009081526040902080546122f0906154d5565b80601f016020809104026020016040519081016040528092919081815260200182805461231c906154d5565b80156123695780601f1061233e57610100808354040283529160200191612369565b820191906000526020600020905b81548152906001019060200180831161234c57829003601f168201915b505050505081565b612379613c55565b6016546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a082319060240160206040518083038186803b1580156123e357600080fd5b505afa1580156123f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061241b91906149e1565b6016546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810183905291925073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb90604401602060405180830381600087803b15801561248e57600080fd5b505af11580156124a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c191906147cc565b60008281526003602090815260408083208490556005825280832083905560068252808320839055600d90915281206124fe91614232565b60008281526012602052604081205461ffff16905b8161ffff168161ffff161161255a576000848152600e6020908152604080832061ffff85168452909152812061254891614232565b8061255281615562565b915050612513565b5050600082815260126020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055601190915281205461ffff16905b8161ffff168161ffff16116125e8576000848152600f6020908152604080832061ffff8516845290915281206125d691614232565b806125e081615562565b9150506125a1565b50600083815260106020526040812061260091614232565b5050600090815260116020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055565b6040517f3ebe8d6c00000000000000000000000000000000000000000000000000000000815260048101839052600090819081903090633ebe8d6c9060240160206040518083038186803b15801561268f57600080fd5b505afa1580156126a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c791906149e1565b90508315806126d65750808410155b156126df578093505b60008581526012602052604081205485919061ffff16805b6000898152600e6020908152604080832061ffff8516845282528083208054825181850281018501909352808352919290919083018282801561275957602002820191906000526020600020905b815481526020019060010190808311612745575b5050505050905060008061276d8388613b1f565b909250905061277c8287615285565b955061278881886153fe565b96506000871161279a575050506127b0565b50505080806127a890615499565b9150506126f7565b5090979596505050505050565b6000606060005a905060006127d4858701876147e7565b60008181526009602090815260408083205460089092528220549293509190838367ffffffffffffffff81111561280d5761280d6156ac565b6040519080825280601f01601f191660200182016040528015612837576020820181803683370190505b50604051602001612849929190615115565b60405160208183030381529060405290506000612864613ba4565b90506000612871866129fa565b90505b835a61288090896153fe565b61288c90612710615285565b10156128cd5781406000908152600c6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055612874565b806128e5576000839850985050505050505050611684565b6040518060400160405280600981526020017f6665656449444865780000000000000000000000000000000000000000000000815250601a6040518060400160405280600b81526020017f626c6f636b4e756d626572000000000000000000000000000000000000000000815250848960405160200161296791815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f7ddd933e0000000000000000000000000000000000000000000000000000000082526129c99594939291600401614e1d565b60405180910390fd5b600f60205282600052604060002060205281600052604060002081815481106112e957600080fd5b600081815260056020526040812054612a1557506001919050565b600082815260036020908152604080832054600490925290912054612a38613ba4565b612a4291906153fe565b101592915050565b60015473ffffffffffffffffffffffffffffffffffffffff163314612acb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016129c9565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6040517fa5f589340000000000000000000000000000000000000000000000000000000081526004810183905260009081908190309063a5f589349060240160206040518083038186803b158015612b9e57600080fd5b505afa158015612bb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bd691906149e1565b9050831580612be55750808410155b15612bee578093505b60008581526011602052604081205485919061ffff16805b6000898152600f6020908152604080832061ffff85168452825280832080548251818502810185019093528083529192909190830182828015612c6857602002820191906000526020600020905b815481526020019060010190808311612c54575b50505050509050600080612c7c8388613b1f565b9092509050612c8b8287615285565b9550612c9781886153fe565b965060008711612ca9575050506127b0565b5050508080612cb790615499565b915050612c06565b6017546040517fcd7f71b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063cd7f71b590612d19908690869086906004016150c1565b600060405180830381600087803b158015612d3357600080fd5b505af1158015612d47573d6000803e3d6000fd5b5050506000848152600b60205260409020612d6491508383614250565b50505050565b6000838152600e6020908152604080832061ffff85168452825280832080548251818502810185019093528083528493830182828015612dc957602002820191906000526020600020905b815481526020019060010190808311612db5575b50505050509050612ddc818583516139bf565b95945050505050565b6000838152600f6020908152604080832061ffff85168452825280832080548251818502810185019093528083528493830182828015612dc95760200282019190600052602060002090815481526020019060010190808311612db55750505050509050612ddc818583516139bf565b6060806000612e6460136139a9565b905060008167ffffffffffffffff811115612e8157612e816156ac565b604051908082528060200260200182016040528015612eaa578160200160208202803683370190505b50905060008267ffffffffffffffff811115612ec857612ec86156ac565b604051908082528060200260200182016040528015612ef1578160200160208202803683370190505b50905060005b838110156115fc576000612f0c6013836139b3565b6000818152600d6020908152604080832080548251818502810185019093528083529495509293909291830182828015612f6557602002820191906000526020600020905b815481526020019060010190808311612f51575b5050505050905081858481518110612f7f57612f7f61567d565b602002602001018181525050612f97818a83516139bf565b848481518110612fa957612fa961567d565b60200260200101818152505050508080612fc290615584565b915050612ef7565b6040805161014081018252600461010082019081527f746573740000000000000000000000000000000000000000000000000000000061012083015281528151602081810184526000808352818401929092523083850181905263ffffffff8916606085015260808401528351808201855282815260a08401528351908101909352825260c08101919091526bffffffffffffffffffffffff841660e082015260165460155473ffffffffffffffffffffffffffffffffffffffff9182169163095ea7b3911661309d60ff8a1688615356565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526bffffffffffffffffffffffff166024820152604401602060405180830381600087803b15801561311657600080fd5b505af115801561312a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061314e91906147cc565b5060008660ff1667ffffffffffffffff81111561316d5761316d6156ac565b604051908082528060200260200182016040528015613196578160200160208202803683370190505b50905060005b8760ff168160ff1610156132095760006131b584613cd8565b905080838360ff16815181106131cd576131cd61567d565b60209081029190910181019190915260009182526008815260408083208890556007909152902084905580613201816155d0565b91505061319c565b507f2ee10f7eb180441fb9fbba75b10c0162b5390b557712c93426243ca8f383c711816040516132399190614d92565b60405180910390a150505050505050565b6016546017546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526bffffffffffffffffffffffff8416602482015291169063095ea7b390604401602060405180830381600087803b1580156132cd57600080fd5b505af11580156132e1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061330591906147cc565b506017546040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063948108f790604401600060405180830381600087803b15801561338657600080fd5b505af115801561339a573d6000803e3d6000fd5b5050604080518581526bffffffffffffffffffffffff851660208201527f8137dc366612bf502338bd8951f835ad8ceba421c4eb3d79c7f9b3ce0ac4762e93500190506118a0565b6000828152600f6020908152604080832061ffff851684528252918290208054835181840281018401909452808452606093928301828280156121d257602002820191906000526020600020908154815260200190600101908083116121be575050505050905092915050565b6000818152600d60209081526040918290208054835181840281018401909452808452606093928301828280156134a557602002820191906000526020600020905b815481526020019060010190808311613491575b50505050509050919050565b601a81815481106134c157600080fd5b9060005260206000200160009150905080546122f0906154d5565b60008181526011602052604081205461ffff1681805b8261ffff168161ffff1611611a4b576000858152600f6020908152604080832061ffff851684529091529020546135299083615285565b91508061353581615562565b9150506134f2565b6017546040517fa72aa27e0000000000000000000000000000000000000000000000000000000081526004810184905263ffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063a72aa27e90604401600060405180830381600087803b1580156135b557600080fd5b505af11580156135c9573d6000803e3d6000fd5b505050600092835250600a602052604090912063ffffffff9091169055565b6017546040517f744bfe610000000000000000000000000000000000000000000000000000000081526004810183905230602482015273ffffffffffffffffffffffffffffffffffffffff9091169063744bfe6190604401600060405180830381600087803b15801561365a57600080fd5b505af11580156122d0573d6000803e3d6000fd5b8060005b818163ffffffff161015612d64573063af953a4a858563ffffffff851681811061369e5761369e61567d565b905060200201356040518263ffffffff1660e01b81526004016136c391815260200190565b600060405180830381600087803b1580156136dd57600080fd5b505af11580156136f1573d6000803e3d6000fd5b505050508080613700906155b6565b915050613672565b6017546040517fc80480220000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff9091169063c804802290602401600060405180830381600087803b15801561377457600080fd5b505af1158015613788573d6000803e3d6000fd5b505050506111c1816013613dda90919063ffffffff16565b6000828152600d602090815260408083208054825181850281018501909352808352849384939291908301828280156137f857602002820191906000526020600020905b8154815260200190600101908083116137e4575b5050505050905061167e8185613b1f565b8060005b81811015612d645760008484838181106138295761382961567d565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc828360405160200161386291815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b815260040161388e929190615115565b600060405180830381600087803b1580156138a857600080fd5b505af11580156138bc573d6000803e3d6000fd5b505050505080806138cc90615584565b91505061380d565b600d60205281600052604060002081815481106138f057600080fd5b90600052602060002001600091509150505481565b61390d613c55565b61391681613de6565b50565b601060205281600052604060002081815481106138f057600080fd5b6000828152600f6020908152604080832061ffff85168452825280832080548251818502810185019093528083528493849392919083018282801561166c5760200282019190600052602060002090815481526020019060010190808311611658575050505050905061167e818251613b1f565b60006112bb825490565b60006119108383613edc565b825160009081908315806139d35750808410155b156139dc578093505b60008467ffffffffffffffff8111156139f7576139f76156ac565b604051908082528060200260200182016040528015613a20578160200160208202803683370190505b509050600092505b84831015613a8e57866001613a3d85856153fe565b613a4791906153fe565b81518110613a5757613a5761567d565b6020026020010151818481518110613a7157613a7161567d565b602090810291909101015282613a8681615584565b935050613a28565b613aa781600060018451613aa291906153fe565b613f06565b8560641415613ae1578060018251613abf91906153fe565b81518110613acf57613acf61567d565b60200260200101519350505050611910565b806064825188613af19190615319565b613afb9190615305565b81518110613b0b57613b0b61567d565b602002602001015193505050509392505050565b815160009081908190841580613b355750808510155b15613b3e578094505b60008092505b85831015613b9a57866001613b5985856153fe565b613b6391906153fe565b81518110613b7357613b7361567d565b602002602001015181613b869190615285565b905082613b9281615584565b935050613b44565b9694955050505050565b60007f000000000000000000000000000000000000000000000000000000000000000015613c5057606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b158015613c1357600080fd5b505afa158015613c27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c4b91906149e1565b905090565b504390565b60005473ffffffffffffffffffffffffffffffffffffffff163314613cd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016129c9565b565b6015546040517f08b79da4000000000000000000000000000000000000000000000000000000008152600091829173ffffffffffffffffffffffffffffffffffffffff909116906308b79da490613d33908690600401614fa1565b602060405180830381600087803b158015613d4d57600080fd5b505af1158015613d61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d8591906149e1565b9050613d92601382614087565b5060608301516000828152600a6020908152604080832063ffffffff90941690935560a0860151600b8252929091208251613dd393919291909101906142ee565b5092915050565b60006119108383614093565b73ffffffffffffffffffffffffffffffffffffffff8116331415613e66576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016129c9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110613ef357613ef361567d565b9060005260206000200154905092915050565b818180821415613f17575050505050565b6000856002613f26878761538a565b613f30919061529d565b613f3a9087615211565b81518110613f4a57613f4a61567d565b602002602001015190505b818313614059575b80868481518110613f7057613f7061567d565b60200260200101511015613f905782613f8881615529565b935050613f5d565b858281518110613fa257613fa261567d565b6020026020010151811015613fc35781613fbb81615441565b925050613f90565b81831361405457858281518110613fdc57613fdc61567d565b6020026020010151868481518110613ff657613ff661567d565b60200260200101518785815181106140105761401061567d565b602002602001018885815181106140295761402961567d565b6020908102919091010191909152528261404281615529565b935050818061405090615441565b9250505b613f55565b8185121561406c5761406c868684613f06565b8383121561407f5761407f868486613f06565b505050505050565b60006119108383614186565b6000818152600183016020526040812054801561417c5760006140b76001836153fe565b85549091506000906140cb906001906153fe565b90508181146141305760008660000182815481106140eb576140eb61567d565b906000526020600020015490508087600001848154811061410e5761410e61567d565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806141415761414161564e565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506112bb565b60009150506112bb565b60008181526001830160205260408120546141cd575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556112bb565b5060006112bb565b828054828255906000526020600020908101928215614222579160200282015b8281111561422257825180516142129184916020909101906142ee565b50916020019190600101906141f5565b5061422e929150614362565b5090565b5080546000825590600052602060002090810190613916919061437f565b82805461425c906154d5565b90600052602060002090601f01602090048101928261427e57600085556142e2565b82601f106142b5578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008235161785556142e2565b828001600101855582156142e2579182015b828111156142e25782358255916020019190600101906142c7565b5061422e92915061437f565b8280546142fa906154d5565b90600052602060002090601f01602090048101928261431c57600085556142e2565b82601f1061433557805160ff19168380011785556142e2565b828001600101855582156142e2579182015b828111156142e2578251825591602001919060010190614347565b8082111561422e5760006143768282614394565b50600101614362565b5b8082111561422e5760008155600101614380565b5080546143a0906154d5565b6000825580601f106143b0575050565b601f016020900490600052602060002090810190613916919061437f565b60006143e16143dc846151cb565b615158565b90508281528383830111156143f557600080fd5b828260208301376000602084830101529392505050565b8051614417816156db565b919050565b60008083601f84011261442e57600080fd5b50813567ffffffffffffffff81111561444657600080fd5b6020830191508360208260051b850101111561168457600080fd5b8051801515811461441757600080fd5b60008083601f84011261448357600080fd5b50813567ffffffffffffffff81111561449b57600080fd5b60208301915083602082850101111561168457600080fd5b600082601f8301126144c457600080fd5b611910838335602085016143ce565b600082601f8301126144e457600080fd5b81516144f26143dc826151cb565b81815284602083860101111561450757600080fd5b614518826020830160208701615415565b949350505050565b803561ffff8116811461441757600080fd5b8051614417816156fd565b805167ffffffffffffffff8116811461441757600080fd5b803560ff8116811461441757600080fd5b80516144178161570f565b60006020828403121561458357600080fd5b8135611910816156db565b600080604083850312156145a157600080fd5b823567ffffffffffffffff808211156145b957600080fd5b818501915085601f8301126145cd57600080fd5b813560206145dd6143dc836151a7565b8083825282820191508286018a848660051b89010111156145fd57600080fd5b60005b858110156146385781358781111561461757600080fd5b6146258d87838c01016144b3565b8552509284019290840190600101614600565b5090975050508601359250508082111561465157600080fd5b5061465e858286016144b3565b9150509250929050565b6000602080838503121561467b57600080fd5b823567ffffffffffffffff8082111561469357600080fd5b818501915085601f8301126146a757600080fd5b81356146b56143dc826151a7565b80828252858201915085850189878560051b88010111156146d557600080fd5b60005b84811015614724578135868111156146ef57600080fd5b8701603f81018c1361470057600080fd5b6147118c8a830135604084016143ce565b85525092870192908701906001016146d8565b50909998505050505050505050565b6000806020838503121561474657600080fd5b823567ffffffffffffffff81111561475d57600080fd5b6147698582860161441c565b90969095509350505050565b60008060006040848603121561478a57600080fd5b833567ffffffffffffffff8111156147a157600080fd5b6147ad8682870161441c565b90945092505060208401356147c1816156fd565b809150509250925092565b6000602082840312156147de57600080fd5b61191082614461565b6000602082840312156147f957600080fd5b5035919050565b6000806020838503121561481357600080fd5b823567ffffffffffffffff81111561482a57600080fd5b61476985828601614471565b60006020828403121561484857600080fd5b8151611910816156db565b600080600080600060a0868803121561486b57600080fd5b85516003811061487a57600080fd5b602087015190955061488b816156fd565b604087015190945061489c816156fd565b60608701519093506148ad816156db565b80925050608086015190509295509295909350565b6000602082840312156148d457600080fd5b815167ffffffffffffffff808211156148ec57600080fd5b90830190610140828603121561490157600080fd5b61490961512e565b6149128361440c565b815261492060208401614532565b602082015260408301518281111561493757600080fd5b614943878286016144d3565b60408301525061495560608401614566565b60608201526149666080840161440c565b608082015261497760a0840161453d565b60a082015261498860c08401614532565b60c082015261499960e08401614566565b60e08201526101006149ac818501614461565b9082015261012083810151838111156149c457600080fd5b6149d0888287016144d3565b918301919091525095945050505050565b6000602082840312156149f357600080fd5b5051919050565b600080600060408486031215614a0f57600080fd5b83359250602084013567ffffffffffffffff811115614a2d57600080fd5b614a3986828701614471565b9497909650939450505050565b60008060408385031215614a5957600080fd5b82359150614a6960208401614520565b90509250929050565b600080600060608486031215614a8757600080fd5b83359250614a9760208501614520565b9150604084013590509250925092565b60008060408385031215614aba57600080fd5b50508035926020909101359150565b600080600060608486031215614ade57600080fd5b8335925060208401359150614af560408501614520565b90509250925092565b600080600060608486031215614b1357600080fd5b505081359360208301359350604090920135919050565b60008060408385031215614b3d57600080fd5b823591506020830135614b4f816156fd565b809150509250929050565b60008060408385031215614b6d57600080fd5b823591506020830135614b4f8161570f565b600060208284031215614b9157600080fd5b61191082614555565b600080600080600060a08688031215614bb257600080fd5b614bbb86614555565b94506020860135614bcb816156fd565b93506040860135614bdb8161570f565b94979396509394606081013594506080013592915050565b600060208284031215614c0557600080fd5b81356119108161570f565b600060208284031215614c2257600080fd5b81516119108161570f565b600081518084526020808501945080840160005b83811015614c5d57815187529582019590820190600101614c41565b509495945050505050565b60008151808452614c80816020860160208601615415565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015614d27577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018552614d15868351614c68565b95509382019390820190600101614cdb565b505085840381870152505050612ddc8185614c68565b6020815281602082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115614d7657600080fd5b8260051b80856040850137600092016040019182525092915050565b6020815260006119106020830184614c2d565b604081526000614db86040830185614c2d565b8281036020840152612ddc8185614c2d565b821515815260406020820152600061190d6040830184614c68565b6020815260006119106020830184614c68565b604081526000614e0b6040830185614c68565b8281036020840152612ddc8185614c68565b60a081526000614e3060a0830188614c68565b6020838203818501528188548084528284019150828160051b85010160008b8152848120815b84811015614f62578784037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001865281548390600181811c9080831680614e9e57607f831692505b8b8310811415614ed5577f4e487b710000000000000000000000000000000000000000000000000000000088526022600452602488fd5b82895260208901818015614ef05760018114614f1f57614f49565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00861682528d82019650614f49565b6000898152602090208a5b86811015614f4357815484820152908501908f01614f2a565b83019750505b505050988a019892965050509190910190600101614e56565b5050508681036040880152614f77818b614c68565b9450505050508460608401528281036080840152614f958185614c68565b98975050505050505050565b6020815260008251610100806020850152614fc0610120850183614c68565b915060208501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe080868503016040870152614ffc8483614c68565b935060408701519150615027606087018373ffffffffffffffffffffffffffffffffffffffff169052565b606087015163ffffffff811660808801529150608087015173ffffffffffffffffffffffffffffffffffffffff811660a0880152915060a08701519150808685030160c08701526150788483614c68565b935060c08701519150808685030160e0870152506150968382614c68565b92505060e08501516150b7828601826bffffffffffffffffffffffff169052565b5090949350505050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b82815260406020820152600061190d6040830184614c68565b604051610140810167ffffffffffffffff81118282101715615152576151526156ac565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561519f5761519f6156ac565b604052919050565b600067ffffffffffffffff8211156151c1576151c16156ac565b5060051b60200190565b600067ffffffffffffffff8211156151e5576151e56156ac565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0384138115161561524b5761524b6155f0565b827f800000000000000000000000000000000000000000000000000000000000000003841281161561527f5761527f6155f0565b50500190565b60008219821115615298576152986155f0565b500190565b6000826152ac576152ac61561f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615300576153006155f0565b500590565b6000826153145761531461561f565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615351576153516155f0565b500290565b60006bffffffffffffffffffffffff80831681851681830481118215151615615381576153816155f0565b02949350505050565b6000808312837f8000000000000000000000000000000000000000000000000000000000000000018312811516156153c4576153c46155f0565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156153f8576153f86155f0565b50500390565b600082821015615410576154106155f0565b500390565b60005b83811015615430578181015183820152602001615418565b83811115612d645750506000910152565b60007f8000000000000000000000000000000000000000000000000000000000000000821415615473576154736155f0565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b600061ffff8216806154ad576154ad6155f0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0192915050565b600181811c908216806154e957607f821691505b60208210811415615523577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561555b5761555b6155f0565b5060010190565b600061ffff8083168181141561557a5761557a6155f0565b6001019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561555b5761555b6155f0565b600063ffffffff8083168181141561557a5761557a6155f0565b600060ff821660ff8114156155e7576155e76155f0565b60010192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461391657600080fd5b63ffffffff8116811461391657600080fd5b6bffffffffffffffffffffffff8116811461391657600080fdfea164736f6c6343000806000a307834353534343832643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030307834323534343332643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030307835353533343434333264353535333434326434313532343234393534353235353464326435343435353335343465343535343030303030303030303030303030", + ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"_registrar\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useArb\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"feeds\",\"type\":\"string[]\"},{\"internalType\":\"string\",\"name\":\"timeParamKey\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"FeedLookup\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"LogEmitted\",\"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\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Received\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"UpkeepTopUp\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"UpkeepsRegistered\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BUCKET_SIZE\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"addLinkAmount\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchCancelUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"number\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"checkGasToBurn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"performGasToBurn\",\"type\":\"uint256\"}],\"name\":\"batchRegisterUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"batchSendLogs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint32\",\"name\":\"interval\",\"type\":\"uint32\"}],\"name\":\"batchSetIntervals\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchUpdatePipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchWithdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bucketedDelays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"buckets\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"startGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"burnPerformGas\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"checkGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"counters\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"delays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"dummyMap\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emittedSig\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feedParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"feedsHex\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"firstPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"gasLimits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"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\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getBucketedDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getBucketedDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getLogTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"logTrigger\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"p\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getPxDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getSumDelayInBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getSumDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"intervals\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"lastTopUpBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkToken\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBalanceThresholdMultiplier\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performDataSizes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"previousPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registrar\",\"outputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contractIKeeperRegistryMaster\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"sendLog\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"setAddLinkAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setCheckGasToBurn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"newRegistrar\",\"type\":\"address\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"newFeeds\",\"type\":\"string[]\"}],\"name\":\"setFeedsHex\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_interval\",\"type\":\"uint256\"}],\"name\":\"setInterval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"newMinBalanceThresholdMultiplier\",\"type\":\"uint8\"}],\"name\":\"setMinBalanceThresholdMultiplier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setPerformDataSize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setPerformGasToBurn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newInterval\",\"type\":\"uint256\"}],\"name\":\"setUpkeepTopUpCheckInterval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timeParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"topUpFund\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pipelineData\",\"type\":\"bytes\"}],\"name\":\"updateUpkeepPipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTopUpCheckInterval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useArbitrumBlockNum\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x7f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf086080526005601455601580546001600160681b0319166c140000000002c68af0bb140000179055606460c0526101c0604052604261014081815260e091829190620050fb6101603981526020016040518060800160405280604281526020016200513d6042913981526020016040518060800160405280604281526020016200517f604291399052620000b89060169060036200035f565b50348015620000c657600080fd5b50604051620051c1380380620051c1833981016040819052620000e9916200044c565b81813380600081620001425760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b038481169190911790915581161562000175576200017581620002b4565b5050601180546001600160a01b0319166001600160a01b038516908117909155604080516330fe427560e21b815281516000945063c3f909d4926004808401939192918290030181865afa158015620001d2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001f891906200048f565b50601380546001600160a01b0319166001600160a01b038381169190911790915560115460408051631b6b6d2360e01b81529051939450911691631b6b6d23916004808201926020929091908290030181865afa1580156200025e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002849190620004c0565b601280546001600160a01b0319166001600160a01b039290921691909117905550151560a0525062000658915050565b336001600160a01b038216036200030e5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000139565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215620003aa579160200282015b82811115620003aa57825182906200039990826200058c565b509160200191906001019062000380565b50620003b8929150620003bc565b5090565b80821115620003b8576000620003d38282620003dd565b50600101620003bc565b508054620003eb90620004fd565b6000825580601f10620003fc575050565b601f0160209004906000526020600020908101906200041c91906200041f565b50565b5b80821115620003b8576000815560010162000420565b6001600160a01b03811681146200041c57600080fd5b600080604083850312156200046057600080fd5b82516200046d8162000436565b602084015190925080151581146200048457600080fd5b809150509250929050565b60008060408385031215620004a357600080fd5b8251620004b08162000436565b6020939093015192949293505050565b600060208284031215620004d357600080fd5b8151620004e08162000436565b9392505050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200051257607f821691505b6020821081036200053357634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200058757600081815260208120601f850160051c81016020861015620005625750805b601f850160051c820191505b8181101562000583578281556001016200056e565b5050505b505050565b81516001600160401b03811115620005a857620005a8620004e7565b620005c081620005b98454620004fd565b8462000539565b602080601f831160018114620005f85760008415620005df5750858301515b600019600386901b1c1916600185901b17855562000583565b600085815260208120601f198616915b82811015620006295788860151825594840194600190910190840162000608565b5085821015620006485787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c051614a5e6200069d6000396000818161052b0152611a3d0152600081816108470152612e69015260008181610b8301526114410152614a5e6000f3fe6080604052600436106103e25760003560e01c8063776898c81161020d578063a72aa27e11610128578063d3558528116100bb578063e0114adb1161008a578063f2fde38b1161006f578063f2fde38b14610e80578063fba7ffa314610ea0578063fcdc1f6314610ecd57600080fd5b8063e0114adb14610e3d578063e455308314610e6a57600080fd5b8063d355852814610d7e578063d6051a7214610ddd578063daee1aeb14610dfd578063dbef701e14610e1d57600080fd5b8063becde0e1116100f7578063becde0e114610c9b578063c357f1f314610cbb578063c804802214610d15578063c98f10b014610d3557600080fd5b8063a72aa27e14610be5578063a79c404314610c05578063af953a4a14610c32578063afb28d1f14610c5257600080fd5b80639ac542eb116101a05780639d6f1cc71161016f5780639d6f1cc714610b51578063a654824814610b71578063a6b5947514610ba5578063a6c60d8914610bc557600080fd5b80639ac542eb14610a975780639b42935414610ad35780639b51fb0d14610b005780639d385eaa14610b3157600080fd5b80638da5cb5b116101dc5780638da5cb5b146109ff5780638fcb3fba14610a2a578063924ca57814610a57578063948108f714610a7757600080fd5b8063776898c81461097d57806379ba50971461099d5780637b103999146109b25780637e7a46dc146109df57600080fd5b806346e7a63e116102fd578063636092e8116102905780636e04ff0d1161025f5780636e04ff0d146108d35780637145f11b146108f357806373644cce14610923578063767213031461095057600080fd5b8063636092e8146107f3578063642f6cef1461083557806369cdbadb1461087957806369e9b773146108a657600080fd5b806359710992116102cc578063597109921461077c5780635d4ee7f3146107915780635f17e616146107a657806360457ff5146107c657600080fd5b806346e7a63e146106d45780634b56a42e1461070157806351c98be31461072f57806357970e931461074f57600080fd5b806320e3dbd411610375578063328ffd1111610344578063328ffd11146106475780633ebe8d6c146106745780634585e33b1461069457806345d2ec17146106b457600080fd5b806320e3dbd41461059557806328c4b57b146105b55780632a9032d3146105d55780632b20e397146105f557600080fd5b80630d4a4fb1116103b15780630d4a4fb1146104cc5780630e577d42146104f957806312c5502714610519578063206c32e81461056057600080fd5b806305e251311461042657806306c1cc001461044857806306e3b63214610468578063077ac6211461049e57600080fd5b3661042157604080513381523460208201527f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f88525874910160405180910390a1005b600080fd5b34801561043257600080fd5b50610446610441366004613796565b610efa565b005b34801561045457600080fd5b506104466104633660046138b7565b610f11565b34801561047457600080fd5b50610488610483366004613953565b6112cd565b6040516104959190613975565b60405180910390f35b3480156104aa57600080fd5b506104be6104b93660046139d0565b6113cc565b604051908152602001610495565b3480156104d857600080fd5b506104ec6104e7366004613a05565b61140a565b6040516104959190613a8c565b34801561050557600080fd5b50610446610514366004613a05565b611527565b34801561052557600080fd5b5061054d7f000000000000000000000000000000000000000000000000000000000000000081565b60405161ffff9091168152602001610495565b34801561056c57600080fd5b5061058061057b366004613a9f565b61156f565b60408051928352602083019190915201610495565b3480156105a157600080fd5b506104466105b0366004613aed565b6115f2565b3480156105c157600080fd5b506104be6105d0366004613b0a565b6117bc565b3480156105e157600080fd5b506104466105f0366004613b7b565b611827565b34801561060157600080fd5b506011546106229073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610495565b34801561065357600080fd5b506104be610662366004613a05565b60036020526000908152604090205481565b34801561068057600080fd5b506104be61068f366004613a05565b6118c1565b3480156106a057600080fd5b506104466106af366004613bff565b61192a565b3480156106c057600080fd5b506104886106cf366004613a9f565b611b55565b3480156106e057600080fd5b506104be6106ef366004613a05565b600a6020526000908152604090205481565b34801561070d57600080fd5b5061072161071c366004613c35565b611bc4565b604051610495929190613d09565b34801561073b57600080fd5b5061044661074a366004613d24565b611c18565b34801561075b57600080fd5b506012546106229073ffffffffffffffffffffffffffffffffffffffff1681565b34801561078857600080fd5b50610446611cbc565b34801561079d57600080fd5b50610446611ea7565b3480156107b257600080fd5b506104466107c1366004613953565b611fde565b3480156107d257600080fd5b506104be6107e1366004613a05565b60076020526000908152604090205481565b3480156107ff57600080fd5b50601554610818906bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff9091168152602001610495565b34801561084157600080fd5b506108697f000000000000000000000000000000000000000000000000000000000000000081565b6040519015158152602001610495565b34801561088557600080fd5b506104be610894366004613a05565b60086020526000908152604090205481565b3480156108b257600080fd5b506104466108c1366004613953565b60009182526008602052604090912055565b3480156108df57600080fd5b506107216108ee366004613bff565b6120ab565b3480156108ff57600080fd5b5061086961090e366004613a05565b600b6020526000908152604090205460ff1681565b34801561092f57600080fd5b506104be61093e366004613a05565b6000908152600c602052604090205490565b34801561095c57600080fd5b506104be61096b366004613a05565b60046020526000908152604090205481565b34801561098957600080fd5b50610869610998366004613a05565b6122c0565b3480156109a957600080fd5b50610446612312565b3480156109be57600080fd5b506013546106229073ffffffffffffffffffffffffffffffffffffffff1681565b3480156109eb57600080fd5b506104466109fa366004613d7b565b61240f565b348015610a0b57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610622565b348015610a3657600080fd5b506104be610a45366004613a05565b60056020526000908152604090205481565b348015610a6357600080fd5b50610446610a72366004613953565b6124a0565b348015610a8357600080fd5b50610446610a92366004613dc7565b6126e5565b348015610aa357600080fd5b50601554610ac1906c01000000000000000000000000900460ff1681565b60405160ff9091168152602001610495565b348015610adf57600080fd5b50610446610aee366004613953565b60009182526009602052604090912055565b348015610b0c57600080fd5b5061054d610b1b366004613a05565b600e6020526000908152604090205461ffff1681565b348015610b3d57600080fd5b50610488610b4c366004613a05565b61282e565b348015610b5d57600080fd5b506104ec610b6c366004613a05565b612890565b348015610b7d57600080fd5b506104be7f000000000000000000000000000000000000000000000000000000000000000081565b348015610bb157600080fd5b50610446610bc0366004613b0a565b61293c565b348015610bd157600080fd5b50610446610be0366004613a05565b601455565b348015610bf157600080fd5b50610446610c00366004613df7565b6129a5565b348015610c1157600080fd5b50610446610c20366004613953565b60009182526007602052604090912055565b348015610c3e57600080fd5b50610446610c4d366004613a05565b612a50565b348015610c5e57600080fd5b506104ec6040518060400160405280600981526020017f666565644964486578000000000000000000000000000000000000000000000081525081565b348015610ca757600080fd5b50610446610cb6366004613b7b565b612ad6565b348015610cc757600080fd5b50610446610cd6366004613e1c565b601580547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff92909216919091179055565b348015610d2157600080fd5b50610446610d30366004613a05565b612b70565b348015610d4157600080fd5b506104ec6040518060400160405280600b81526020017f626c6f636b4e756d62657200000000000000000000000000000000000000000081525081565b348015610d8a57600080fd5b50610446610d99366004613e39565b6015805460ff9092166c01000000000000000000000000027fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff909216919091179055565b348015610de957600080fd5b50610580610df8366004613953565b612c08565b348015610e0957600080fd5b50610446610e18366004613b7b565b612c71565b348015610e2957600080fd5b506104be610e38366004613953565b612d3c565b348015610e4957600080fd5b506104be610e58366004613a05565b60096020526000908152604090205481565b348015610e7657600080fd5b506104be60145481565b348015610e8c57600080fd5b50610446610e9b366004613aed565b612d6d565b348015610eac57600080fd5b506104be610ebb366004613a05565b60066020526000908152604090205481565b348015610ed957600080fd5b506104be610ee8366004613a05565b60026020526000908152604090205481565b8051610f0d906016906020840190613566565b5050565b6040805161018081018252600461014082019081527f746573740000000000000000000000000000000000000000000000000000000061016083015281528151602081810184526000808352818401929092523083850181905263ffffffff8b166060850152608084015260ff808a1660a08501528451808301865283815260c085015260e0840189905284519182019094529081526101008201526bffffffffffffffffffffffff8516610120820152601254601154919273ffffffffffffffffffffffffffffffffffffffff9182169263095ea7b3921690610ff7908c1688613e85565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526bffffffffffffffffffffffff1660248201526044016020604051808303816000875af1158015611075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110999190613ec9565b5060008860ff1667ffffffffffffffff8111156110b8576110b8613646565b6040519080825280602002602001820160405280156110e1578160200160208202803683370190505b50905060005b8960ff168160ff16101561128a57600061110084612d81565b90508860ff16600103611238576040517f0d4a4fb1000000000000000000000000000000000000000000000000000000008152600481018290526000903090630d4a4fb190602401600060405180830381865afa158015611165573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526111ab9190810190613f31565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634ee88d35906112049085908590600401613f66565b600060405180830381600087803b15801561121e57600080fd5b505af1158015611232573d6000803e3d6000fd5b50505050505b80838360ff168151811061124e5761124e613f7f565b6020908102919091018101919091526000918252600881526040808320889055600790915290208490558061128281613fae565b9150506110e7565b507f2ee10f7eb180441fb9fbba75b10c0162b5390b557712c93426243ca8f383c711816040516112ba9190613975565b60405180910390a1505050505050505050565b606060006112db600f612e4f565b9050808410611316576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260000361132b576113288482613fcd565b92505b60008367ffffffffffffffff81111561134657611346613646565b60405190808252806020026020018201604052801561136f578160200160208202803683370190505b50905060005b848110156113c15761139261138a8288613fe0565b600f90612e59565b8282815181106113a4576113a4613f7f565b6020908102919091010152806113b981613ff3565b915050611375565b509150505b92915050565b600d60205282600052604060002060205281600052604060002081815481106113f457600080fd5b9060005260206000200160009250925050505481565b606060006040518060c001604052803073ffffffffffffffffffffffffffffffffffffffff168152602001600160ff1681526020017f000000000000000000000000000000000000000000000000000000000000000081526020018460405160200161147891815260200190565b6040516020818303038152906040526114909061402b565b81526020016000801b81526020016000801b8152509050806040516020016115109190600060c08201905073ffffffffffffffffffffffffffffffffffffffff835116825260ff602084015116602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015292915050565b604051602081830303815290604052915050919050565b6000611531612e65565b604051308152909150819083907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf089060200160405180910390a35050565b6000828152600d6020908152604080832061ffff8516845282528083208054825181850281018501909352808352849384939291908301828280156115d357602002820191906000526020600020905b8154815260200190600101908083116115bf575b505050505090506115e5818251612f07565b92509250505b9250929050565b601180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117909155604080517fc3f909d400000000000000000000000000000000000000000000000000000000815281516000939263c3f909d492600480820193918290030181865afa158015611688573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ac919061407b565b50601380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691909117909155601154604080517f1b6b6d230000000000000000000000000000000000000000000000000000000081529051939450911691631b6b6d23916004808201926020929091908290030181865afa15801561174f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061177391906140a9565b601280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555050565b6000838152600c60209081526040808320805482518185028101850190935280835261181d9383018282801561181157602002820191906000526020600020905b8154815260200190600101908083116117fd575b50505050508484612f8c565b90505b9392505050565b8060005b818160ff1610156118bb573063c8048022858560ff851681811061185157611851613f7f565b905060200201356040518263ffffffff1660e01b815260040161187691815260200190565b600060405180830381600087803b15801561189057600080fd5b505af11580156118a4573d6000803e3d6000fd5b5050505080806118b390613fae565b91505061182b565b50505050565b6000818152600e602052604081205461ffff1681805b8261ffff168161ffff1611611922576000858152600d6020908152604080832061ffff8516845290915290205461190e9083613fe0565b91508061191a816140c6565b9150506118d7565b509392505050565b60005a905060008061193e84860186613c35565b9150915060008180602001905181019061195891906140e7565b6000818152600560209081526040808320546004909252822054929350919061197f612e65565b90508260000361199f576000848152600560205260409020819055611afa565b6000848152600360205260408120546119b88484613fcd565b6119c29190613fcd565b6000868152600e6020908152604080832054600d835281842061ffff909116808552908352818420805483518186028101860190945280845295965090949192909190830182828015611a3457602002820191906000526020600020905b815481526020019060010190808311611a20575b505050505090507f000000000000000000000000000000000000000000000000000000000000000061ffff16815103611aaf5781611a71816140c6565b6000898152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff83161790559250505b506000868152600d6020908152604080832061ffff909416835292815282822080546001818101835591845282842001859055888352600c8252928220805493840181558252902001555b600084815260066020526040812054611b14906001613fe0565b6000868152600660209081526040808320849055600490915290208390559050611b3e85836124a0565b611b4985898461293c565b50505050505050505050565b6000828152600d6020908152604080832061ffff85168452825291829020805483518184028101840190945280845260609392830182828015611bb757602002820191906000526020600020905b815481526020019060010190808311611ba3575b5050505050905092915050565b6000606060008484604051602001611bdd929190614100565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181529190526001969095509350505050565b8160005b81811015611cb55730635f17e616868684818110611c3c57611c3c613f7f565b90506020020135856040518363ffffffff1660e01b8152600401611c7092919091825263ffffffff16602082015260400190565b600060405180830381600087803b158015611c8a57600080fd5b505af1158015611c9e573d6000803e3d6000fd5b505050508080611cad90613ff3565b915050611c1c565b5050505050565b6013546040517f06e3b632000000000000000000000000000000000000000000000000000000008152600060048201819052602482018190529173ffffffffffffffffffffffffffffffffffffffff16906306e3b63290604401600060405180830381865afa158015611d33573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611d799190810190614194565b80519091506000611d88612e65565b905060005b828110156118bb576000848281518110611da957611da9613f7f565b60209081029190910101516013546040517f5147cd590000000000000000000000000000000000000000000000000000000081526004810183905291925060009173ffffffffffffffffffffffffffffffffffffffff90911690635147cd5990602401602060405180830381865afa158015611e29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e4d9190614225565b90508060ff16600103611e9257604051308152849083907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf089060200160405180910390a35b50508080611e9f90613ff3565b915050611d8d565b611eaf6130eb565b6012546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611f1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f4291906140e7565b6012546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810183905291925073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb906044016020604051808303816000875af1158015611fba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0d9190613ec9565b60008281526003602090815260408083208490556005825280832083905560068252808320839055600c9091528120612016916135bc565b6000828152600e602052604081205461ffff16905b8161ffff168161ffff1611612072576000848152600d6020908152604080832061ffff851684529091528120612060916135bc565b8061206a816140c6565b91505061202b565b5050506000908152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055565b6000606060005a905060006120c285870187613a05565b60008181526009602090815260408083205460089092528220549293509190838367ffffffffffffffff8111156120fb576120fb613646565b6040519080825280601f01601f191660200182016040528015612125576020820181803683370190505b50604051602001612137929190613f66565b60405160208183030381529060405290506000612152612e65565b9050600061215f866122c0565b90505b835a61216e9089613fcd565b61217a90612710613fe0565b10156121bb5781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055612162565b806121d35760008398509850505050505050506115eb565b6040518060400160405280600981526020017f666565644964486578000000000000000000000000000000000000000000000081525060166040518060400160405280600b81526020017f626c6f636b4e756d626572000000000000000000000000000000000000000000815250848960405160200161225591815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f7ddd933e0000000000000000000000000000000000000000000000000000000082526122b7959493929160040161428f565b60405180910390fd5b60008181526005602052604081205481036122dd57506001919050565b600082815260036020908152604080832054600490925290912054612300612e65565b61230a9190613fcd565b101592915050565b60015473ffffffffffffffffffffffffffffffffffffffff163314612393576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016122b7565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6013546040517fcd7f71b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063cd7f71b590612469908690869086906004016143dc565b600060405180830381600087803b15801561248357600080fd5b505af1158015612497573d6000803e3d6000fd5b50505050505050565b6014546000838152600260205260409020546124bc9083613fcd565b1115610f0d576013546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810184905260009173ffffffffffffffffffffffffffffffffffffffff169063c7c3a19a90602401600060405180830381865afa158015612532573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612578919081019061445e565b6013546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810186905291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063b657bc9c90602401602060405180830381865afa1580156125ed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612611919061457d565b6015549091506126359082906c01000000000000000000000000900460ff16613e85565b6bffffffffffffffffffffffff1682606001516bffffffffffffffffffffffff1610156118bb576015546126789085906bffffffffffffffffffffffff166126e5565b60008481526002602090815260409182902085905560155482518781526bffffffffffffffffffffffff909116918101919091529081018490527f49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c09060600160405180910390a150505050565b6012546013546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526bffffffffffffffffffffffff8416602482015291169063095ea7b3906044016020604051808303816000875af115801561276d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127919190613ec9565b506013546040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063948108f790604401600060405180830381600087803b15801561281257600080fd5b505af1158015612826573d6000803e3d6000fd5b505050505050565b6000818152600c602090815260409182902080548351818402810184019094528084526060939283018282801561288457602002820191906000526020600020905b815481526020019060010190808311612870575b50505050509050919050565b601681815481106128a057600080fd5b9060005260206000200160009150905080546128bb90614242565b80601f01602080910402602001604051908101604052809291908181526020018280546128e790614242565b80156129345780601f1061290957610100808354040283529160200191612934565b820191906000526020600020905b81548152906001019060200180831161291757829003601f168201915b505050505081565b6000838152600760205260409020545b805a6129589085613fcd565b61296490612710613fe0565b10156118bb5781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905561294c565b6013546040517fa72aa27e0000000000000000000000000000000000000000000000000000000081526004810184905263ffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063a72aa27e90604401600060405180830381600087803b158015612a1d57600080fd5b505af1158015612a31573d6000803e3d6000fd5b505050600092835250600a602052604090912063ffffffff9091169055565b6013546040517f744bfe610000000000000000000000000000000000000000000000000000000081526004810183905230602482015273ffffffffffffffffffffffffffffffffffffffff9091169063744bfe6190604401600060405180830381600087803b158015612ac257600080fd5b505af1158015611cb5573d6000803e3d6000fd5b8060005b818163ffffffff1610156118bb573063af953a4a858563ffffffff8516818110612b0657612b06613f7f565b905060200201356040518263ffffffff1660e01b8152600401612b2b91815260200190565b600060405180830381600087803b158015612b4557600080fd5b505af1158015612b59573d6000803e3d6000fd5b505050508080612b689061459a565b915050612ada565b6013546040517fc80480220000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff9091169063c804802290602401600060405180830381600087803b158015612bdc57600080fd5b505af1158015612bf0573d6000803e3d6000fd5b50505050610f0d81600f61316e90919063ffffffff16565b6000828152600c60209081526040808320805482518185028101850190935280835284938493929190830182828015612c6057602002820191906000526020600020905b815481526020019060010190808311612c4c575b505050505090506115e58185612f07565b8060005b818110156118bb576000848483818110612c9157612c91613f7f565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc8283604051602001612cca91815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401612cf6929190613f66565b600060405180830381600087803b158015612d1057600080fd5b505af1158015612d24573d6000803e3d6000fd5b50505050508080612d3490613ff3565b915050612c75565b600c6020528160005260406000208181548110612d5857600080fd5b90600052602060002001600091509150505481565b612d756130eb565b612d7e8161317a565b50565b6011546040517f3f678e11000000000000000000000000000000000000000000000000000000008152600091829173ffffffffffffffffffffffffffffffffffffffff90911690633f678e1190612ddc9086906004016145b3565b6020604051808303816000875af1158015612dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e1f91906140e7565b9050612e2c600f8261326f565b506060909201516000838152600a6020526040902063ffffffff90911690555090565b60006113c6825490565b6000611820838361327b565b60007f000000000000000000000000000000000000000000000000000000000000000015612f0257606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ed9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612efd91906140e7565b905090565b504390565b815160009081908190841580612f1d5750808510155b15612f26578094505b60008092505b85831015612f8257866001612f418585613fcd565b612f4b9190613fcd565b81518110612f5b57612f5b613f7f565b602002602001015181612f6e9190613fe0565b905082612f7a81613ff3565b935050612f2c565b9694955050505050565b82516000908190831580612fa05750808410155b15612fa9578093505b60008467ffffffffffffffff811115612fc457612fc4613646565b604051908082528060200260200182016040528015612fed578160200160208202803683370190505b509050600092505b8483101561305b5786600161300a8585613fcd565b6130149190613fcd565b8151811061302457613024613f7f565b602002602001015181848151811061303e5761303e613f7f565b60209081029190910101528261305381613ff3565b935050612ff5565b6130748160006001845161306f9190613fcd565b6132a5565b856064036130ad57806001825161308b9190613fcd565b8151811061309b5761309b613f7f565b60200260200101519350505050611820565b8060648251886130bd9190614705565b6130c79190614771565b815181106130d7576130d7613f7f565b602002602001015193505050509392505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461316c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016122b7565b565b6000611820838361341d565b3373ffffffffffffffffffffffffffffffffffffffff8216036131f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016122b7565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006118208383613517565b600082600001828154811061329257613292613f7f565b9060005260206000200154905092915050565b81818082036132b5575050505050565b60008560026132c48787614785565b6132ce91906147a5565b6132d8908761480d565b815181106132e8576132e8613f7f565b602002602001015190505b8183136133f7575b8086848151811061330e5761330e613f7f565b6020026020010151101561332e578261332681614835565b9350506132fb565b85828151811061334057613340613f7f565b6020026020010151811015613361578161335981614866565b92505061332e565b8183136133f25785828151811061337a5761337a613f7f565b602002602001015186848151811061339457613394613f7f565b60200260200101518785815181106133ae576133ae613f7f565b602002602001018885815181106133c7576133c7613f7f565b602090810291909101019190915252826133e081614835565b93505081806133ee90614866565b9250505b6132f3565b8185121561340a5761340a8686846132a5565b83831215612826576128268684866132a5565b60008181526001830160205260408120548015613506576000613441600183613fcd565b855490915060009061345590600190613fcd565b90508181146134ba57600086600001828154811061347557613475613f7f565b906000526020600020015490508087600001848154811061349857613498613f7f565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806134cb576134cb6148bd565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506113c6565b60009150506113c6565b5092915050565b600081815260018301602052604081205461355e575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556113c6565b5060006113c6565b8280548282559060005260206000209081019282156135ac579160200282015b828111156135ac578251829061359c9082614937565b5091602001919060010190613586565b506135b89291506135da565b5090565b5080546000825590600052602060002090810190612d7e91906135f7565b808211156135b85760006135ee828261360c565b506001016135da565b5b808211156135b857600081556001016135f8565b50805461361890614242565b6000825580601f10613628575050565b601f016020900490600052602060002090810190612d7e91906135f7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff8111828210171561369957613699613646565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156136e6576136e6613646565b604052919050565b600067ffffffffffffffff82111561370857613708613646565b5060051b60200190565b600067ffffffffffffffff82111561372c5761372c613646565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600061376b61376684613712565b61369f565b905082815283838301111561377f57600080fd5b828260208301376000602084830101529392505050565b600060208083850312156137a957600080fd5b823567ffffffffffffffff808211156137c157600080fd5b818501915085601f8301126137d557600080fd5b81356137e3613766826136ee565b81815260059190911b8301840190848101908883111561380257600080fd5b8585015b8381101561384f5780358581111561381e5760008081fd5b8601603f81018b136138305760008081fd5b6138418b8983013560408401613758565b845250918601918601613806565b5098975050505050505050565b60ff81168114612d7e57600080fd5b63ffffffff81168114612d7e57600080fd5b600082601f83011261388e57600080fd5b61182083833560208501613758565b6bffffffffffffffffffffffff81168114612d7e57600080fd5b600080600080600080600060e0888a0312156138d257600080fd5b87356138dd8161385c565b965060208801356138ed8161386b565b955060408801356138fd8161385c565b9450606088013567ffffffffffffffff81111561391957600080fd5b6139258a828b0161387d565b94505060808801356139368161389d565b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561396657600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b818110156139ad57835183529284019291840191600101613991565b50909695505050505050565b803561ffff811681146139cb57600080fd5b919050565b6000806000606084860312156139e557600080fd5b833592506139f5602085016139b9565b9150604084013590509250925092565b600060208284031215613a1757600080fd5b5035919050565b60005b83811015613a39578181015183820152602001613a21565b50506000910152565b60008151808452613a5a816020860160208601613a1e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006118206020830184613a42565b60008060408385031215613ab257600080fd5b82359150613ac2602084016139b9565b90509250929050565b73ffffffffffffffffffffffffffffffffffffffff81168114612d7e57600080fd5b600060208284031215613aff57600080fd5b813561182081613acb565b600080600060608486031215613b1f57600080fd5b505081359360208301359350604090920135919050565b60008083601f840112613b4857600080fd5b50813567ffffffffffffffff811115613b6057600080fd5b6020830191508360208260051b85010111156115eb57600080fd5b60008060208385031215613b8e57600080fd5b823567ffffffffffffffff811115613ba557600080fd5b613bb185828601613b36565b90969095509350505050565b60008083601f840112613bcf57600080fd5b50813567ffffffffffffffff811115613be757600080fd5b6020830191508360208285010111156115eb57600080fd5b60008060208385031215613c1257600080fd5b823567ffffffffffffffff811115613c2957600080fd5b613bb185828601613bbd565b60008060408385031215613c4857600080fd5b823567ffffffffffffffff80821115613c6057600080fd5b818501915085601f830112613c7457600080fd5b81356020613c84613766836136ee565b82815260059290921b84018101918181019089841115613ca357600080fd5b8286015b84811015613cdb57803586811115613cbf5760008081fd5b613ccd8c86838b010161387d565b845250918301918301613ca7565b5096505086013592505080821115613cf257600080fd5b50613cff8582860161387d565b9150509250929050565b821515815260406020820152600061181d6040830184613a42565b600080600060408486031215613d3957600080fd5b833567ffffffffffffffff811115613d5057600080fd5b613d5c86828701613b36565b9094509250506020840135613d708161386b565b809150509250925092565b600080600060408486031215613d9057600080fd5b83359250602084013567ffffffffffffffff811115613dae57600080fd5b613dba86828701613bbd565b9497909650939450505050565b60008060408385031215613dda57600080fd5b823591506020830135613dec8161389d565b809150509250929050565b60008060408385031215613e0a57600080fd5b823591506020830135613dec8161386b565b600060208284031215613e2e57600080fd5b81356118208161389d565b600060208284031215613e4b57600080fd5b81356118208161385c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006bffffffffffffffffffffffff80831681851681830481118215151615613eb057613eb0613e56565b02949350505050565b805180151581146139cb57600080fd5b600060208284031215613edb57600080fd5b61182082613eb9565b600082601f830112613ef557600080fd5b8151613f0361376682613712565b818152846020838601011115613f1857600080fd5b613f29826020830160208701613a1e565b949350505050565b600060208284031215613f4357600080fd5b815167ffffffffffffffff811115613f5a57600080fd5b613f2984828501613ee4565b82815260406020820152600061181d6040830184613a42565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff821660ff8103613fc457613fc4613e56565b60010192915050565b818103818111156113c6576113c6613e56565b808201808211156113c6576113c6613e56565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361402457614024613e56565b5060010190565b8051602080830151919081101561406a577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b80516139cb81613acb565b6000806040838503121561408e57600080fd5b825161409981613acb565b6020939093015192949293505050565b6000602082840312156140bb57600080fd5b815161182081613acb565b600061ffff8083168181036140dd576140dd613e56565b6001019392505050565b6000602082840312156140f957600080fd5b5051919050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015614175577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018552614163868351613a42565b95509382019390820190600101614129565b50508584038187015250505061418b8185613a42565b95945050505050565b600060208083850312156141a757600080fd5b825167ffffffffffffffff8111156141be57600080fd5b8301601f810185136141cf57600080fd5b80516141dd613766826136ee565b81815260059190911b820183019083810190878311156141fc57600080fd5b928401925b8284101561421a57835182529284019290840190614201565b979650505050505050565b60006020828403121561423757600080fd5b81516118208161385c565b600181811c9082168061425657607f821691505b60208210810361406a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60a0815260006142a260a0830188613a42565b602083820381850152818854808452828401915060058382821b86010160008c8152858120815b8581101561439c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe089850301875282825461430481614242565b8087526001828116801561431f576001811461435657614385565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0084168d8a01528c8315158b1b8a01019450614385565b8688528c8820885b8481101561437d5781548f828d01015283820191508e8101905061435e565b8a018e019550505b50998b0199929650505091909101906001016142c9565b50505087810360408901526143b1818c613a42565b9550505050505084606084015282810360808401526143d08185613a42565b98975050505050505050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b80516139cb8161386b565b80516139cb8161389d565b805167ffffffffffffffff811681146139cb57600080fd5b60006020828403121561447057600080fd5b815167ffffffffffffffff8082111561448857600080fd5b90830190610140828603121561449d57600080fd5b6144a5613675565b6144ae83614070565b81526144bc60208401614430565b60208201526040830151828111156144d357600080fd5b6144df87828601613ee4565b6040830152506144f16060840161443b565b606082015261450260808401614070565b608082015261451360a08401614446565b60a082015261452460c08401614430565b60c082015261453560e0840161443b565b60e0820152610100614548818501613eb9565b90820152610120838101518381111561456057600080fd5b61456c88828701613ee4565b918301919091525095945050505050565b60006020828403121561458f57600080fd5b81516118208161389d565b600063ffffffff8083168181036140dd576140dd613e56565b60208152600082516101408060208501526145d2610160850183613a42565b915060208501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08086850301604087015261460e8483613a42565b935060408701519150614639606087018373ffffffffffffffffffffffffffffffffffffffff169052565b606087015163ffffffff811660808801529150608087015173ffffffffffffffffffffffffffffffffffffffff811660a0880152915060a087015160ff811660c0880152915060c08701519150808685030160e087015261469a8483613a42565b935060e087015191506101008187860301818801526146b98584613a42565b9450808801519250506101208187860301818801526146d88584613a42565b945080880151925050506146fb828601826bffffffffffffffffffffffff169052565b5090949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561473d5761473d613e56565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261478057614780614742565b500490565b818103600083128015838313168383128216171561351057613510613e56565b6000826147b4576147b4614742565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561480857614808613e56565b500590565b808201828112600083128015821682158216171561482d5761482d613e56565b505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361402457614024613e56565b60007f8000000000000000000000000000000000000000000000000000000000000000820361489757614897613e56565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b601f82111561493257600081815260208120601f850160051c810160208610156149135750805b601f850160051c820191505b818110156128265782815560010161491f565b505050565b815167ffffffffffffffff81111561495157614951613646565b6149658161495f8454614242565b846148ec565b602080601f8311600181146149b857600084156149825750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555612826565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015614a05578886015182559484019460019091019084016149e6565b5085821015614a4157878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000810000a307834353534343832643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030307834323534343332643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030307835353533343434333264353535333434326434313532343234393534353235353464326435343435353335343465343535343030303030303030303030303030", } var VerifiableLoadMercuryUpkeepABI = VerifiableLoadMercuryUpkeepMetaData.ABI var VerifiableLoadMercuryUpkeepBin = VerifiableLoadMercuryUpkeepMetaData.Bin -func DeployVerifiableLoadMercuryUpkeep(auth *bind.TransactOpts, backend bind.ContractBackend, registrarAddress common.Address, useArb bool) (common.Address, *types.Transaction, *VerifiableLoadMercuryUpkeep, error) { +func DeployVerifiableLoadMercuryUpkeep(auth *bind.TransactOpts, backend bind.ContractBackend, _registrar common.Address, _useArb bool) (common.Address, *types.Transaction, *VerifiableLoadMercuryUpkeep, error) { parsed, err := VerifiableLoadMercuryUpkeepMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -48,7 +48,7 @@ func DeployVerifiableLoadMercuryUpkeep(auth *bind.TransactOpts, backend bind.Con return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(VerifiableLoadMercuryUpkeepBin), backend, registrarAddress, useArb) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(VerifiableLoadMercuryUpkeepBin), backend, _registrar, _useArb) if err != nil { return common.Address{}, nil, nil, err } @@ -193,28 +193,6 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) BU return _VerifiableLoadMercuryUpkeep.Contract.BUCKETSIZE(&_VerifiableLoadMercuryUpkeep.CallOpts) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) TIMESTAMPINTERVAL(opts *bind.CallOpts) (uint16, error) { - var out []interface{} - err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "TIMESTAMP_INTERVAL") - - if err != nil { - return *new(uint16), err - } - - out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) - - return out0, err - -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) TIMESTAMPINTERVAL() (uint16, error) { - return _VerifiableLoadMercuryUpkeep.Contract.TIMESTAMPINTERVAL(&_VerifiableLoadMercuryUpkeep.CallOpts) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) TIMESTAMPINTERVAL() (uint16, error) { - return _VerifiableLoadMercuryUpkeep.Contract.TIMESTAMPINTERVAL(&_VerifiableLoadMercuryUpkeep.CallOpts) -} - func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) AddLinkAmount(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "addLinkAmount") @@ -304,28 +282,6 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) Ch return _VerifiableLoadMercuryUpkeep.Contract.CheckCallback(&_VerifiableLoadMercuryUpkeep.CallOpts, values, extraData) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) CheckDatas(opts *bind.CallOpts, arg0 *big.Int) ([]byte, error) { - var out []interface{} - err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "checkDatas", arg0) - - if err != nil { - return *new([]byte), err - } - - out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) - - return out0, err - -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) CheckDatas(arg0 *big.Int) ([]byte, error) { - return _VerifiableLoadMercuryUpkeep.Contract.CheckDatas(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) CheckDatas(arg0 *big.Int) ([]byte, error) { - return _VerifiableLoadMercuryUpkeep.Contract.CheckDatas(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0) -} - func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) CheckGasToBurns(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { var out []interface{} err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "checkGasToBurns", arg0) @@ -436,6 +392,28 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) El return _VerifiableLoadMercuryUpkeep.Contract.Eligible(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId) } +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) EmittedSig(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "emittedSig") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) EmittedSig() ([32]byte, error) { + return _VerifiableLoadMercuryUpkeep.Contract.EmittedSig(&_VerifiableLoadMercuryUpkeep.CallOpts) +} + +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) EmittedSig() ([32]byte, error) { + return _VerifiableLoadMercuryUpkeep.Contract.EmittedSig(&_VerifiableLoadMercuryUpkeep.CallOpts) +} + func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) FeedParamKey(opts *bind.CallOpts) (string, error) { var out []interface{} err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "feedParamKey") @@ -634,138 +612,26 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) Ge return _VerifiableLoadMercuryUpkeep.Contract.GetDelaysLength(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetDelaysLengthAtBucket(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) (*big.Int, error) { - var out []interface{} - err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getDelaysLengthAtBucket", upkeepId, bucket) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GetDelaysLengthAtBucket(upkeepId *big.Int, bucket uint16) (*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetDelaysLengthAtBucket(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, bucket) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GetDelaysLengthAtBucket(upkeepId *big.Int, bucket uint16) (*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetDelaysLengthAtBucket(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, bucket) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetDelaysLengthAtTimestampBucket(opts *bind.CallOpts, upkeepId *big.Int, timestampBucket uint16) (*big.Int, error) { - var out []interface{} - err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getDelaysLengthAtTimestampBucket", upkeepId, timestampBucket) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GetDelaysLengthAtTimestampBucket(upkeepId *big.Int, timestampBucket uint16) (*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetDelaysLengthAtTimestampBucket(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, timestampBucket) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GetDelaysLengthAtTimestampBucket(upkeepId *big.Int, timestampBucket uint16) (*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetDelaysLengthAtTimestampBucket(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, timestampBucket) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetPxBucketedDelaysForAllUpkeeps(opts *bind.CallOpts, p *big.Int) ([]*big.Int, []*big.Int, error) { - var out []interface{} - err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getPxBucketedDelaysForAllUpkeeps", p) - - if err != nil { - return *new([]*big.Int), *new([]*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) - out1 := *abi.ConvertType(out[1], new([]*big.Int)).(*[]*big.Int) - - return out0, out1, err - -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GetPxBucketedDelaysForAllUpkeeps(p *big.Int) ([]*big.Int, []*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetPxBucketedDelaysForAllUpkeeps(&_VerifiableLoadMercuryUpkeep.CallOpts, p) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GetPxBucketedDelaysForAllUpkeeps(p *big.Int) ([]*big.Int, []*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetPxBucketedDelaysForAllUpkeeps(&_VerifiableLoadMercuryUpkeep.CallOpts, p) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetPxDelayForAllUpkeeps(opts *bind.CallOpts, p *big.Int) ([]*big.Int, []*big.Int, error) { - var out []interface{} - err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getPxDelayForAllUpkeeps", p) - - if err != nil { - return *new([]*big.Int), *new([]*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) - out1 := *abi.ConvertType(out[1], new([]*big.Int)).(*[]*big.Int) - - return out0, out1, err - -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GetPxDelayForAllUpkeeps(p *big.Int) ([]*big.Int, []*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetPxDelayForAllUpkeeps(&_VerifiableLoadMercuryUpkeep.CallOpts, p) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GetPxDelayForAllUpkeeps(p *big.Int) ([]*big.Int, []*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetPxDelayForAllUpkeeps(&_VerifiableLoadMercuryUpkeep.CallOpts, p) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetPxDelayInBucket(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, bucket uint16) (*big.Int, error) { - var out []interface{} - err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getPxDelayInBucket", upkeepId, p, bucket) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GetPxDelayInBucket(upkeepId *big.Int, p *big.Int, bucket uint16) (*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetPxDelayInBucket(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, p, bucket) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GetPxDelayInBucket(upkeepId *big.Int, p *big.Int, bucket uint16) (*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetPxDelayInBucket(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, p, bucket) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetPxDelayInTimestampBucket(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, timestampBucket uint16) (*big.Int, error) { +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetLogTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) { var out []interface{} - err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getPxDelayInTimestampBucket", upkeepId, p, timestampBucket) + err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getLogTriggerConfig", upkeepId) if err != nil { - return *new(*big.Int), err + return *new([]byte), err } - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) return out0, err } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GetPxDelayInTimestampBucket(upkeepId *big.Int, p *big.Int, timestampBucket uint16) (*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetPxDelayInTimestampBucket(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, p, timestampBucket) +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GetLogTriggerConfig(upkeepId *big.Int) ([]byte, error) { + return _VerifiableLoadMercuryUpkeep.Contract.GetLogTriggerConfig(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GetPxDelayInTimestampBucket(upkeepId *big.Int, p *big.Int, timestampBucket uint16) (*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetPxDelayInTimestampBucket(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, p, timestampBucket) +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GetLogTriggerConfig(upkeepId *big.Int) ([]byte, error) { + return _VerifiableLoadMercuryUpkeep.Contract.GetLogTriggerConfig(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId) } func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetPxDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, n *big.Int) (*big.Int, error) { @@ -790,29 +656,6 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) Ge return _VerifiableLoadMercuryUpkeep.Contract.GetPxDelayLastNPerforms(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, p, n) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetSumBucketedDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) { - var out []interface{} - err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getSumBucketedDelayLastNPerforms", upkeepId, n) - - if err != nil { - return *new(*big.Int), *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - - return out0, out1, err - -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GetSumBucketedDelayLastNPerforms(upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetSumBucketedDelayLastNPerforms(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, n) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GetSumBucketedDelayLastNPerforms(upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetSumBucketedDelayLastNPerforms(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, n) -} - func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetSumDelayInBucket(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) (*big.Int, *big.Int, error) { var out []interface{} err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getSumDelayInBucket", upkeepId, bucket) @@ -836,29 +679,6 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) Ge return _VerifiableLoadMercuryUpkeep.Contract.GetSumDelayInBucket(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, bucket) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetSumDelayInTimestampBucket(opts *bind.CallOpts, upkeepId *big.Int, timestampBucket uint16) (*big.Int, *big.Int, error) { - var out []interface{} - err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getSumDelayInTimestampBucket", upkeepId, timestampBucket) - - if err != nil { - return *new(*big.Int), *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - - return out0, out1, err - -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GetSumDelayInTimestampBucket(upkeepId *big.Int, timestampBucket uint16) (*big.Int, *big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetSumDelayInTimestampBucket(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, timestampBucket) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GetSumDelayInTimestampBucket(upkeepId *big.Int, timestampBucket uint16) (*big.Int, *big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetSumDelayInTimestampBucket(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, timestampBucket) -} - func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetSumDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) { var out []interface{} err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getSumDelayLastNPerforms", upkeepId, n) @@ -882,73 +702,6 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) Ge return _VerifiableLoadMercuryUpkeep.Contract.GetSumDelayLastNPerforms(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, n) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetSumTimestampBucketedDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) { - var out []interface{} - err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getSumTimestampBucketedDelayLastNPerforms", upkeepId, n) - - if err != nil { - return *new(*big.Int), *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - - return out0, out1, err - -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GetSumTimestampBucketedDelayLastNPerforms(upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetSumTimestampBucketedDelayLastNPerforms(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, n) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GetSumTimestampBucketedDelayLastNPerforms(upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetSumTimestampBucketedDelayLastNPerforms(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, n) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetTimestampBucketedDelaysLength(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error) { - var out []interface{} - err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getTimestampBucketedDelaysLength", upkeepId) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GetTimestampBucketedDelaysLength(upkeepId *big.Int) (*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetTimestampBucketedDelaysLength(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GetTimestampBucketedDelaysLength(upkeepId *big.Int) (*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetTimestampBucketedDelaysLength(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetTimestampDelays(opts *bind.CallOpts, upkeepId *big.Int, timestampBucket uint16) ([]*big.Int, error) { - var out []interface{} - err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getTimestampDelays", upkeepId, timestampBucket) - - if err != nil { - return *new([]*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) - - return out0, err - -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GetTimestampDelays(upkeepId *big.Int, timestampBucket uint16) ([]*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetTimestampDelays(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, timestampBucket) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GetTimestampDelays(upkeepId *big.Int, timestampBucket uint16) ([]*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.GetTimestampDelays(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, timestampBucket) -} - func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) Intervals(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { var out []interface{} err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "intervals", arg0) @@ -1191,162 +944,108 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) Ti return _VerifiableLoadMercuryUpkeep.Contract.TimeParamKey(&_VerifiableLoadMercuryUpkeep.CallOpts) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) TimestampBuckets(opts *bind.CallOpts, arg0 *big.Int) (uint16, error) { +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) UpkeepTopUpCheckInterval(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "timestampBuckets", arg0) + err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "upkeepTopUpCheckInterval") if err != nil { - return *new(uint16), err + return *new(*big.Int), err } - out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) return out0, err } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) TimestampBuckets(arg0 *big.Int) (uint16, error) { - return _VerifiableLoadMercuryUpkeep.Contract.TimestampBuckets(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0) +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) UpkeepTopUpCheckInterval() (*big.Int, error) { + return _VerifiableLoadMercuryUpkeep.Contract.UpkeepTopUpCheckInterval(&_VerifiableLoadMercuryUpkeep.CallOpts) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) TimestampBuckets(arg0 *big.Int) (uint16, error) { - return _VerifiableLoadMercuryUpkeep.Contract.TimestampBuckets(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0) +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) UpkeepTopUpCheckInterval() (*big.Int, error) { + return _VerifiableLoadMercuryUpkeep.Contract.UpkeepTopUpCheckInterval(&_VerifiableLoadMercuryUpkeep.CallOpts) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) TimestampDelays(opts *bind.CallOpts, arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error) { +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) UseArbitrumBlockNum(opts *bind.CallOpts) (bool, error) { var out []interface{} - err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "timestampDelays", arg0, arg1, arg2) + err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "useArbitrumBlockNum") if err != nil { - return *new(*big.Int), err + return *new(bool), err } - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) return out0, err } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) TimestampDelays(arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.TimestampDelays(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0, arg1, arg2) +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) UseArbitrumBlockNum() (bool, error) { + return _VerifiableLoadMercuryUpkeep.Contract.UseArbitrumBlockNum(&_VerifiableLoadMercuryUpkeep.CallOpts) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) TimestampDelays(arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.TimestampDelays(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0, arg1, arg2) +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) UseArbitrumBlockNum() (bool, error) { + return _VerifiableLoadMercuryUpkeep.Contract.UseArbitrumBlockNum(&_VerifiableLoadMercuryUpkeep.CallOpts) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) Timestamps(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { - var out []interface{} - err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "timestamps", arg0, arg1) +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "acceptOwnership") +} - if err != nil { - return *new(*big.Int), err - } +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) AcceptOwnership() (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.Contract.AcceptOwnership(&_VerifiableLoadMercuryUpkeep.TransactOpts) +} - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.Contract.AcceptOwnership(&_VerifiableLoadMercuryUpkeep.TransactOpts) +} - return out0, err +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) AddFunds(opts *bind.TransactOpts, upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "addFunds", upkeepId, amount) +} +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) AddFunds(upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.Contract.AddFunds(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, amount) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) Timestamps(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.Timestamps(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0, arg1) +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) AddFunds(upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.Contract.AddFunds(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, amount) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) Timestamps(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.Timestamps(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0, arg1) +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) BatchCancelUpkeeps(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "batchCancelUpkeeps", upkeepIds) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) UpkeepTopUpCheckInterval(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "upkeepTopUpCheckInterval") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) UpkeepTopUpCheckInterval() (*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.UpkeepTopUpCheckInterval(&_VerifiableLoadMercuryUpkeep.CallOpts) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) UpkeepTopUpCheckInterval() (*big.Int, error) { - return _VerifiableLoadMercuryUpkeep.Contract.UpkeepTopUpCheckInterval(&_VerifiableLoadMercuryUpkeep.CallOpts) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) UseArbitrumBlockNum(opts *bind.CallOpts) (bool, error) { - var out []interface{} - err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "useArbitrumBlockNum") - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) UseArbitrumBlockNum() (bool, error) { - return _VerifiableLoadMercuryUpkeep.Contract.UseArbitrumBlockNum(&_VerifiableLoadMercuryUpkeep.CallOpts) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) UseArbitrumBlockNum() (bool, error) { - return _VerifiableLoadMercuryUpkeep.Contract.UseArbitrumBlockNum(&_VerifiableLoadMercuryUpkeep.CallOpts) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "acceptOwnership") -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) AcceptOwnership() (*types.Transaction, error) { - return _VerifiableLoadMercuryUpkeep.Contract.AcceptOwnership(&_VerifiableLoadMercuryUpkeep.TransactOpts) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) AcceptOwnership() (*types.Transaction, error) { - return _VerifiableLoadMercuryUpkeep.Contract.AcceptOwnership(&_VerifiableLoadMercuryUpkeep.TransactOpts) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) AddFunds(opts *bind.TransactOpts, upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) { - return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "addFunds", upkeepId, amount) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) AddFunds(upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) { - return _VerifiableLoadMercuryUpkeep.Contract.AddFunds(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, amount) +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) BatchCancelUpkeeps(upkeepIds []*big.Int) (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.Contract.BatchCancelUpkeeps(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepIds) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) AddFunds(upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) { - return _VerifiableLoadMercuryUpkeep.Contract.AddFunds(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, amount) +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) BatchCancelUpkeeps(upkeepIds []*big.Int) (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.Contract.BatchCancelUpkeeps(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepIds) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) BatchCancelUpkeeps(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error) { - return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "batchCancelUpkeeps", upkeepIds) +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) BatchRegisterUpkeeps(opts *bind.TransactOpts, number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "batchRegisterUpkeeps", number, gasLimit, triggerType, triggerConfig, amount, checkGasToBurn, performGasToBurn) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) BatchCancelUpkeeps(upkeepIds []*big.Int) (*types.Transaction, error) { - return _VerifiableLoadMercuryUpkeep.Contract.BatchCancelUpkeeps(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepIds) +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) BatchRegisterUpkeeps(number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.Contract.BatchRegisterUpkeeps(&_VerifiableLoadMercuryUpkeep.TransactOpts, number, gasLimit, triggerType, triggerConfig, amount, checkGasToBurn, performGasToBurn) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) BatchCancelUpkeeps(upkeepIds []*big.Int) (*types.Transaction, error) { - return _VerifiableLoadMercuryUpkeep.Contract.BatchCancelUpkeeps(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepIds) +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) BatchRegisterUpkeeps(number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.Contract.BatchRegisterUpkeeps(&_VerifiableLoadMercuryUpkeep.TransactOpts, number, gasLimit, triggerType, triggerConfig, amount, checkGasToBurn, performGasToBurn) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) BatchRegisterUpkeeps(opts *bind.TransactOpts, number uint8, gasLimit uint32, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) { - return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "batchRegisterUpkeeps", number, gasLimit, amount, checkGasToBurn, performGasToBurn) +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) BatchSendLogs(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "batchSendLogs") } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) BatchRegisterUpkeeps(number uint8, gasLimit uint32, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) { - return _VerifiableLoadMercuryUpkeep.Contract.BatchRegisterUpkeeps(&_VerifiableLoadMercuryUpkeep.TransactOpts, number, gasLimit, amount, checkGasToBurn, performGasToBurn) +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) BatchSendLogs() (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.Contract.BatchSendLogs(&_VerifiableLoadMercuryUpkeep.TransactOpts) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) BatchRegisterUpkeeps(number uint8, gasLimit uint32, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) { - return _VerifiableLoadMercuryUpkeep.Contract.BatchRegisterUpkeeps(&_VerifiableLoadMercuryUpkeep.TransactOpts, number, gasLimit, amount, checkGasToBurn, performGasToBurn) +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) BatchSendLogs() (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.Contract.BatchSendLogs(&_VerifiableLoadMercuryUpkeep.TransactOpts) } func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) BatchSetIntervals(opts *bind.TransactOpts, upkeepIds []*big.Int, interval uint32) (*types.Transaction, error) { @@ -1385,6 +1084,18 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession return _VerifiableLoadMercuryUpkeep.Contract.BatchWithdrawLinks(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepIds) } +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) BurnPerformGas(opts *bind.TransactOpts, upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "burnPerformGas", upkeepId, startGas, blockNum) +} + +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) BurnPerformGas(upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.Contract.BurnPerformGas(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, startGas, blockNum) +} + +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) BurnPerformGas(upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.Contract.BurnPerformGas(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, startGas, blockNum) +} + func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) CancelUpkeep(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) { return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "cancelUpkeep", upkeepId) } @@ -1421,6 +1132,18 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession return _VerifiableLoadMercuryUpkeep.Contract.PerformUpkeep(&_VerifiableLoadMercuryUpkeep.TransactOpts, performData) } +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) SendLog(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "sendLog", upkeepId) +} + +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) SendLog(upkeepId *big.Int) (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.Contract.SendLog(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId) +} + +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) SendLog(upkeepId *big.Int) (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.Contract.SendLog(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId) +} + func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) SetAddLinkAmount(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "setAddLinkAmount", amount) } @@ -1541,6 +1264,18 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession return _VerifiableLoadMercuryUpkeep.Contract.SetUpkeepTopUpCheckInterval(&_VerifiableLoadMercuryUpkeep.TransactOpts, newInterval) } +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) TopUpFund(opts *bind.TransactOpts, upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "topUpFund", upkeepId, blockNum) +} + +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) TopUpFund(upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.Contract.TopUpFund(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, blockNum) +} + +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) TopUpFund(upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.Contract.TopUpFund(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, blockNum) +} + func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "transferOwnership", to) } @@ -1587,677 +1322,22 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) Withdraw func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) WithdrawLinks0(upkeepId *big.Int) (*types.Transaction, error) { return _VerifiableLoadMercuryUpkeep.Contract.WithdrawLinks0(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { - return _VerifiableLoadMercuryUpkeep.contract.RawTransact(opts, nil) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) Receive() (*types.Transaction, error) { - return _VerifiableLoadMercuryUpkeep.Contract.Receive(&_VerifiableLoadMercuryUpkeep.TransactOpts) -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) Receive() (*types.Transaction, error) { - return _VerifiableLoadMercuryUpkeep.Contract.Receive(&_VerifiableLoadMercuryUpkeep.TransactOpts) -} - -type VerifiableLoadMercuryUpkeepFundsAddedIterator struct { - Event *VerifiableLoadMercuryUpkeepFundsAdded - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VerifiableLoadMercuryUpkeepFundsAddedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VerifiableLoadMercuryUpkeepFundsAdded) - 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(VerifiableLoadMercuryUpkeepFundsAdded) - 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 *VerifiableLoadMercuryUpkeepFundsAddedIterator) Error() error { - return it.fail -} - -func (it *VerifiableLoadMercuryUpkeepFundsAddedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VerifiableLoadMercuryUpkeepFundsAdded struct { - UpkeepId *big.Int - Amount *big.Int - Raw types.Log -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) FilterFundsAdded(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepFundsAddedIterator, error) { - - logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.FilterLogs(opts, "FundsAdded") - if err != nil { - return nil, err - } - return &VerifiableLoadMercuryUpkeepFundsAddedIterator{contract: _VerifiableLoadMercuryUpkeep.contract, event: "FundsAdded", logs: logs, sub: sub}, nil -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchFundsAdded(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepFundsAdded) (event.Subscription, error) { - - logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.WatchLogs(opts, "FundsAdded") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(VerifiableLoadMercuryUpkeepFundsAdded) - if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "FundsAdded", 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 (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParseFundsAdded(log types.Log) (*VerifiableLoadMercuryUpkeepFundsAdded, error) { - event := new(VerifiableLoadMercuryUpkeepFundsAdded) - if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "FundsAdded", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VerifiableLoadMercuryUpkeepInsufficientFundsIterator struct { - Event *VerifiableLoadMercuryUpkeepInsufficientFunds - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VerifiableLoadMercuryUpkeepInsufficientFundsIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VerifiableLoadMercuryUpkeepInsufficientFunds) - 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(VerifiableLoadMercuryUpkeepInsufficientFunds) - 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 *VerifiableLoadMercuryUpkeepInsufficientFundsIterator) Error() error { - return it.fail -} - -func (it *VerifiableLoadMercuryUpkeepInsufficientFundsIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VerifiableLoadMercuryUpkeepInsufficientFunds struct { - Balance *big.Int - BlockNum *big.Int - Raw types.Log -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) FilterInsufficientFunds(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepInsufficientFundsIterator, error) { - - logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.FilterLogs(opts, "InsufficientFunds") - if err != nil { - return nil, err - } - return &VerifiableLoadMercuryUpkeepInsufficientFundsIterator{contract: _VerifiableLoadMercuryUpkeep.contract, event: "InsufficientFunds", logs: logs, sub: sub}, nil -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchInsufficientFunds(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepInsufficientFunds) (event.Subscription, error) { - - logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.WatchLogs(opts, "InsufficientFunds") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(VerifiableLoadMercuryUpkeepInsufficientFunds) - if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "InsufficientFunds", 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 (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParseInsufficientFunds(log types.Log) (*VerifiableLoadMercuryUpkeepInsufficientFunds, error) { - event := new(VerifiableLoadMercuryUpkeepInsufficientFunds) - if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "InsufficientFunds", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VerifiableLoadMercuryUpkeepMercuryPerformEventIterator struct { - Event *VerifiableLoadMercuryUpkeepMercuryPerformEvent - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VerifiableLoadMercuryUpkeepMercuryPerformEventIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VerifiableLoadMercuryUpkeepMercuryPerformEvent) - 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(VerifiableLoadMercuryUpkeepMercuryPerformEvent) - 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 *VerifiableLoadMercuryUpkeepMercuryPerformEventIterator) Error() error { - return it.fail -} - -func (it *VerifiableLoadMercuryUpkeepMercuryPerformEventIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VerifiableLoadMercuryUpkeepMercuryPerformEvent struct { - Origin common.Address - UpkeepId *big.Int - BlockNumber *big.Int - V0 []byte - Ed []byte - Raw types.Log -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) FilterMercuryPerformEvent(opts *bind.FilterOpts, origin []common.Address, upkeepId []*big.Int, blockNumber []*big.Int) (*VerifiableLoadMercuryUpkeepMercuryPerformEventIterator, error) { - - var originRule []interface{} - for _, originItem := range origin { - originRule = append(originRule, originItem) - } - var upkeepIdRule []interface{} - for _, upkeepIdItem := range upkeepId { - upkeepIdRule = append(upkeepIdRule, upkeepIdItem) - } - var blockNumberRule []interface{} - for _, blockNumberItem := range blockNumber { - blockNumberRule = append(blockNumberRule, blockNumberItem) - } - - logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.FilterLogs(opts, "MercuryPerformEvent", originRule, upkeepIdRule, blockNumberRule) - if err != nil { - return nil, err - } - return &VerifiableLoadMercuryUpkeepMercuryPerformEventIterator{contract: _VerifiableLoadMercuryUpkeep.contract, event: "MercuryPerformEvent", logs: logs, sub: sub}, nil -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchMercuryPerformEvent(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepMercuryPerformEvent, origin []common.Address, upkeepId []*big.Int, blockNumber []*big.Int) (event.Subscription, error) { - - var originRule []interface{} - for _, originItem := range origin { - originRule = append(originRule, originItem) - } - var upkeepIdRule []interface{} - for _, upkeepIdItem := range upkeepId { - upkeepIdRule = append(upkeepIdRule, upkeepIdItem) - } - var blockNumberRule []interface{} - for _, blockNumberItem := range blockNumber { - blockNumberRule = append(blockNumberRule, blockNumberItem) - } - - logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.WatchLogs(opts, "MercuryPerformEvent", originRule, upkeepIdRule, blockNumberRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(VerifiableLoadMercuryUpkeepMercuryPerformEvent) - if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "MercuryPerformEvent", 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 (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParseMercuryPerformEvent(log types.Log) (*VerifiableLoadMercuryUpkeepMercuryPerformEvent, error) { - event := new(VerifiableLoadMercuryUpkeepMercuryPerformEvent) - if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "MercuryPerformEvent", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VerifiableLoadMercuryUpkeepOwnershipTransferRequestedIterator struct { - Event *VerifiableLoadMercuryUpkeepOwnershipTransferRequested - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VerifiableLoadMercuryUpkeepOwnershipTransferRequestedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VerifiableLoadMercuryUpkeepOwnershipTransferRequested) - 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(VerifiableLoadMercuryUpkeepOwnershipTransferRequested) - 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 *VerifiableLoadMercuryUpkeepOwnershipTransferRequestedIterator) Error() error { - return it.fail -} - -func (it *VerifiableLoadMercuryUpkeepOwnershipTransferRequestedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VerifiableLoadMercuryUpkeepOwnershipTransferRequested struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadMercuryUpkeepOwnershipTransferRequestedIterator, 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 := _VerifiableLoadMercuryUpkeep.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) - if err != nil { - return nil, err - } - return &VerifiableLoadMercuryUpkeepOwnershipTransferRequestedIterator{contract: _VerifiableLoadMercuryUpkeep.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepOwnershipTransferRequested, 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 := _VerifiableLoadMercuryUpkeep.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(VerifiableLoadMercuryUpkeepOwnershipTransferRequested) - if err := _VerifiableLoadMercuryUpkeep.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 (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParseOwnershipTransferRequested(log types.Log) (*VerifiableLoadMercuryUpkeepOwnershipTransferRequested, error) { - event := new(VerifiableLoadMercuryUpkeepOwnershipTransferRequested) - if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VerifiableLoadMercuryUpkeepOwnershipTransferredIterator struct { - Event *VerifiableLoadMercuryUpkeepOwnershipTransferred - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VerifiableLoadMercuryUpkeepOwnershipTransferredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VerifiableLoadMercuryUpkeepOwnershipTransferred) - 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(VerifiableLoadMercuryUpkeepOwnershipTransferred) - 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 *VerifiableLoadMercuryUpkeepOwnershipTransferredIterator) Error() error { - return it.fail -} - -func (it *VerifiableLoadMercuryUpkeepOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VerifiableLoadMercuryUpkeepOwnershipTransferred struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadMercuryUpkeepOwnershipTransferredIterator, 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 := _VerifiableLoadMercuryUpkeep.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) - if err != nil { - return nil, err - } - return &VerifiableLoadMercuryUpkeepOwnershipTransferredIterator{contract: _VerifiableLoadMercuryUpkeep.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil -} - -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepOwnershipTransferred, 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 := _VerifiableLoadMercuryUpkeep.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(VerifiableLoadMercuryUpkeepOwnershipTransferred) - if err := _VerifiableLoadMercuryUpkeep.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 (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.contract.RawTransact(opts, nil) } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParseOwnershipTransferred(log types.Log) (*VerifiableLoadMercuryUpkeepOwnershipTransferred, error) { - event := new(VerifiableLoadMercuryUpkeepOwnershipTransferred) - if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) Receive() (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.Contract.Receive(&_VerifiableLoadMercuryUpkeep.TransactOpts) +} + +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) Receive() (*types.Transaction, error) { + return _VerifiableLoadMercuryUpkeep.Contract.Receive(&_VerifiableLoadMercuryUpkeep.TransactOpts) } -type VerifiableLoadMercuryUpkeepPerformingUpkeepIterator struct { - Event *VerifiableLoadMercuryUpkeepPerformingUpkeep +type VerifiableLoadMercuryUpkeepLogEmittedIterator struct { + Event *VerifiableLoadMercuryUpkeepLogEmitted contract *bind.BoundContract event string @@ -2268,7 +1348,7 @@ type VerifiableLoadMercuryUpkeepPerformingUpkeepIterator struct { fail error } -func (it *VerifiableLoadMercuryUpkeepPerformingUpkeepIterator) Next() bool { +func (it *VerifiableLoadMercuryUpkeepLogEmittedIterator) Next() bool { if it.fail != nil { return false @@ -2277,7 +1357,7 @@ func (it *VerifiableLoadMercuryUpkeepPerformingUpkeepIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(VerifiableLoadMercuryUpkeepPerformingUpkeep) + it.Event = new(VerifiableLoadMercuryUpkeepLogEmitted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2292,7 +1372,7 @@ func (it *VerifiableLoadMercuryUpkeepPerformingUpkeepIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(VerifiableLoadMercuryUpkeepPerformingUpkeep) + it.Event = new(VerifiableLoadMercuryUpkeepLogEmitted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2307,35 +1387,52 @@ func (it *VerifiableLoadMercuryUpkeepPerformingUpkeepIterator) Next() bool { } } -func (it *VerifiableLoadMercuryUpkeepPerformingUpkeepIterator) Error() error { +func (it *VerifiableLoadMercuryUpkeepLogEmittedIterator) Error() error { return it.fail } -func (it *VerifiableLoadMercuryUpkeepPerformingUpkeepIterator) Close() error { +func (it *VerifiableLoadMercuryUpkeepLogEmittedIterator) Close() error { it.sub.Unsubscribe() return nil } -type VerifiableLoadMercuryUpkeepPerformingUpkeep struct { - FirstPerformBlock *big.Int - LastBlock *big.Int - PreviousBlock *big.Int - Counter *big.Int - Raw types.Log +type VerifiableLoadMercuryUpkeepLogEmitted struct { + UpkeepId *big.Int + BlockNum *big.Int + Addr common.Address + Raw types.Log } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) FilterPerformingUpkeep(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepPerformingUpkeepIterator, error) { +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) FilterLogEmitted(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int) (*VerifiableLoadMercuryUpkeepLogEmittedIterator, error) { + + var upkeepIdRule []interface{} + for _, upkeepIdItem := range upkeepId { + upkeepIdRule = append(upkeepIdRule, upkeepIdItem) + } + var blockNumRule []interface{} + for _, blockNumItem := range blockNum { + blockNumRule = append(blockNumRule, blockNumItem) + } - logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.FilterLogs(opts, "PerformingUpkeep") + logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.FilterLogs(opts, "LogEmitted", upkeepIdRule, blockNumRule) if err != nil { return nil, err } - return &VerifiableLoadMercuryUpkeepPerformingUpkeepIterator{contract: _VerifiableLoadMercuryUpkeep.contract, event: "PerformingUpkeep", logs: logs, sub: sub}, nil + return &VerifiableLoadMercuryUpkeepLogEmittedIterator{contract: _VerifiableLoadMercuryUpkeep.contract, event: "LogEmitted", logs: logs, sub: sub}, nil } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchPerformingUpkeep(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepPerformingUpkeep) (event.Subscription, error) { +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchLogEmitted(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepLogEmitted, upkeepId []*big.Int, blockNum []*big.Int) (event.Subscription, error) { + + var upkeepIdRule []interface{} + for _, upkeepIdItem := range upkeepId { + upkeepIdRule = append(upkeepIdRule, upkeepIdItem) + } + var blockNumRule []interface{} + for _, blockNumItem := range blockNum { + blockNumRule = append(blockNumRule, blockNumItem) + } - logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.WatchLogs(opts, "PerformingUpkeep") + logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.WatchLogs(opts, "LogEmitted", upkeepIdRule, blockNumRule) if err != nil { return nil, err } @@ -2345,8 +1442,8 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchPe select { case log := <-logs: - event := new(VerifiableLoadMercuryUpkeepPerformingUpkeep) - if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "PerformingUpkeep", log); err != nil { + event := new(VerifiableLoadMercuryUpkeepLogEmitted) + if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "LogEmitted", log); err != nil { return err } event.Raw = log @@ -2367,17 +1464,17 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchPe }), nil } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParsePerformingUpkeep(log types.Log) (*VerifiableLoadMercuryUpkeepPerformingUpkeep, error) { - event := new(VerifiableLoadMercuryUpkeepPerformingUpkeep) - if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "PerformingUpkeep", log); err != nil { +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParseLogEmitted(log types.Log) (*VerifiableLoadMercuryUpkeepLogEmitted, error) { + event := new(VerifiableLoadMercuryUpkeepLogEmitted) + if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "LogEmitted", log); err != nil { return nil, err } event.Raw = log return event, nil } -type VerifiableLoadMercuryUpkeepReceivedIterator struct { - Event *VerifiableLoadMercuryUpkeepReceived +type VerifiableLoadMercuryUpkeepOwnershipTransferRequestedIterator struct { + Event *VerifiableLoadMercuryUpkeepOwnershipTransferRequested contract *bind.BoundContract event string @@ -2388,7 +1485,7 @@ type VerifiableLoadMercuryUpkeepReceivedIterator struct { fail error } -func (it *VerifiableLoadMercuryUpkeepReceivedIterator) Next() bool { +func (it *VerifiableLoadMercuryUpkeepOwnershipTransferRequestedIterator) Next() bool { if it.fail != nil { return false @@ -2397,7 +1494,7 @@ func (it *VerifiableLoadMercuryUpkeepReceivedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(VerifiableLoadMercuryUpkeepReceived) + it.Event = new(VerifiableLoadMercuryUpkeepOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2412,7 +1509,7 @@ func (it *VerifiableLoadMercuryUpkeepReceivedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(VerifiableLoadMercuryUpkeepReceived) + it.Event = new(VerifiableLoadMercuryUpkeepOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2427,33 +1524,51 @@ func (it *VerifiableLoadMercuryUpkeepReceivedIterator) Next() bool { } } -func (it *VerifiableLoadMercuryUpkeepReceivedIterator) Error() error { +func (it *VerifiableLoadMercuryUpkeepOwnershipTransferRequestedIterator) Error() error { return it.fail } -func (it *VerifiableLoadMercuryUpkeepReceivedIterator) Close() error { +func (it *VerifiableLoadMercuryUpkeepOwnershipTransferRequestedIterator) Close() error { it.sub.Unsubscribe() return nil } -type VerifiableLoadMercuryUpkeepReceived struct { - Sender common.Address - Value *big.Int - Raw types.Log +type VerifiableLoadMercuryUpkeepOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) FilterReceived(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepReceivedIterator, error) { +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadMercuryUpkeepOwnershipTransferRequestedIterator, error) { - logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.FilterLogs(opts, "Received") + 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 := _VerifiableLoadMercuryUpkeep.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } - return &VerifiableLoadMercuryUpkeepReceivedIterator{contract: _VerifiableLoadMercuryUpkeep.contract, event: "Received", logs: logs, sub: sub}, nil + return &VerifiableLoadMercuryUpkeepOwnershipTransferRequestedIterator{contract: _VerifiableLoadMercuryUpkeep.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchReceived(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepReceived) (event.Subscription, error) { +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { - logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.WatchLogs(opts, "Received") + 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 := _VerifiableLoadMercuryUpkeep.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } @@ -2463,8 +1578,8 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchRe select { case log := <-logs: - event := new(VerifiableLoadMercuryUpkeepReceived) - if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "Received", log); err != nil { + event := new(VerifiableLoadMercuryUpkeepOwnershipTransferRequested) + if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return err } event.Raw = log @@ -2485,17 +1600,17 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchRe }), nil } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParseReceived(log types.Log) (*VerifiableLoadMercuryUpkeepReceived, error) { - event := new(VerifiableLoadMercuryUpkeepReceived) - if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "Received", log); err != nil { +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParseOwnershipTransferRequested(log types.Log) (*VerifiableLoadMercuryUpkeepOwnershipTransferRequested, error) { + event := new(VerifiableLoadMercuryUpkeepOwnershipTransferRequested) + if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return nil, err } event.Raw = log return event, nil } -type VerifiableLoadMercuryUpkeepRegistrarSetIterator struct { - Event *VerifiableLoadMercuryUpkeepRegistrarSet +type VerifiableLoadMercuryUpkeepOwnershipTransferredIterator struct { + Event *VerifiableLoadMercuryUpkeepOwnershipTransferred contract *bind.BoundContract event string @@ -2506,7 +1621,7 @@ type VerifiableLoadMercuryUpkeepRegistrarSetIterator struct { fail error } -func (it *VerifiableLoadMercuryUpkeepRegistrarSetIterator) Next() bool { +func (it *VerifiableLoadMercuryUpkeepOwnershipTransferredIterator) Next() bool { if it.fail != nil { return false @@ -2515,7 +1630,7 @@ func (it *VerifiableLoadMercuryUpkeepRegistrarSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(VerifiableLoadMercuryUpkeepRegistrarSet) + it.Event = new(VerifiableLoadMercuryUpkeepOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2530,7 +1645,7 @@ func (it *VerifiableLoadMercuryUpkeepRegistrarSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(VerifiableLoadMercuryUpkeepRegistrarSet) + it.Event = new(VerifiableLoadMercuryUpkeepOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2545,32 +1660,51 @@ func (it *VerifiableLoadMercuryUpkeepRegistrarSetIterator) Next() bool { } } -func (it *VerifiableLoadMercuryUpkeepRegistrarSetIterator) Error() error { +func (it *VerifiableLoadMercuryUpkeepOwnershipTransferredIterator) Error() error { return it.fail } -func (it *VerifiableLoadMercuryUpkeepRegistrarSetIterator) Close() error { +func (it *VerifiableLoadMercuryUpkeepOwnershipTransferredIterator) Close() error { it.sub.Unsubscribe() return nil } -type VerifiableLoadMercuryUpkeepRegistrarSet struct { - NewRegistrar common.Address - Raw types.Log +type VerifiableLoadMercuryUpkeepOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) FilterRegistrarSet(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepRegistrarSetIterator, error) { +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadMercuryUpkeepOwnershipTransferredIterator, 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 := _VerifiableLoadMercuryUpkeep.contract.FilterLogs(opts, "RegistrarSet") + logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) if err != nil { return nil, err } - return &VerifiableLoadMercuryUpkeepRegistrarSetIterator{contract: _VerifiableLoadMercuryUpkeep.contract, event: "RegistrarSet", logs: logs, sub: sub}, nil + return &VerifiableLoadMercuryUpkeepOwnershipTransferredIterator{contract: _VerifiableLoadMercuryUpkeep.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchRegistrarSet(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepRegistrarSet) (event.Subscription, error) { +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepOwnershipTransferred, 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 := _VerifiableLoadMercuryUpkeep.contract.WatchLogs(opts, "RegistrarSet") + logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) if err != nil { return nil, err } @@ -2580,8 +1714,8 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchRe select { case log := <-logs: - event := new(VerifiableLoadMercuryUpkeepRegistrarSet) - if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "RegistrarSet", log); err != nil { + event := new(VerifiableLoadMercuryUpkeepOwnershipTransferred) + if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return err } event.Raw = log @@ -2602,17 +1736,17 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchRe }), nil } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParseRegistrarSet(log types.Log) (*VerifiableLoadMercuryUpkeepRegistrarSet, error) { - event := new(VerifiableLoadMercuryUpkeepRegistrarSet) - if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "RegistrarSet", log); err != nil { +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParseOwnershipTransferred(log types.Log) (*VerifiableLoadMercuryUpkeepOwnershipTransferred, error) { + event := new(VerifiableLoadMercuryUpkeepOwnershipTransferred) + if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return nil, err } event.Raw = log return event, nil } -type VerifiableLoadMercuryUpkeepUpkeepTopUpIterator struct { - Event *VerifiableLoadMercuryUpkeepUpkeepTopUp +type VerifiableLoadMercuryUpkeepReceivedIterator struct { + Event *VerifiableLoadMercuryUpkeepReceived contract *bind.BoundContract event string @@ -2623,7 +1757,7 @@ type VerifiableLoadMercuryUpkeepUpkeepTopUpIterator struct { fail error } -func (it *VerifiableLoadMercuryUpkeepUpkeepTopUpIterator) Next() bool { +func (it *VerifiableLoadMercuryUpkeepReceivedIterator) Next() bool { if it.fail != nil { return false @@ -2632,7 +1766,7 @@ func (it *VerifiableLoadMercuryUpkeepUpkeepTopUpIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(VerifiableLoadMercuryUpkeepUpkeepTopUp) + it.Event = new(VerifiableLoadMercuryUpkeepReceived) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2647,7 +1781,7 @@ func (it *VerifiableLoadMercuryUpkeepUpkeepTopUpIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(VerifiableLoadMercuryUpkeepUpkeepTopUp) + it.Event = new(VerifiableLoadMercuryUpkeepReceived) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2662,34 +1796,33 @@ func (it *VerifiableLoadMercuryUpkeepUpkeepTopUpIterator) Next() bool { } } -func (it *VerifiableLoadMercuryUpkeepUpkeepTopUpIterator) Error() error { +func (it *VerifiableLoadMercuryUpkeepReceivedIterator) Error() error { return it.fail } -func (it *VerifiableLoadMercuryUpkeepUpkeepTopUpIterator) Close() error { +func (it *VerifiableLoadMercuryUpkeepReceivedIterator) Close() error { it.sub.Unsubscribe() return nil } -type VerifiableLoadMercuryUpkeepUpkeepTopUp struct { - UpkeepId *big.Int - Amount *big.Int - BlockNum *big.Int - Raw types.Log +type VerifiableLoadMercuryUpkeepReceived struct { + Sender common.Address + Value *big.Int + Raw types.Log } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) FilterUpkeepTopUp(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepUpkeepTopUpIterator, error) { +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) FilterReceived(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepReceivedIterator, error) { - logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.FilterLogs(opts, "UpkeepTopUp") + logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.FilterLogs(opts, "Received") if err != nil { return nil, err } - return &VerifiableLoadMercuryUpkeepUpkeepTopUpIterator{contract: _VerifiableLoadMercuryUpkeep.contract, event: "UpkeepTopUp", logs: logs, sub: sub}, nil + return &VerifiableLoadMercuryUpkeepReceivedIterator{contract: _VerifiableLoadMercuryUpkeep.contract, event: "Received", logs: logs, sub: sub}, nil } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchUpkeepTopUp(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepUpkeepTopUp) (event.Subscription, error) { +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchReceived(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepReceived) (event.Subscription, error) { - logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.WatchLogs(opts, "UpkeepTopUp") + logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.WatchLogs(opts, "Received") if err != nil { return nil, err } @@ -2699,8 +1832,8 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchUp select { case log := <-logs: - event := new(VerifiableLoadMercuryUpkeepUpkeepTopUp) - if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "UpkeepTopUp", log); err != nil { + event := new(VerifiableLoadMercuryUpkeepReceived) + if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "Received", log); err != nil { return err } event.Raw = log @@ -2721,17 +1854,17 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchUp }), nil } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParseUpkeepTopUp(log types.Log) (*VerifiableLoadMercuryUpkeepUpkeepTopUp, error) { - event := new(VerifiableLoadMercuryUpkeepUpkeepTopUp) - if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "UpkeepTopUp", log); err != nil { +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParseReceived(log types.Log) (*VerifiableLoadMercuryUpkeepReceived, error) { + event := new(VerifiableLoadMercuryUpkeepReceived) + if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "Received", log); err != nil { return nil, err } event.Raw = log return event, nil } -type VerifiableLoadMercuryUpkeepUpkeepsCancelledIterator struct { - Event *VerifiableLoadMercuryUpkeepUpkeepsCancelled +type VerifiableLoadMercuryUpkeepUpkeepTopUpIterator struct { + Event *VerifiableLoadMercuryUpkeepUpkeepTopUp contract *bind.BoundContract event string @@ -2742,7 +1875,7 @@ type VerifiableLoadMercuryUpkeepUpkeepsCancelledIterator struct { fail error } -func (it *VerifiableLoadMercuryUpkeepUpkeepsCancelledIterator) Next() bool { +func (it *VerifiableLoadMercuryUpkeepUpkeepTopUpIterator) Next() bool { if it.fail != nil { return false @@ -2751,7 +1884,7 @@ func (it *VerifiableLoadMercuryUpkeepUpkeepsCancelledIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(VerifiableLoadMercuryUpkeepUpkeepsCancelled) + it.Event = new(VerifiableLoadMercuryUpkeepUpkeepTopUp) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2766,7 +1899,7 @@ func (it *VerifiableLoadMercuryUpkeepUpkeepsCancelledIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(VerifiableLoadMercuryUpkeepUpkeepsCancelled) + it.Event = new(VerifiableLoadMercuryUpkeepUpkeepTopUp) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2781,32 +1914,34 @@ func (it *VerifiableLoadMercuryUpkeepUpkeepsCancelledIterator) Next() bool { } } -func (it *VerifiableLoadMercuryUpkeepUpkeepsCancelledIterator) Error() error { +func (it *VerifiableLoadMercuryUpkeepUpkeepTopUpIterator) Error() error { return it.fail } -func (it *VerifiableLoadMercuryUpkeepUpkeepsCancelledIterator) Close() error { +func (it *VerifiableLoadMercuryUpkeepUpkeepTopUpIterator) Close() error { it.sub.Unsubscribe() return nil } -type VerifiableLoadMercuryUpkeepUpkeepsCancelled struct { - UpkeepIds []*big.Int - Raw types.Log +type VerifiableLoadMercuryUpkeepUpkeepTopUp struct { + UpkeepId *big.Int + Amount *big.Int + BlockNum *big.Int + Raw types.Log } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) FilterUpkeepsCancelled(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepUpkeepsCancelledIterator, error) { +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) FilterUpkeepTopUp(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepUpkeepTopUpIterator, error) { - logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.FilterLogs(opts, "UpkeepsCancelled") + logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.FilterLogs(opts, "UpkeepTopUp") if err != nil { return nil, err } - return &VerifiableLoadMercuryUpkeepUpkeepsCancelledIterator{contract: _VerifiableLoadMercuryUpkeep.contract, event: "UpkeepsCancelled", logs: logs, sub: sub}, nil + return &VerifiableLoadMercuryUpkeepUpkeepTopUpIterator{contract: _VerifiableLoadMercuryUpkeep.contract, event: "UpkeepTopUp", logs: logs, sub: sub}, nil } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchUpkeepsCancelled(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepUpkeepsCancelled) (event.Subscription, error) { +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchUpkeepTopUp(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepUpkeepTopUp) (event.Subscription, error) { - logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.WatchLogs(opts, "UpkeepsCancelled") + logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.WatchLogs(opts, "UpkeepTopUp") if err != nil { return nil, err } @@ -2816,8 +1951,8 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchUp select { case log := <-logs: - event := new(VerifiableLoadMercuryUpkeepUpkeepsCancelled) - if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "UpkeepsCancelled", log); err != nil { + event := new(VerifiableLoadMercuryUpkeepUpkeepTopUp) + if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "UpkeepTopUp", log); err != nil { return err } event.Raw = log @@ -2838,9 +1973,9 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchUp }), nil } -func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParseUpkeepsCancelled(log types.Log) (*VerifiableLoadMercuryUpkeepUpkeepsCancelled, error) { - event := new(VerifiableLoadMercuryUpkeepUpkeepsCancelled) - if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "UpkeepsCancelled", log); err != nil { +func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParseUpkeepTopUp(log types.Log) (*VerifiableLoadMercuryUpkeepUpkeepTopUp, error) { + event := new(VerifiableLoadMercuryUpkeepUpkeepTopUp) + if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "UpkeepTopUp", log); err != nil { return nil, err } event.Raw = log @@ -2966,26 +2101,16 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParseUp func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeep) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { - case _VerifiableLoadMercuryUpkeep.abi.Events["FundsAdded"].ID: - return _VerifiableLoadMercuryUpkeep.ParseFundsAdded(log) - case _VerifiableLoadMercuryUpkeep.abi.Events["InsufficientFunds"].ID: - return _VerifiableLoadMercuryUpkeep.ParseInsufficientFunds(log) - case _VerifiableLoadMercuryUpkeep.abi.Events["MercuryPerformEvent"].ID: - return _VerifiableLoadMercuryUpkeep.ParseMercuryPerformEvent(log) + case _VerifiableLoadMercuryUpkeep.abi.Events["LogEmitted"].ID: + return _VerifiableLoadMercuryUpkeep.ParseLogEmitted(log) case _VerifiableLoadMercuryUpkeep.abi.Events["OwnershipTransferRequested"].ID: return _VerifiableLoadMercuryUpkeep.ParseOwnershipTransferRequested(log) case _VerifiableLoadMercuryUpkeep.abi.Events["OwnershipTransferred"].ID: return _VerifiableLoadMercuryUpkeep.ParseOwnershipTransferred(log) - case _VerifiableLoadMercuryUpkeep.abi.Events["PerformingUpkeep"].ID: - return _VerifiableLoadMercuryUpkeep.ParsePerformingUpkeep(log) case _VerifiableLoadMercuryUpkeep.abi.Events["Received"].ID: return _VerifiableLoadMercuryUpkeep.ParseReceived(log) - case _VerifiableLoadMercuryUpkeep.abi.Events["RegistrarSet"].ID: - return _VerifiableLoadMercuryUpkeep.ParseRegistrarSet(log) case _VerifiableLoadMercuryUpkeep.abi.Events["UpkeepTopUp"].ID: return _VerifiableLoadMercuryUpkeep.ParseUpkeepTopUp(log) - case _VerifiableLoadMercuryUpkeep.abi.Events["UpkeepsCancelled"].ID: - return _VerifiableLoadMercuryUpkeep.ParseUpkeepsCancelled(log) case _VerifiableLoadMercuryUpkeep.abi.Events["UpkeepsRegistered"].ID: return _VerifiableLoadMercuryUpkeep.ParseUpkeepsRegistered(log) @@ -2994,16 +2119,8 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeep) ParseLog(log ty } } -func (VerifiableLoadMercuryUpkeepFundsAdded) Topic() common.Hash { - return common.HexToHash("0x8137dc366612bf502338bd8951f835ad8ceba421c4eb3d79c7f9b3ce0ac4762e") -} - -func (VerifiableLoadMercuryUpkeepInsufficientFunds) Topic() common.Hash { - return common.HexToHash("0x03eb8b54a949acec2cd08fdb6d6bd4647a1f2c907d75d6900648effa92eb147f") -} - -func (VerifiableLoadMercuryUpkeepMercuryPerformEvent) Topic() common.Hash { - return common.HexToHash("0xcad583be2d908a590c81c7e332cf11c7a4ea41ecf1e059efac3ea7e83e34f1a5") +func (VerifiableLoadMercuryUpkeepLogEmitted) Topic() common.Hash { + return common.HexToHash("0x97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf08") } func (VerifiableLoadMercuryUpkeepOwnershipTransferRequested) Topic() common.Hash { @@ -3014,26 +2131,14 @@ func (VerifiableLoadMercuryUpkeepOwnershipTransferred) Topic() common.Hash { return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") } -func (VerifiableLoadMercuryUpkeepPerformingUpkeep) Topic() common.Hash { - return common.HexToHash("0x6b6b3eeaaf107627513e76a81662118e7b1d8c78866f70760262115ddcfeede3") -} - func (VerifiableLoadMercuryUpkeepReceived) Topic() common.Hash { return common.HexToHash("0x88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f88525874") } -func (VerifiableLoadMercuryUpkeepRegistrarSet) Topic() common.Hash { - return common.HexToHash("0x6263309d5d4d1cfececd45a387cda7f14dccde21cf7a1bee1be6561075e61014") -} - func (VerifiableLoadMercuryUpkeepUpkeepTopUp) Topic() common.Hash { return common.HexToHash("0x49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c0") } -func (VerifiableLoadMercuryUpkeepUpkeepsCancelled) Topic() common.Hash { - return common.HexToHash("0xbeac20a03a6674e40498fac4356bc86e356c0d761a8d35d436712dc93bc7c74b") -} - func (VerifiableLoadMercuryUpkeepUpkeepsRegistered) Topic() common.Hash { return common.HexToHash("0x2ee10f7eb180441fb9fbba75b10c0162b5390b557712c93426243ca8f383c711") } @@ -3045,8 +2150,6 @@ func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeep) Address() commo type VerifiableLoadMercuryUpkeepInterface interface { BUCKETSIZE(opts *bind.CallOpts) (uint16, error) - TIMESTAMPINTERVAL(opts *bind.CallOpts) (uint16, error) - AddLinkAmount(opts *bind.CallOpts) (*big.Int, error) BucketedDelays(opts *bind.CallOpts, arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error) @@ -3055,8 +2158,6 @@ type VerifiableLoadMercuryUpkeepInterface interface { CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (bool, []byte, error) - CheckDatas(opts *bind.CallOpts, arg0 *big.Int) ([]byte, error) - CheckGasToBurns(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) Counters(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) @@ -3067,6 +2168,8 @@ type VerifiableLoadMercuryUpkeepInterface interface { Eligible(opts *bind.CallOpts, upkeepId *big.Int) (bool, error) + EmittedSig(opts *bind.CallOpts) ([32]byte, error) + FeedParamKey(opts *bind.CallOpts) (string, error) FeedsHex(opts *bind.CallOpts, arg0 *big.Int) (string, error) @@ -3085,34 +2188,14 @@ type VerifiableLoadMercuryUpkeepInterface interface { GetDelaysLength(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error) - GetDelaysLengthAtBucket(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) (*big.Int, error) - - GetDelaysLengthAtTimestampBucket(opts *bind.CallOpts, upkeepId *big.Int, timestampBucket uint16) (*big.Int, error) - - GetPxBucketedDelaysForAllUpkeeps(opts *bind.CallOpts, p *big.Int) ([]*big.Int, []*big.Int, error) - - GetPxDelayForAllUpkeeps(opts *bind.CallOpts, p *big.Int) ([]*big.Int, []*big.Int, error) - - GetPxDelayInBucket(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, bucket uint16) (*big.Int, error) - - GetPxDelayInTimestampBucket(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, timestampBucket uint16) (*big.Int, error) + GetLogTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) GetPxDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, n *big.Int) (*big.Int, error) - GetSumBucketedDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) - GetSumDelayInBucket(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) (*big.Int, *big.Int, error) - GetSumDelayInTimestampBucket(opts *bind.CallOpts, upkeepId *big.Int, timestampBucket uint16) (*big.Int, *big.Int, error) - GetSumDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) - GetSumTimestampBucketedDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) - - GetTimestampBucketedDelaysLength(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error) - - GetTimestampDelays(opts *bind.CallOpts, upkeepId *big.Int, timestampBucket uint16) ([]*big.Int, error) - Intervals(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) LastTopUpBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) @@ -3135,12 +2218,6 @@ type VerifiableLoadMercuryUpkeepInterface interface { TimeParamKey(opts *bind.CallOpts) (string, error) - TimestampBuckets(opts *bind.CallOpts, arg0 *big.Int) (uint16, error) - - TimestampDelays(opts *bind.CallOpts, arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error) - - Timestamps(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) - UpkeepTopUpCheckInterval(opts *bind.CallOpts) (*big.Int, error) UseArbitrumBlockNum(opts *bind.CallOpts) (bool, error) @@ -3151,7 +2228,9 @@ type VerifiableLoadMercuryUpkeepInterface interface { BatchCancelUpkeeps(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error) - BatchRegisterUpkeeps(opts *bind.TransactOpts, number uint8, gasLimit uint32, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) + BatchRegisterUpkeeps(opts *bind.TransactOpts, number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) + + BatchSendLogs(opts *bind.TransactOpts) (*types.Transaction, error) BatchSetIntervals(opts *bind.TransactOpts, upkeepIds []*big.Int, interval uint32) (*types.Transaction, error) @@ -3159,12 +2238,16 @@ type VerifiableLoadMercuryUpkeepInterface interface { BatchWithdrawLinks(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error) + BurnPerformGas(opts *bind.TransactOpts, upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error) + CancelUpkeep(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) CheckUpkeep(opts *bind.TransactOpts, checkData []byte) (*types.Transaction, error) PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error) + SendLog(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) + SetAddLinkAmount(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) SetCheckGasToBurn(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error) @@ -3185,6 +2268,8 @@ type VerifiableLoadMercuryUpkeepInterface interface { SetUpkeepTopUpCheckInterval(opts *bind.TransactOpts, newInterval *big.Int) (*types.Transaction, error) + TopUpFund(opts *bind.TransactOpts, upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error) + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) UpdateUpkeepPipelineData(opts *bind.TransactOpts, upkeepId *big.Int, pipelineData []byte) (*types.Transaction, error) @@ -3195,23 +2280,11 @@ type VerifiableLoadMercuryUpkeepInterface interface { Receive(opts *bind.TransactOpts) (*types.Transaction, error) - FilterFundsAdded(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepFundsAddedIterator, error) - - WatchFundsAdded(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepFundsAdded) (event.Subscription, error) - - ParseFundsAdded(log types.Log) (*VerifiableLoadMercuryUpkeepFundsAdded, error) - - FilterInsufficientFunds(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepInsufficientFundsIterator, error) + FilterLogEmitted(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int) (*VerifiableLoadMercuryUpkeepLogEmittedIterator, error) - WatchInsufficientFunds(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepInsufficientFunds) (event.Subscription, error) + WatchLogEmitted(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepLogEmitted, upkeepId []*big.Int, blockNum []*big.Int) (event.Subscription, error) - ParseInsufficientFunds(log types.Log) (*VerifiableLoadMercuryUpkeepInsufficientFunds, error) - - FilterMercuryPerformEvent(opts *bind.FilterOpts, origin []common.Address, upkeepId []*big.Int, blockNumber []*big.Int) (*VerifiableLoadMercuryUpkeepMercuryPerformEventIterator, error) - - WatchMercuryPerformEvent(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepMercuryPerformEvent, origin []common.Address, upkeepId []*big.Int, blockNumber []*big.Int) (event.Subscription, error) - - ParseMercuryPerformEvent(log types.Log) (*VerifiableLoadMercuryUpkeepMercuryPerformEvent, error) + ParseLogEmitted(log types.Log) (*VerifiableLoadMercuryUpkeepLogEmitted, error) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadMercuryUpkeepOwnershipTransferRequestedIterator, error) @@ -3225,36 +2298,18 @@ type VerifiableLoadMercuryUpkeepInterface interface { ParseOwnershipTransferred(log types.Log) (*VerifiableLoadMercuryUpkeepOwnershipTransferred, error) - FilterPerformingUpkeep(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepPerformingUpkeepIterator, error) - - WatchPerformingUpkeep(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepPerformingUpkeep) (event.Subscription, error) - - ParsePerformingUpkeep(log types.Log) (*VerifiableLoadMercuryUpkeepPerformingUpkeep, error) - FilterReceived(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepReceivedIterator, error) WatchReceived(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepReceived) (event.Subscription, error) ParseReceived(log types.Log) (*VerifiableLoadMercuryUpkeepReceived, error) - FilterRegistrarSet(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepRegistrarSetIterator, error) - - WatchRegistrarSet(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepRegistrarSet) (event.Subscription, error) - - ParseRegistrarSet(log types.Log) (*VerifiableLoadMercuryUpkeepRegistrarSet, error) - FilterUpkeepTopUp(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepUpkeepTopUpIterator, error) WatchUpkeepTopUp(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepUpkeepTopUp) (event.Subscription, error) ParseUpkeepTopUp(log types.Log) (*VerifiableLoadMercuryUpkeepUpkeepTopUp, error) - FilterUpkeepsCancelled(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepUpkeepsCancelledIterator, error) - - WatchUpkeepsCancelled(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepUpkeepsCancelled) (event.Subscription, error) - - ParseUpkeepsCancelled(log types.Log) (*VerifiableLoadMercuryUpkeepUpkeepsCancelled, error) - FilterUpkeepsRegistered(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepUpkeepsRegisteredIterator, error) WatchUpkeepsRegistered(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepUpkeepsRegistered) (event.Subscription, error) diff --git a/core/gethwrappers/generated/verifiable_load_upkeep_wrapper/verifiable_load_upkeep_wrapper.go b/core/gethwrappers/generated/verifiable_load_upkeep_wrapper/verifiable_load_upkeep_wrapper.go index 5d0105bba68..41d3ee1ff61 100644 --- a/core/gethwrappers/generated/verifiable_load_upkeep_wrapper/verifiable_load_upkeep_wrapper.go +++ b/core/gethwrappers/generated/verifiable_load_upkeep_wrapper/verifiable_load_upkeep_wrapper.go @@ -31,15 +31,15 @@ var ( ) var VerifiableLoadUpkeepMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"registrarAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"useArb\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"InsufficientFunds\",\"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\":\"uint256\",\"name\":\"firstPerformBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"lastBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"counter\",\"type\":\"uint256\"}],\"name\":\"PerformingUpkeep\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Received\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRegistrar\",\"type\":\"address\"}],\"name\":\"RegistrarSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"UpkeepTopUp\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"UpkeepsCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"UpkeepsRegistered\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BUCKET_SIZE\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TIMESTAMP_INTERVAL\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"addLinkAmount\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchCancelUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"number\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"checkGasToBurn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"performGasToBurn\",\"type\":\"uint256\"}],\"name\":\"batchRegisterUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint32\",\"name\":\"interval\",\"type\":\"uint32\"}],\"name\":\"batchSetIntervals\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchUpdatePipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchWithdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bucketedDelays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"buckets\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"checkDatas\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"checkGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"counters\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"delays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"dummyMap\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"firstPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"gasLimits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"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\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getBucketedDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getBucketedDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getDelaysLengthAtBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"timestampBucket\",\"type\":\"uint16\"}],\"name\":\"getDelaysLengthAtTimestampBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"p\",\"type\":\"uint256\"}],\"name\":\"getPxBucketedDelaysForAllUpkeeps\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"p\",\"type\":\"uint256\"}],\"name\":\"getPxDelayForAllUpkeeps\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"p\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getPxDelayInBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"p\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"timestampBucket\",\"type\":\"uint16\"}],\"name\":\"getPxDelayInTimestampBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"p\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getPxDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getSumBucketedDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getSumDelayInBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"timestampBucket\",\"type\":\"uint16\"}],\"name\":\"getSumDelayInTimestampBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getSumDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getSumTimestampBucketedDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTimestampBucketedDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"timestampBucket\",\"type\":\"uint16\"}],\"name\":\"getTimestampDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"intervals\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"lastTopUpBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkToken\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBalanceThresholdMultiplier\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performDataSizes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"previousPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registrar\",\"outputs\":[{\"internalType\":\"contractKeeperRegistrar2_0\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contractIKeeperRegistryMaster\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"setAddLinkAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setCheckGasToBurn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractKeeperRegistrar2_0\",\"name\":\"newRegistrar\",\"type\":\"address\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_interval\",\"type\":\"uint256\"}],\"name\":\"setInterval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"newMinBalanceThresholdMultiplier\",\"type\":\"uint8\"}],\"name\":\"setMinBalanceThresholdMultiplier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setPerformDataSize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setPerformGasToBurn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newInterval\",\"type\":\"uint256\"}],\"name\":\"setUpkeepTopUpCheckInterval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"timestampBuckets\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"timestampDelays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"timestamps\",\"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\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pipelineData\",\"type\":\"bytes\"}],\"name\":\"updateUpkeepPipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTopUpCheckInterval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useArbitrumBlockNum\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", - Bin: "0x60e06040526005601855601980546001600160681b0319166c140000000002c68af0bb140000179055601960f21b60a05260e160f41b60c0523480156200004557600080fd5b50604051620053bc380380620053bc833981016040819052620000689162000320565b81813380600081620000c15760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000f457620000f4816200025a565b5050601580546001600160a01b0319166001600160a01b0385169081179091556040805163850af0cb60e01b815290516000935063850af0cb9160048082019260a092909190829003018186803b1580156200014f57600080fd5b505afa15801562000164573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200018a91906200038a565b50601780546001600160a01b0319166001600160a01b038381169190911790915560155460408051631b6b6d2360e01b8152905193975091169450631b6b6d2393506004808201935060209291829003018186803b158015620001ec57600080fd5b505afa15801562000201573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000227919062000363565b601680546001600160a01b0319166001600160a01b039290921691909117905550151560f81b6080525062000413915050565b6001600160a01b038116331415620002b55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000b8565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b805163ffffffff811681146200031b57600080fd5b919050565b600080604083850312156200033457600080fd5b82516200034181620003fa565b602084015190925080151581146200035857600080fd5b809150509250929050565b6000602082840312156200037657600080fd5b81516200038381620003fa565b9392505050565b600080600080600060a08688031215620003a357600080fd5b855160038110620003b357600080fd5b9450620003c36020870162000306565b9350620003d36040870162000306565b92506060860151620003e581620003fa565b80925050608086015190509295509295909350565b6001600160a01b03811681146200041057600080fd5b50565b60805160f81c60a05160f01c60c05160f01c614f5b620004616000396000818161064d015261199e0152600081816105230152611ab20152600081816108fc015261383f0152614f5b6000f3fe6080604052600436106104695760003560e01c80637b10399911610243578063a72aa27e11610143578063daee1aeb116100bb578063f2fde38b1161008a578063fba7ffa31161006f578063fba7ffa314610fbb578063fbfb4f7614610fe8578063fcdc1f631461100857600080fd5b8063f2fde38b14610f7b578063fb0ceb0414610f9b57600080fd5b8063daee1aeb14610ef8578063dbef701e14610f18578063e0114adb14610f38578063e455308314610f6557600080fd5b8063becde0e111610112578063c8048022116100f7578063c804802214610e59578063d355852814610e79578063d6051a7214610ed857600080fd5b8063becde0e114610ddf578063c357f1f314610dff57600080fd5b8063a72aa27e14610d34578063a79c404314610d54578063af953a4a14610d81578063b0971e1a14610da157600080fd5b80639095aa35116101d65780639b429354116101a55780639d385eaa1161018a5780639d385eaa14610cd4578063a5f5893414610cf4578063a6c60d8914610d1457600080fd5b80639b42935414610c765780639b51fb0d14610ca357600080fd5b80639095aa3514610bda578063948108f714610bfa57806399cc6b0b14610c1a5780639ac542eb14610c3a57600080fd5b806387dfa9001161021257806387dfa90014610b425780638bc7b77214610b625780638da5cb5b14610b825780638fcb3fba14610bad57600080fd5b80637b10399914610ab55780637e4087b814610ae25780637e7a46dc14610b025780638237831714610b2257600080fd5b806351c98be31161036957806369cdbadb116102e15780637145f11b116102b057806376721303116102955780637672130314610a53578063776898c814610a8057806379ba509714610aa057600080fd5b80637145f11b146109f657806373644cce14610a2657600080fd5b806369cdbadb1461094e57806369e9b7731461097b5780636e04ff0d146109a85780637137a702146109d657600080fd5b80635f17e61611610338578063636092e81161031d578063636092e8146108a8578063642f6cef146108ea578063643b34e91461092e57600080fd5b80635f17e6161461085b57806360457ff51461087b57600080fd5b806351c98be3146107cc57806357970e93146107ec57806358c52c04146108195780635d4ee7f31461084657600080fd5b806329f0e496116103fc57806333774d1c116103cb5780634585e33b116103b05780634585e33b1461075f57806345d2ec171461077f57806346e7a63e1461079f57600080fd5b806333774d1c1461070e5780633ebe8d6c1461073f57600080fd5b806329f0e4961461063b5780632a9032d31461066f5780632b20e3971461068f578063328ffd11146106e157600080fd5b80631bee0080116104385780631bee008014610596578063206c32e8146105c457806320e3dbd4146105f957806328c4b57b1461061b57600080fd5b806306e3b632146104ad578063077ac621146104e357806312c5502714610511578063177b0eb91461055857600080fd5b366104a857604080513381523460208201527f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f88525874910160405180910390a1005b600080fd5b3480156104b957600080fd5b506104cd6104c8366004614515565b611035565b6040516104da9190614775565b60405180910390f35b3480156104ef57600080fd5b506105036104fe3660046144e0565b611131565b6040519081526020016104da565b34801561051d57600080fd5b506105457f000000000000000000000000000000000000000000000000000000000000000081565b60405161ffff90911681526020016104da565b34801561056457600080fd5b506105036105733660046144b4565b6000918252600f6020908152604080842061ffff93909316845291905290205490565b3480156105a257600080fd5b506105b66105b13660046141d0565b61116f565b6040516104da929190614788565b3480156105d057600080fd5b506105e46105df3660046144b4565b611478565b604080519283526020830191909152016104da565b34801561060557600080fd5b506106196106143660046140ff565b6114fb565b005b34801561062757600080fd5b5061050361063636600461456c565b61171c565b34801561064757600080fd5b506105457f000000000000000000000000000000000000000000000000000000000000000081565b34801561067b57600080fd5b5061061961068a36600461411c565b611787565b34801561069b57600080fd5b506015546106bc9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016104da565b3480156106ed57600080fd5b506105036106fc3660046141d0565b60036020526000908152604090205481565b34801561071a57600080fd5b506105456107293660046141d0565b60116020526000908152604090205461ffff1681565b34801561074b57600080fd5b5061050361075a3660046141d0565b61185a565b34801561076b57600080fd5b5061061961077a3660046141e9565b6118c3565b34801561078b57600080fd5b506104cd61079a3660046144b4565b611f65565b3480156107ab57600080fd5b506105036107ba3660046141d0565b600a6020526000908152604090205481565b3480156107d857600080fd5b506106196107e736600461415e565b611fd4565b3480156107f857600080fd5b506016546106bc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561082557600080fd5b506108396108343660046141d0565b612078565b6040516104da91906147c8565b34801561085257600080fd5b50610619612112565b34801561086757600080fd5b50610619610876366004614515565b61226b565b34801561088757600080fd5b506105036108963660046141d0565b60076020526000908152604090205481565b3480156108b457600080fd5b506019546108cd906bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff90911681526020016104da565b3480156108f657600080fd5b5061091e7f000000000000000000000000000000000000000000000000000000000000000081565b60405190151581526020016104da565b34801561093a57600080fd5b506105e4610949366004614515565b6123dd565b34801561095a57600080fd5b506105036109693660046141d0565b60086020526000908152604090205481565b34801561098757600080fd5b50610619610996366004614515565b60009182526008602052604090912055565b3480156109b457600080fd5b506109c86109c33660046141e9565b612562565b6040516104da9291906147ad565b3480156109e257600080fd5b506105036109f13660046144e0565b61268f565b348015610a0257600080fd5b5061091e610a113660046141d0565b600c6020526000908152604090205460ff1681565b348015610a3257600080fd5b50610503610a413660046141d0565b6000908152600d602052604090205490565b348015610a5f57600080fd5b50610503610a6e3660046141d0565b60046020526000908152604090205481565b348015610a8c57600080fd5b5061091e610a9b3660046141d0565b6126b7565b348015610aac57600080fd5b50610619612707565b348015610ac157600080fd5b506017546106bc9073ffffffffffffffffffffffffffffffffffffffff1681565b348015610aee57600080fd5b506105e4610afd366004614515565b612809565b348015610b0e57600080fd5b50610619610b1d3660046143e3565b612981565b348015610b2e57600080fd5b50610503610b3d366004614537565b612a2c565b348015610b4e57600080fd5b50610503610b5d366004614537565b612aa7565b348015610b6e57600080fd5b506105b6610b7d3660046141d0565b612b17565b348015610b8e57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166106bc565b348015610bb957600080fd5b50610503610bc83660046141d0565b60056020526000908152604090205481565b348015610be657600080fd5b50610619610bf5366004614608565b612c8c565b348015610c0657600080fd5b50610619610c153660046145c8565b612f0c565b348015610c2657600080fd5b506104cd610c353660046144b4565b6130a4565b348015610c4657600080fd5b50601954610c64906c01000000000000000000000000900460ff1681565b60405160ff90911681526020016104da565b348015610c8257600080fd5b50610619610c91366004614515565b60009182526009602052604090912055565b348015610caf57600080fd5b50610545610cbe3660046141d0565b60126020526000908152604090205461ffff1681565b348015610ce057600080fd5b506104cd610cef3660046141d0565b613111565b348015610d0057600080fd5b50610503610d0f3660046141d0565b613173565b348015610d2057600080fd5b50610619610d2f3660046141d0565b601855565b348015610d4057600080fd5b50610619610d4f366004614598565b6131d4565b348015610d6057600080fd5b50610619610d6f366004614515565b60009182526007602052604090912055565b348015610d8d57600080fd5b50610619610d9c3660046141d0565b61327f565b348015610dad57600080fd5b50610503610dbc3660046144b4565b6000918252600e6020908152604080842061ffff93909316845291905290205490565b348015610deb57600080fd5b50610619610dfa36600461411c565b613305565b348015610e0b57600080fd5b50610619610e1a366004614661565b601980547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff92909216919091179055565b348015610e6557600080fd5b50610619610e743660046141d0565b61339f565b348015610e8557600080fd5b50610619610e943660046145ed565b6019805460ff9092166c01000000000000000000000000027fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff909216919091179055565b348015610ee457600080fd5b506105e4610ef3366004614515565b613437565b348015610f0457600080fd5b50610619610f1336600461411c565b6134a0565b348015610f2457600080fd5b50610503610f33366004614515565b61356b565b348015610f4457600080fd5b50610503610f533660046141d0565b60096020526000908152604090205481565b348015610f7157600080fd5b5061050360185481565b348015610f8757600080fd5b50610619610f963660046140ff565b61359c565b348015610fa757600080fd5b50610503610fb6366004614515565b6135b0565b348015610fc757600080fd5b50610503610fd63660046141d0565b60066020526000908152604090205481565b348015610ff457600080fd5b506105e46110033660046144b4565b6135cc565b34801561101457600080fd5b506105036110233660046141d0565b60026020526000908152604090205481565b606060006110436013613640565b905080841061107e576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826110905761108d8482614c14565b92505b60008367ffffffffffffffff8111156110ab576110ab614ed1565b6040519080825280602002602001820160405280156110d4578160200160208202803683370190505b50905060005b84811015611126576110f76110ef8288614a9b565b60139061364a565b82828151811061110957611109614ea2565b60209081029190910101528061111e81614da9565b9150506110da565b509150505b92915050565b600e602052826000526040600020602052816000526040600020818154811061115957600080fd5b9060005260206000200160009250925050505481565b606080600061117e6013613640565b905060008167ffffffffffffffff81111561119b5761119b614ed1565b6040519080825280602002602001820160405280156111c4578160200160208202803683370190505b50905060008267ffffffffffffffff8111156111e2576111e2614ed1565b60405190808252806020026020018201604052801561120b578160200160208202803683370190505b50905060005b8381101561146c57600061122660138361364a565b90508084838151811061123b5761123b614ea2565b6020908102919091018101919091526000828152601290915260408082205490517f3ebe8d6c0000000000000000000000000000000000000000000000000000000081526004810184905261ffff90911691903090633ebe8d6c9060240160206040518083038186803b1580156112b157600080fd5b505afa1580156112c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e991906143ca565b905060008167ffffffffffffffff81111561130657611306614ed1565b60405190808252806020026020018201604052801561132f578160200160208202803683370190505b506000858152600e6020526040812091925090815b8561ffff168161ffff16116114295761ffff8116600090815260208381526040808320805482518185028101850190935280835291929091908301828280156113ac57602002820191906000526020600020905b815481526020019060010190808311611398575b5050505050905060005b8151811015611414578181815181106113d1576113d1614ea2565b60200260200101518686806113e590614da9565b9750815181106113f7576113f7614ea2565b60209081029190910101528061140c81614da9565b9150506113b6565b5050808061142190614d87565b915050611344565b50611435838e86613656565b88888151811061144757611447614ea2565b602002602001018181525050505050505050808061146490614da9565b915050611211565b50909590945092505050565b6000828152600e6020908152604080832061ffff8516845282528083208054825181850281018501909352808352849384939291908301828280156114dc57602002820191906000526020600020905b8154815260200190600101908083116114c8575b505050505090506114ee8182516137b6565b92509250505b9250929050565b601580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117909155604080517f850af0cb00000000000000000000000000000000000000000000000000000000815290516000929163850af0cb9160048083019260a0929190829003018186803b15801561159057600080fd5b505afa1580156115a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115c8919061423c565b50601780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691909117909155601554604080517f1b6b6d23000000000000000000000000000000000000000000000000000000008152905193975091169450631b6b6d2393506004808201935060209291829003018186803b15801561166757600080fd5b505afa15801561167b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169f919061421f565b601680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055601554604051911681527f6263309d5d4d1cfececd45a387cda7f14dccde21cf7a1bee1be6561075e61014906020015b60405180910390a15050565b6000838152600d60209081526040808320805482518185028101850190935280835261177d9383018282801561177157602002820191906000526020600020905b81548152602001906001019080831161175d575b50505050508484613656565b90505b9392505050565b8060005b818160ff16101561181b573063c8048022858560ff85168181106117b1576117b1614ea2565b905060200201356040518263ffffffff1660e01b81526004016117d691815260200190565b600060405180830381600087803b1580156117f057600080fd5b505af1158015611804573d6000803e3d6000fd5b50505050808061181390614df5565b91505061178b565b507fbeac20a03a6674e40498fac4356bc86e356c0d761a8d35d436712dc93bc7c74b838360405161184d929190614720565b60405180910390a1505050565b60008181526012602052604081205461ffff1681805b8261ffff168161ffff16116118bb576000858152600e6020908152604080832061ffff851684529091529020546118a79083614a9b565b9150806118b381614d87565b915050611870565b509392505050565b60005a905060006118d68385018561442f565b50600081815260056020908152604080832054600490925282205492935091906118fe61383b565b9050826119385760008481526005602090815260408083208490556010825282208054600181018255908352912042910155915081611b98565b6000848152600360205260408120546119518484614c14565b61195b9190614c14565b6000868152601160209081526040808320546010909252909120805492935061ffff909116918290811061199157611991614ea2565b90600052602060002001547f000000000000000000000000000000000000000000000000000000000000000061ffff16426119cc9190614c14565b1115611a3b57600086815260106020908152604082208054600181018255908352912042910155806119fd81614d87565b600088815260116020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff83161790559150505b600086815260126020908152604080832054600e835281842061ffff9091168085529083528184208054835181860281018601909452808452919493909190830182828015611aa957602002820191906000526020600020905b815481526020019060010190808311611a95575b505050505090507f000000000000000000000000000000000000000000000000000000000000000061ffff1681511415611b255781611ae781614d87565b60008a815260126020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff83161790559250505b506000878152600e6020908152604080832061ffff94851684528252808320805460018181018355918552838520018790558a8452600f83528184209590941683529381528382208054808501825590835281832001859055888252600d81529281208054928301815581529190912001555b600084815260066020526040812054611bb2906001614a9b565b6000868152600660209081526040918290208390558151878152908101859052908101859052606081018290529091507f6b6b3eeaaf107627513e76a81662118e7b1d8c78866f70760262115ddcfeede39060800160405180910390a16000858152600460209081526040808320859055601854600290925290912054611c399084614c14565b1115611ee4576017546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810187905260009173ffffffffffffffffffffffffffffffffffffffff169063c7c3a19a9060240160006040518083038186803b158015611caa57600080fd5b505afa158015611cbe573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611d0491908101906142ab565b6017546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810189905291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063b657bc9c9060240160206040518083038186803b158015611d7457600080fd5b505afa158015611d88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dac919061467e565b601954909150611dd09082906c01000000000000000000000000900460ff16614b6c565b6bffffffffffffffffffffffff1682606001516bffffffffffffffffffffffff161015611ee1576019546040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018990526bffffffffffffffffffffffff9091166024820152309063948108f790604401600060405180830381600087803b158015611e6157600080fd5b505af1158015611e75573d6000803e3d6000fd5b50505060008881526002602090815260409182902087905560195482518b81526bffffffffffffffffffffffff909116918101919091529081018690527f49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c0915060600160405180910390a15b50505b6000858152600760205260409020545b805a611f009089614c14565b611f0c90612710614a9b565b1015611f5a5782406000908152600c6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905582611f5281614ceb565b935050611ef4565b505050505050505050565b6000828152600e6020908152604080832061ffff85168452825291829020805483518184028101840190945280845260609392830182828015611fc757602002820191906000526020600020905b815481526020019060010190808311611fb3575b5050505050905092915050565b8160005b818110156120715730635f17e616868684818110611ff857611ff8614ea2565b90506020020135856040518363ffffffff1660e01b815260040161202c92919091825263ffffffff16602082015260400190565b600060405180830381600087803b15801561204657600080fd5b505af115801561205a573d6000803e3d6000fd5b50505050808061206990614da9565b915050611fd8565b5050505050565b600b602052600090815260409020805461209190614cfa565b80601f01602080910402602001604051908101604052809291908181526020018280546120bd90614cfa565b801561210a5780601f106120df5761010080835404028352916020019161210a565b820191906000526020600020905b8154815290600101906020018083116120ed57829003601f168201915b505050505081565b61211a6138ec565b6016546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a082319060240160206040518083038186803b15801561218457600080fd5b505afa158015612198573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121bc91906143ca565b6016546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810183905291925073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb90604401602060405180830381600087803b15801561222f57600080fd5b505af1158015612243573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061226791906141b5565b5050565b60008281526003602090815260408083208490556005825280832083905560068252808320839055600d90915281206122a391613e6c565b60008281526012602052604081205461ffff16905b8161ffff168161ffff16116122ff576000848152600e6020908152604080832061ffff8516845290915281206122ed91613e6c565b806122f781614d87565b9150506122b8565b5050600082815260126020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055601190915281205461ffff16905b8161ffff168161ffff161161238d576000848152600f6020908152604080832061ffff85168452909152812061237b91613e6c565b8061238581614d87565b915050612346565b5060008381526010602052604081206123a591613e6c565b5050600090815260116020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055565b6040517f3ebe8d6c00000000000000000000000000000000000000000000000000000000815260048101839052600090819081903090633ebe8d6c9060240160206040518083038186803b15801561243457600080fd5b505afa158015612448573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061246c91906143ca565b905083158061247b5750808410155b15612484578093505b60008581526012602052604081205485919061ffff16805b6000898152600e6020908152604080832061ffff851684528252808320805482518185028101850190935280835291929091908301828280156124fe57602002820191906000526020600020905b8154815260200190600101908083116124ea575b5050505050905060008061251283886137b6565b90925090506125218287614a9b565b955061252d8188614c14565b96506000871161253f57505050612555565b505050808061254d90614caf565b91505061249c565b5090979596505050505050565b6000606060005a90506000612579858701876141d0565b60008181526009602090815260408083205460089092528220549293509190838367ffffffffffffffff8111156125b2576125b2614ed1565b6040519080825280601f01601f1916602001820160405280156125dc576020820181803683370190505b506040516020016125ee92919061494f565b6040516020818303038152906040529050600061260961383b565b90506000612616866126b7565b90505b835a6126259089614c14565b61263190612710614a9b565b101561267f5781406000908152600c6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690558161267781614ceb565b925050612619565b9a91995090975050505050505050565b600f602052826000526040600020602052816000526040600020818154811061115957600080fd5b6000818152600560205260408120546126d257506001919050565b6000828152600360209081526040808320546004909252909120546126f561383b565b6126ff9190614c14565b101592915050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461278d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6040517fa5f589340000000000000000000000000000000000000000000000000000000081526004810183905260009081908190309063a5f589349060240160206040518083038186803b15801561286057600080fd5b505afa158015612874573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061289891906143ca565b90508315806128a75750808410155b156128b0578093505b60008581526011602052604081205485919061ffff16805b6000898152600f6020908152604080832061ffff8516845282528083208054825181850281018501909352808352919290919083018282801561292a57602002820191906000526020600020905b815481526020019060010190808311612916575b5050505050905060008061293e83886137b6565b909250905061294d8287614a9b565b95506129598188614c14565b96506000871161296b57505050612555565b505050808061297990614caf565b9150506128c8565b6017546040517fcd7f71b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063cd7f71b5906129db908690869086906004016148fb565b600060405180830381600087803b1580156129f557600080fd5b505af1158015612a09573d6000803e3d6000fd5b5050506000848152600b60205260409020612a2691508383613e8a565b50505050565b6000838152600e6020908152604080832061ffff85168452825280832080548251818502810185019093528083528493830182828015612a8b57602002820191906000526020600020905b815481526020019060010190808311612a77575b50505050509050612a9e81858351613656565b95945050505050565b6000838152600f6020908152604080832061ffff85168452825280832080548251818502810185019093528083528493830182828015612a8b5760200282019190600052602060002090815481526020019060010190808311612a775750505050509050612a9e81858351613656565b6060806000612b266013613640565b905060008167ffffffffffffffff811115612b4357612b43614ed1565b604051908082528060200260200182016040528015612b6c578160200160208202803683370190505b50905060008267ffffffffffffffff811115612b8a57612b8a614ed1565b604051908082528060200260200182016040528015612bb3578160200160208202803683370190505b50905060005b8381101561146c576000612bce60138361364a565b6000818152600d6020908152604080832080548251818502810185019093528083529495509293909291830182828015612c2757602002820191906000526020600020905b815481526020019060010190808311612c13575b5050505050905081858481518110612c4157612c41614ea2565b602002602001018181525050612c59818a8351613656565b848481518110612c6b57612c6b614ea2565b60200260200101818152505050508080612c8490614da9565b915050612bb9565b6040805161014081018252600461010082019081527f746573740000000000000000000000000000000000000000000000000000000061012083015281528151602081810184526000808352818401929092523083850181905263ffffffff8916606085015260808401528351808201855282815260a08401528351908101909352825260c08101919091526bffffffffffffffffffffffff841660e082015260165460155473ffffffffffffffffffffffffffffffffffffffff9182169163095ea7b39116612d5f60ff8a1688614b6c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526bffffffffffffffffffffffff166024820152604401602060405180830381600087803b158015612dd857600080fd5b505af1158015612dec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e1091906141b5565b5060008660ff1667ffffffffffffffff811115612e2f57612e2f614ed1565b604051908082528060200260200182016040528015612e58578160200160208202803683370190505b50905060005b8760ff168160ff161015612ecb576000612e778461396f565b905080838360ff1681518110612e8f57612e8f614ea2565b60209081029190910181019190915260009182526008815260408083208890556007909152902084905580612ec381614df5565b915050612e5e565b507f2ee10f7eb180441fb9fbba75b10c0162b5390b557712c93426243ca8f383c71181604051612efb9190614775565b60405180910390a150505050505050565b6016546017546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526bffffffffffffffffffffffff8416602482015291169063095ea7b390604401602060405180830381600087803b158015612f8f57600080fd5b505af1158015612fa3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fc791906141b5565b506017546040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063948108f790604401600060405180830381600087803b15801561304857600080fd5b505af115801561305c573d6000803e3d6000fd5b5050604080518581526bffffffffffffffffffffffff851660208201527f8137dc366612bf502338bd8951f835ad8ceba421c4eb3d79c7f9b3ce0ac4762e9350019050611710565b6000828152600f6020908152604080832061ffff85168452825291829020805483518184028101840190945280845260609392830182828015611fc75760200282019190600052602060002090815481526020019060010190808311611fb3575050505050905092915050565b6000818152600d602090815260409182902080548351818402810184019094528084526060939283018282801561316757602002820191906000526020600020905b815481526020019060010190808311613153575b50505050509050919050565b60008181526011602052604081205461ffff1681805b8261ffff168161ffff16116118bb576000858152600f6020908152604080832061ffff851684529091529020546131c09083614a9b565b9150806131cc81614d87565b915050613189565b6017546040517fa72aa27e0000000000000000000000000000000000000000000000000000000081526004810184905263ffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063a72aa27e90604401600060405180830381600087803b15801561324c57600080fd5b505af1158015613260573d6000803e3d6000fd5b505050600092835250600a602052604090912063ffffffff9091169055565b6017546040517f744bfe610000000000000000000000000000000000000000000000000000000081526004810183905230602482015273ffffffffffffffffffffffffffffffffffffffff9091169063744bfe6190604401600060405180830381600087803b1580156132f157600080fd5b505af1158015612071573d6000803e3d6000fd5b8060005b818163ffffffff161015612a26573063af953a4a858563ffffffff851681811061333557613335614ea2565b905060200201356040518263ffffffff1660e01b815260040161335a91815260200190565b600060405180830381600087803b15801561337457600080fd5b505af1158015613388573d6000803e3d6000fd5b50505050808061339790614ddb565b915050613309565b6017546040517fc80480220000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff9091169063c804802290602401600060405180830381600087803b15801561340b57600080fd5b505af115801561341f573d6000803e3d6000fd5b50505050612267816013613a7190919063ffffffff16565b6000828152600d6020908152604080832080548251818502810185019093528083528493849392919083018282801561348f57602002820191906000526020600020905b81548152602001906001019080831161347b575b505050505090506114ee81856137b6565b8060005b81811015612a265760008484838181106134c0576134c0614ea2565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc82836040516020016134f991815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b815260040161352592919061494f565b600060405180830381600087803b15801561353f57600080fd5b505af1158015613553573d6000803e3d6000fd5b5050505050808061356390614da9565b9150506134a4565b600d602052816000526040600020818154811061358757600080fd5b90600052602060002001600091509150505481565b6135a46138ec565b6135ad81613a7d565b50565b6010602052816000526040600020818154811061358757600080fd5b6000828152600f6020908152604080832061ffff8516845282528083208054825181850281018501909352808352849384939291908301828280156114dc57602002820191906000526020600020908154815260200190600101908083116114c857505050505090506114ee8182516137b6565b600061112b825490565b60006117808383613b73565b8251600090819083158061366a5750808410155b15613673578093505b60008467ffffffffffffffff81111561368e5761368e614ed1565b6040519080825280602002602001820160405280156136b7578160200160208202803683370190505b509050600092505b84831015613725578660016136d48585614c14565b6136de9190614c14565b815181106136ee576136ee614ea2565b602002602001015181848151811061370857613708614ea2565b60209081029190910101528261371d81614da9565b9350506136bf565b61373e816000600184516137399190614c14565b613b9d565b85606414156137785780600182516137569190614c14565b8151811061376657613766614ea2565b60200260200101519350505050611780565b8060648251886137889190614b2f565b6137929190614b1b565b815181106137a2576137a2614ea2565b602002602001015193505050509392505050565b8151600090819081908415806137cc5750808510155b156137d5578094505b60008092505b85831015613831578660016137f08585614c14565b6137fa9190614c14565b8151811061380a5761380a614ea2565b60200260200101518161381d9190614a9b565b90508261382981614da9565b9350506137db565b9694955050505050565b60007f0000000000000000000000000000000000000000000000000000000000000000156138e757606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156138aa57600080fd5b505afa1580156138be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138e291906143ca565b905090565b504390565b60005473ffffffffffffffffffffffffffffffffffffffff16331461396d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401612784565b565b6015546040517f08b79da4000000000000000000000000000000000000000000000000000000008152600091829173ffffffffffffffffffffffffffffffffffffffff909116906308b79da4906139ca9086906004016147db565b602060405180830381600087803b1580156139e457600080fd5b505af11580156139f8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a1c91906143ca565b9050613a29601382613d1e565b5060608301516000828152600a6020908152604080832063ffffffff90941690935560a0860151600b8252929091208251613a6a9391929190910190613f2c565b5092915050565b60006117808383613d2a565b73ffffffffffffffffffffffffffffffffffffffff8116331415613afd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401612784565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110613b8a57613b8a614ea2565b9060005260206000200154905092915050565b818180821415613bae575050505050565b6000856002613bbd8787614ba0565b613bc79190614ab3565b613bd19087614a27565b81518110613be157613be1614ea2565b602002602001015190505b818313613cf0575b80868481518110613c0757613c07614ea2565b60200260200101511015613c275782613c1f81614d4e565b935050613bf4565b858281518110613c3957613c39614ea2565b6020026020010151811015613c5a5781613c5281614c57565b925050613c27565b818313613ceb57858281518110613c7357613c73614ea2565b6020026020010151868481518110613c8d57613c8d614ea2565b6020026020010151878581518110613ca757613ca7614ea2565b60200260200101888581518110613cc057613cc0614ea2565b60209081029190910101919091525282613cd981614d4e565b9350508180613ce790614c57565b9250505b613bec565b81851215613d0357613d03868684613b9d565b83831215613d1657613d16868486613b9d565b505050505050565b60006117808383613e1d565b60008181526001830160205260408120548015613e13576000613d4e600183614c14565b8554909150600090613d6290600190614c14565b9050818114613dc7576000866000018281548110613d8257613d82614ea2565b9060005260206000200154905080876000018481548110613da557613da5614ea2565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613dd857613dd8614e73565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061112b565b600091505061112b565b6000818152600183016020526040812054613e645750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561112b565b50600061112b565b50805460008255906000526020600020908101906135ad9190613fa0565b828054613e9690614cfa565b90600052602060002090601f016020900481019282613eb85760008555613f1c565b82601f10613eef578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00823516178555613f1c565b82800160010185558215613f1c579182015b82811115613f1c578235825591602001919060010190613f01565b50613f28929150613fa0565b5090565b828054613f3890614cfa565b90600052602060002090601f016020900481019282613f5a5760008555613f1c565b82601f10613f7357805160ff1916838001178555613f1c565b82800160010185558215613f1c579182015b82811115613f1c578251825591602001919060010190613f85565b5b80821115613f285760008155600101613fa1565b8051613fc081614f00565b919050565b60008083601f840112613fd757600080fd5b50813567ffffffffffffffff811115613fef57600080fd5b6020830191508360208260051b85010111156114f457600080fd5b80518015158114613fc057600080fd5b60008083601f84011261402c57600080fd5b50813567ffffffffffffffff81111561404457600080fd5b6020830191508360208285010111156114f457600080fd5b600082601f83011261406d57600080fd5b815161408061407b826149e1565b614992565b81815284602083860101111561409557600080fd5b6140a6826020830160208701614c2b565b949350505050565b803561ffff81168114613fc057600080fd5b8051613fc081614f22565b805167ffffffffffffffff81168114613fc057600080fd5b803560ff81168114613fc057600080fd5b8051613fc081614f34565b60006020828403121561411157600080fd5b813561178081614f00565b6000806020838503121561412f57600080fd5b823567ffffffffffffffff81111561414657600080fd5b61415285828601613fc5565b90969095509350505050565b60008060006040848603121561417357600080fd5b833567ffffffffffffffff81111561418a57600080fd5b61419686828701613fc5565b90945092505060208401356141aa81614f22565b809150509250925092565b6000602082840312156141c757600080fd5b6117808261400a565b6000602082840312156141e257600080fd5b5035919050565b600080602083850312156141fc57600080fd5b823567ffffffffffffffff81111561421357600080fd5b6141528582860161401a565b60006020828403121561423157600080fd5b815161178081614f00565b600080600080600060a0868803121561425457600080fd5b85516003811061426357600080fd5b602087015190955061427481614f22565b604087015190945061428581614f22565b606087015190935061429681614f00565b80925050608086015190509295509295909350565b6000602082840312156142bd57600080fd5b815167ffffffffffffffff808211156142d557600080fd5b9083019061014082860312156142ea57600080fd5b6142f2614968565b6142fb83613fb5565b8152614309602084016140c0565b602082015260408301518281111561432057600080fd5b61432c8782860161405c565b60408301525061433e606084016140f4565b606082015261434f60808401613fb5565b608082015261436060a084016140cb565b60a082015261437160c084016140c0565b60c082015261438260e084016140f4565b60e082015261010061439581850161400a565b9082015261012083810151838111156143ad57600080fd5b6143b98882870161405c565b918301919091525095945050505050565b6000602082840312156143dc57600080fd5b5051919050565b6000806000604084860312156143f857600080fd5b83359250602084013567ffffffffffffffff81111561441657600080fd5b6144228682870161401a565b9497909650939450505050565b6000806040838503121561444257600080fd5b82359150602083013567ffffffffffffffff81111561446057600080fd5b8301601f8101851361447157600080fd5b803561447f61407b826149e1565b81815286602083850101111561449457600080fd5b816020840160208301376000602083830101528093505050509250929050565b600080604083850312156144c757600080fd5b823591506144d7602084016140ae565b90509250929050565b6000806000606084860312156144f557600080fd5b83359250614505602085016140ae565b9150604084013590509250925092565b6000806040838503121561452857600080fd5b50508035926020909101359150565b60008060006060848603121561454c57600080fd5b8335925060208401359150614563604085016140ae565b90509250925092565b60008060006060848603121561458157600080fd5b505081359360208301359350604090920135919050565b600080604083850312156145ab57600080fd5b8235915060208301356145bd81614f22565b809150509250929050565b600080604083850312156145db57600080fd5b8235915060208301356145bd81614f34565b6000602082840312156145ff57600080fd5b611780826140e3565b600080600080600060a0868803121561462057600080fd5b614629866140e3565b9450602086013561463981614f22565b9350604086013561464981614f34565b94979396509394606081013594506080013592915050565b60006020828403121561467357600080fd5b813561178081614f34565b60006020828403121561469057600080fd5b815161178081614f34565b600081518084526020808501945080840160005b838110156146cb578151875295820195908201906001016146af565b509495945050505050565b600081518084526146ee816020860160208601614c2b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815281602082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561475957600080fd5b8260051b80856040850137600092016040019182525092915050565b602081526000611780602083018461469b565b60408152600061479b604083018561469b565b8281036020840152612a9e818561469b565b821515815260406020820152600061177d60408301846146d6565b60208152600061178060208301846146d6565b60208152600082516101008060208501526147fa6101208501836146d6565b915060208501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08086850301604087015261483684836146d6565b935060408701519150614861606087018373ffffffffffffffffffffffffffffffffffffffff169052565b606087015163ffffffff811660808801529150608087015173ffffffffffffffffffffffffffffffffffffffff811660a0880152915060a08701519150808685030160c08701526148b284836146d6565b935060c08701519150808685030160e0870152506148d083826146d6565b92505060e08501516148f1828601826bffffffffffffffffffffffff169052565b5090949350505050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b82815260406020820152600061177d60408301846146d6565b604051610140810167ffffffffffffffff8111828210171561498c5761498c614ed1565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156149d9576149d9614ed1565b604052919050565b600067ffffffffffffffff8211156149fb576149fb614ed1565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03841381151615614a6157614a61614e15565b827f8000000000000000000000000000000000000000000000000000000000000000038412811615614a9557614a95614e15565b50500190565b60008219821115614aae57614aae614e15565b500190565b600082614ac257614ac2614e44565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615614b1657614b16614e15565b500590565b600082614b2a57614b2a614e44565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614b6757614b67614e15565b500290565b60006bffffffffffffffffffffffff80831681851681830481118215151615614b9757614b97614e15565b02949350505050565b6000808312837f800000000000000000000000000000000000000000000000000000000000000001831281151615614bda57614bda614e15565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018313811615614c0e57614c0e614e15565b50500390565b600082821015614c2657614c26614e15565b500390565b60005b83811015614c46578181015183820152602001614c2e565b83811115612a265750506000910152565b60007f8000000000000000000000000000000000000000000000000000000000000000821415614c8957614c89614e15565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b600061ffff821680614cc357614cc3614e15565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0192915050565b600081614c8957614c89614e15565b600181811c90821680614d0e57607f821691505b60208210811415614d48577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415614d8057614d80614e15565b5060010190565b600061ffff80831681811415614d9f57614d9f614e15565b6001019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415614d8057614d80614e15565b600063ffffffff80831681811415614d9f57614d9f614e15565b600060ff821660ff811415614e0c57614e0c614e15565b60010192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff811681146135ad57600080fd5b63ffffffff811681146135ad57600080fd5b6bffffffffffffffffffffffff811681146135ad57600080fdfea164736f6c6343000806000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"_registrar\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useArb\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"LogEmitted\",\"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\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Received\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"UpkeepTopUp\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"UpkeepsRegistered\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BUCKET_SIZE\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"addLinkAmount\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchCancelUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"number\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"checkGasToBurn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"performGasToBurn\",\"type\":\"uint256\"}],\"name\":\"batchRegisterUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"batchSendLogs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint32\",\"name\":\"interval\",\"type\":\"uint32\"}],\"name\":\"batchSetIntervals\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchUpdatePipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchWithdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bucketedDelays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"buckets\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"startGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"burnPerformGas\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"checkGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"counters\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"delays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"dummyMap\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emittedSig\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"firstPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"gasLimits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"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\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getBucketedDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getBucketedDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getLogTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"logTrigger\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"p\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getPxDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getSumDelayInBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getSumDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"intervals\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"lastTopUpBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkToken\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBalanceThresholdMultiplier\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performDataSizes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"previousPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registrar\",\"outputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contractIKeeperRegistryMaster\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"sendLog\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"setAddLinkAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setCheckGasToBurn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"newRegistrar\",\"type\":\"address\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_interval\",\"type\":\"uint256\"}],\"name\":\"setInterval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"newMinBalanceThresholdMultiplier\",\"type\":\"uint8\"}],\"name\":\"setMinBalanceThresholdMultiplier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setPerformDataSize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setPerformGasToBurn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newInterval\",\"type\":\"uint256\"}],\"name\":\"setUpkeepTopUpCheckInterval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"topUpFund\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pipelineData\",\"type\":\"bytes\"}],\"name\":\"updateUpkeepPipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTopUpCheckInterval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useArbitrumBlockNum\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x60e06040527f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf086080526005601455601580546001600160681b0319166c140000000002c68af0bb140000179055606460c0523480156200005e57600080fd5b506040516200456738038062004567833981016040819052620000819162000310565b81813380600081620000da5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156200010d576200010d816200024c565b5050601180546001600160a01b0319166001600160a01b038516908117909155604080516330fe427560e21b815281516000945063c3f909d4926004808401939192918290030181865afa1580156200016a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000190919062000353565b50601380546001600160a01b0319166001600160a01b038381169190911790915560115460408051631b6b6d2360e01b81529051939450911691631b6b6d23916004808201926020929091908290030181865afa158015620001f6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200021c919062000384565b601280546001600160a01b0319166001600160a01b039290921691909117905550151560a05250620003ab915050565b336001600160a01b03821603620002a65760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000d1565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200030d57600080fd5b50565b600080604083850312156200032457600080fd5b82516200033181620002f7565b602084015190925080151581146200034857600080fd5b809150509250929050565b600080604083850312156200036757600080fd5b82516200037481620002f7565b6020939093015192949293505050565b6000602082840312156200039757600080fd5b8151620003a481620002f7565b9392505050565b60805160a05160c051614177620003f0600039600081816104c401526118d30152600081816107b20152612b1e015260008181610adc01526112f101526141776000f3fe60806040526004361061039b5760003560e01c8063776898c8116101dc578063a72aa27e11610102578063d6051a72116100a0578063e45530831161006f578063e455308314610d31578063f2fde38b14610d47578063fba7ffa314610d67578063fcdc1f6314610d9457600080fd5b8063d6051a7214610ca4578063daee1aeb14610cc4578063dbef701e14610ce4578063e0114adb14610d0457600080fd5b8063becde0e1116100dc578063becde0e114610bab578063c357f1f314610bcb578063c804802214610c25578063d355852814610c4557600080fd5b8063a72aa27e14610b3e578063a79c404314610b5e578063af953a4a14610b8b57600080fd5b8063948108f71161017a5780639d385eaa116101495780639d385eaa14610aaa578063a654824814610aca578063a6b5947514610afe578063a6c60d8914610b1e57600080fd5b8063948108f7146109f05780639ac542eb14610a105780639b42935414610a4c5780639b51fb0d14610a7957600080fd5b80637e7a46dc116101b65780637e7a46dc146109585780638da5cb5b146109785780638fcb3fba146109a3578063924ca578146109d057600080fd5b8063776898c8146108f657806379ba5097146109165780637b1039991461092b57600080fd5b806346e7a63e116102c1578063636092e81161025f5780636e04ff0d1161022e5780636e04ff0d1461083e5780637145f11b1461086c57806373644cce1461089c57806376721303146108c957600080fd5b8063636092e81461075e578063642f6cef146107a057806369cdbadb146107e457806369e9b7731461081157600080fd5b8063597109921161029b57806359710992146106e75780635d4ee7f3146106fc5780635f17e6161461071157806360457ff51461073157600080fd5b806346e7a63e1461066d57806351c98be31461069a57806357970e93146106ba57600080fd5b806320e3dbd411610339578063328ffd1111610308578063328ffd11146105e05780633ebe8d6c1461060d5780634585e33b1461062d57806345d2ec171461064d57600080fd5b806320e3dbd41461052e57806328c4b57b1461054e5780632a9032d31461056e5780632b20e3971461058e57600080fd5b80630d4a4fb1116103755780630d4a4fb1146104655780630e577d421461049257806312c55027146104b2578063206c32e8146104f957600080fd5b806306c1cc00146103df57806306e3b63214610401578063077ac6211461043757600080fd5b366103da57604080513381523460208201527f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f88525874910160405180910390a1005b600080fd5b3480156103eb57600080fd5b506103ff6103fa3660046133cc565b610dc1565b005b34801561040d57600080fd5b5061042161041c366004613468565b61117d565b60405161042e919061348a565b60405180910390f35b34801561044357600080fd5b506104576104523660046134e5565b61127c565b60405190815260200161042e565b34801561047157600080fd5b5061048561048036600461351a565b6112ba565b60405161042e91906135a1565b34801561049e57600080fd5b506103ff6104ad36600461351a565b6113d7565b3480156104be57600080fd5b506104e67f000000000000000000000000000000000000000000000000000000000000000081565b60405161ffff909116815260200161042e565b34801561050557600080fd5b506105196105143660046135b4565b61141f565b6040805192835260208301919091520161042e565b34801561053a57600080fd5b506103ff610549366004613602565b6114a2565b34801561055a57600080fd5b5061045761056936600461361f565b61166c565b34801561057a57600080fd5b506103ff610589366004613690565b6116d7565b34801561059a57600080fd5b506011546105bb9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161042e565b3480156105ec57600080fd5b506104576105fb36600461351a565b60036020526000908152604090205481565b34801561061957600080fd5b5061045761062836600461351a565b611771565b34801561063957600080fd5b506103ff610648366004613714565b6117da565b34801561065957600080fd5b506104216106683660046135b4565b6119e9565b34801561067957600080fd5b5061045761068836600461351a565b600a6020526000908152604090205481565b3480156106a657600080fd5b506103ff6106b536600461374a565b611a58565b3480156106c657600080fd5b506012546105bb9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156106f357600080fd5b506103ff611afc565b34801561070857600080fd5b506103ff611ce7565b34801561071d57600080fd5b506103ff61072c366004613468565b611e22565b34801561073d57600080fd5b5061045761074c36600461351a565b60076020526000908152604090205481565b34801561076a57600080fd5b50601554610783906bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff909116815260200161042e565b3480156107ac57600080fd5b506107d47f000000000000000000000000000000000000000000000000000000000000000081565b604051901515815260200161042e565b3480156107f057600080fd5b506104576107ff36600461351a565b60086020526000908152604090205481565b34801561081d57600080fd5b506103ff61082c366004613468565b60009182526008602052604090912055565b34801561084a57600080fd5b5061085e610859366004613714565b611eef565b60405161042e9291906137a1565b34801561087857600080fd5b506107d461088736600461351a565b600b6020526000908152604090205460ff1681565b3480156108a857600080fd5b506104576108b736600461351a565b6000908152600c602052604090205490565b3480156108d557600080fd5b506104576108e436600461351a565b60046020526000908152604090205481565b34801561090257600080fd5b506107d461091136600461351a565b61201c565b34801561092257600080fd5b506103ff61206e565b34801561093757600080fd5b506013546105bb9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561096457600080fd5b506103ff6109733660046137bc565b612170565b34801561098457600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166105bb565b3480156109af57600080fd5b506104576109be36600461351a565b60056020526000908152604090205481565b3480156109dc57600080fd5b506103ff6109eb366004613468565b612201565b3480156109fc57600080fd5b506103ff610a0b366004613808565b612446565b348015610a1c57600080fd5b50601554610a3a906c01000000000000000000000000900460ff1681565b60405160ff909116815260200161042e565b348015610a5857600080fd5b506103ff610a67366004613468565b60009182526009602052604090912055565b348015610a8557600080fd5b506104e6610a9436600461351a565b600e6020526000908152604090205461ffff1681565b348015610ab657600080fd5b50610421610ac536600461351a565b61258f565b348015610ad657600080fd5b506104577f000000000000000000000000000000000000000000000000000000000000000081565b348015610b0a57600080fd5b506103ff610b1936600461361f565b6125f1565b348015610b2a57600080fd5b506103ff610b3936600461351a565b601455565b348015610b4a57600080fd5b506103ff610b59366004613838565b61265a565b348015610b6a57600080fd5b506103ff610b79366004613468565b60009182526007602052604090912055565b348015610b9757600080fd5b506103ff610ba636600461351a565b612705565b348015610bb757600080fd5b506103ff610bc6366004613690565b61278b565b348015610bd757600080fd5b506103ff610be636600461385d565b601580547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff92909216919091179055565b348015610c3157600080fd5b506103ff610c4036600461351a565b612825565b348015610c5157600080fd5b506103ff610c6036600461387a565b6015805460ff9092166c01000000000000000000000000027fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff909216919091179055565b348015610cb057600080fd5b50610519610cbf366004613468565b6128bd565b348015610cd057600080fd5b506103ff610cdf366004613690565b612926565b348015610cf057600080fd5b50610457610cff366004613468565b6129f1565b348015610d1057600080fd5b50610457610d1f36600461351a565b60096020526000908152604090205481565b348015610d3d57600080fd5b5061045760145481565b348015610d5357600080fd5b506103ff610d62366004613602565b612a22565b348015610d7357600080fd5b50610457610d8236600461351a565b60066020526000908152604090205481565b348015610da057600080fd5b50610457610daf36600461351a565b60026020526000908152604090205481565b6040805161018081018252600461014082019081527f746573740000000000000000000000000000000000000000000000000000000061016083015281528151602081810184526000808352818401929092523083850181905263ffffffff8b166060850152608084015260ff808a1660a08501528451808301865283815260c085015260e0840189905284519182019094529081526101008201526bffffffffffffffffffffffff8516610120820152601254601154919273ffffffffffffffffffffffffffffffffffffffff9182169263095ea7b3921690610ea7908c16886138c6565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526bffffffffffffffffffffffff1660248201526044016020604051808303816000875af1158015610f25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f49919061390a565b5060008860ff1667ffffffffffffffff811115610f6857610f6861326e565b604051908082528060200260200182016040528015610f91578160200160208202803683370190505b50905060005b8960ff168160ff16101561113a576000610fb084612a36565b90508860ff166001036110e8576040517f0d4a4fb1000000000000000000000000000000000000000000000000000000008152600481018290526000903090630d4a4fb190602401600060405180830381865afa158015611015573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261105b9190810190613972565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634ee88d35906110b490859085906004016139a7565b600060405180830381600087803b1580156110ce57600080fd5b505af11580156110e2573d6000803e3d6000fd5b50505050505b80838360ff16815181106110fe576110fe6139c0565b60209081029190910181019190915260009182526008815260408083208890556007909152902084905580611132816139ef565b915050610f97565b507f2ee10f7eb180441fb9fbba75b10c0162b5390b557712c93426243ca8f383c7118160405161116a919061348a565b60405180910390a1505050505050505050565b6060600061118b600f612b04565b90508084106111c6576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826000036111db576111d88482613a0e565b92505b60008367ffffffffffffffff8111156111f6576111f661326e565b60405190808252806020026020018201604052801561121f578160200160208202803683370190505b50905060005b848110156112715761124261123a8288613a21565b600f90612b0e565b828281518110611254576112546139c0565b60209081029190910101528061126981613a34565b915050611225565b509150505b92915050565b600d60205282600052604060002060205281600052604060002081815481106112a457600080fd5b9060005260206000200160009250925050505481565b606060006040518060c001604052803073ffffffffffffffffffffffffffffffffffffffff168152602001600160ff1681526020017f000000000000000000000000000000000000000000000000000000000000000081526020018460405160200161132891815260200190565b60405160208183030381529060405261134090613a6c565b81526020016000801b81526020016000801b8152509050806040516020016113c09190600060c08201905073ffffffffffffffffffffffffffffffffffffffff835116825260ff602084015116602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015292915050565b604051602081830303815290604052915050919050565b60006113e1612b1a565b604051308152909150819083907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf089060200160405180910390a35050565b6000828152600d6020908152604080832061ffff85168452825280832080548251818502810185019093528083528493849392919083018282801561148357602002820191906000526020600020905b81548152602001906001019080831161146f575b50505050509050611495818251612bbc565b92509250505b9250929050565b601180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117909155604080517fc3f909d400000000000000000000000000000000000000000000000000000000815281516000939263c3f909d492600480820193918290030181865afa158015611538573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155c9190613abc565b50601380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691909117909155601154604080517f1b6b6d230000000000000000000000000000000000000000000000000000000081529051939450911691631b6b6d23916004808201926020929091908290030181865afa1580156115ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116239190613aea565b601280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555050565b6000838152600c6020908152604080832080548251818502810185019093528083526116cd938301828280156116c157602002820191906000526020600020905b8154815260200190600101908083116116ad575b50505050508484612c41565b90505b9392505050565b8060005b818160ff16101561176b573063c8048022858560ff8516818110611701576117016139c0565b905060200201356040518263ffffffff1660e01b815260040161172691815260200190565b600060405180830381600087803b15801561174057600080fd5b505af1158015611754573d6000803e3d6000fd5b505050508080611763906139ef565b9150506116db565b50505050565b6000818152600e602052604081205461ffff1681805b8261ffff168161ffff16116117d2576000858152600d6020908152604080832061ffff851684529091529020546117be9083613a21565b9150806117ca81613b07565b915050611787565b509392505050565b60005a905060006117ed83850185613b28565b5060008181526005602090815260408083205460049092528220549293509190611815612b1a565b905082600003611835576000848152600560205260409020819055611990565b60008481526003602052604081205461184e8484613a0e565b6118589190613a0e565b6000868152600e6020908152604080832054600d835281842061ffff9091168085529083528184208054835181860281018601909452808452959650909491929091908301828280156118ca57602002820191906000526020600020905b8154815260200190600101908083116118b6575b505050505090507f000000000000000000000000000000000000000000000000000000000000000061ffff16815103611945578161190781613b07565b6000898152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff83161790559250505b506000868152600d6020908152604080832061ffff909416835292815282822080546001818101835591845282842001859055888352600c8252928220805493840181558252902001555b6000848152600660205260408120546119aa906001613a21565b60008681526006602090815260408083208490556004909152902083905590506119d48583612201565b6119df8587846125f1565b5050505050505050565b6000828152600d6020908152604080832061ffff85168452825291829020805483518184028101840190945280845260609392830182828015611a4b57602002820191906000526020600020905b815481526020019060010190808311611a37575b5050505050905092915050565b8160005b81811015611af55730635f17e616868684818110611a7c57611a7c6139c0565b90506020020135856040518363ffffffff1660e01b8152600401611ab092919091825263ffffffff16602082015260400190565b600060405180830381600087803b158015611aca57600080fd5b505af1158015611ade573d6000803e3d6000fd5b505050508080611aed90613a34565b915050611a5c565b5050505050565b6013546040517f06e3b632000000000000000000000000000000000000000000000000000000008152600060048201819052602482018190529173ffffffffffffffffffffffffffffffffffffffff16906306e3b63290604401600060405180830381865afa158015611b73573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611bb99190810190613b6f565b80519091506000611bc8612b1a565b905060005b8281101561176b576000848281518110611be957611be96139c0565b60209081029190910101516013546040517f5147cd590000000000000000000000000000000000000000000000000000000081526004810183905291925060009173ffffffffffffffffffffffffffffffffffffffff90911690635147cd5990602401602060405180830381865afa158015611c69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c8d9190613c15565b90508060ff16600103611cd257604051308152849083907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf089060200160405180910390a35b50508080611cdf90613a34565b915050611bcd565b611cef612da0565b6012546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d829190613c32565b6012546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810183905291925073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb906044016020604051808303816000875af1158015611dfa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1e919061390a565b5050565b60008281526003602090815260408083208490556005825280832083905560068252808320839055600c9091528120611e5a9161321b565b6000828152600e602052604081205461ffff16905b8161ffff168161ffff1611611eb6576000848152600d6020908152604080832061ffff851684529091528120611ea49161321b565b80611eae81613b07565b915050611e6f565b5050506000908152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055565b6000606060005a90506000611f068587018761351a565b60008181526009602090815260408083205460089092528220549293509190838367ffffffffffffffff811115611f3f57611f3f61326e565b6040519080825280601f01601f191660200182016040528015611f69576020820181803683370190505b50604051602001611f7b9291906139a7565b60405160208183030381529060405290506000611f96612b1a565b90506000611fa38661201c565b90505b835a611fb29089613a0e565b611fbe90612710613a21565b101561200c5781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690558161200481613c4b565b925050611fa6565b9a91995090975050505050505050565b600081815260056020526040812054810361203957506001919050565b60008281526003602090815260408083205460049092529091205461205c612b1a565b6120669190613a0e565b101592915050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146120f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6013546040517fcd7f71b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063cd7f71b5906121ca90869086908690600401613c80565b600060405180830381600087803b1580156121e457600080fd5b505af11580156121f8573d6000803e3d6000fd5b50505050505050565b60145460008381526002602052604090205461221d9083613a0e565b1115611e1e576013546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810184905260009173ffffffffffffffffffffffffffffffffffffffff169063c7c3a19a90602401600060405180830381865afa158015612293573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526122d99190810190613d02565b6013546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810186905291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063b657bc9c90602401602060405180830381865afa15801561234e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123729190613e21565b6015549091506123969082906c01000000000000000000000000900460ff166138c6565b6bffffffffffffffffffffffff1682606001516bffffffffffffffffffffffff16101561176b576015546123d99085906bffffffffffffffffffffffff16612446565b60008481526002602090815260409182902085905560155482518781526bffffffffffffffffffffffff909116918101919091529081018490527f49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c09060600160405180910390a150505050565b6012546013546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526bffffffffffffffffffffffff8416602482015291169063095ea7b3906044016020604051808303816000875af11580156124ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f2919061390a565b506013546040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063948108f790604401600060405180830381600087803b15801561257357600080fd5b505af1158015612587573d6000803e3d6000fd5b505050505050565b6000818152600c60209081526040918290208054835181840281018401909452808452606093928301828280156125e557602002820191906000526020600020905b8154815260200190600101908083116125d1575b50505050509050919050565b6000838152600760205260409020545b805a61260d9085613a0e565b61261990612710613a21565b101561176b5781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055612601565b6013546040517fa72aa27e0000000000000000000000000000000000000000000000000000000081526004810184905263ffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063a72aa27e90604401600060405180830381600087803b1580156126d257600080fd5b505af11580156126e6573d6000803e3d6000fd5b505050600092835250600a602052604090912063ffffffff9091169055565b6013546040517f744bfe610000000000000000000000000000000000000000000000000000000081526004810183905230602482015273ffffffffffffffffffffffffffffffffffffffff9091169063744bfe6190604401600060405180830381600087803b15801561277757600080fd5b505af1158015611af5573d6000803e3d6000fd5b8060005b818163ffffffff16101561176b573063af953a4a858563ffffffff85168181106127bb576127bb6139c0565b905060200201356040518263ffffffff1660e01b81526004016127e091815260200190565b600060405180830381600087803b1580156127fa57600080fd5b505af115801561280e573d6000803e3d6000fd5b50505050808061281d90613e3e565b91505061278f565b6013546040517fc80480220000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff9091169063c804802290602401600060405180830381600087803b15801561289157600080fd5b505af11580156128a5573d6000803e3d6000fd5b50505050611e1e81600f612e2390919063ffffffff16565b6000828152600c6020908152604080832080548251818502810185019093528083528493849392919083018282801561291557602002820191906000526020600020905b815481526020019060010190808311612901575b505050505090506114958185612bbc565b8060005b8181101561176b576000848483818110612946576129466139c0565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc828360405160200161297f91815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b81526004016129ab9291906139a7565b600060405180830381600087803b1580156129c557600080fd5b505af11580156129d9573d6000803e3d6000fd5b505050505080806129e990613a34565b91505061292a565b600c6020528160005260406000208181548110612a0d57600080fd5b90600052602060002001600091509150505481565b612a2a612da0565b612a3381612e2f565b50565b6011546040517f3f678e11000000000000000000000000000000000000000000000000000000008152600091829173ffffffffffffffffffffffffffffffffffffffff90911690633f678e1190612a91908690600401613e57565b6020604051808303816000875af1158015612ab0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ad49190613c32565b9050612ae1600f82612f24565b506060909201516000838152600a6020526040902063ffffffff90911690555090565b6000611276825490565b60006116d08383612f30565b60007f000000000000000000000000000000000000000000000000000000000000000015612bb757606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bb29190613c32565b905090565b504390565b815160009081908190841580612bd25750808510155b15612bdb578094505b60008092505b85831015612c3757866001612bf68585613a0e565b612c009190613a0e565b81518110612c1057612c106139c0565b602002602001015181612c239190613a21565b905082612c2f81613a34565b935050612be1565b9694955050505050565b82516000908190831580612c555750808410155b15612c5e578093505b60008467ffffffffffffffff811115612c7957612c7961326e565b604051908082528060200260200182016040528015612ca2578160200160208202803683370190505b509050600092505b84831015612d1057866001612cbf8585613a0e565b612cc99190613a0e565b81518110612cd957612cd96139c0565b6020026020010151818481518110612cf357612cf36139c0565b602090810291909101015282612d0881613a34565b935050612caa565b612d2981600060018451612d249190613a0e565b612f5a565b85606403612d62578060018251612d409190613a0e565b81518110612d5057612d506139c0565b602002602001015193505050506116d0565b806064825188612d729190613fa9565b612d7c9190614015565b81518110612d8c57612d8c6139c0565b602002602001015193505050509392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612e21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016120eb565b565b60006116d083836130d2565b3373ffffffffffffffffffffffffffffffffffffffff821603612eae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016120eb565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006116d083836131cc565b6000826000018281548110612f4757612f476139c0565b9060005260206000200154905092915050565b8181808203612f6a575050505050565b6000856002612f798787614029565b612f839190614049565b612f8d90876140b1565b81518110612f9d57612f9d6139c0565b602002602001015190505b8183136130ac575b80868481518110612fc357612fc36139c0565b60200260200101511015612fe35782612fdb816140d9565b935050612fb0565b858281518110612ff557612ff56139c0565b6020026020010151811015613016578161300e8161410a565b925050612fe3565b8183136130a75785828151811061302f5761302f6139c0565b6020026020010151868481518110613049576130496139c0565b6020026020010151878581518110613063576130636139c0565b6020026020010188858151811061307c5761307c6139c0565b60209081029190910101919091525282613095816140d9565b93505081806130a39061410a565b9250505b612fa8565b818512156130bf576130bf868684612f5a565b8383121561258757612587868486612f5a565b600081815260018301602052604081205480156131bb5760006130f6600183613a0e565b855490915060009061310a90600190613a0e565b905081811461316f57600086600001828154811061312a5761312a6139c0565b906000526020600020015490508087600001848154811061314d5761314d6139c0565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806131805761318061413b565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611276565b6000915050611276565b5092915050565b600081815260018301602052604081205461321357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611276565b506000611276565b5080546000825590600052602060002090810190612a3391905b808211156132495760008155600101613235565b5090565b60ff81168114612a3357600080fd5b63ffffffff81168114612a3357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff811182821017156132c1576132c161326e565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561330e5761330e61326e565b604052919050565b600067ffffffffffffffff8211156133305761333061326e565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261336d57600080fd5b813561338061337b82613316565b6132c7565b81815284602083860101111561339557600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff81168114612a3357600080fd5b600080600080600080600060e0888a0312156133e757600080fd5b87356133f28161324d565b965060208801356134028161325c565b955060408801356134128161324d565b9450606088013567ffffffffffffffff81111561342e57600080fd5b61343a8a828b0161335c565b945050608088013561344b816133b2565b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561347b57600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b818110156134c2578351835292840192918401916001016134a6565b50909695505050505050565b803561ffff811681146134e057600080fd5b919050565b6000806000606084860312156134fa57600080fd5b8335925061350a602085016134ce565b9150604084013590509250925092565b60006020828403121561352c57600080fd5b5035919050565b60005b8381101561354e578181015183820152602001613536565b50506000910152565b6000815180845261356f816020860160208601613533565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006116d06020830184613557565b600080604083850312156135c757600080fd5b823591506135d7602084016134ce565b90509250929050565b73ffffffffffffffffffffffffffffffffffffffff81168114612a3357600080fd5b60006020828403121561361457600080fd5b81356116d0816135e0565b60008060006060848603121561363457600080fd5b505081359360208301359350604090920135919050565b60008083601f84011261365d57600080fd5b50813567ffffffffffffffff81111561367557600080fd5b6020830191508360208260051b850101111561149b57600080fd5b600080602083850312156136a357600080fd5b823567ffffffffffffffff8111156136ba57600080fd5b6136c68582860161364b565b90969095509350505050565b60008083601f8401126136e457600080fd5b50813567ffffffffffffffff8111156136fc57600080fd5b60208301915083602082850101111561149b57600080fd5b6000806020838503121561372757600080fd5b823567ffffffffffffffff81111561373e57600080fd5b6136c6858286016136d2565b60008060006040848603121561375f57600080fd5b833567ffffffffffffffff81111561377657600080fd5b6137828682870161364b565b90945092505060208401356137968161325c565b809150509250925092565b82151581526040602082015260006116cd6040830184613557565b6000806000604084860312156137d157600080fd5b83359250602084013567ffffffffffffffff8111156137ef57600080fd5b6137fb868287016136d2565b9497909650939450505050565b6000806040838503121561381b57600080fd5b82359150602083013561382d816133b2565b809150509250929050565b6000806040838503121561384b57600080fd5b82359150602083013561382d8161325c565b60006020828403121561386f57600080fd5b81356116d0816133b2565b60006020828403121561388c57600080fd5b81356116d08161324d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006bffffffffffffffffffffffff808316818516818304811182151516156138f1576138f1613897565b02949350505050565b805180151581146134e057600080fd5b60006020828403121561391c57600080fd5b6116d0826138fa565b600082601f83011261393657600080fd5b815161394461337b82613316565b81815284602083860101111561395957600080fd5b61396a826020830160208701613533565b949350505050565b60006020828403121561398457600080fd5b815167ffffffffffffffff81111561399b57600080fd5b61396a84828501613925565b8281526040602082015260006116cd6040830184613557565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff821660ff8103613a0557613a05613897565b60010192915050565b8181038181111561127657611276613897565b8082018082111561127657611276613897565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613a6557613a65613897565b5060010190565b80516020808301519190811015613aab577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b80516134e0816135e0565b60008060408385031215613acf57600080fd5b8251613ada816135e0565b6020939093015192949293505050565b600060208284031215613afc57600080fd5b81516116d0816135e0565b600061ffff808316818103613b1e57613b1e613897565b6001019392505050565b60008060408385031215613b3b57600080fd5b82359150602083013567ffffffffffffffff811115613b5957600080fd5b613b658582860161335c565b9150509250929050565b60006020808385031215613b8257600080fd5b825167ffffffffffffffff80821115613b9a57600080fd5b818501915085601f830112613bae57600080fd5b815181811115613bc057613bc061326e565b8060051b9150613bd18483016132c7565b8181529183018401918481019088841115613beb57600080fd5b938501935b83851015613c0957845182529385019390850190613bf0565b98975050505050505050565b600060208284031215613c2757600080fd5b81516116d08161324d565b600060208284031215613c4457600080fd5b5051919050565b600081613c5a57613c5a613897565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b83815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b80516134e08161325c565b80516134e0816133b2565b805167ffffffffffffffff811681146134e057600080fd5b600060208284031215613d1457600080fd5b815167ffffffffffffffff80821115613d2c57600080fd5b908301906101408286031215613d4157600080fd5b613d4961329d565b613d5283613ab1565b8152613d6060208401613cd4565b6020820152604083015182811115613d7757600080fd5b613d8387828601613925565b604083015250613d9560608401613cdf565b6060820152613da660808401613ab1565b6080820152613db760a08401613cea565b60a0820152613dc860c08401613cd4565b60c0820152613dd960e08401613cdf565b60e0820152610100613dec8185016138fa565b908201526101208381015183811115613e0457600080fd5b613e1088828701613925565b918301919091525095945050505050565b600060208284031215613e3357600080fd5b81516116d0816133b2565b600063ffffffff808316818103613b1e57613b1e613897565b6020815260008251610140806020850152613e76610160850183613557565b915060208501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe080868503016040870152613eb28483613557565b935060408701519150613edd606087018373ffffffffffffffffffffffffffffffffffffffff169052565b606087015163ffffffff811660808801529150608087015173ffffffffffffffffffffffffffffffffffffffff811660a0880152915060a087015160ff811660c0880152915060c08701519150808685030160e0870152613f3e8483613557565b935060e08701519150610100818786030181880152613f5d8584613557565b945080880151925050610120818786030181880152613f7c8584613557565b94508088015192505050613f9f828601826bffffffffffffffffffffffff169052565b5090949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613fe157613fe1613897565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261402457614024613fe6565b500490565b81810360008312801583831316838312821617156131c5576131c5613897565b60008261405857614058613fe6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156140ac576140ac613897565b500590565b80820182811260008312801582168215821617156140d1576140d1613897565b505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613a6557613a65613897565b60007f80000000000000000000000000000000000000000000000000000000000000008203613c5a57613c5a613897565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000810000a", } var VerifiableLoadUpkeepABI = VerifiableLoadUpkeepMetaData.ABI var VerifiableLoadUpkeepBin = VerifiableLoadUpkeepMetaData.Bin -func DeployVerifiableLoadUpkeep(auth *bind.TransactOpts, backend bind.ContractBackend, registrarAddress common.Address, useArb bool) (common.Address, *types.Transaction, *VerifiableLoadUpkeep, error) { +func DeployVerifiableLoadUpkeep(auth *bind.TransactOpts, backend bind.ContractBackend, _registrar common.Address, _useArb bool) (common.Address, *types.Transaction, *VerifiableLoadUpkeep, error) { parsed, err := VerifiableLoadUpkeepMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -48,7 +48,7 @@ func DeployVerifiableLoadUpkeep(auth *bind.TransactOpts, backend bind.ContractBa return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(VerifiableLoadUpkeepBin), backend, registrarAddress, useArb) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(VerifiableLoadUpkeepBin), backend, _registrar, _useArb) if err != nil { return common.Address{}, nil, nil, err } @@ -193,28 +193,6 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) BUCKETSIZE() (ui return _VerifiableLoadUpkeep.Contract.BUCKETSIZE(&_VerifiableLoadUpkeep.CallOpts) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) TIMESTAMPINTERVAL(opts *bind.CallOpts) (uint16, error) { - var out []interface{} - err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "TIMESTAMP_INTERVAL") - - if err != nil { - return *new(uint16), err - } - - out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) - - return out0, err - -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) TIMESTAMPINTERVAL() (uint16, error) { - return _VerifiableLoadUpkeep.Contract.TIMESTAMPINTERVAL(&_VerifiableLoadUpkeep.CallOpts) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) TIMESTAMPINTERVAL() (uint16, error) { - return _VerifiableLoadUpkeep.Contract.TIMESTAMPINTERVAL(&_VerifiableLoadUpkeep.CallOpts) -} - func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) AddLinkAmount(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "addLinkAmount") @@ -281,28 +259,6 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) Buckets(arg0 *bi return _VerifiableLoadUpkeep.Contract.Buckets(&_VerifiableLoadUpkeep.CallOpts, arg0) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) CheckDatas(opts *bind.CallOpts, arg0 *big.Int) ([]byte, error) { - var out []interface{} - err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "checkDatas", arg0) - - if err != nil { - return *new([]byte), err - } - - out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) - - return out0, err - -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) CheckDatas(arg0 *big.Int) ([]byte, error) { - return _VerifiableLoadUpkeep.Contract.CheckDatas(&_VerifiableLoadUpkeep.CallOpts, arg0) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) CheckDatas(arg0 *big.Int) ([]byte, error) { - return _VerifiableLoadUpkeep.Contract.CheckDatas(&_VerifiableLoadUpkeep.CallOpts, arg0) -} - func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) CheckGasToBurns(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { var out []interface{} err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "checkGasToBurns", arg0) @@ -413,6 +369,28 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) Eligible(upkeepI return _VerifiableLoadUpkeep.Contract.Eligible(&_VerifiableLoadUpkeep.CallOpts, upkeepId) } +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) EmittedSig(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "emittedSig") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) EmittedSig() ([32]byte, error) { + return _VerifiableLoadUpkeep.Contract.EmittedSig(&_VerifiableLoadUpkeep.CallOpts) +} + +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) EmittedSig() ([32]byte, error) { + return _VerifiableLoadUpkeep.Contract.EmittedSig(&_VerifiableLoadUpkeep.CallOpts) +} + func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) FirstPerformBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { var out []interface{} err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "firstPerformBlocks", arg0) @@ -567,138 +545,26 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetDelaysLength( return _VerifiableLoadUpkeep.Contract.GetDelaysLength(&_VerifiableLoadUpkeep.CallOpts, upkeepId) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetDelaysLengthAtBucket(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) (*big.Int, error) { - var out []interface{} - err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getDelaysLengthAtBucket", upkeepId, bucket) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetDelaysLengthAtBucket(upkeepId *big.Int, bucket uint16) (*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetDelaysLengthAtBucket(&_VerifiableLoadUpkeep.CallOpts, upkeepId, bucket) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetDelaysLengthAtBucket(upkeepId *big.Int, bucket uint16) (*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetDelaysLengthAtBucket(&_VerifiableLoadUpkeep.CallOpts, upkeepId, bucket) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetDelaysLengthAtTimestampBucket(opts *bind.CallOpts, upkeepId *big.Int, timestampBucket uint16) (*big.Int, error) { - var out []interface{} - err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getDelaysLengthAtTimestampBucket", upkeepId, timestampBucket) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetDelaysLengthAtTimestampBucket(upkeepId *big.Int, timestampBucket uint16) (*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetDelaysLengthAtTimestampBucket(&_VerifiableLoadUpkeep.CallOpts, upkeepId, timestampBucket) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetDelaysLengthAtTimestampBucket(upkeepId *big.Int, timestampBucket uint16) (*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetDelaysLengthAtTimestampBucket(&_VerifiableLoadUpkeep.CallOpts, upkeepId, timestampBucket) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetPxBucketedDelaysForAllUpkeeps(opts *bind.CallOpts, p *big.Int) ([]*big.Int, []*big.Int, error) { - var out []interface{} - err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getPxBucketedDelaysForAllUpkeeps", p) - - if err != nil { - return *new([]*big.Int), *new([]*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) - out1 := *abi.ConvertType(out[1], new([]*big.Int)).(*[]*big.Int) - - return out0, out1, err - -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetPxBucketedDelaysForAllUpkeeps(p *big.Int) ([]*big.Int, []*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetPxBucketedDelaysForAllUpkeeps(&_VerifiableLoadUpkeep.CallOpts, p) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetPxBucketedDelaysForAllUpkeeps(p *big.Int) ([]*big.Int, []*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetPxBucketedDelaysForAllUpkeeps(&_VerifiableLoadUpkeep.CallOpts, p) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetPxDelayForAllUpkeeps(opts *bind.CallOpts, p *big.Int) ([]*big.Int, []*big.Int, error) { - var out []interface{} - err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getPxDelayForAllUpkeeps", p) - - if err != nil { - return *new([]*big.Int), *new([]*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) - out1 := *abi.ConvertType(out[1], new([]*big.Int)).(*[]*big.Int) - - return out0, out1, err - -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetPxDelayForAllUpkeeps(p *big.Int) ([]*big.Int, []*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetPxDelayForAllUpkeeps(&_VerifiableLoadUpkeep.CallOpts, p) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetPxDelayForAllUpkeeps(p *big.Int) ([]*big.Int, []*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetPxDelayForAllUpkeeps(&_VerifiableLoadUpkeep.CallOpts, p) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetPxDelayInBucket(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, bucket uint16) (*big.Int, error) { - var out []interface{} - err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getPxDelayInBucket", upkeepId, p, bucket) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetPxDelayInBucket(upkeepId *big.Int, p *big.Int, bucket uint16) (*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetPxDelayInBucket(&_VerifiableLoadUpkeep.CallOpts, upkeepId, p, bucket) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetPxDelayInBucket(upkeepId *big.Int, p *big.Int, bucket uint16) (*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetPxDelayInBucket(&_VerifiableLoadUpkeep.CallOpts, upkeepId, p, bucket) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetPxDelayInTimestampBucket(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, timestampBucket uint16) (*big.Int, error) { +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetLogTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) { var out []interface{} - err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getPxDelayInTimestampBucket", upkeepId, p, timestampBucket) + err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getLogTriggerConfig", upkeepId) if err != nil { - return *new(*big.Int), err + return *new([]byte), err } - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) return out0, err } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetPxDelayInTimestampBucket(upkeepId *big.Int, p *big.Int, timestampBucket uint16) (*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetPxDelayInTimestampBucket(&_VerifiableLoadUpkeep.CallOpts, upkeepId, p, timestampBucket) +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetLogTriggerConfig(upkeepId *big.Int) ([]byte, error) { + return _VerifiableLoadUpkeep.Contract.GetLogTriggerConfig(&_VerifiableLoadUpkeep.CallOpts, upkeepId) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetPxDelayInTimestampBucket(upkeepId *big.Int, p *big.Int, timestampBucket uint16) (*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetPxDelayInTimestampBucket(&_VerifiableLoadUpkeep.CallOpts, upkeepId, p, timestampBucket) +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetLogTriggerConfig(upkeepId *big.Int) ([]byte, error) { + return _VerifiableLoadUpkeep.Contract.GetLogTriggerConfig(&_VerifiableLoadUpkeep.CallOpts, upkeepId) } func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetPxDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, n *big.Int) (*big.Int, error) { @@ -723,29 +589,6 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetPxDelayLastNP return _VerifiableLoadUpkeep.Contract.GetPxDelayLastNPerforms(&_VerifiableLoadUpkeep.CallOpts, upkeepId, p, n) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetSumBucketedDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) { - var out []interface{} - err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getSumBucketedDelayLastNPerforms", upkeepId, n) - - if err != nil { - return *new(*big.Int), *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - - return out0, out1, err - -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetSumBucketedDelayLastNPerforms(upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetSumBucketedDelayLastNPerforms(&_VerifiableLoadUpkeep.CallOpts, upkeepId, n) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetSumBucketedDelayLastNPerforms(upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetSumBucketedDelayLastNPerforms(&_VerifiableLoadUpkeep.CallOpts, upkeepId, n) -} - func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetSumDelayInBucket(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) (*big.Int, *big.Int, error) { var out []interface{} err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getSumDelayInBucket", upkeepId, bucket) @@ -769,29 +612,6 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetSumDelayInBuc return _VerifiableLoadUpkeep.Contract.GetSumDelayInBucket(&_VerifiableLoadUpkeep.CallOpts, upkeepId, bucket) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetSumDelayInTimestampBucket(opts *bind.CallOpts, upkeepId *big.Int, timestampBucket uint16) (*big.Int, *big.Int, error) { - var out []interface{} - err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getSumDelayInTimestampBucket", upkeepId, timestampBucket) - - if err != nil { - return *new(*big.Int), *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - - return out0, out1, err - -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetSumDelayInTimestampBucket(upkeepId *big.Int, timestampBucket uint16) (*big.Int, *big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetSumDelayInTimestampBucket(&_VerifiableLoadUpkeep.CallOpts, upkeepId, timestampBucket) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetSumDelayInTimestampBucket(upkeepId *big.Int, timestampBucket uint16) (*big.Int, *big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetSumDelayInTimestampBucket(&_VerifiableLoadUpkeep.CallOpts, upkeepId, timestampBucket) -} - func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetSumDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) { var out []interface{} err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getSumDelayLastNPerforms", upkeepId, n) @@ -815,73 +635,6 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetSumDelayLastN return _VerifiableLoadUpkeep.Contract.GetSumDelayLastNPerforms(&_VerifiableLoadUpkeep.CallOpts, upkeepId, n) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetSumTimestampBucketedDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) { - var out []interface{} - err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getSumTimestampBucketedDelayLastNPerforms", upkeepId, n) - - if err != nil { - return *new(*big.Int), *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - - return out0, out1, err - -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetSumTimestampBucketedDelayLastNPerforms(upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetSumTimestampBucketedDelayLastNPerforms(&_VerifiableLoadUpkeep.CallOpts, upkeepId, n) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetSumTimestampBucketedDelayLastNPerforms(upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetSumTimestampBucketedDelayLastNPerforms(&_VerifiableLoadUpkeep.CallOpts, upkeepId, n) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetTimestampBucketedDelaysLength(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error) { - var out []interface{} - err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getTimestampBucketedDelaysLength", upkeepId) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetTimestampBucketedDelaysLength(upkeepId *big.Int) (*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetTimestampBucketedDelaysLength(&_VerifiableLoadUpkeep.CallOpts, upkeepId) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetTimestampBucketedDelaysLength(upkeepId *big.Int) (*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetTimestampBucketedDelaysLength(&_VerifiableLoadUpkeep.CallOpts, upkeepId) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetTimestampDelays(opts *bind.CallOpts, upkeepId *big.Int, timestampBucket uint16) ([]*big.Int, error) { - var out []interface{} - err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getTimestampDelays", upkeepId, timestampBucket) - - if err != nil { - return *new([]*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) - - return out0, err - -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetTimestampDelays(upkeepId *big.Int, timestampBucket uint16) ([]*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetTimestampDelays(&_VerifiableLoadUpkeep.CallOpts, upkeepId, timestampBucket) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetTimestampDelays(upkeepId *big.Int, timestampBucket uint16) ([]*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.GetTimestampDelays(&_VerifiableLoadUpkeep.CallOpts, upkeepId, timestampBucket) -} - func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) Intervals(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { var out []interface{} err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "intervals", arg0) @@ -1102,162 +855,108 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) Registry() (comm return _VerifiableLoadUpkeep.Contract.Registry(&_VerifiableLoadUpkeep.CallOpts) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) TimestampBuckets(opts *bind.CallOpts, arg0 *big.Int) (uint16, error) { +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) UpkeepTopUpCheckInterval(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "timestampBuckets", arg0) + err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "upkeepTopUpCheckInterval") if err != nil { - return *new(uint16), err + return *new(*big.Int), err } - out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) return out0, err } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) TimestampBuckets(arg0 *big.Int) (uint16, error) { - return _VerifiableLoadUpkeep.Contract.TimestampBuckets(&_VerifiableLoadUpkeep.CallOpts, arg0) +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) UpkeepTopUpCheckInterval() (*big.Int, error) { + return _VerifiableLoadUpkeep.Contract.UpkeepTopUpCheckInterval(&_VerifiableLoadUpkeep.CallOpts) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) TimestampBuckets(arg0 *big.Int) (uint16, error) { - return _VerifiableLoadUpkeep.Contract.TimestampBuckets(&_VerifiableLoadUpkeep.CallOpts, arg0) +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) UpkeepTopUpCheckInterval() (*big.Int, error) { + return _VerifiableLoadUpkeep.Contract.UpkeepTopUpCheckInterval(&_VerifiableLoadUpkeep.CallOpts) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) TimestampDelays(opts *bind.CallOpts, arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error) { +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) UseArbitrumBlockNum(opts *bind.CallOpts) (bool, error) { var out []interface{} - err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "timestampDelays", arg0, arg1, arg2) + err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "useArbitrumBlockNum") if err != nil { - return *new(*big.Int), err + return *new(bool), err } - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) return out0, err } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) TimestampDelays(arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.TimestampDelays(&_VerifiableLoadUpkeep.CallOpts, arg0, arg1, arg2) +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) UseArbitrumBlockNum() (bool, error) { + return _VerifiableLoadUpkeep.Contract.UseArbitrumBlockNum(&_VerifiableLoadUpkeep.CallOpts) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) TimestampDelays(arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.TimestampDelays(&_VerifiableLoadUpkeep.CallOpts, arg0, arg1, arg2) +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) UseArbitrumBlockNum() (bool, error) { + return _VerifiableLoadUpkeep.Contract.UseArbitrumBlockNum(&_VerifiableLoadUpkeep.CallOpts) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) Timestamps(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { - var out []interface{} - err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "timestamps", arg0, arg1) +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.contract.Transact(opts, "acceptOwnership") +} - if err != nil { - return *new(*big.Int), err - } +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) AcceptOwnership() (*types.Transaction, error) { + return _VerifiableLoadUpkeep.Contract.AcceptOwnership(&_VerifiableLoadUpkeep.TransactOpts) +} - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _VerifiableLoadUpkeep.Contract.AcceptOwnership(&_VerifiableLoadUpkeep.TransactOpts) +} - return out0, err +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) AddFunds(opts *bind.TransactOpts, upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.contract.Transact(opts, "addFunds", upkeepId, amount) +} +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) AddFunds(upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.Contract.AddFunds(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, amount) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) Timestamps(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.Timestamps(&_VerifiableLoadUpkeep.CallOpts, arg0, arg1) +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) AddFunds(upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.Contract.AddFunds(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, amount) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) Timestamps(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.Timestamps(&_VerifiableLoadUpkeep.CallOpts, arg0, arg1) +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) BatchCancelUpkeeps(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.contract.Transact(opts, "batchCancelUpkeeps", upkeepIds) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) UpkeepTopUpCheckInterval(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "upkeepTopUpCheckInterval") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) UpkeepTopUpCheckInterval() (*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.UpkeepTopUpCheckInterval(&_VerifiableLoadUpkeep.CallOpts) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) UpkeepTopUpCheckInterval() (*big.Int, error) { - return _VerifiableLoadUpkeep.Contract.UpkeepTopUpCheckInterval(&_VerifiableLoadUpkeep.CallOpts) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) UseArbitrumBlockNum(opts *bind.CallOpts) (bool, error) { - var out []interface{} - err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "useArbitrumBlockNum") - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) UseArbitrumBlockNum() (bool, error) { - return _VerifiableLoadUpkeep.Contract.UseArbitrumBlockNum(&_VerifiableLoadUpkeep.CallOpts) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) UseArbitrumBlockNum() (bool, error) { - return _VerifiableLoadUpkeep.Contract.UseArbitrumBlockNum(&_VerifiableLoadUpkeep.CallOpts) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _VerifiableLoadUpkeep.contract.Transact(opts, "acceptOwnership") -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) AcceptOwnership() (*types.Transaction, error) { - return _VerifiableLoadUpkeep.Contract.AcceptOwnership(&_VerifiableLoadUpkeep.TransactOpts) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) AcceptOwnership() (*types.Transaction, error) { - return _VerifiableLoadUpkeep.Contract.AcceptOwnership(&_VerifiableLoadUpkeep.TransactOpts) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) AddFunds(opts *bind.TransactOpts, upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) { - return _VerifiableLoadUpkeep.contract.Transact(opts, "addFunds", upkeepId, amount) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) AddFunds(upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) { - return _VerifiableLoadUpkeep.Contract.AddFunds(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, amount) +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) BatchCancelUpkeeps(upkeepIds []*big.Int) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.Contract.BatchCancelUpkeeps(&_VerifiableLoadUpkeep.TransactOpts, upkeepIds) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) AddFunds(upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) { - return _VerifiableLoadUpkeep.Contract.AddFunds(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, amount) +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) BatchCancelUpkeeps(upkeepIds []*big.Int) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.Contract.BatchCancelUpkeeps(&_VerifiableLoadUpkeep.TransactOpts, upkeepIds) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) BatchCancelUpkeeps(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error) { - return _VerifiableLoadUpkeep.contract.Transact(opts, "batchCancelUpkeeps", upkeepIds) +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) BatchRegisterUpkeeps(opts *bind.TransactOpts, number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.contract.Transact(opts, "batchRegisterUpkeeps", number, gasLimit, triggerType, triggerConfig, amount, checkGasToBurn, performGasToBurn) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) BatchCancelUpkeeps(upkeepIds []*big.Int) (*types.Transaction, error) { - return _VerifiableLoadUpkeep.Contract.BatchCancelUpkeeps(&_VerifiableLoadUpkeep.TransactOpts, upkeepIds) +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) BatchRegisterUpkeeps(number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.Contract.BatchRegisterUpkeeps(&_VerifiableLoadUpkeep.TransactOpts, number, gasLimit, triggerType, triggerConfig, amount, checkGasToBurn, performGasToBurn) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) BatchCancelUpkeeps(upkeepIds []*big.Int) (*types.Transaction, error) { - return _VerifiableLoadUpkeep.Contract.BatchCancelUpkeeps(&_VerifiableLoadUpkeep.TransactOpts, upkeepIds) +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) BatchRegisterUpkeeps(number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.Contract.BatchRegisterUpkeeps(&_VerifiableLoadUpkeep.TransactOpts, number, gasLimit, triggerType, triggerConfig, amount, checkGasToBurn, performGasToBurn) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) BatchRegisterUpkeeps(opts *bind.TransactOpts, number uint8, gasLimit uint32, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) { - return _VerifiableLoadUpkeep.contract.Transact(opts, "batchRegisterUpkeeps", number, gasLimit, amount, checkGasToBurn, performGasToBurn) +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) BatchSendLogs(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.contract.Transact(opts, "batchSendLogs") } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) BatchRegisterUpkeeps(number uint8, gasLimit uint32, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) { - return _VerifiableLoadUpkeep.Contract.BatchRegisterUpkeeps(&_VerifiableLoadUpkeep.TransactOpts, number, gasLimit, amount, checkGasToBurn, performGasToBurn) +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) BatchSendLogs() (*types.Transaction, error) { + return _VerifiableLoadUpkeep.Contract.BatchSendLogs(&_VerifiableLoadUpkeep.TransactOpts) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) BatchRegisterUpkeeps(number uint8, gasLimit uint32, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) { - return _VerifiableLoadUpkeep.Contract.BatchRegisterUpkeeps(&_VerifiableLoadUpkeep.TransactOpts, number, gasLimit, amount, checkGasToBurn, performGasToBurn) +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) BatchSendLogs() (*types.Transaction, error) { + return _VerifiableLoadUpkeep.Contract.BatchSendLogs(&_VerifiableLoadUpkeep.TransactOpts) } func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) BatchSetIntervals(opts *bind.TransactOpts, upkeepIds []*big.Int, interval uint32) (*types.Transaction, error) { @@ -1296,6 +995,18 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) BatchWithdra return _VerifiableLoadUpkeep.Contract.BatchWithdrawLinks(&_VerifiableLoadUpkeep.TransactOpts, upkeepIds) } +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) BurnPerformGas(opts *bind.TransactOpts, upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.contract.Transact(opts, "burnPerformGas", upkeepId, startGas, blockNum) +} + +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) BurnPerformGas(upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.Contract.BurnPerformGas(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, startGas, blockNum) +} + +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) BurnPerformGas(upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.Contract.BurnPerformGas(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, startGas, blockNum) +} + func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) CancelUpkeep(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) { return _VerifiableLoadUpkeep.contract.Transact(opts, "cancelUpkeep", upkeepId) } @@ -1332,6 +1043,18 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) PerformUpkee return _VerifiableLoadUpkeep.Contract.PerformUpkeep(&_VerifiableLoadUpkeep.TransactOpts, performData) } +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) SendLog(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.contract.Transact(opts, "sendLog", upkeepId) +} + +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) SendLog(upkeepId *big.Int) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.Contract.SendLog(&_VerifiableLoadUpkeep.TransactOpts, upkeepId) +} + +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) SendLog(upkeepId *big.Int) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.Contract.SendLog(&_VerifiableLoadUpkeep.TransactOpts, upkeepId) +} + func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) SetAddLinkAmount(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { return _VerifiableLoadUpkeep.contract.Transact(opts, "setAddLinkAmount", amount) } @@ -1440,6 +1163,18 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) SetUpkeepTop return _VerifiableLoadUpkeep.Contract.SetUpkeepTopUpCheckInterval(&_VerifiableLoadUpkeep.TransactOpts, newInterval) } +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) TopUpFund(opts *bind.TransactOpts, upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.contract.Transact(opts, "topUpFund", upkeepId, blockNum) +} + +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) TopUpFund(upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.Contract.TopUpFund(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, blockNum) +} + +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) TopUpFund(upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.Contract.TopUpFund(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, blockNum) +} + func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { return _VerifiableLoadUpkeep.contract.Transact(opts, "transferOwnership", to) } @@ -1480,536 +1215,28 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) WithdrawLinks0(opts return _VerifiableLoadUpkeep.contract.Transact(opts, "withdrawLinks0", upkeepId) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) WithdrawLinks0(upkeepId *big.Int) (*types.Transaction, error) { - return _VerifiableLoadUpkeep.Contract.WithdrawLinks0(&_VerifiableLoadUpkeep.TransactOpts, upkeepId) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) WithdrawLinks0(upkeepId *big.Int) (*types.Transaction, error) { - return _VerifiableLoadUpkeep.Contract.WithdrawLinks0(&_VerifiableLoadUpkeep.TransactOpts, upkeepId) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { - return _VerifiableLoadUpkeep.contract.RawTransact(opts, nil) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) Receive() (*types.Transaction, error) { - return _VerifiableLoadUpkeep.Contract.Receive(&_VerifiableLoadUpkeep.TransactOpts) -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) Receive() (*types.Transaction, error) { - return _VerifiableLoadUpkeep.Contract.Receive(&_VerifiableLoadUpkeep.TransactOpts) -} - -type VerifiableLoadUpkeepFundsAddedIterator struct { - Event *VerifiableLoadUpkeepFundsAdded - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VerifiableLoadUpkeepFundsAddedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VerifiableLoadUpkeepFundsAdded) - 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(VerifiableLoadUpkeepFundsAdded) - 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 *VerifiableLoadUpkeepFundsAddedIterator) Error() error { - return it.fail -} - -func (it *VerifiableLoadUpkeepFundsAddedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VerifiableLoadUpkeepFundsAdded struct { - UpkeepId *big.Int - Amount *big.Int - Raw types.Log -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterFundsAdded(opts *bind.FilterOpts) (*VerifiableLoadUpkeepFundsAddedIterator, error) { - - logs, sub, err := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "FundsAdded") - if err != nil { - return nil, err - } - return &VerifiableLoadUpkeepFundsAddedIterator{contract: _VerifiableLoadUpkeep.contract, event: "FundsAdded", logs: logs, sub: sub}, nil -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchFundsAdded(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepFundsAdded) (event.Subscription, error) { - - logs, sub, err := _VerifiableLoadUpkeep.contract.WatchLogs(opts, "FundsAdded") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(VerifiableLoadUpkeepFundsAdded) - if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "FundsAdded", 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 (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseFundsAdded(log types.Log) (*VerifiableLoadUpkeepFundsAdded, error) { - event := new(VerifiableLoadUpkeepFundsAdded) - if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "FundsAdded", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VerifiableLoadUpkeepInsufficientFundsIterator struct { - Event *VerifiableLoadUpkeepInsufficientFunds - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VerifiableLoadUpkeepInsufficientFundsIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VerifiableLoadUpkeepInsufficientFunds) - 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(VerifiableLoadUpkeepInsufficientFunds) - 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 *VerifiableLoadUpkeepInsufficientFundsIterator) Error() error { - return it.fail -} - -func (it *VerifiableLoadUpkeepInsufficientFundsIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VerifiableLoadUpkeepInsufficientFunds struct { - Balance *big.Int - BlockNum *big.Int - Raw types.Log -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterInsufficientFunds(opts *bind.FilterOpts) (*VerifiableLoadUpkeepInsufficientFundsIterator, error) { - - logs, sub, err := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "InsufficientFunds") - if err != nil { - return nil, err - } - return &VerifiableLoadUpkeepInsufficientFundsIterator{contract: _VerifiableLoadUpkeep.contract, event: "InsufficientFunds", logs: logs, sub: sub}, nil -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchInsufficientFunds(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepInsufficientFunds) (event.Subscription, error) { - - logs, sub, err := _VerifiableLoadUpkeep.contract.WatchLogs(opts, "InsufficientFunds") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(VerifiableLoadUpkeepInsufficientFunds) - if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "InsufficientFunds", 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 (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseInsufficientFunds(log types.Log) (*VerifiableLoadUpkeepInsufficientFunds, error) { - event := new(VerifiableLoadUpkeepInsufficientFunds) - if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "InsufficientFunds", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VerifiableLoadUpkeepOwnershipTransferRequestedIterator struct { - Event *VerifiableLoadUpkeepOwnershipTransferRequested - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VerifiableLoadUpkeepOwnershipTransferRequestedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VerifiableLoadUpkeepOwnershipTransferRequested) - 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(VerifiableLoadUpkeepOwnershipTransferRequested) - 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 *VerifiableLoadUpkeepOwnershipTransferRequestedIterator) Error() error { - return it.fail -} - -func (it *VerifiableLoadUpkeepOwnershipTransferRequestedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VerifiableLoadUpkeepOwnershipTransferRequested struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadUpkeepOwnershipTransferRequestedIterator, 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 := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) - if err != nil { - return nil, err - } - return &VerifiableLoadUpkeepOwnershipTransferRequestedIterator{contract: _VerifiableLoadUpkeep.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepOwnershipTransferRequested, 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 := _VerifiableLoadUpkeep.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(VerifiableLoadUpkeepOwnershipTransferRequested) - if err := _VerifiableLoadUpkeep.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 (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseOwnershipTransferRequested(log types.Log) (*VerifiableLoadUpkeepOwnershipTransferRequested, error) { - event := new(VerifiableLoadUpkeepOwnershipTransferRequested) - if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VerifiableLoadUpkeepOwnershipTransferredIterator struct { - Event *VerifiableLoadUpkeepOwnershipTransferred - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VerifiableLoadUpkeepOwnershipTransferredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VerifiableLoadUpkeepOwnershipTransferred) - 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(VerifiableLoadUpkeepOwnershipTransferred) - 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 *VerifiableLoadUpkeepOwnershipTransferredIterator) Error() error { - return it.fail -} - -func (it *VerifiableLoadUpkeepOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VerifiableLoadUpkeepOwnershipTransferred struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadUpkeepOwnershipTransferredIterator, 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 := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) - if err != nil { - return nil, err - } - return &VerifiableLoadUpkeepOwnershipTransferredIterator{contract: _VerifiableLoadUpkeep.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil -} - -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepOwnershipTransferred, 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 := _VerifiableLoadUpkeep.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(VerifiableLoadUpkeepOwnershipTransferred) - if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return err - } - event.Raw = log +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) WithdrawLinks0(upkeepId *big.Int) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.Contract.WithdrawLinks0(&_VerifiableLoadUpkeep.TransactOpts, upkeepId) +} - 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 (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) WithdrawLinks0(upkeepId *big.Int) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.Contract.WithdrawLinks0(&_VerifiableLoadUpkeep.TransactOpts, upkeepId) } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseOwnershipTransferred(log types.Log) (*VerifiableLoadUpkeepOwnershipTransferred, error) { - event := new(VerifiableLoadUpkeepOwnershipTransferred) - if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VerifiableLoadUpkeep.contract.RawTransact(opts, nil) +} + +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) Receive() (*types.Transaction, error) { + return _VerifiableLoadUpkeep.Contract.Receive(&_VerifiableLoadUpkeep.TransactOpts) +} + +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) Receive() (*types.Transaction, error) { + return _VerifiableLoadUpkeep.Contract.Receive(&_VerifiableLoadUpkeep.TransactOpts) } -type VerifiableLoadUpkeepPerformingUpkeepIterator struct { - Event *VerifiableLoadUpkeepPerformingUpkeep +type VerifiableLoadUpkeepLogEmittedIterator struct { + Event *VerifiableLoadUpkeepLogEmitted contract *bind.BoundContract event string @@ -2020,7 +1247,7 @@ type VerifiableLoadUpkeepPerformingUpkeepIterator struct { fail error } -func (it *VerifiableLoadUpkeepPerformingUpkeepIterator) Next() bool { +func (it *VerifiableLoadUpkeepLogEmittedIterator) Next() bool { if it.fail != nil { return false @@ -2029,7 +1256,7 @@ func (it *VerifiableLoadUpkeepPerformingUpkeepIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(VerifiableLoadUpkeepPerformingUpkeep) + it.Event = new(VerifiableLoadUpkeepLogEmitted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2044,7 +1271,7 @@ func (it *VerifiableLoadUpkeepPerformingUpkeepIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(VerifiableLoadUpkeepPerformingUpkeep) + it.Event = new(VerifiableLoadUpkeepLogEmitted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2059,35 +1286,52 @@ func (it *VerifiableLoadUpkeepPerformingUpkeepIterator) Next() bool { } } -func (it *VerifiableLoadUpkeepPerformingUpkeepIterator) Error() error { +func (it *VerifiableLoadUpkeepLogEmittedIterator) Error() error { return it.fail } -func (it *VerifiableLoadUpkeepPerformingUpkeepIterator) Close() error { +func (it *VerifiableLoadUpkeepLogEmittedIterator) Close() error { it.sub.Unsubscribe() return nil } -type VerifiableLoadUpkeepPerformingUpkeep struct { - FirstPerformBlock *big.Int - LastBlock *big.Int - PreviousBlock *big.Int - Counter *big.Int - Raw types.Log +type VerifiableLoadUpkeepLogEmitted struct { + UpkeepId *big.Int + BlockNum *big.Int + Addr common.Address + Raw types.Log } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterPerformingUpkeep(opts *bind.FilterOpts) (*VerifiableLoadUpkeepPerformingUpkeepIterator, error) { +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterLogEmitted(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int) (*VerifiableLoadUpkeepLogEmittedIterator, error) { - logs, sub, err := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "PerformingUpkeep") + var upkeepIdRule []interface{} + for _, upkeepIdItem := range upkeepId { + upkeepIdRule = append(upkeepIdRule, upkeepIdItem) + } + var blockNumRule []interface{} + for _, blockNumItem := range blockNum { + blockNumRule = append(blockNumRule, blockNumItem) + } + + logs, sub, err := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "LogEmitted", upkeepIdRule, blockNumRule) if err != nil { return nil, err } - return &VerifiableLoadUpkeepPerformingUpkeepIterator{contract: _VerifiableLoadUpkeep.contract, event: "PerformingUpkeep", logs: logs, sub: sub}, nil + return &VerifiableLoadUpkeepLogEmittedIterator{contract: _VerifiableLoadUpkeep.contract, event: "LogEmitted", logs: logs, sub: sub}, nil } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchPerformingUpkeep(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepPerformingUpkeep) (event.Subscription, error) { +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchLogEmitted(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepLogEmitted, upkeepId []*big.Int, blockNum []*big.Int) (event.Subscription, error) { + + var upkeepIdRule []interface{} + for _, upkeepIdItem := range upkeepId { + upkeepIdRule = append(upkeepIdRule, upkeepIdItem) + } + var blockNumRule []interface{} + for _, blockNumItem := range blockNum { + blockNumRule = append(blockNumRule, blockNumItem) + } - logs, sub, err := _VerifiableLoadUpkeep.contract.WatchLogs(opts, "PerformingUpkeep") + logs, sub, err := _VerifiableLoadUpkeep.contract.WatchLogs(opts, "LogEmitted", upkeepIdRule, blockNumRule) if err != nil { return nil, err } @@ -2097,8 +1341,8 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchPerformingUpkeep select { case log := <-logs: - event := new(VerifiableLoadUpkeepPerformingUpkeep) - if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "PerformingUpkeep", log); err != nil { + event := new(VerifiableLoadUpkeepLogEmitted) + if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "LogEmitted", log); err != nil { return err } event.Raw = log @@ -2119,17 +1363,17 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchPerformingUpkeep }), nil } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParsePerformingUpkeep(log types.Log) (*VerifiableLoadUpkeepPerformingUpkeep, error) { - event := new(VerifiableLoadUpkeepPerformingUpkeep) - if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "PerformingUpkeep", log); err != nil { +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseLogEmitted(log types.Log) (*VerifiableLoadUpkeepLogEmitted, error) { + event := new(VerifiableLoadUpkeepLogEmitted) + if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "LogEmitted", log); err != nil { return nil, err } event.Raw = log return event, nil } -type VerifiableLoadUpkeepReceivedIterator struct { - Event *VerifiableLoadUpkeepReceived +type VerifiableLoadUpkeepOwnershipTransferRequestedIterator struct { + Event *VerifiableLoadUpkeepOwnershipTransferRequested contract *bind.BoundContract event string @@ -2140,7 +1384,7 @@ type VerifiableLoadUpkeepReceivedIterator struct { fail error } -func (it *VerifiableLoadUpkeepReceivedIterator) Next() bool { +func (it *VerifiableLoadUpkeepOwnershipTransferRequestedIterator) Next() bool { if it.fail != nil { return false @@ -2149,7 +1393,7 @@ func (it *VerifiableLoadUpkeepReceivedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(VerifiableLoadUpkeepReceived) + it.Event = new(VerifiableLoadUpkeepOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2164,7 +1408,7 @@ func (it *VerifiableLoadUpkeepReceivedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(VerifiableLoadUpkeepReceived) + it.Event = new(VerifiableLoadUpkeepOwnershipTransferRequested) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2179,33 +1423,51 @@ func (it *VerifiableLoadUpkeepReceivedIterator) Next() bool { } } -func (it *VerifiableLoadUpkeepReceivedIterator) Error() error { +func (it *VerifiableLoadUpkeepOwnershipTransferRequestedIterator) Error() error { return it.fail } -func (it *VerifiableLoadUpkeepReceivedIterator) Close() error { +func (it *VerifiableLoadUpkeepOwnershipTransferRequestedIterator) Close() error { it.sub.Unsubscribe() return nil } -type VerifiableLoadUpkeepReceived struct { - Sender common.Address - Value *big.Int - Raw types.Log +type VerifiableLoadUpkeepOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterReceived(opts *bind.FilterOpts) (*VerifiableLoadUpkeepReceivedIterator, error) { +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadUpkeepOwnershipTransferRequestedIterator, error) { - logs, sub, err := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "Received") + 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 := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } - return &VerifiableLoadUpkeepReceivedIterator{contract: _VerifiableLoadUpkeep.contract, event: "Received", logs: logs, sub: sub}, nil + return &VerifiableLoadUpkeepOwnershipTransferRequestedIterator{contract: _VerifiableLoadUpkeep.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchReceived(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepReceived) (event.Subscription, error) { +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { - logs, sub, err := _VerifiableLoadUpkeep.contract.WatchLogs(opts, "Received") + 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 := _VerifiableLoadUpkeep.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) if err != nil { return nil, err } @@ -2215,8 +1477,8 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchReceived(opts *b select { case log := <-logs: - event := new(VerifiableLoadUpkeepReceived) - if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "Received", log); err != nil { + event := new(VerifiableLoadUpkeepOwnershipTransferRequested) + if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return err } event.Raw = log @@ -2237,17 +1499,17 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchReceived(opts *b }), nil } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseReceived(log types.Log) (*VerifiableLoadUpkeepReceived, error) { - event := new(VerifiableLoadUpkeepReceived) - if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "Received", log); err != nil { +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseOwnershipTransferRequested(log types.Log) (*VerifiableLoadUpkeepOwnershipTransferRequested, error) { + event := new(VerifiableLoadUpkeepOwnershipTransferRequested) + if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { return nil, err } event.Raw = log return event, nil } -type VerifiableLoadUpkeepRegistrarSetIterator struct { - Event *VerifiableLoadUpkeepRegistrarSet +type VerifiableLoadUpkeepOwnershipTransferredIterator struct { + Event *VerifiableLoadUpkeepOwnershipTransferred contract *bind.BoundContract event string @@ -2258,7 +1520,7 @@ type VerifiableLoadUpkeepRegistrarSetIterator struct { fail error } -func (it *VerifiableLoadUpkeepRegistrarSetIterator) Next() bool { +func (it *VerifiableLoadUpkeepOwnershipTransferredIterator) Next() bool { if it.fail != nil { return false @@ -2267,7 +1529,7 @@ func (it *VerifiableLoadUpkeepRegistrarSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(VerifiableLoadUpkeepRegistrarSet) + it.Event = new(VerifiableLoadUpkeepOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2282,7 +1544,7 @@ func (it *VerifiableLoadUpkeepRegistrarSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(VerifiableLoadUpkeepRegistrarSet) + it.Event = new(VerifiableLoadUpkeepOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2297,32 +1559,51 @@ func (it *VerifiableLoadUpkeepRegistrarSetIterator) Next() bool { } } -func (it *VerifiableLoadUpkeepRegistrarSetIterator) Error() error { +func (it *VerifiableLoadUpkeepOwnershipTransferredIterator) Error() error { return it.fail } -func (it *VerifiableLoadUpkeepRegistrarSetIterator) Close() error { +func (it *VerifiableLoadUpkeepOwnershipTransferredIterator) Close() error { it.sub.Unsubscribe() return nil } -type VerifiableLoadUpkeepRegistrarSet struct { - NewRegistrar common.Address - Raw types.Log +type VerifiableLoadUpkeepOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterRegistrarSet(opts *bind.FilterOpts) (*VerifiableLoadUpkeepRegistrarSetIterator, error) { +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadUpkeepOwnershipTransferredIterator, 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 := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "RegistrarSet") + logs, sub, err := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) if err != nil { return nil, err } - return &VerifiableLoadUpkeepRegistrarSetIterator{contract: _VerifiableLoadUpkeep.contract, event: "RegistrarSet", logs: logs, sub: sub}, nil + return &VerifiableLoadUpkeepOwnershipTransferredIterator{contract: _VerifiableLoadUpkeep.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchRegistrarSet(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepRegistrarSet) (event.Subscription, error) { +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepOwnershipTransferred, 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 := _VerifiableLoadUpkeep.contract.WatchLogs(opts, "RegistrarSet") + logs, sub, err := _VerifiableLoadUpkeep.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) if err != nil { return nil, err } @@ -2332,8 +1613,8 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchRegistrarSet(opt select { case log := <-logs: - event := new(VerifiableLoadUpkeepRegistrarSet) - if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "RegistrarSet", log); err != nil { + event := new(VerifiableLoadUpkeepOwnershipTransferred) + if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return err } event.Raw = log @@ -2354,17 +1635,17 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchRegistrarSet(opt }), nil } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseRegistrarSet(log types.Log) (*VerifiableLoadUpkeepRegistrarSet, error) { - event := new(VerifiableLoadUpkeepRegistrarSet) - if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "RegistrarSet", log); err != nil { +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseOwnershipTransferred(log types.Log) (*VerifiableLoadUpkeepOwnershipTransferred, error) { + event := new(VerifiableLoadUpkeepOwnershipTransferred) + if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return nil, err } event.Raw = log return event, nil } -type VerifiableLoadUpkeepUpkeepTopUpIterator struct { - Event *VerifiableLoadUpkeepUpkeepTopUp +type VerifiableLoadUpkeepReceivedIterator struct { + Event *VerifiableLoadUpkeepReceived contract *bind.BoundContract event string @@ -2375,7 +1656,7 @@ type VerifiableLoadUpkeepUpkeepTopUpIterator struct { fail error } -func (it *VerifiableLoadUpkeepUpkeepTopUpIterator) Next() bool { +func (it *VerifiableLoadUpkeepReceivedIterator) Next() bool { if it.fail != nil { return false @@ -2384,7 +1665,7 @@ func (it *VerifiableLoadUpkeepUpkeepTopUpIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(VerifiableLoadUpkeepUpkeepTopUp) + it.Event = new(VerifiableLoadUpkeepReceived) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2399,7 +1680,7 @@ func (it *VerifiableLoadUpkeepUpkeepTopUpIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(VerifiableLoadUpkeepUpkeepTopUp) + it.Event = new(VerifiableLoadUpkeepReceived) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2414,34 +1695,33 @@ func (it *VerifiableLoadUpkeepUpkeepTopUpIterator) Next() bool { } } -func (it *VerifiableLoadUpkeepUpkeepTopUpIterator) Error() error { +func (it *VerifiableLoadUpkeepReceivedIterator) Error() error { return it.fail } -func (it *VerifiableLoadUpkeepUpkeepTopUpIterator) Close() error { +func (it *VerifiableLoadUpkeepReceivedIterator) Close() error { it.sub.Unsubscribe() return nil } -type VerifiableLoadUpkeepUpkeepTopUp struct { - UpkeepId *big.Int - Amount *big.Int - BlockNum *big.Int - Raw types.Log +type VerifiableLoadUpkeepReceived struct { + Sender common.Address + Value *big.Int + Raw types.Log } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterUpkeepTopUp(opts *bind.FilterOpts) (*VerifiableLoadUpkeepUpkeepTopUpIterator, error) { +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterReceived(opts *bind.FilterOpts) (*VerifiableLoadUpkeepReceivedIterator, error) { - logs, sub, err := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "UpkeepTopUp") + logs, sub, err := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "Received") if err != nil { return nil, err } - return &VerifiableLoadUpkeepUpkeepTopUpIterator{contract: _VerifiableLoadUpkeep.contract, event: "UpkeepTopUp", logs: logs, sub: sub}, nil + return &VerifiableLoadUpkeepReceivedIterator{contract: _VerifiableLoadUpkeep.contract, event: "Received", logs: logs, sub: sub}, nil } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchUpkeepTopUp(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepUpkeepTopUp) (event.Subscription, error) { +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchReceived(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepReceived) (event.Subscription, error) { - logs, sub, err := _VerifiableLoadUpkeep.contract.WatchLogs(opts, "UpkeepTopUp") + logs, sub, err := _VerifiableLoadUpkeep.contract.WatchLogs(opts, "Received") if err != nil { return nil, err } @@ -2451,8 +1731,8 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchUpkeepTopUp(opts select { case log := <-logs: - event := new(VerifiableLoadUpkeepUpkeepTopUp) - if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "UpkeepTopUp", log); err != nil { + event := new(VerifiableLoadUpkeepReceived) + if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "Received", log); err != nil { return err } event.Raw = log @@ -2473,17 +1753,17 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchUpkeepTopUp(opts }), nil } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseUpkeepTopUp(log types.Log) (*VerifiableLoadUpkeepUpkeepTopUp, error) { - event := new(VerifiableLoadUpkeepUpkeepTopUp) - if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "UpkeepTopUp", log); err != nil { +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseReceived(log types.Log) (*VerifiableLoadUpkeepReceived, error) { + event := new(VerifiableLoadUpkeepReceived) + if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "Received", log); err != nil { return nil, err } event.Raw = log return event, nil } -type VerifiableLoadUpkeepUpkeepsCancelledIterator struct { - Event *VerifiableLoadUpkeepUpkeepsCancelled +type VerifiableLoadUpkeepUpkeepTopUpIterator struct { + Event *VerifiableLoadUpkeepUpkeepTopUp contract *bind.BoundContract event string @@ -2494,7 +1774,7 @@ type VerifiableLoadUpkeepUpkeepsCancelledIterator struct { fail error } -func (it *VerifiableLoadUpkeepUpkeepsCancelledIterator) Next() bool { +func (it *VerifiableLoadUpkeepUpkeepTopUpIterator) Next() bool { if it.fail != nil { return false @@ -2503,7 +1783,7 @@ func (it *VerifiableLoadUpkeepUpkeepsCancelledIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(VerifiableLoadUpkeepUpkeepsCancelled) + it.Event = new(VerifiableLoadUpkeepUpkeepTopUp) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2518,7 +1798,7 @@ func (it *VerifiableLoadUpkeepUpkeepsCancelledIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(VerifiableLoadUpkeepUpkeepsCancelled) + it.Event = new(VerifiableLoadUpkeepUpkeepTopUp) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2533,32 +1813,34 @@ func (it *VerifiableLoadUpkeepUpkeepsCancelledIterator) Next() bool { } } -func (it *VerifiableLoadUpkeepUpkeepsCancelledIterator) Error() error { +func (it *VerifiableLoadUpkeepUpkeepTopUpIterator) Error() error { return it.fail } -func (it *VerifiableLoadUpkeepUpkeepsCancelledIterator) Close() error { +func (it *VerifiableLoadUpkeepUpkeepTopUpIterator) Close() error { it.sub.Unsubscribe() return nil } -type VerifiableLoadUpkeepUpkeepsCancelled struct { - UpkeepIds []*big.Int - Raw types.Log +type VerifiableLoadUpkeepUpkeepTopUp struct { + UpkeepId *big.Int + Amount *big.Int + BlockNum *big.Int + Raw types.Log } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterUpkeepsCancelled(opts *bind.FilterOpts) (*VerifiableLoadUpkeepUpkeepsCancelledIterator, error) { +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterUpkeepTopUp(opts *bind.FilterOpts) (*VerifiableLoadUpkeepUpkeepTopUpIterator, error) { - logs, sub, err := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "UpkeepsCancelled") + logs, sub, err := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "UpkeepTopUp") if err != nil { return nil, err } - return &VerifiableLoadUpkeepUpkeepsCancelledIterator{contract: _VerifiableLoadUpkeep.contract, event: "UpkeepsCancelled", logs: logs, sub: sub}, nil + return &VerifiableLoadUpkeepUpkeepTopUpIterator{contract: _VerifiableLoadUpkeep.contract, event: "UpkeepTopUp", logs: logs, sub: sub}, nil } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchUpkeepsCancelled(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepUpkeepsCancelled) (event.Subscription, error) { +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchUpkeepTopUp(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepUpkeepTopUp) (event.Subscription, error) { - logs, sub, err := _VerifiableLoadUpkeep.contract.WatchLogs(opts, "UpkeepsCancelled") + logs, sub, err := _VerifiableLoadUpkeep.contract.WatchLogs(opts, "UpkeepTopUp") if err != nil { return nil, err } @@ -2568,8 +1850,8 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchUpkeepsCancelled select { case log := <-logs: - event := new(VerifiableLoadUpkeepUpkeepsCancelled) - if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "UpkeepsCancelled", log); err != nil { + event := new(VerifiableLoadUpkeepUpkeepTopUp) + if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "UpkeepTopUp", log); err != nil { return err } event.Raw = log @@ -2590,9 +1872,9 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchUpkeepsCancelled }), nil } -func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseUpkeepsCancelled(log types.Log) (*VerifiableLoadUpkeepUpkeepsCancelled, error) { - event := new(VerifiableLoadUpkeepUpkeepsCancelled) - if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "UpkeepsCancelled", log); err != nil { +func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseUpkeepTopUp(log types.Log) (*VerifiableLoadUpkeepUpkeepTopUp, error) { + event := new(VerifiableLoadUpkeepUpkeepTopUp) + if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "UpkeepTopUp", log); err != nil { return nil, err } event.Raw = log @@ -2718,24 +2000,16 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseUpkeepsRegistere func (_VerifiableLoadUpkeep *VerifiableLoadUpkeep) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { - case _VerifiableLoadUpkeep.abi.Events["FundsAdded"].ID: - return _VerifiableLoadUpkeep.ParseFundsAdded(log) - case _VerifiableLoadUpkeep.abi.Events["InsufficientFunds"].ID: - return _VerifiableLoadUpkeep.ParseInsufficientFunds(log) + case _VerifiableLoadUpkeep.abi.Events["LogEmitted"].ID: + return _VerifiableLoadUpkeep.ParseLogEmitted(log) case _VerifiableLoadUpkeep.abi.Events["OwnershipTransferRequested"].ID: return _VerifiableLoadUpkeep.ParseOwnershipTransferRequested(log) case _VerifiableLoadUpkeep.abi.Events["OwnershipTransferred"].ID: return _VerifiableLoadUpkeep.ParseOwnershipTransferred(log) - case _VerifiableLoadUpkeep.abi.Events["PerformingUpkeep"].ID: - return _VerifiableLoadUpkeep.ParsePerformingUpkeep(log) case _VerifiableLoadUpkeep.abi.Events["Received"].ID: return _VerifiableLoadUpkeep.ParseReceived(log) - case _VerifiableLoadUpkeep.abi.Events["RegistrarSet"].ID: - return _VerifiableLoadUpkeep.ParseRegistrarSet(log) case _VerifiableLoadUpkeep.abi.Events["UpkeepTopUp"].ID: return _VerifiableLoadUpkeep.ParseUpkeepTopUp(log) - case _VerifiableLoadUpkeep.abi.Events["UpkeepsCancelled"].ID: - return _VerifiableLoadUpkeep.ParseUpkeepsCancelled(log) case _VerifiableLoadUpkeep.abi.Events["UpkeepsRegistered"].ID: return _VerifiableLoadUpkeep.ParseUpkeepsRegistered(log) @@ -2744,12 +2018,8 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeep) ParseLog(log types.Log) (gene } } -func (VerifiableLoadUpkeepFundsAdded) Topic() common.Hash { - return common.HexToHash("0x8137dc366612bf502338bd8951f835ad8ceba421c4eb3d79c7f9b3ce0ac4762e") -} - -func (VerifiableLoadUpkeepInsufficientFunds) Topic() common.Hash { - return common.HexToHash("0x03eb8b54a949acec2cd08fdb6d6bd4647a1f2c907d75d6900648effa92eb147f") +func (VerifiableLoadUpkeepLogEmitted) Topic() common.Hash { + return common.HexToHash("0x97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf08") } func (VerifiableLoadUpkeepOwnershipTransferRequested) Topic() common.Hash { @@ -2760,26 +2030,14 @@ func (VerifiableLoadUpkeepOwnershipTransferred) Topic() common.Hash { return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") } -func (VerifiableLoadUpkeepPerformingUpkeep) Topic() common.Hash { - return common.HexToHash("0x6b6b3eeaaf107627513e76a81662118e7b1d8c78866f70760262115ddcfeede3") -} - func (VerifiableLoadUpkeepReceived) Topic() common.Hash { return common.HexToHash("0x88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f88525874") } -func (VerifiableLoadUpkeepRegistrarSet) Topic() common.Hash { - return common.HexToHash("0x6263309d5d4d1cfececd45a387cda7f14dccde21cf7a1bee1be6561075e61014") -} - func (VerifiableLoadUpkeepUpkeepTopUp) Topic() common.Hash { return common.HexToHash("0x49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c0") } -func (VerifiableLoadUpkeepUpkeepsCancelled) Topic() common.Hash { - return common.HexToHash("0xbeac20a03a6674e40498fac4356bc86e356c0d761a8d35d436712dc93bc7c74b") -} - func (VerifiableLoadUpkeepUpkeepsRegistered) Topic() common.Hash { return common.HexToHash("0x2ee10f7eb180441fb9fbba75b10c0162b5390b557712c93426243ca8f383c711") } @@ -2791,16 +2049,12 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeep) Address() common.Address { type VerifiableLoadUpkeepInterface interface { BUCKETSIZE(opts *bind.CallOpts) (uint16, error) - TIMESTAMPINTERVAL(opts *bind.CallOpts) (uint16, error) - AddLinkAmount(opts *bind.CallOpts) (*big.Int, error) BucketedDelays(opts *bind.CallOpts, arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error) Buckets(opts *bind.CallOpts, arg0 *big.Int) (uint16, error) - CheckDatas(opts *bind.CallOpts, arg0 *big.Int) ([]byte, error) - CheckGasToBurns(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) Counters(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) @@ -2811,6 +2065,8 @@ type VerifiableLoadUpkeepInterface interface { Eligible(opts *bind.CallOpts, upkeepId *big.Int) (bool, error) + EmittedSig(opts *bind.CallOpts) ([32]byte, error) + FirstPerformBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) GasLimits(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) @@ -2825,34 +2081,14 @@ type VerifiableLoadUpkeepInterface interface { GetDelaysLength(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error) - GetDelaysLengthAtBucket(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) (*big.Int, error) - - GetDelaysLengthAtTimestampBucket(opts *bind.CallOpts, upkeepId *big.Int, timestampBucket uint16) (*big.Int, error) - - GetPxBucketedDelaysForAllUpkeeps(opts *bind.CallOpts, p *big.Int) ([]*big.Int, []*big.Int, error) - - GetPxDelayForAllUpkeeps(opts *bind.CallOpts, p *big.Int) ([]*big.Int, []*big.Int, error) - - GetPxDelayInBucket(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, bucket uint16) (*big.Int, error) - - GetPxDelayInTimestampBucket(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, timestampBucket uint16) (*big.Int, error) + GetLogTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) GetPxDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, n *big.Int) (*big.Int, error) - GetSumBucketedDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) - GetSumDelayInBucket(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) (*big.Int, *big.Int, error) - GetSumDelayInTimestampBucket(opts *bind.CallOpts, upkeepId *big.Int, timestampBucket uint16) (*big.Int, *big.Int, error) - GetSumDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) - GetSumTimestampBucketedDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) - - GetTimestampBucketedDelaysLength(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error) - - GetTimestampDelays(opts *bind.CallOpts, upkeepId *big.Int, timestampBucket uint16) ([]*big.Int, error) - Intervals(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) LastTopUpBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) @@ -2873,12 +2109,6 @@ type VerifiableLoadUpkeepInterface interface { Registry(opts *bind.CallOpts) (common.Address, error) - TimestampBuckets(opts *bind.CallOpts, arg0 *big.Int) (uint16, error) - - TimestampDelays(opts *bind.CallOpts, arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error) - - Timestamps(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) - UpkeepTopUpCheckInterval(opts *bind.CallOpts) (*big.Int, error) UseArbitrumBlockNum(opts *bind.CallOpts) (bool, error) @@ -2889,7 +2119,9 @@ type VerifiableLoadUpkeepInterface interface { BatchCancelUpkeeps(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error) - BatchRegisterUpkeeps(opts *bind.TransactOpts, number uint8, gasLimit uint32, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) + BatchRegisterUpkeeps(opts *bind.TransactOpts, number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) + + BatchSendLogs(opts *bind.TransactOpts) (*types.Transaction, error) BatchSetIntervals(opts *bind.TransactOpts, upkeepIds []*big.Int, interval uint32) (*types.Transaction, error) @@ -2897,12 +2129,16 @@ type VerifiableLoadUpkeepInterface interface { BatchWithdrawLinks(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error) + BurnPerformGas(opts *bind.TransactOpts, upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error) + CancelUpkeep(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) CheckUpkeep(opts *bind.TransactOpts, checkData []byte) (*types.Transaction, error) PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error) + SendLog(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) + SetAddLinkAmount(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) SetCheckGasToBurn(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error) @@ -2921,6 +2157,8 @@ type VerifiableLoadUpkeepInterface interface { SetUpkeepTopUpCheckInterval(opts *bind.TransactOpts, newInterval *big.Int) (*types.Transaction, error) + TopUpFund(opts *bind.TransactOpts, upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error) + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) UpdateUpkeepPipelineData(opts *bind.TransactOpts, upkeepId *big.Int, pipelineData []byte) (*types.Transaction, error) @@ -2931,17 +2169,11 @@ type VerifiableLoadUpkeepInterface interface { Receive(opts *bind.TransactOpts) (*types.Transaction, error) - FilterFundsAdded(opts *bind.FilterOpts) (*VerifiableLoadUpkeepFundsAddedIterator, error) + FilterLogEmitted(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int) (*VerifiableLoadUpkeepLogEmittedIterator, error) - WatchFundsAdded(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepFundsAdded) (event.Subscription, error) + WatchLogEmitted(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepLogEmitted, upkeepId []*big.Int, blockNum []*big.Int) (event.Subscription, error) - ParseFundsAdded(log types.Log) (*VerifiableLoadUpkeepFundsAdded, error) - - FilterInsufficientFunds(opts *bind.FilterOpts) (*VerifiableLoadUpkeepInsufficientFundsIterator, error) - - WatchInsufficientFunds(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepInsufficientFunds) (event.Subscription, error) - - ParseInsufficientFunds(log types.Log) (*VerifiableLoadUpkeepInsufficientFunds, error) + ParseLogEmitted(log types.Log) (*VerifiableLoadUpkeepLogEmitted, error) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadUpkeepOwnershipTransferRequestedIterator, error) @@ -2955,36 +2187,18 @@ type VerifiableLoadUpkeepInterface interface { ParseOwnershipTransferred(log types.Log) (*VerifiableLoadUpkeepOwnershipTransferred, error) - FilterPerformingUpkeep(opts *bind.FilterOpts) (*VerifiableLoadUpkeepPerformingUpkeepIterator, error) - - WatchPerformingUpkeep(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepPerformingUpkeep) (event.Subscription, error) - - ParsePerformingUpkeep(log types.Log) (*VerifiableLoadUpkeepPerformingUpkeep, error) - FilterReceived(opts *bind.FilterOpts) (*VerifiableLoadUpkeepReceivedIterator, error) WatchReceived(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepReceived) (event.Subscription, error) ParseReceived(log types.Log) (*VerifiableLoadUpkeepReceived, error) - FilterRegistrarSet(opts *bind.FilterOpts) (*VerifiableLoadUpkeepRegistrarSetIterator, error) - - WatchRegistrarSet(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepRegistrarSet) (event.Subscription, error) - - ParseRegistrarSet(log types.Log) (*VerifiableLoadUpkeepRegistrarSet, error) - FilterUpkeepTopUp(opts *bind.FilterOpts) (*VerifiableLoadUpkeepUpkeepTopUpIterator, error) WatchUpkeepTopUp(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepUpkeepTopUp) (event.Subscription, error) ParseUpkeepTopUp(log types.Log) (*VerifiableLoadUpkeepUpkeepTopUp, error) - FilterUpkeepsCancelled(opts *bind.FilterOpts) (*VerifiableLoadUpkeepUpkeepsCancelledIterator, error) - - WatchUpkeepsCancelled(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepUpkeepsCancelled) (event.Subscription, error) - - ParseUpkeepsCancelled(log types.Log) (*VerifiableLoadUpkeepUpkeepsCancelled, error) - FilterUpkeepsRegistered(opts *bind.FilterOpts) (*VerifiableLoadUpkeepUpkeepsRegisteredIterator, error) WatchUpkeepsRegistered(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepUpkeepsRegistered) (event.Subscription, error) diff --git a/core/gethwrappers/generated/vrf_coordinator_v2_plus_v2_example/vrf_coordinator_v2_plus_v2_example.go b/core/gethwrappers/generated/vrf_coordinator_v2_plus_v2_example/vrf_coordinator_v2_plus_v2_example.go new file mode 100644 index 00000000000..93faeada261 --- /dev/null +++ b/core/gethwrappers/generated/vrf_coordinator_v2_plus_v2_example/vrf_coordinator_v2_plus_v2_example.go @@ -0,0 +1,480 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package vrf_coordinator_v2_plus_v2_example + +import ( + "errors" + "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" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type VRFV2PlusClientRandomWordsRequest struct { + KeyHash [32]byte + SubId *big.Int + RequestConfirmations uint16 + CallbackGasLimit uint32 + NumWords uint32 + ExtraArgs []byte +} + +var VRFCoordinatorV2PlusV2ExampleMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevCoordinator\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transferredValue\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"expectedValue\",\"type\":\"uint96\"}],\"name\":\"InvalidNativeBalance\",\"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\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"previousCoordinator\",\"type\":\"address\"}],\"name\":\"MustBePreviousCoordinator\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"name\":\"fulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"}],\"name\":\"generateFakeRandomness\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"},{\"internalType\":\"uint96\",\"name\":\"linkBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeBalance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedData\",\"type\":\"bytes\"}],\"name\":\"onMigration\",\"outputs\":[],\"stateMutability\":\"payable\",\"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\":\"\",\"type\":\"tuple\"}],\"name\":\"requestRandomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_link\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_prevCoordinator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requestConsumerMapping\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_subscriptions\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"linkBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeBalance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalLinkBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalNativeBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6080604052600060035534801561001557600080fd5b50604051610f65380380610f6583398101604081905261003491610081565b600580546001600160a01b039384166001600160a01b031991821617909155600480549290931691161790556100b4565b80516001600160a01b038116811461007c57600080fd5b919050565b6000806040838503121561009457600080fd5b61009d83610065565b91506100ab60208401610065565b90509250929050565b610ea2806100c36000396000f3fe6080604052600436106100c75760003560e01c8063ce3f471911610074578063dc311dd31161004e578063dc311dd314610325578063e89e106a14610355578063ed8b558f1461036b57600080fd5b8063ce3f4719146102c3578063d6100d1c146102d8578063da4f5e6d146102f857600080fd5b806386175f58116100a557806386175f581461022557806393f3acb6146102685780639b1c385e1461029557600080fd5b80630495f265146100cc578063086597b31461018157806318e3dd27146101d3575b600080fd5b3480156100d857600080fd5b5061013b6100e7366004610c86565b6000602081905290815260409020805460029091015473ffffffffffffffffffffffffffffffffffffffff909116906bffffffffffffffffffffffff808216916c0100000000000000000000000090041683565b6040805173ffffffffffffffffffffffffffffffffffffffff90941684526bffffffffffffffffffffffff92831660208501529116908201526060015b60405180910390f35b34801561018d57600080fd5b506004546101ae9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610178565b3480156101df57600080fd5b50600254610208906c0100000000000000000000000090046bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff9091168152602001610178565b34801561023157600080fd5b506101ae610240366004610c86565b60016020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b34801561027457600080fd5b50610288610283366004610c86565b610390565b6040516101789190610d63565b3480156102a157600080fd5b506102b56102b0366004610b81565b61043b565b604051908152602001610178565b6102d66102d1366004610b0f565b61044c565b005b3480156102e457600080fd5b506102d66102f3366004610c86565b610746565b34801561030457600080fd5b506005546101ae9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561033157600080fd5b50610345610340366004610c86565b6107ce565b6040516101789493929190610cda565b34801561036157600080fd5b506102b560035481565b34801561037757600080fd5b50600254610208906bffffffffffffffffffffffff1681565b6040805160018082528183019092526060916000919060208083019080368337019050509050826040516020016103fe918152604060208201819052600a908201527f6e6f742072616e646f6d00000000000000000000000000000000000000000000606082015260800190565b6040516020818303038152906040528051906020012060001c8160008151811061042a5761042a610e37565b602090810291909101015292915050565b6000610446336108f9565b92915050565b60045473ffffffffffffffffffffffffffffffffffffffff1633146104c557600480546040517ff5828f73000000000000000000000000000000000000000000000000000000008152339281019290925273ffffffffffffffffffffffffffffffffffffffff1660248201526044015b60405180910390fd5b60006104d382840184610bc3565b9050806000015160ff166001146105255780516040517f8df4607c00000000000000000000000000000000000000000000000000000000815260ff9091166004820152600160248201526044016104bc565b8060a001516bffffffffffffffffffffffff16341461058c5760a08101516040517f6acf13500000000000000000000000000000000000000000000000000000000081523460048201526bffffffffffffffffffffffff90911660248201526044016104bc565b60408051608080820183528383015173ffffffffffffffffffffffffffffffffffffffff90811683526060808601516020808601918252938701516bffffffffffffffffffffffff9081168688015260a0880151169185019190915282860151600090815280845294909420835181547fffffffffffffffffffffffff00000000000000000000000000000000000000001692169190911781559251805192939261063d9260018501920190610965565b506040820151600291820180546060909401516bffffffffffffffffffffffff9283167fffffffffffffffff000000000000000000000000000000000000000000000000909516949094176c01000000000000000000000000948316850217905560a084015182549093600c926106b8928692900416610dd8565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508060800151600260008282829054906101000a90046bffffffffffffffffffffffff166107139190610dd8565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505050565b60008181526001602052604090205473ffffffffffffffffffffffffffffffffffffffff1680631fe543e38361077b81610390565b6040518363ffffffff1660e01b8152600401610798929190610d76565b600060405180830381600087803b1580156107b257600080fd5b505af11580156107c6573d6000803e3d6000fd5b505050505050565b6000818152602081905260408120546060908290819073ffffffffffffffffffffffffffffffffffffffff16610830576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008581526020818152604091829020805460028201546001909201805485518186028101860190965280865273ffffffffffffffffffffffffffffffffffffffff9092169490936bffffffffffffffffffffffff808516946c010000000000000000000000009004169285918301828280156108e357602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116108b8575b5050505050925093509350935093509193509193565b6000600354600161090a9190610dc0565b6003819055600081815260016020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff94909416939093179092555090565b8280548282559060005260206000209081019282156109df579160200282015b828111156109df57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190610985565b506109eb9291506109ef565b5090565b5b808211156109eb57600081556001016109f0565b803573ffffffffffffffffffffffffffffffffffffffff81168114610a2857600080fd5b919050565b600082601f830112610a3e57600080fd5b8135602067ffffffffffffffff80831115610a5b57610a5b610e66565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715610a9e57610a9e610e66565b60405284815283810192508684018288018501891015610abd57600080fd5b600092505b85831015610ae757610ad381610a04565b845292840192600192909201918401610ac2565b50979650505050505050565b80356bffffffffffffffffffffffff81168114610a2857600080fd5b60008060208385031215610b2257600080fd5b823567ffffffffffffffff80821115610b3a57600080fd5b818501915085601f830112610b4e57600080fd5b813581811115610b5d57600080fd5b866020828501011115610b6f57600080fd5b60209290920196919550909350505050565b600060208284031215610b9357600080fd5b813567ffffffffffffffff811115610baa57600080fd5b820160c08185031215610bbc57600080fd5b9392505050565b600060208284031215610bd557600080fd5b813567ffffffffffffffff80821115610bed57600080fd5b9083019060c08286031215610c0157600080fd5b610c09610d97565b823560ff81168114610c1a57600080fd5b815260208381013590820152610c3260408401610a04565b6040820152606083013582811115610c4957600080fd5b610c5587828601610a2d565b606083015250610c6760808401610af3565b6080820152610c7860a08401610af3565b60a082015295945050505050565b600060208284031215610c9857600080fd5b5035919050565b600081518084526020808501945080840160005b83811015610ccf57815187529582019590820190600101610cb3565b509495945050505050565b60006080820173ffffffffffffffffffffffffffffffffffffffff8088168452602060808186015282885180855260a087019150828a01945060005b81811015610d34578551851683529483019491830191600101610d16565b50506bffffffffffffffffffffffff978816604087015295909616606090940193909352509195945050505050565b602081526000610bbc6020830184610c9f565b828152604060208201526000610d8f6040830184610c9f565b949350505050565b60405160c0810167ffffffffffffffff81118282101715610dba57610dba610e66565b60405290565b60008219821115610dd357610dd3610e08565b500190565b60006bffffffffffffffffffffffff808316818516808303821115610dff57610dff610e08565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", +} + +var VRFCoordinatorV2PlusV2ExampleABI = VRFCoordinatorV2PlusV2ExampleMetaData.ABI + +var VRFCoordinatorV2PlusV2ExampleBin = VRFCoordinatorV2PlusV2ExampleMetaData.Bin + +func DeployVRFCoordinatorV2PlusV2Example(auth *bind.TransactOpts, backend bind.ContractBackend, link common.Address, prevCoordinator common.Address) (common.Address, *types.Transaction, *VRFCoordinatorV2PlusV2Example, error) { + parsed, err := VRFCoordinatorV2PlusV2ExampleMetaData.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(VRFCoordinatorV2PlusV2ExampleBin), backend, link, prevCoordinator) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &VRFCoordinatorV2PlusV2Example{VRFCoordinatorV2PlusV2ExampleCaller: VRFCoordinatorV2PlusV2ExampleCaller{contract: contract}, VRFCoordinatorV2PlusV2ExampleTransactor: VRFCoordinatorV2PlusV2ExampleTransactor{contract: contract}, VRFCoordinatorV2PlusV2ExampleFilterer: VRFCoordinatorV2PlusV2ExampleFilterer{contract: contract}}, nil +} + +type VRFCoordinatorV2PlusV2Example struct { + address common.Address + abi abi.ABI + VRFCoordinatorV2PlusV2ExampleCaller + VRFCoordinatorV2PlusV2ExampleTransactor + VRFCoordinatorV2PlusV2ExampleFilterer +} + +type VRFCoordinatorV2PlusV2ExampleCaller struct { + contract *bind.BoundContract +} + +type VRFCoordinatorV2PlusV2ExampleTransactor struct { + contract *bind.BoundContract +} + +type VRFCoordinatorV2PlusV2ExampleFilterer struct { + contract *bind.BoundContract +} + +type VRFCoordinatorV2PlusV2ExampleSession struct { + Contract *VRFCoordinatorV2PlusV2Example + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type VRFCoordinatorV2PlusV2ExampleCallerSession struct { + Contract *VRFCoordinatorV2PlusV2ExampleCaller + CallOpts bind.CallOpts +} + +type VRFCoordinatorV2PlusV2ExampleTransactorSession struct { + Contract *VRFCoordinatorV2PlusV2ExampleTransactor + TransactOpts bind.TransactOpts +} + +type VRFCoordinatorV2PlusV2ExampleRaw struct { + Contract *VRFCoordinatorV2PlusV2Example +} + +type VRFCoordinatorV2PlusV2ExampleCallerRaw struct { + Contract *VRFCoordinatorV2PlusV2ExampleCaller +} + +type VRFCoordinatorV2PlusV2ExampleTransactorRaw struct { + Contract *VRFCoordinatorV2PlusV2ExampleTransactor +} + +func NewVRFCoordinatorV2PlusV2Example(address common.Address, backend bind.ContractBackend) (*VRFCoordinatorV2PlusV2Example, error) { + abi, err := abi.JSON(strings.NewReader(VRFCoordinatorV2PlusV2ExampleABI)) + if err != nil { + return nil, err + } + contract, err := bindVRFCoordinatorV2PlusV2Example(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &VRFCoordinatorV2PlusV2Example{address: address, abi: abi, VRFCoordinatorV2PlusV2ExampleCaller: VRFCoordinatorV2PlusV2ExampleCaller{contract: contract}, VRFCoordinatorV2PlusV2ExampleTransactor: VRFCoordinatorV2PlusV2ExampleTransactor{contract: contract}, VRFCoordinatorV2PlusV2ExampleFilterer: VRFCoordinatorV2PlusV2ExampleFilterer{contract: contract}}, nil +} + +func NewVRFCoordinatorV2PlusV2ExampleCaller(address common.Address, caller bind.ContractCaller) (*VRFCoordinatorV2PlusV2ExampleCaller, error) { + contract, err := bindVRFCoordinatorV2PlusV2Example(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &VRFCoordinatorV2PlusV2ExampleCaller{contract: contract}, nil +} + +func NewVRFCoordinatorV2PlusV2ExampleTransactor(address common.Address, transactor bind.ContractTransactor) (*VRFCoordinatorV2PlusV2ExampleTransactor, error) { + contract, err := bindVRFCoordinatorV2PlusV2Example(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &VRFCoordinatorV2PlusV2ExampleTransactor{contract: contract}, nil +} + +func NewVRFCoordinatorV2PlusV2ExampleFilterer(address common.Address, filterer bind.ContractFilterer) (*VRFCoordinatorV2PlusV2ExampleFilterer, error) { + contract, err := bindVRFCoordinatorV2PlusV2Example(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &VRFCoordinatorV2PlusV2ExampleFilterer{contract: contract}, nil +} + +func bindVRFCoordinatorV2PlusV2Example(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := VRFCoordinatorV2PlusV2ExampleMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VRFCoordinatorV2PlusV2Example.Contract.VRFCoordinatorV2PlusV2ExampleCaller.contract.Call(opts, result, method, params...) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.VRFCoordinatorV2PlusV2ExampleTransactor.contract.Transfer(opts) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.VRFCoordinatorV2PlusV2ExampleTransactor.contract.Transact(opts, method, params...) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VRFCoordinatorV2PlusV2Example.Contract.contract.Call(opts, result, method, params...) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.contract.Transfer(opts) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.contract.Transact(opts, method, params...) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleCaller) GenerateFakeRandomness(opts *bind.CallOpts, requestID *big.Int) ([]*big.Int, error) { + var out []interface{} + err := _VRFCoordinatorV2PlusV2Example.contract.Call(opts, &out, "generateFakeRandomness", requestID) + + if err != nil { + return *new([]*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) + + return out0, err + +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleSession) GenerateFakeRandomness(requestID *big.Int) ([]*big.Int, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.GenerateFakeRandomness(&_VRFCoordinatorV2PlusV2Example.CallOpts, requestID) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleCallerSession) GenerateFakeRandomness(requestID *big.Int) ([]*big.Int, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.GenerateFakeRandomness(&_VRFCoordinatorV2PlusV2Example.CallOpts, requestID) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleCaller) GetSubscription(opts *bind.CallOpts, subId *big.Int) (GetSubscription, + + error) { + var out []interface{} + err := _VRFCoordinatorV2PlusV2Example.contract.Call(opts, &out, "getSubscription", subId) + + outstruct := new(GetSubscription) + if err != nil { + return *outstruct, err + } + + outstruct.Owner = *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + outstruct.Consumers = *abi.ConvertType(out[1], new([]common.Address)).(*[]common.Address) + outstruct.LinkBalance = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + outstruct.NativeBalance = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleSession) GetSubscription(subId *big.Int) (GetSubscription, + + error) { + return _VRFCoordinatorV2PlusV2Example.Contract.GetSubscription(&_VRFCoordinatorV2PlusV2Example.CallOpts, subId) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleCallerSession) GetSubscription(subId *big.Int) (GetSubscription, + + error) { + return _VRFCoordinatorV2PlusV2Example.Contract.GetSubscription(&_VRFCoordinatorV2PlusV2Example.CallOpts, subId) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleCaller) SLink(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFCoordinatorV2PlusV2Example.contract.Call(opts, &out, "s_link") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleSession) SLink() (common.Address, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.SLink(&_VRFCoordinatorV2PlusV2Example.CallOpts) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleCallerSession) SLink() (common.Address, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.SLink(&_VRFCoordinatorV2PlusV2Example.CallOpts) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleCaller) SPrevCoordinator(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFCoordinatorV2PlusV2Example.contract.Call(opts, &out, "s_prevCoordinator") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleSession) SPrevCoordinator() (common.Address, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.SPrevCoordinator(&_VRFCoordinatorV2PlusV2Example.CallOpts) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleCallerSession) SPrevCoordinator() (common.Address, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.SPrevCoordinator(&_VRFCoordinatorV2PlusV2Example.CallOpts) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleCaller) SRequestConsumerMapping(opts *bind.CallOpts, arg0 *big.Int) (common.Address, error) { + var out []interface{} + err := _VRFCoordinatorV2PlusV2Example.contract.Call(opts, &out, "s_requestConsumerMapping", arg0) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleSession) SRequestConsumerMapping(arg0 *big.Int) (common.Address, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.SRequestConsumerMapping(&_VRFCoordinatorV2PlusV2Example.CallOpts, arg0) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleCallerSession) SRequestConsumerMapping(arg0 *big.Int) (common.Address, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.SRequestConsumerMapping(&_VRFCoordinatorV2PlusV2Example.CallOpts, arg0) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleCaller) SRequestId(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFCoordinatorV2PlusV2Example.contract.Call(opts, &out, "s_requestId") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleSession) SRequestId() (*big.Int, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.SRequestId(&_VRFCoordinatorV2PlusV2Example.CallOpts) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleCallerSession) SRequestId() (*big.Int, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.SRequestId(&_VRFCoordinatorV2PlusV2Example.CallOpts) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleCaller) SSubscriptions(opts *bind.CallOpts, arg0 *big.Int) (SSubscriptions, + + error) { + var out []interface{} + err := _VRFCoordinatorV2PlusV2Example.contract.Call(opts, &out, "s_subscriptions", arg0) + + outstruct := new(SSubscriptions) + if err != nil { + return *outstruct, err + } + + outstruct.Owner = *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + outstruct.LinkBalance = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.NativeBalance = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleSession) SSubscriptions(arg0 *big.Int) (SSubscriptions, + + error) { + return _VRFCoordinatorV2PlusV2Example.Contract.SSubscriptions(&_VRFCoordinatorV2PlusV2Example.CallOpts, arg0) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleCallerSession) SSubscriptions(arg0 *big.Int) (SSubscriptions, + + error) { + return _VRFCoordinatorV2PlusV2Example.Contract.SSubscriptions(&_VRFCoordinatorV2PlusV2Example.CallOpts, arg0) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleCaller) STotalLinkBalance(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFCoordinatorV2PlusV2Example.contract.Call(opts, &out, "s_totalLinkBalance") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleSession) STotalLinkBalance() (*big.Int, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.STotalLinkBalance(&_VRFCoordinatorV2PlusV2Example.CallOpts) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleCallerSession) STotalLinkBalance() (*big.Int, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.STotalLinkBalance(&_VRFCoordinatorV2PlusV2Example.CallOpts) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleCaller) STotalNativeBalance(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFCoordinatorV2PlusV2Example.contract.Call(opts, &out, "s_totalNativeBalance") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleSession) STotalNativeBalance() (*big.Int, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.STotalNativeBalance(&_VRFCoordinatorV2PlusV2Example.CallOpts) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleCallerSession) STotalNativeBalance() (*big.Int, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.STotalNativeBalance(&_VRFCoordinatorV2PlusV2Example.CallOpts) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleTransactor) FulfillRandomWords(opts *bind.TransactOpts, requestId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusV2Example.contract.Transact(opts, "fulfillRandomWords", requestId) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleSession) FulfillRandomWords(requestId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.FulfillRandomWords(&_VRFCoordinatorV2PlusV2Example.TransactOpts, requestId) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleTransactorSession) FulfillRandomWords(requestId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.FulfillRandomWords(&_VRFCoordinatorV2PlusV2Example.TransactOpts, requestId) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleTransactor) OnMigration(opts *bind.TransactOpts, encodedData []byte) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusV2Example.contract.Transact(opts, "onMigration", encodedData) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleSession) OnMigration(encodedData []byte) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.OnMigration(&_VRFCoordinatorV2PlusV2Example.TransactOpts, encodedData) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleTransactorSession) OnMigration(encodedData []byte) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.OnMigration(&_VRFCoordinatorV2PlusV2Example.TransactOpts, encodedData) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleTransactor) RequestRandomWords(opts *bind.TransactOpts, arg0 VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusV2Example.contract.Transact(opts, "requestRandomWords", arg0) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleSession) RequestRandomWords(arg0 VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.RequestRandomWords(&_VRFCoordinatorV2PlusV2Example.TransactOpts, arg0) +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleTransactorSession) RequestRandomWords(arg0 VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.RequestRandomWords(&_VRFCoordinatorV2PlusV2Example.TransactOpts, arg0) +} + +type GetSubscription struct { + Owner common.Address + Consumers []common.Address + LinkBalance *big.Int + NativeBalance *big.Int +} +type SSubscriptions struct { + Owner common.Address + LinkBalance *big.Int + NativeBalance *big.Int +} + +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2Example) Address() common.Address { + return _VRFCoordinatorV2PlusV2Example.address +} + +type VRFCoordinatorV2PlusV2ExampleInterface interface { + GenerateFakeRandomness(opts *bind.CallOpts, requestID *big.Int) ([]*big.Int, error) + + GetSubscription(opts *bind.CallOpts, subId *big.Int) (GetSubscription, + + error) + + SLink(opts *bind.CallOpts) (common.Address, error) + + SPrevCoordinator(opts *bind.CallOpts) (common.Address, error) + + SRequestConsumerMapping(opts *bind.CallOpts, arg0 *big.Int) (common.Address, error) + + SRequestId(opts *bind.CallOpts) (*big.Int, error) + + SSubscriptions(opts *bind.CallOpts, arg0 *big.Int) (SSubscriptions, + + error) + + STotalLinkBalance(opts *bind.CallOpts) (*big.Int, error) + + STotalNativeBalance(opts *bind.CallOpts) (*big.Int, error) + + FulfillRandomWords(opts *bind.TransactOpts, requestId *big.Int) (*types.Transaction, error) + + OnMigration(opts *bind.TransactOpts, encodedData []byte) (*types.Transaction, error) + + RequestRandomWords(opts *bind.TransactOpts, arg0 VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/vrf_coordinator_v2plus/vrf_coordinator_v2plus.go b/core/gethwrappers/generated/vrf_coordinator_v2plus/vrf_coordinator_v2plus.go index 33b05e4c4a9..f4f52e85382 100644 --- a/core/gethwrappers/generated/vrf_coordinator_v2plus/vrf_coordinator_v2plus.go +++ b/core/gethwrappers/generated/vrf_coordinator_v2plus/vrf_coordinator_v2plus.go @@ -66,8 +66,8 @@ type VRFV2PlusClientRandomWordsRequest struct { } var VRFCoordinatorV2PlusMetaData = &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\":\"FailedToSendEther\",\"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\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"have\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"want\",\"type\":\"uint256\"}],\"name\":\"InsufficientGasForConsumer\",\"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\":\"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\":[],\"name\":\"LinkAlreadySet\",\"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\":\"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\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeEthPPM\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structVRFCoordinatorV2Plus.FeeConfig\",\"name\":\"feeConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"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\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"EthFundsRecovered\",\"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\":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\":true,\"internalType\":\"address\",\"name\":\"oracle\",\"type\":\"address\"}],\"name\":\"ProvingKeyDeregistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oracle\",\"type\":\"address\"}],\"name\":\"ProvingKeyRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"outputSeed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"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\":\"amountEth\",\"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\":\"oldEthBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newEthBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFundedWithEth\",\"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_ETH_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\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"deregisterMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"}],\"name\":\"deregisterProvingKey\",\"outputs\":[],\"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\":\"structVRFCoordinatorV2Plus.RequestCommitment\",\"name\":\"rc\",\"type\":\"tuple\"}],\"name\":\"fulfillRandomWords\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"fundSubscriptionWithEth\",\"outputs\":[],\"stateMutability\":\"payable\",\"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\":\"ethBalance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"owner\",\"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\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdrawEth\",\"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\":\"addresspayable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverEthFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"registerMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"oracle\",\"type\":\"address\"},{\"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\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"}],\"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\":[],\"name\":\"s_feeConfig\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeEthPPM\",\"type\":\"uint32\"}],\"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\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"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_totalEthBalance\",\"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\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeEthPPM\",\"type\":\"uint32\"}],\"internalType\":\"structVRFCoordinatorV2Plus.FeeConfig\",\"name\":\"feeConfig\",\"type\":\"tuple\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"}],\"name\":\"setLINK\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"linkEthFeed\",\"type\":\"address\"}],\"name\":\"setLinkEthFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b50604051620060b0380380620060b0833981016040819052620000349162000188565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000dc565b505060016002555060601b6001600160601b031916608052620001ba565b6001600160a01b038116331415620001375760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019b57600080fd5b81516001600160a01b0381168114620001b357600080fd5b9392505050565b60805160601c615ed0620001e0600039600081816105e30152613b350152615ed06000f3fe6080604052600436106102fc5760003560e01c8063981837d51161018f578063bec4c08c116100e1578063dc311dd31161008a578063e95704bd11610064578063e95704bd14610972578063ee9d2d3814610999578063f2fde38b146109c657600080fd5b8063dc311dd31461090f578063e72f6e301461093f578063e8509bff1461095f57600080fd5b8063d98e620e116100bb578063d98e620e14610899578063da2f2610146108b9578063dac83d29146108ef57600080fd5b8063bec4c08c14610839578063caf70c4a14610859578063cb6317971461087957600080fd5b8063a4c0ed3611610143578063ad1783611161011d578063ad178361146107d9578063b08c8795146107f9578063b2a7cac51461081957600080fd5b8063a4c0ed3614610779578063a8cb447b14610799578063aa433aff146107b957600080fd5b80639d40a6fd116101745780639d40a6fd1461070a578063a02e061614610744578063a21a23e41461076457600080fd5b8063981837d5146106ca5780639b1c385e146106ea57600080fd5b806340d6bb8211610253578063689c4517116101fc57806379ba5097116101d657806379ba50971461066b57806386fe91c7146106805780638da5cb5b146106ac57600080fd5b8063689c4517146105d15780636b6feccc146106055780636f64f03f1461064b57600080fd5b80635d06b4ab1161022d5780635d06b4ab1461057c57806364d51a2a1461059c57806366316d8d146105b157600080fd5b806340d6bb821461050157806341af6c871461052c57806346d8d4861461055c57600080fd5b80630ae09540116102b5578063294daa491161028f578063294daa491461048d578063330987b3146104a9578063405b84fa146104e157600080fd5b80630ae095401461040d57806315c48b841461042d5780631b6b6d231461045557600080fd5b8063043bd6ae116102e6578063043bd6ae14610350578063088070f51461037457806308821d58146103ed57600080fd5b80620122911461030157806304104edb1461032e575b600080fd5b34801561030d57600080fd5b506103166109e6565b604051610325939291906159ab565b60405180910390f35b34801561033a57600080fd5b5061034e61034936600461533f565b610a62565b005b34801561035c57600080fd5b50610366600e5481565b604051908152602001610325565b34801561038057600080fd5b50600f546103bc9061ffff81169063ffffffff620100008204811691660100000000000081048216916a01000000000000000000009091041684565b6040805161ffff909516855263ffffffff938416602086015291831691840191909152166060820152608001610325565b3480156103f957600080fd5b5061034e610408366004615447565b610c24565b34801561041957600080fd5b5061034e610428366004615704565b610db8565b34801561043957600080fd5b5061044260c881565b60405161ffff9091168152602001610325565b34801561046157600080fd5b50600354610475906001600160a01b031681565b6040516001600160a01b039091168152602001610325565b34801561049957600080fd5b5060405160018152602001610325565b3480156104b557600080fd5b506104c96104c436600461551a565b610ea4565b6040516001600160601b039091168152602001610325565b3480156104ed57600080fd5b5061034e6104fc366004615704565b61135e565b34801561050d57600080fd5b506105176101f481565b60405163ffffffff9091168152602001610325565b34801561053857600080fd5b5061054c61054736600461549c565b61173d565b6040519015158152602001610325565b34801561056857600080fd5b5061034e61057736600461535c565b61193f565b34801561058857600080fd5b5061034e61059736600461533f565b611ada565b3480156105a857600080fd5b50610442606481565b3480156105bd57600080fd5b5061034e6105cc36600461535c565b611bb1565b3480156105dd57600080fd5b506104757f000000000000000000000000000000000000000000000000000000000000000081565b34801561061157600080fd5b5060105461062e9063ffffffff8082169164010000000090041682565b6040805163ffffffff938416815292909116602083015201610325565b34801561065757600080fd5b5061034e610666366004615391565b611d6e565b34801561067757600080fd5b5061034e611e86565b34801561068c57600080fd5b506007546104c9906801000000000000000090046001600160601b031681565b3480156106b857600080fd5b506000546001600160a01b0316610475565b3480156106d657600080fd5b5061034e6106e536600461533f565b611f37565b3480156106f657600080fd5b50610366610705366004615616565b611f61565b34801561071657600080fd5b5060075461072b9067ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610325565b34801561075057600080fd5b5061034e61075f36600461533f565b6123a2565b34801561077057600080fd5b5061036661240f565b34801561078557600080fd5b5061034e6107943660046153be565b61266f565b3480156107a557600080fd5b5061034e6107b436600461533f565b61285f565b3480156107c557600080fd5b5061034e6107d436600461549c565b61297b565b3480156107e557600080fd5b50600a54610475906001600160a01b031681565b34801561080557600080fd5b5061034e610814366004615666565b6129db565b34801561082557600080fd5b5061034e61083436600461549c565b612b65565b34801561084557600080fd5b5061034e610854366004615704565b612cd2565b34801561086557600080fd5b50610366610874366004615463565b612ea5565b34801561088557600080fd5b5061034e610894366004615704565b612ed5565b3480156108a557600080fd5b506103666108b436600461549c565b6131f2565b3480156108c557600080fd5b506104756108d436600461549c565b600b602052600090815260409020546001600160a01b031681565b3480156108fb57600080fd5b5061034e61090a366004615704565b613213565b34801561091b57600080fd5b5061092f61092a36600461549c565b61334b565b6040516103259493929190615ba9565b34801561094b57600080fd5b5061034e61095a36600461533f565b61342e565b61034e61096d36600461549c565b6135f6565b34801561097e57600080fd5b506007546104c990600160a01b90046001600160601b031681565b3480156109a557600080fd5b506103666109b436600461549c565b600d6020526000908152604090205481565b3480156109d257600080fd5b5061034e6109e136600461533f565b61374e565b600f54600c805460408051602080840282018101909252828152600094859460609461ffff8316946201000090930463ffffffff16939192839190830182828015610a5057602002820191906000526020600020905b815481526020019060010190808311610a3c575b50505050509050925092509250909192565b610a6a61375f565b60115460005b81811015610bf757826001600160a01b031660118281548110610a9557610a95615e54565b6000918252602090912001546001600160a01b03161415610be5576011610abd600184615d4c565b81548110610acd57610acd615e54565b600091825260209091200154601180546001600160a01b039092169183908110610af957610af9615e54565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055826011610b30600185615d4c565b81548110610b4057610b40615e54565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506011805480610b7f57610b7f615e3e565b6000828152602090819020600019908301810180546001600160a01b03191690559091019091556040516001600160a01b03851681527ff80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af37910160405180910390a1505050565b80610bef81615dbb565b915050610a70565b50604051635428d44960e01b81526001600160a01b03831660048201526024015b60405180910390fd5b50565b610c2c61375f565b604080518082018252600091610c5b919084906002908390839080828437600092019190915250612ea5915050565b6000818152600b60205260409020549091506001600160a01b031680610c9757604051631dfd6e1360e21b815260048101839052602401610c18565b6000828152600b6020526040812080546001600160a01b03191690555b600c54811015610d6f5782600c8281548110610cd257610cd2615e54565b90600052602060002001541415610d5d57600c805460009190610cf790600190615d4c565b81548110610d0757610d07615e54565b9060005260206000200154905080600c8381548110610d2857610d28615e54565b600091825260209091200155600c805480610d4557610d45615e3e565b60019003818190600052602060002001600090559055505b80610d6781615dbb565b915050610cb4565b50806001600160a01b03167f72be339577868f868798bac2c93e52d6f034fef4689a9848996c14ebb7416c0d83604051610dab91815260200190565b60405180910390a2505050565b60008281526005602052604090205482906001600160a01b031680610df057604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614610e2457604051636c51fda960e11b81526001600160a01b0382166004820152602401610c18565b600280541415610e645760405162461bcd60e51b815260206004820152601f6024820152600080516020615ea48339815191526044820152606401610c18565b60028055610e718461173d565b15610e8f57604051631685ecdd60e31b815260040160405180910390fd5b610e9984846137bb565b505060016002555050565b6000600280541415610ee65760405162461bcd60e51b815260206004820152601f6024820152600080516020615ea48339815191526044820152606401610c18565b6002805560005a90506000610efb8585613952565b90506000610f0f6080860160608701615734565b63ffffffff1667ffffffffffffffff811115610f2d57610f2d615e6a565b604051908082528060200260200182016040528015610f56578160200160208202803683370190505b50905060005b610f6c6080870160608801615734565b63ffffffff16811015610fe157826040015181604051602001610f99929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c828281518110610fc457610fc4615e54565b602090810291909101015280610fd981615dbb565b915050610f5c565b50602080830180516000908152600d90925260408083208390559051905182917f1fe543e3000000000000000000000000000000000000000000000000000000009161103291908690602401615a1e565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b03199094169390931790925291506000906110ae906110929060608b01908b01615734565b63ffffffff166110a860a08b0160808c0161533f565b84613ca7565b905060006110c76110c260a08b018b615bee565b613cf5565b51600f549091506000906110f29089906a0100000000000000000000900463ffffffff163a85613da4565b905081156111fb576020808b01356000908152600690915260409020546001600160601b03808316600160601b90920416101561114257604051631e9acf1760e31b815260040160405180910390fd5b60208a81013560009081526006909152604090208054829190600c90611179908490600160601b90046001600160601b0316615d63565b82546101009290920a6001600160601b0381810219909316918316021790915588516000908152600b60209081526040808320546001600160a01b0316835260099091528120805485945090926111d291859116615cf7565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506112e7565b6020808b01356000908152600690915260409020546001600160601b038083169116101561123c57604051631e9acf1760e31b815260040160405180910390fd5b6020808b0135600090815260069091526040812080548392906112699084906001600160601b0316615d63565b82546101009290920a6001600160601b0381810219909316918316021790915588516000908152600b60209081526040808320546001600160a01b0316835260089091528120805485945090926112c291859116615cf7565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b60006113026040518060200160405280851515815250613df4565b905087602001517f2c7b705f67f9ae2cbd3edc06b5b99afb00441ee4aea7bb77f109273bc1f3b5eb89604001518484886040516113429493929190615b6e565b60405180910390a25060016002559a9950505050505050505050565b61136781613e7a565b61138f57604051635428d44960e01b81526001600160a01b0382166004820152602401610c18565b60008060008061139e8661334b565b9350935093509350336001600160a01b0316826001600160a01b0316146114075760405162461bcd60e51b815260206004820152601660248201527f4e6f7420737562736372697074696f6e206f776e6572000000000000000000006044820152606401610c18565b6114108661173d565b1561145d5760405162461bcd60e51b815260206004820152601660248201527f50656e64696e67207265717565737420657869737473000000000000000000006044820152606401610c18565b60006040518060c00160405280611472600190565b60ff168152602001888152602001846001600160a01b03168152602001838152602001866001600160601b03168152602001856001600160601b031681525090506000816040516020016114c69190615936565b60405160208183030381529060405290506114e088613ee4565b50506040517fce3f47190000000000000000000000000000000000000000000000000000000081526001600160a01b0388169063ce3f4719906001600160601b03881690611532908590600401615923565b6000604051808303818588803b15801561154b57600080fd5b505af115801561155f573d6000803e3d6000fd5b505060035460405163a9059cbb60e01b81526001600160a01b038c811660048301526001600160601b038c166024830152909116935063a9059cbb92506044019050602060405180830381600087803b1580156115bb57600080fd5b505af11580156115cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115f3919061547f565b61163f5760405162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e647300000000000000000000000000006044820152606401610c18565b60005b83518110156116f05783818151811061165d5761165d615e54565b60209081029190910101516040517f8ea981170000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116600483015290911690638ea9811790602401600060405180830381600087803b1580156116c557600080fd5b505af11580156116d9573d6000803e3d6000fd5b5050505080806116e890615dbb565b915050611642565b50604080516001600160a01b0389168152602081018a90527fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187910160405180910390a15050505050505050565b6000818152600560209081526040808320815160608101835281546001600160a01b03908116825260018301541681850152600282018054845181870281018701865281815287969395860193909291908301828280156117c757602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116117a9575b505050505081525050905060005b8160400151518110156119355760005b600c548110156119225760006118eb600c838154811061180757611807615e54565b90600052602060002001548560400151858151811061182857611828615e54565b602002602001015188600460008960400151898151811061184b5761184b615e54565b6020908102919091018101516001600160a01b03908116835282820193909352604091820160009081208e825282528290205482518083018890529590931685830152606085019390935267ffffffffffffffff9091166080808501919091528151808503909101815260a08401825280519083012060c084019490945260e0808401859052815180850390910181526101009093019052815191012091565b506000818152600d60205260409020549091501561190f5750600195945050505050565b508061191a81615dbb565b9150506117e5565b508061192d81615dbb565b9150506117d5565b5060009392505050565b60028054141561197f5760405162461bcd60e51b815260206004820152601f6024820152600080516020615ea48339815191526044820152606401610c18565b60028055336000908152600960205260409020546001600160601b03808316911610156119bf57604051631e9acf1760e31b815260040160405180910390fd5b33600090815260096020526040812080548392906119e79084906001600160601b0316615d63565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600760148282829054906101000a90046001600160601b0316611a2f9190615d63565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506000826001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114611aa9576040519150601f19603f3d011682016040523d82523d6000602084013e611aae565b606091505b5050905080611ad057604051630dcf35db60e41b815260040160405180910390fd5b5050600160025550565b611ae261375f565b611aeb81613e7a565b15611b2d576040517fac8a27ef0000000000000000000000000000000000000000000000000000000081526001600160a01b0382166004820152602401610c18565b601180546001810182556000919091527f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c680180546001600160a01b0319166001600160a01b0383169081179091556040519081527fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af016259060200160405180910390a150565b600280541415611bf15760405162461bcd60e51b815260206004820152601f6024820152600080516020615ea48339815191526044820152606401610c18565b60028055336000908152600860205260409020546001600160601b0380831691161015611c3157604051631e9acf1760e31b815260040160405180910390fd5b3360009081526008602052604081208054839290611c599084906001600160601b0316615d63565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600760088282829054906101000a90046001600160601b0316611ca19190615d63565b82546101009290920a6001600160601b0381810219909316918316021790915560035460405163a9059cbb60e01b81526001600160a01b03868116600483015292851660248201529116915063a9059cbb90604401602060405180830381600087803b158015611d1057600080fd5b505af1158015611d24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d48919061547f565b611d6557604051631e9acf1760e31b815260040160405180910390fd5b50506001600255565b611d7661375f565b604080518082018252600091611da5919084906002908390839080828437600092019190915250612ea5915050565b6000818152600b60205260409020549091506001600160a01b031615611dfa576040517f4a0b8fa700000000000000000000000000000000000000000000000000000000815260048101829052602401610c18565b6000818152600b6020908152604080832080546001600160a01b0319166001600160a01b038816908117909155600c805460018101825594527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7909301849055518381527fe729ae16526293f74ade739043022254f1489f616295a25bf72dfb4511ed73b89101610dab565b6001546001600160a01b03163314611ee05760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610c18565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611f3f61375f565b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b6000600280541415611fa35760405162461bcd60e51b815260206004820152601f6024820152600080516020615ea48339815191526044820152606401610c18565b600280556020808301356000908152600590915260409020546001600160a01b0316611fe257604051630fb532db60e11b815260040160405180910390fd5b33600090815260046020908152604080832085830135845290915290205467ffffffffffffffff1680612034576040516379bfd40160e01b815260208401356004820152336024820152604401610c18565b600f5461ffff1661204b606085016040860161564b565b61ffff16108061206e575060c8612068606085016040860161564b565b61ffff16115b156120b457612083606084016040850161564b565b600f5460405163539c34bb60e11b815261ffff92831660048201529116602482015260c86044820152606401610c18565b600f5462010000900463ffffffff166120d36080850160608601615734565b63ffffffff16111561213c576120ef6080840160608501615734565b600f546040517ff5d7e01e00000000000000000000000000000000000000000000000000000000815263ffffffff9283166004820152620100009091049091166024820152604401610c18565b6101f461214f60a0850160808601615734565b63ffffffff1611156121ae5761216b60a0840160808501615734565b6040517f47386bec00000000000000000000000000000000000000000000000000000000815263ffffffff90911660048201526101f46024820152604401610c18565b60006121bb826001615ccb565b6040805186356020808301829052338385015280890135606084015267ffffffffffffffff85166080808501919091528451808503909101815260a0808501865281519183019190912060c085019390935260e080850184905285518086039091018152610100909401909452825192019190912092935090600090612247906110c290890189615bee565b9050600061225482613df4565b90508361225f614136565b60208a013561227460808c0160608d01615734565b61228460a08d0160808e01615734565b338660405160200161229c9796959493929190615aab565b60405160208183030381529060405280519060200120600d600086815260200190815260200160002081905550336001600160a01b0316886020013589600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e87878d6040016020810190612313919061564b565b8e60600160208101906123269190615734565b8f60800160208101906123399190615734565b8960405161234c96959493929190615a6c565b60405180910390a4505033600090815260046020908152604080832098820135835297905295909520805467ffffffffffffffff191667ffffffffffffffff939093169290921790915560016002559392505050565b6123aa61375f565b6003546001600160a01b0316156123ed576040517f2d118a6e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b60006002805414156124515760405162461bcd60e51b815260206004820152601f6024820152600080516020615ea48339815191526044820152606401610c18565b60028055600033612463600143615d4c565b600754604051606093841b6bffffffffffffffffffffffff199081166020830152924060348201523090931b909116605483015260c01b77ffffffffffffffffffffffffffffffffffffffffffffffff1916606882015260700160408051601f1981840301815291905280516020909101206007805491925067ffffffffffffffff9091169060006124f483615dd6565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505060008067ffffffffffffffff81111561253657612536615e6a565b60405190808252806020026020018201604052801561255f578160200160208202803683370190505b5060408051808201825260008082526020808301828152878352600682528483209351845491516001600160601b03908116600160601b0277ffffffffffffffffffffffffffffffffffffffffffffffff199093169116171790925582516060810184523381528083018281528185018681528884526005855294909220815181546001600160a01b039182166001600160a01b0319918216178355935160018301805491909216941693909317909255925180519495509293909261262c92600285019291019061516a565b50506040513381528391507f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d9060200160405180910390a2509050600160025590565b6002805414156126af5760405162461bcd60e51b815260206004820152601f6024820152600080516020615ea48339815191526044820152606401610c18565b600280556003546001600160a01b031633146126f7576040517f44b0e3c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114612731576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061273f8284018461549c565b6000818152600560205260409020549091506001600160a01b031661277757604051630fb532db60e11b815260040160405180910390fd5b600081815260066020526040812080546001600160601b03169186919061279e8385615cf7565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600760088282829054906101000a90046001600160601b03166127e69190615cf7565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a8287846128399190615cb3565b604080519283526020830191909152015b60405180910390a25050600160025550505050565b61286761375f565b6007544790600160a01b90046001600160601b0316818111156128a7576040516354ced18160e11b81526004810182905260248101839052604401610c18565b818110156129765760006128bb8284615d4c565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d806000811461290a576040519150601f19603f3d011682016040523d82523d6000602084013e61290f565b606091505b505090508061293157604051630dcf35db60e41b815260040160405180910390fd5b604080516001600160a01b0387168152602081018490527f879c9ea2b9d5345b84ccd12610b032602808517cebdb795007f3dcb4df377317910160405180910390a150505b505050565b61298361375f565b6000818152600560205260409020546001600160a01b03166129b857604051630fb532db60e11b815260040160405180910390fd5b600081815260056020526040902054610c219082906001600160a01b03166137bb565b6129e361375f565b60c861ffff87161115612a1d5760405163539c34bb60e11b815261ffff871660048201819052602482015260c86044820152606401610c18565b60008213612a41576040516321ea67b360e11b815260048101839052602401610c18565b604080516080808201835261ffff891680835263ffffffff89811660208086018290528a83168688018190528a84166060978801819052600f805465ffffffffffff19168717620100008602176dffffffffffffffff0000000000001916660100000000000084026dffffffff000000000000000000001916176a010000000000000000000083021790558951601080548c86015192881667ffffffffffffffff1990911617640100000000928816929092029190911790819055600e8c9055895196875286840194909452978501529483019590955291810186905283821660a08201529290911c1660c08201527f777357bb93f63d088f18112d3dba38457aec633eb8f1341e1d418380ad328e789060e00160405180910390a1505050505050565b600280541415612ba55760405162461bcd60e51b815260206004820152601f6024820152600080516020615ea48339815191526044820152606401610c18565b600280556000818152600560205260409020546001600160a01b0316612bde57604051630fb532db60e11b815260040160405180910390fd5b6000818152600560205260409020600101546001600160a01b03163314612c5057600081815260056020526040908190206001015490517fd084e9750000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610c18565b6000818152600560209081526040918290208054336001600160a01b0319808316821784556001909301805490931690925583516001600160a01b0390911680825292810191909152909183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c938691015b60405180910390a250506001600255565b60008281526005602052604090205482906001600160a01b031680612d0a57604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614612d3e57604051636c51fda960e11b81526001600160a01b0382166004820152602401610c18565b600280541415612d7e5760405162461bcd60e51b815260206004820152601f6024820152600080516020615ea48339815191526044820152606401610c18565b60028080556000858152600560205260409020015460641415612dcd576040517f05a48e0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038316600090815260046020908152604080832087845290915290205467ffffffffffffffff1615612e0557610e99565b6001600160a01b03831660008181526004602090815260408083208884528252808320805467ffffffffffffffff19166001908117909155600583528184206002018054918201815584529282902090920180546001600160a01b03191684179055905191825285917f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e191015b60405180910390a2505060016002555050565b600081604051602001612eb89190615915565b604051602081830303815290604052805190602001209050919050565b60008281526005602052604090205482906001600160a01b031680612f0d57604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614612f4157604051636c51fda960e11b81526001600160a01b0382166004820152602401610c18565b600280541415612f815760405162461bcd60e51b815260206004820152601f6024820152600080516020615ea48339815191526044820152606401610c18565b60028055612f8e8461173d565b15612fac57604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b038316600090815260046020908152604080832087845290915290205467ffffffffffffffff16613009576040516379bfd40160e01b8152600481018590526001600160a01b0384166024820152604401610c18565b60008481526005602090815260408083206002018054825181850281018501909352808352919290919083018282801561306c57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161304e575b505050505090506000600182516130839190615d4c565b905060005b825181101561318f57856001600160a01b03168382815181106130ad576130ad615e54565b60200260200101516001600160a01b0316141561317d5760008383815181106130d8576130d8615e54565b6020026020010151905080600560008a8152602001908152602001600020600201838154811061310a5761310a615e54565b600091825260208083209190910180546001600160a01b0319166001600160a01b03949094169390931790925589815260059091526040902060020180548061315557613155615e3e565b600082815260209020810160001990810180546001600160a01b03191690550190555061318f565b8061318781615dbb565b915050613088565b506001600160a01b03851660008181526004602090815260408083208a8452825291829020805467ffffffffffffffff19169055905191825287917f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a7910161284a565b600c818154811061320257600080fd5b600091825260209091200154905081565b60008281526005602052604090205482906001600160a01b03168061324b57604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b0382161461327f57604051636c51fda960e11b81526001600160a01b0382166004820152602401610c18565b6002805414156132bf5760405162461bcd60e51b815260206004820152601f6024820152600080516020615ea48339815191526044820152606401610c18565b600280556000848152600560205260409020600101546001600160a01b03848116911614610e995760008481526005602090815260409182902060010180546001600160a01b0319166001600160a01b03871690811790915582513381529182015285917f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a19101612e92565b600081815260056020526040812054819081906060906001600160a01b031661338757604051630fb532db60e11b815260040160405180910390fd5b60008581526006602090815260408083205460058352928190208054600290910180548351818602810186019094528084526001600160601b0380871696600160601b900416946001600160a01b0390931693919283919083018282801561341857602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116133fa575b5050505050905093509350935093509193509193565b61343661375f565b6003546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561349357600080fd5b505afa1580156134a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134cb91906154b5565b6007549091506801000000000000000090046001600160601b031681811115613511576040516354ced18160e11b81526004810182905260248101839052604401610c18565b818110156129765760006135258284615d4c565b60035460405163a9059cbb60e01b81526001600160a01b0387811660048301526024820184905292935091169063a9059cbb90604401602060405180830381600087803b15801561357557600080fd5b505af1158015613589573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135ad919061547f565b50604080516001600160a01b0386168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a150505050565b6002805414156136365760405162461bcd60e51b815260206004820152601f6024820152600080516020615ea48339815191526044820152606401610c18565b600280556000818152600560205260409020546001600160a01b031661366f57604051630fb532db60e11b815260040160405180910390fd5b60008181526006602052604090208054600160601b90046001600160601b0316903490600c61369e8385615cf7565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600760148282829054906101000a90046001600160601b03166136e69190615cf7565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f3f1ddc3ab1bdb39001ad76ca51a0e6f57ce6627c69f251d1de41622847721cde8234846137399190615cb3565b60408051928352602083019190915201612cc1565b61375661375f565b610c21816141cf565b6000546001600160a01b031633146137b95760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610c18565b565b6000806137c784613ee4565b60035460405163a9059cbb60e01b81526001600160a01b0387811660048301526001600160601b0385166024830152939550919350919091169063a9059cbb90604401602060405180830381600087803b15801561382457600080fd5b505af1158015613838573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061385c919061547f565b61387957604051631e9acf1760e31b815260040160405180910390fd5b6000836001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d80600081146138cf576040519150601f19603f3d011682016040523d82523d6000602084013e6138d4565b606091505b50509050806138f657604051630dcf35db60e41b815260040160405180910390fd5b604080516001600160a01b03861681526001600160601b038581166020830152841681830152905186917f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c4919081900360600190a25050505050565b60408051606081018252600080825260208201819052818301819052825180840184529192909161399b9186906002908390839080828437600092019190915250612ea5915050565b6000818152600b60205260409020549091506001600160a01b0316806139d757604051631dfd6e1360e21b815260048101839052602401610c18565b6000828660c001356040516020016139f9929190918252602082015260400190565b60408051601f1981840301815291815281516020928301206000818152600d90935291205490915080613a58576040517f3688124a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81613a66602088018861574f565b6020880135613a7b60608a0160408b01615734565b613a8b60808b0160608c01615734565b613a9b60a08c0160808d0161533f565b613aa860a08d018d615bee565b604051602001613abf989796959493929190615af5565b604051602081830303815290604052805190602001208114613b0d576040517fd529142c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000613b24613b1f602089018961574f565b614279565b905080613c32576001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663e9413d38613b6760208a018a61574f565b6040516001600160e01b031960e084901b16815267ffffffffffffffff909116600482015260240160206040518083038186803b158015613ba757600080fd5b505afa158015613bbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bdf91906154b5565b905080613c3257613bf3602088018861574f565b6040517f175dadad00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610c18565b6040805160c08a0135602080830191909152818301849052825180830384018152606090920190925280519101206000613c7a613c74368c90038c018c615572565b83614380565b90506040518060600160405280888152602001868152602001828152509750505050505050505b92915050565b60005a611388811015613cb957600080fd5b611388810390508460408204820311613cd157600080fd5b50823b613cdd57600080fd5b60008083516020850160008789f190505b9392505050565b60408051602081019091526000815281613d1e5750604080516020810190915260008152613ca1565b7f92fd133800000000000000000000000000000000000000000000000000000000613d498385615d8b565b6001600160e01b03191614613d8a576040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613d978260048186615c89565b810190613cee91906154ce565b60008115613dd257601054613dcb9086908690640100000000900463ffffffff16866143eb565b9050613dec565b601054613de9908690869063ffffffff1686614455565b90505b949350505050565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401613e2d91511515815260200190565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b03199093169290921790915292915050565b6000805b601154811015613edb57826001600160a01b031660118281548110613ea557613ea5615e54565b6000918252602090912001546001600160a01b03161415613ec95750600192915050565b80613ed381615dbb565b915050613e7e565b50600092915050565b6000818152600560209081526040808320815160608101835281546001600160a01b03908116825260018301541681850152600282018054845181870281018701865281815287968796949594860193919290830182828015613f7057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613f52575b5050509190925250505060008581526006602090815260408083208151808301909252546001600160601b03808216808452600160601b9092041692820183905296509094509192505b826040015151811015614032576004600084604001518381518110613fe157613fe1615e54565b6020908102919091018101516001600160a01b0316825281810192909252604090810160009081208982529092529020805467ffffffffffffffff191690558061402a81615dbb565b915050613fba565b50600085815260056020526040812080546001600160a01b0319908116825560018201805490911690559061406a60028301826151cf565b50506000858152600660205260409020805477ffffffffffffffffffffffffffffffffffffffffffffffff19169055600780548591906008906140c39084906801000000000000000090046001600160601b0316615d63565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555082600760148282829054906101000a90046001600160601b031661410b9190615d63565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050915091565b60004661a4b181148061414b575062066eed81145b156141c85760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561418a57600080fd5b505afa15801561419e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141c291906154b5565b91505090565b4391505090565b6001600160a01b0381163314156142285760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610c18565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60004661a4b181148061428e575062066eed81145b15614370576101008367ffffffffffffffff166142a9614136565b6142b39190615d4c565b11806142d057506142c2614136565b8367ffffffffffffffff1610155b156142de5750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152606490632b407a829060240160206040518083038186803b15801561433857600080fd5b505afa15801561434c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cee91906154b5565b505067ffffffffffffffff164090565b60006143b48360000151846020015185604001518660600151868860a001518960c001518a60e001518b610100015161455c565b600383602001516040516020016143cc929190615a0a565b60408051601f1981840301815291905280516020909101209392505050565b6000806143f6614797565b905060005a6144058888615cb3565b61440f9190615d4c565b6144199085615d2d565b9050600061443263ffffffff871664e8d4a51000615d2d565b90508261443f8284615cb3565b6144499190615cb3565b98975050505050505050565b6000806144606147f3565b905060008113614486576040516321ea67b360e11b815260048101829052602401610c18565b6000614490614797565b9050600082825a6144a18b8b615cb3565b6144ab9190615d4c565b6144b59088615d2d565b6144bf9190615cb3565b6144d190670de0b6b3a7640000615d2d565b6144db9190615d19565b905060006144f463ffffffff881664e8d4a51000615d2d565b905061450c816b033b2e3c9fd0803ce8000000615d4c565b821115614545576040517fe80fa38100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61454f8183615cb3565b9998505050505050505050565b614565896148da565b6145b15760405162461bcd60e51b815260206004820152601a60248201527f7075626c6963206b6579206973206e6f74206f6e2063757276650000000000006044820152606401610c18565b6145ba886148da565b6146065760405162461bcd60e51b815260206004820152601560248201527f67616d6d61206973206e6f74206f6e20637572766500000000000000000000006044820152606401610c18565b61460f836148da565b61465b5760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e2063757276650000006044820152606401610c18565b614664826148da565b6146b05760405162461bcd60e51b815260206004820152601c60248201527f73486173685769746e657373206973206e6f74206f6e206375727665000000006044820152606401610c18565b6146bc878a88876149b3565b6147085760405162461bcd60e51b815260206004820152601960248201527f6164647228632a706b2b732a6729213d5f755769746e657373000000000000006044820152606401610c18565b60006147148a87614ae8565b90506000614727898b878b868989614b4c565b90506000614738838d8d8a86614c6c565b9050808a146147895760405162461bcd60e51b815260206004820152600d60248201527f696e76616c69642070726f6f66000000000000000000000000000000000000006044820152606401610c18565b505050505050505050505050565b60004661a4b18114806147ac575062066eed81145b156147eb57606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561418a57600080fd5b600091505090565b600f54600a54604080517ffeaf968c00000000000000000000000000000000000000000000000000000000815290516000936601000000000000900463ffffffff169283151592859283926001600160a01b03169163feaf968c9160048083019260a0929190829003018186803b15801561486d57600080fd5b505afa158015614881573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148a59190615779565b5094509092508491505080156148c957506148c08242615d4c565b8463ffffffff16105b15613dec5750600e54949350505050565b80516000906401000003d019116149335760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420782d6f7264696e61746500000000000000000000000000006044820152606401610c18565b60208201516401000003d0191161498c5760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420792d6f7264696e61746500000000000000000000000000006044820152606401610c18565b60208201516401000003d0199080096149ac8360005b6020020151614cac565b1492915050565b60006001600160a01b038216614a0b5760405162461bcd60e51b815260206004820152600b60248201527f626164207769746e6573730000000000000000000000000000000000000000006044820152606401610c18565b602084015160009060011615614a2257601c614a25565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe19918203925060009190890987516040805160008082526020820180845287905260ff88169282019290925260608101929092526080820183905291925060019060a0016020604051602081039080840390855afa158015614ac0573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b614af06151ed565b614b1d60018484604051602001614b09939291906158f4565b604051602081830303815290604052614cd0565b90505b614b29816148da565b613ca1578051604080516020810192909252614b459101614b09565b9050614b20565b614b546151ed565b825186516401000003d0199081900691061415614bb35760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e637400006044820152606401610c18565b614bbe878988614d1f565b614c0a5760405162461bcd60e51b815260206004820152601660248201527f4669727374206d756c20636865636b206661696c6564000000000000000000006044820152606401610c18565b614c15848685614d1f565b614c615760405162461bcd60e51b815260206004820152601760248201527f5365636f6e64206d756c20636865636b206661696c65640000000000000000006044820152606401610c18565b614449868484614e59565b600060028686868587604051602001614c8a96959493929190615895565b60408051601f1981840301815291905280516020909101209695505050505050565b6000806401000003d01980848509840990506401000003d019600782089392505050565b614cd86151ed565b614ce182614f20565b8152614cf6614cf18260006149a2565b614f5b565b602082018190526002900660011415614d1a576020810180516401000003d0190390525b919050565b600082614d6e5760405162461bcd60e51b815260206004820152600b60248201527f7a65726f207363616c61720000000000000000000000000000000000000000006044820152606401610c18565b83516020850151600090614d8490600290615dfe565b15614d9057601c614d93565b601b5b9050600070014551231950b75fc4402da1732fc9bebe198387096040805160008082526020820180845281905260ff86169282019290925260608101869052608081018390529192509060019060a0016020604051602081039080840390855afa158015614e05573d6000803e3d6000fd5b505050602060405103519050600086604051602001614e249190615883565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614e616151ed565b835160208086015185519186015160009384938493614e8293909190614f7b565b919450925090506401000003d019858209600114614ee25760405162461bcd60e51b815260206004820152601960248201527f696e765a206d75737420626520696e7665727365206f66207a000000000000006044820152606401610c18565b60405180604001604052806401000003d01980614f0157614f01615e28565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d0198110614d1a57604080516020808201939093528151808203840181529082019091528051910120614f28565b6000613ca1826002614f746401000003d0196001615cb3565b901c61505b565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614fbb838385856150fd565b9098509050614fcc88828e88615121565b9098509050614fdd88828c87615121565b90985090506000614ff08d878b85615121565b9098509050615001888286866150fd565b909850905061501288828e89615121565b9098509050818114615047576401000003d019818a0998506401000003d01982890997506401000003d019818309965061504b565b8196505b5050505050509450945094915050565b60008061506661520b565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a0820152615098615229565b60208160c0846005600019fa9250826150f35760405162461bcd60e51b815260206004820152601260248201527f6269674d6f64457870206661696c7572652100000000000000000000000000006044820152606401610c18565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b8280548282559060005260206000209081019282156151bf579160200282015b828111156151bf57825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019061518a565b506151cb929150615247565b5090565b5080546000825590600052602060002090810190610c219190615247565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b808211156151cb5760008155600101615248565b8035614d1a81615e80565b8060408101831015613ca157600080fd5b600082601f83011261528957600080fd5b615291615c3c565b8083856040860111156152a357600080fd5b60005b60028110156152c55781358452602093840193909101906001016152a6565b509095945050505050565b600060c082840312156152e257600080fd5b50919050565b803561ffff81168114614d1a57600080fd5b803563ffffffff81168114614d1a57600080fd5b805169ffffffffffffffffffff81168114614d1a57600080fd5b80356001600160601b0381168114614d1a57600080fd5b60006020828403121561535157600080fd5b8135613cee81615e80565b6000806040838503121561536f57600080fd5b823561537a81615e80565b915061538860208401615328565b90509250929050565b600080606083850312156153a457600080fd5b82356153af81615e80565b91506153888460208501615267565b600080600080606085870312156153d457600080fd5b84356153df81615e80565b935060208501359250604085013567ffffffffffffffff8082111561540357600080fd5b818701915087601f83011261541757600080fd5b81358181111561542657600080fd5b88602082850101111561543857600080fd5b95989497505060200194505050565b60006040828403121561545957600080fd5b613cee8383615267565b60006040828403121561547557600080fd5b613cee8383615278565b60006020828403121561549157600080fd5b8151613cee81615e95565b6000602082840312156154ae57600080fd5b5035919050565b6000602082840312156154c757600080fd5b5051919050565b6000602082840312156154e057600080fd5b6040516020810181811067ffffffffffffffff8211171561550357615503615e6a565b604052823561551181615e95565b81529392505050565b6000808284036101c081121561552f57600080fd5b6101a08082121561553f57600080fd5b849350830135905067ffffffffffffffff81111561555c57600080fd5b615568858286016152d0565b9150509250929050565b60006101a0828403121561558557600080fd5b61558d615c65565b6155978484615278565b81526155a68460408501615278565b60208201526080830135604082015260a0830135606082015260c083013560808201526155d560e0840161525c565b60a08201526101006155e985828601615278565b60c08301526155fc856101408601615278565b60e083015261018084013581830152508091505092915050565b60006020828403121561562857600080fd5b813567ffffffffffffffff81111561563f57600080fd5b613dec848285016152d0565b60006020828403121561565d57600080fd5b613cee826152e8565b60008060008060008086880360e081121561568057600080fd5b615689886152e8565b9650615697602089016152fa565b95506156a5604089016152fa565b94506156b3606089016152fa565b9350608088013592506040609f19820112156156ce57600080fd5b506156d7615c3c565b6156e360a089016152fa565b81526156f160c089016152fa565b6020820152809150509295509295509295565b6000806040838503121561571757600080fd5b82359150602083013561572981615e80565b809150509250929050565b60006020828403121561574657600080fd5b613cee826152fa565b60006020828403121561576157600080fd5b813567ffffffffffffffff81168114613cee57600080fd5b600080600080600060a0868803121561579157600080fd5b61579a8661530e565b94506020860151935060408601519250606086015191506157bd6080870161530e565b90509295509295909350565b600081518084526020808501945080840160005b838110156158025781516001600160a01b0316875295820195908201906001016157dd565b509495945050505050565b8060005b6002811015615830578151845260209384019390910190600101615811565b50505050565b6000815180845260005b8181101561585c57602081850181015186830182015201615840565b8181111561586e576000602083870101525b50601f01601f19169290920160200192915050565b61588d818361580d565b604001919050565b8681526158a5602082018761580d565b6158b2606082018661580d565b6158bf60a082018561580d565b6158cc60e082018461580d565b60609190911b6bffffffffffffffffffffffff19166101208201526101340195945050505050565b838152615904602082018461580d565b606081019190915260800192915050565b60408101613ca1828461580d565b602081526000613cee6020830184615836565b6020815260ff8251166020820152602082015160408201526001600160a01b0360408301511660608201526000606083015160c0608084015261597c60e08401826157c9565b905060808401516001600160601b0380821660a08601528060a08701511660c086015250508091505092915050565b60006060820161ffff86168352602063ffffffff86168185015260606040850152818551808452608086019150828701935060005b818110156159fc578451835293830193918301916001016159e0565b509098975050505050505050565b82815260608101613cee602083018461580d565b6000604082018483526020604081850152818551808452606086019150828701935060005b81811015615a5f57845183529383019391830191600101615a43565b5090979650505050505050565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a083015261444960c0830184615836565b878152866020820152856040820152600063ffffffff80871660608401528086166080840152506001600160a01b03841660a083015260e060c083015261454f60e0830184615836565b88815267ffffffffffffffff88166020820152866040820152600063ffffffff80881660608401528087166080840152506001600160a01b03851660a083015260e060c08301528260e08301526101008385828501376000838501820152601f909301601f191690910190910198975050505050505050565b8481526001600160601b0384166020820152608060408201526000615b966080830185615836565b9050821515606083015295945050505050565b60006001600160601b0380871683528086166020840152506001600160a01b038416604083015260806060830152615be460808301846157c9565b9695505050505050565b6000808335601e19843603018112615c0557600080fd5b83018035915067ffffffffffffffff821115615c2057600080fd5b602001915036819003821315615c3557600080fd5b9250929050565b6040805190810167ffffffffffffffff81118282101715615c5f57615c5f615e6a565b60405290565b604051610120810167ffffffffffffffff81118282101715615c5f57615c5f615e6a565b60008085851115615c9957600080fd5b83861115615ca657600080fd5b5050820193919092039150565b60008219821115615cc657615cc6615e12565b500190565b600067ffffffffffffffff808316818516808303821115615cee57615cee615e12565b01949350505050565b60006001600160601b03808316818516808303821115615cee57615cee615e12565b600082615d2857615d28615e28565b500490565b6000816000190483118215151615615d4757615d47615e12565b500290565b600082821015615d5e57615d5e615e12565b500390565b60006001600160601b0383811690831681811015615d8357615d83615e12565b039392505050565b6001600160e01b03198135818116916004851015615db35780818660040360031b1b83161692505b505092915050565b6000600019821415615dcf57615dcf615e12565b5060010190565b600067ffffffffffffffff80831681811415615df457615df4615e12565b6001019392505050565b600082615e0d57615e0d615e28565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610c2157600080fd5b8015158114610c2157600080fdfe5265656e7472616e637947756172643a207265656e7472616e742063616c6c00a164736f6c6343000806000a", + 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\":\"FailedToSendEther\",\"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\":[{\"internalType\":\"uint256\",\"name\":\"have\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"want\",\"type\":\"uint256\"}],\"name\":\"InsufficientGasForConsumer\",\"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\":\"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\":[],\"name\":\"LinkAlreadySet\",\"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\":\"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\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeEthPPM\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structVRFCoordinatorV2Plus.FeeConfig\",\"name\":\"feeConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"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\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"EthFundsRecovered\",\"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\":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\":true,\"internalType\":\"address\",\"name\":\"oracle\",\"type\":\"address\"}],\"name\":\"ProvingKeyDeregistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oracle\",\"type\":\"address\"}],\"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\":\"amountEth\",\"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\":\"oldEthBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newEthBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFundedWithEth\",\"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_ETH_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\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"deregisterMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"}],\"name\":\"deregisterProvingKey\",\"outputs\":[],\"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\":\"structVRFCoordinatorV2Plus.RequestCommitment\",\"name\":\"rc\",\"type\":\"tuple\"}],\"name\":\"fulfillRandomWords\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"fundSubscriptionWithEth\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveSubscriptionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"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\":\"ethBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"reqCount\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"owner\",\"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\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdrawEth\",\"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\":\"addresspayable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverEthFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"registerMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"oracle\",\"type\":\"address\"},{\"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\"}],\"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\":[],\"name\":\"s_feeConfig\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeEthPPM\",\"type\":\"uint32\"}],\"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\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"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_totalEthBalance\",\"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\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeEthPPM\",\"type\":\"uint32\"}],\"internalType\":\"structVRFCoordinatorV2Plus.FeeConfig\",\"name\":\"feeConfig\",\"type\":\"tuple\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkEthFeed\",\"type\":\"address\"}],\"name\":\"setLINKAndLINKETHFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b506040516200604038038062006040833981016040819052620000349162000183565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d7565b50505060601b6001600160601b031916608052620001b5565b6001600160a01b038116331415620001325760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019657600080fd5b81516001600160a01b0381168114620001ae57600080fd5b9392505050565b60805160601c615e65620001db600039600081816105ee015261397a0152615e656000f3fe6080604052600436106102dc5760003560e01c80638da5cb5b1161017f578063bec4c08c116100e1578063dc311dd31161008a578063e95704bd11610064578063e95704bd1461095d578063ee9d2d3814610984578063f2fde38b146109b157600080fd5b8063dc311dd3146108f9578063e72f6e301461092a578063e8509bff1461094a57600080fd5b8063d98e620e116100bb578063d98e620e14610883578063da2f2610146108a3578063dac83d29146108d957600080fd5b8063bec4c08c14610823578063caf70c4a14610843578063cb6317971461086357600080fd5b8063a8cb447b11610143578063aefb212f1161011d578063aefb212f146107b6578063b08c8795146107e3578063b2a7cac51461080357600080fd5b8063a8cb447b14610756578063aa433aff14610776578063ad1783611461079657600080fd5b80638da5cb5b146106ab5780639b1c385e146106c95780639d40a6fd146106e9578063a21a23e414610721578063a4c0ed361461073657600080fd5b806340d6bb821161024357806366316d8d116101ec5780636f64f03f116101c65780636f64f03f1461065657806379ba50971461067657806386fe91c71461068b57600080fd5b806366316d8d146105bc578063689c4517146105dc5780636b6feccc1461061057600080fd5b806357133e641161021d57806357133e64146105675780635d06b4ab1461058757806364d51a2a146105a757600080fd5b806340d6bb82146104ec57806341af6c871461051757806346d8d4861461054757600080fd5b80630ae09540116102a5578063294daa491161027f578063294daa4914610478578063330987b314610494578063405b84fa146104cc57600080fd5b80630ae09540146103f857806315c48b84146104185780631b6b6d231461044057600080fd5b8062012291146102e157806304104edb1461030e578063043bd6ae14610330578063088070f51461035457806308821d58146103d8575b600080fd5b3480156102ed57600080fd5b506102f66109d1565b604051610305939291906159c9565b60405180910390f35b34801561031a57600080fd5b5061032e610329366004615316565b610a4d565b005b34801561033c57600080fd5b5061034660115481565b604051908152602001610305565b34801561036057600080fd5b50600d546103a09061ffff81169063ffffffff62010000820481169160ff600160301b820416916701000000000000008204811691600160581b90041685565b6040805161ffff909616865263ffffffff9485166020870152921515928501929092528216606084015216608082015260a001610305565b3480156103e457600080fd5b5061032e6103f3366004615456565b610c0f565b34801561040457600080fd5b5061032e6104133660046156f8565b610da3565b34801561042457600080fd5b5061042d60c881565b60405161ffff9091168152602001610305565b34801561044c57600080fd5b50600254610460906001600160a01b031681565b6040516001600160a01b039091168152602001610305565b34801561048457600080fd5b5060405160018152602001610305565b3480156104a057600080fd5b506104b46104af366004615528565b610e71565b6040516001600160601b039091168152602001610305565b3480156104d857600080fd5b5061032e6104e73660046156f8565b61135b565b3480156104f857600080fd5b506105026101f481565b60405163ffffffff9091168152602001610305565b34801561052357600080fd5b506105376105323660046154ab565b611709565b6040519015158152602001610305565b34801561055357600080fd5b5061032e610562366004615333565b61190a565b34801561057357600080fd5b5061032e610582366004615368565b611a87565b34801561059357600080fd5b5061032e6105a2366004615316565b611ae7565b3480156105b357600080fd5b5061042d606481565b3480156105c857600080fd5b5061032e6105d7366004615333565b611ba5565b3480156105e857600080fd5b506104607f000000000000000000000000000000000000000000000000000000000000000081565b34801561061c57600080fd5b506012546106399063ffffffff8082169164010000000090041682565b6040805163ffffffff938416815292909116602083015201610305565b34801561066257600080fd5b5061032e6106713660046153a1565b611d44565b34801561068257600080fd5b5061032e611e43565b34801561069757600080fd5b50600a546104b4906001600160601b031681565b3480156106b757600080fd5b506000546001600160a01b0316610460565b3480156106d557600080fd5b506103466106e4366004615605565b611ef4565b3480156106f557600080fd5b50600754610709906001600160401b031681565b6040516001600160401b039091168152602001610305565b34801561072d57600080fd5b506103466122e9565b34801561074257600080fd5b5061032e6107513660046153ce565b612539565b34801561076257600080fd5b5061032e610771366004615316565b6126d9565b34801561078257600080fd5b5061032e6107913660046154ab565b6127f4565b3480156107a257600080fd5b50600354610460906001600160a01b031681565b3480156107c257600080fd5b506107d66107d136600461571d565b612854565b604051610305919061592e565b3480156107ef57600080fd5b5061032e6107fe36600461565a565b612955565b34801561080f57600080fd5b5061032e61081e3660046154ab565b612ae9565b34801561082f57600080fd5b5061032e61083e3660046156f8565b612c1f565b34801561084f57600080fd5b5061034661085e366004615472565b612dbb565b34801561086f57600080fd5b5061032e61087e3660046156f8565b612deb565b34801561088f57600080fd5b5061034661089e3660046154ab565b6130ee565b3480156108af57600080fd5b506104606108be3660046154ab565b600e602052600090815260409020546001600160a01b031681565b3480156108e557600080fd5b5061032e6108f43660046156f8565b61310f565b34801561090557600080fd5b506109196109143660046154ab565b61322e565b604051610305959493929190615b31565b34801561093657600080fd5b5061032e610945366004615316565b613329565b61032e6109583660046154ab565b6134cc565b34801561096957600080fd5b50600a546104b490600160601b90046001600160601b031681565b34801561099057600080fd5b5061034661099f3660046154ab565b60106020526000908152604090205481565b3480156109bd57600080fd5b5061032e6109cc366004615316565b61360b565b600d54600f805460408051602080840282018101909252828152600094859460609461ffff8316946201000090930463ffffffff16939192839190830182828015610a3b57602002820191906000526020600020905b815481526020019060010190808311610a27575b50505050509050925092509250909192565b610a5561361c565b60135460005b81811015610be257826001600160a01b031660138281548110610a8057610a80615e09565b6000918252602090912001546001600160a01b03161415610bd0576013610aa8600184615d02565b81548110610ab857610ab8615e09565b600091825260209091200154601380546001600160a01b039092169183908110610ae457610ae4615e09565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055826013610b1b600185615d02565b81548110610b2b57610b2b615e09565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506013805480610b6a57610b6a615df3565b6000828152602090819020600019908301810180546001600160a01b03191690559091019091556040516001600160a01b03851681527ff80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af37910160405180910390a1505050565b80610bda81615d71565b915050610a5b565b50604051635428d44960e01b81526001600160a01b03831660048201526024015b60405180910390fd5b50565b610c1761361c565b604080518082018252600091610c46919084906002908390839080828437600092019190915250612dbb915050565b6000818152600e60205260409020549091506001600160a01b031680610c8257604051631dfd6e1360e21b815260048101839052602401610c03565b6000828152600e6020526040812080546001600160a01b03191690555b600f54811015610d5a5782600f8281548110610cbd57610cbd615e09565b90600052602060002001541415610d4857600f805460009190610ce290600190615d02565b81548110610cf257610cf2615e09565b9060005260206000200154905080600f8381548110610d1357610d13615e09565b600091825260209091200155600f805480610d3057610d30615df3565b60019003818190600052602060002001600090559055505b80610d5281615d71565b915050610c9f565b50806001600160a01b03167f72be339577868f868798bac2c93e52d6f034fef4689a9848996c14ebb7416c0d83604051610d9691815260200190565b60405180910390a2505050565b60008281526005602052604090205482906001600160a01b031680610ddb57604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614610e0f57604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff1615610e3a5760405163769dd35360e11b815260040160405180910390fd5b610e4384611709565b15610e6157604051631685ecdd60e31b815260040160405180910390fd5b610e6b8484613678565b50505050565b600d54600090600160301b900460ff1615610e9f5760405163769dd35360e11b815260040160405180910390fd5b60005a90506000610eb0858561380f565b90506000846060015163ffffffff166001600160401b03811115610ed657610ed6615e1f565b604051908082528060200260200182016040528015610eff578160200160208202803683370190505b50905060005b856060015163ffffffff16811015610f7f57826040015181604051602001610f37929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c828281518110610f6257610f62615e09565b602090810291909101015280610f7781615d71565b915050610f05565b5060208083018051600090815260109092526040808320839055905190518291631fe543e360e01b91610fb791908690602401615a3c565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600d805466ff0000000000001916600160301b17905590880151608089015191925060009161101f9163ffffffff169084613a9c565b600d805466ff00000000000019169055602089810151600090815260069091526040902054909150600160c01b90046001600160401b0316611062816001615c82565b6020808b0151600090815260069091526040812080546001600160401b0393909316600160c01b026001600160c01b039093169290921790915560a08a015180516110af90600190615d02565b815181106110bf576110bf615e09565b602091010151600d5460f89190911c60011491506000906110f0908a90600160581b900463ffffffff163a85613aea565b905081156111f9576020808c01516000908152600690915260409020546001600160601b03808316600160601b90920416101561114057604051631e9acf1760e31b815260040160405180910390fd5b60208b81015160009081526006909152604090208054829190600c90611177908490600160601b90046001600160601b0316615d19565b82546101009290920a6001600160601b0381810219909316918316021790915589516000908152600e60209081526040808320546001600160a01b03168352600c9091528120805485945090926111d091859116615cad565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506112e5565b6020808c01516000908152600690915260409020546001600160601b038083169116101561123a57604051631e9acf1760e31b815260040160405180910390fd5b6020808c0151600090815260069091526040812080548392906112679084906001600160601b0316615d19565b82546101009290920a6001600160601b0381810219909316918316021790915589516000908152600e60209081526040808320546001600160a01b03168352600b9091528120805485945090926112c091859116615cad565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b8a6020015188602001517f49580fdfd9497e1ed5c1b1cec0495087ae8e3f1267470ec2fb015db32e3d6aa78a604001518488604051611342939291909283526001600160601b039190911660208301521515604082015260600190565b60405180910390a3985050505050505050505b92915050565b61136481613b3a565b61138c57604051635428d44960e01b81526001600160a01b0382166004820152602401610c03565b60008060008061139b8661322e565b945094505093509350336001600160a01b0316826001600160a01b0316146114055760405162461bcd60e51b815260206004820152601660248201527f4e6f7420737562736372697074696f6e206f776e6572000000000000000000006044820152606401610c03565b61140e86611709565b1561145b5760405162461bcd60e51b815260206004820152601660248201527f50656e64696e67207265717565737420657869737473000000000000000000006044820152606401610c03565b60006040518060c00160405280611470600190565b60ff168152602001888152602001846001600160a01b03168152602001838152602001866001600160601b03168152602001856001600160601b031681525090506000816040516020016114c49190615954565b60405160208183030381529060405290506114de88613ba4565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b03881690611517908590600401615941565b6000604051808303818588803b15801561153057600080fd5b505af1158015611544573d6000803e3d6000fd5b505060025460405163a9059cbb60e01b81526001600160a01b038c811660048301526001600160601b038c166024830152909116935063a9059cbb92506044019050602060405180830381600087803b1580156115a057600080fd5b505af11580156115b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d8919061548e565b6116245760405162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e647300000000000000000000000000006044820152606401610c03565b60005b83518110156116bc5783818151811061164257611642615e09565b6020908102919091010151604051638ea9811760e01b81526001600160a01b038a8116600483015290911690638ea9811790602401600060405180830381600087803b15801561169157600080fd5b505af11580156116a5573d6000803e3d6000fd5b5050505080806116b490615d71565b915050611627565b50604080516001600160a01b0389168152602081018a90527fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187910160405180910390a15050505050505050565b6000818152600560209081526040808320815160608101835281546001600160a01b039081168252600183015416818501526002820180548451818702810187018652818152879693958601939092919083018282801561179357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611775575b505050505081525050905060005b8160400151518110156119005760005b600f548110156118ed5760006118b6600f83815481106117d3576117d3615e09565b9060005260206000200154856040015185815181106117f4576117f4615e09565b602002602001015188600460008960400151898151811061181757611817615e09565b6020908102919091018101516001600160a01b03908116835282820193909352604091820160009081208e82528252829020548251808301889052959093168583015260608501939093526001600160401b039091166080808501919091528151808503909101815260a08401825280519083012060c084019490945260e0808401859052815180850390910181526101009093019052815191012091565b50600081815260106020526040902054909150156118da5750600195945050505050565b50806118e581615d71565b9150506117b1565b50806118f881615d71565b9150506117a1565b5060009392505050565b600d54600160301b900460ff16156119355760405163769dd35360e11b815260040160405180910390fd5b336000908152600c60205260409020546001600160601b038083169116101561197157604051631e9acf1760e31b815260040160405180910390fd5b336000908152600c6020526040812080548392906119999084906001600160601b0316615d19565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a600c8282829054906101000a90046001600160601b03166119e19190615d19565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506000826001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114611a5b576040519150601f19603f3d011682016040523d82523d6000602084013e611a60565b606091505b5050905080611a8257604051630dcf35db60e41b815260040160405180910390fd5b505050565b611a8f61361c565b6002546001600160a01b031615611ab957604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b611aef61361c565b611af881613b3a565b15611b215760405163ac8a27ef60e01b81526001600160a01b0382166004820152602401610c03565b601380546001810182556000919091527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900180546001600160a01b0319166001600160a01b0383169081179091556040519081527fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af016259060200160405180910390a150565b600d54600160301b900460ff1615611bd05760405163769dd35360e11b815260040160405180910390fd5b336000908152600b60205260409020546001600160601b0380831691161015611c0c57604051631e9acf1760e31b815260040160405180910390fd5b336000908152600b602052604081208054839290611c349084906001600160601b0316615d19565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a60008282829054906101000a90046001600160601b0316611c7c9190615d19565b82546101009290920a6001600160601b0381810219909316918316021790915560025460405163a9059cbb60e01b81526001600160a01b03868116600483015292851660248201529116915063a9059cbb90604401602060405180830381600087803b158015611ceb57600080fd5b505af1158015611cff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d23919061548e565b611d4057604051631e9acf1760e31b815260040160405180910390fd5b5050565b611d4c61361c565b604080518082018252600091611d7b919084906002908390839080828437600092019190915250612dbb915050565b6000818152600e60205260409020549091506001600160a01b031615611db757604051634a0b8fa760e01b815260048101829052602401610c03565b6000818152600e6020908152604080832080546001600160a01b0319166001600160a01b038816908117909155600f805460018101825594527f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802909301849055518381527fe729ae16526293f74ade739043022254f1489f616295a25bf72dfb4511ed73b89101610d96565b6001546001600160a01b03163314611e9d5760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610c03565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600d54600090600160301b900460ff1615611f225760405163769dd35360e11b815260040160405180910390fd5b6020808301356000908152600590915260409020546001600160a01b0316611f5d57604051630fb532db60e11b815260040160405180910390fd5b3360009081526004602090815260408083208583013584529091529020546001600160401b031680611fae576040516379bfd40160e01b815260208401356004820152336024820152604401610c03565b600d5461ffff16611fc5606085016040860161563f565b61ffff161080611fe8575060c8611fe2606085016040860161563f565b61ffff16115b1561202e57611ffd606084016040850161563f565b600d5460405163539c34bb60e11b815261ffff92831660048201529116602482015260c86044820152606401610c03565b600d5462010000900463ffffffff1661204d608085016060860161573f565b63ffffffff16111561209d57612069608084016060850161573f565b600d54604051637aebf00f60e11b815263ffffffff9283166004820152620100009091049091166024820152604401610c03565b6101f46120b060a085016080860161573f565b63ffffffff1611156120f6576120cc60a084016080850161573f565b6040516311ce1afb60e21b815263ffffffff90911660048201526101f46024820152604401610c03565b6000612103826001615c82565b604080518635602080830182905233838501528089013560608401526001600160401b0385166080808501919091528451808503909101815260a0808501865281519183019190912060c085019390935260e0808501849052855180860390910181526101009094019094528251920191909120929350906000906121939061218e90890189615b86565b613df3565b905060006121a082613e70565b9050836121ab613ee1565b60208a01356121c060808c0160608d0161573f565b6121d060a08d0160808e0161573f565b33866040516020016121e89796959493929190615a94565b604051602081830303815290604052805190602001206010600086815260200190815260200160002081905550336001600160a01b0316886020013589600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e87878d604001602081019061225f919061563f565b8e6060016020810190612272919061573f565b8f6080016020810190612285919061573f565b8960405161229896959493929190615a55565b60405180910390a450503360009081526004602090815260408083208983013584529091529020805467ffffffffffffffff19166001600160401b039490941693909317909255925050505b919050565b600d54600090600160301b900460ff16156123175760405163769dd35360e11b815260040160405180910390fd5b600033612325600143615d02565b600754604051606093841b6bffffffffffffffffffffffff199081166020830152924060348201523090931b909116605483015260c01b6001600160c01b031916606882015260700160408051601f198184030181529190528051602090910120600780549192506001600160401b039091169060006123a483615d8c565b91906101000a8154816001600160401b0302191690836001600160401b03160217905550506000806001600160401b038111156123e3576123e3615e1f565b60405190808252806020026020018201604052801561240c578160200160208202803683370190505b506040805160608082018352600080835260208084018281528486018381528984526006835286842095518654925191516001600160601b039182166001600160c01b031990941693909317600160601b9190921602176001600160c01b0316600160c01b6001600160401b039092169190910217909355835191820184523382528183018181528285018681528883526005855294909120825181546001600160a01b03199081166001600160a01b0392831617835592516001830180549094169116179091559251805194955090936124ed926002850192019061502c565b506124fd91506008905083613f7a565b5060405133815282907f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d9060200160405180910390a250905090565b600d54600160301b900460ff16156125645760405163769dd35360e11b815260040160405180910390fd5b6002546001600160a01b0316331461258f576040516344b0e3c360e01b815260040160405180910390fd5b602081146125b057604051638129bbcd60e01b815260040160405180910390fd5b60006125be828401846154ab565b6000818152600560205260409020549091506001600160a01b03166125f657604051630fb532db60e11b815260040160405180910390fd5b600081815260066020526040812080546001600160601b03169186919061261d8385615cad565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b03166126659190615cad565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a8287846126b89190615c6a565b604080519283526020830191909152015b60405180910390a2505050505050565b6126e161361c565b600a544790600160601b90046001600160601b031681811115612721576040516354ced18160e11b81526004810182905260248101839052604401610c03565b81811015611a825760006127358284615d02565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d8060008114612784576040519150601f19603f3d011682016040523d82523d6000602084013e612789565b606091505b50509050806127ab57604051630dcf35db60e41b815260040160405180910390fd5b604080516001600160a01b0387168152602081018490527f879c9ea2b9d5345b84ccd12610b032602808517cebdb795007f3dcb4df377317910160405180910390a15050505050565b6127fc61361c565b6000818152600560205260409020546001600160a01b031661283157604051630fb532db60e11b815260040160405180910390fd5b600081815260056020526040902054610c0c9082906001600160a01b0316613678565b606060006128626008613f86565b905080841061288457604051631390f2a160e01b815260040160405180910390fd5b60006128908486615c6a565b90508181118061289e575083155b6128a857806128aa565b815b905060006128b88683615d02565b6001600160401b038111156128cf576128cf615e1f565b6040519080825280602002602001820160405280156128f8578160200160208202803683370190505b50905060005b815181101561294b5761291c6129148883615c6a565b600890613f90565b82828151811061292e5761292e615e09565b60209081029190910101528061294381615d71565b9150506128fe565b5095945050505050565b61295d61361c565b60c861ffff871611156129975760405163539c34bb60e11b815261ffff871660048201819052602482015260c86044820152606401610c03565b600082136129bb576040516321ea67b360e11b815260048101839052602401610c03565b6040805160a0808201835261ffff891680835263ffffffff89811660208086018290526000868801528a831660608088018290528b85166080988901819052600d805465ffffffffffff19168817620100008702176effffffffffffffffff000000000000191667010000000000000085026effffffff0000000000000000000000191617600160581b83021790558a51601280548d87015192891667ffffffffffffffff199091161764010000000092891692909202919091179081905560118d90558a519788528785019590955298860191909152840196909652938201879052838116928201929092529190921c90911660c08201527f777357bb93f63d088f18112d3dba38457aec633eb8f1341e1d418380ad328e789060e00160405180910390a1505050505050565b600d54600160301b900460ff1615612b145760405163769dd35360e11b815260040160405180910390fd5b6000818152600560205260409020546001600160a01b0316612b4957604051630fb532db60e11b815260040160405180910390fd5b6000818152600560205260409020600101546001600160a01b03163314612ba2576000818152600560205260409081902060010154905163d084e97560e01b81526001600160a01b039091166004820152602401610c03565b6000818152600560209081526040918290208054336001600160a01b0319808316821784556001909301805490931690925583516001600160a01b0390911680825292810191909152909183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c938691015b60405180910390a25050565b60008281526005602052604090205482906001600160a01b031680612c5757604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614612c8b57604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff1615612cb65760405163769dd35360e11b815260040160405180910390fd5b60008481526005602052604090206002015460641415612ce9576040516305a48e0f60e01b815260040160405180910390fd5b6001600160a01b03831660009081526004602090815260408083208784529091529020546001600160401b031615612d2057610e6b565b6001600160a01b03831660008181526004602090815260408083208884528252808320805467ffffffffffffffff19166001908117909155600583528184206002018054918201815584529282902090920180546001600160a01b03191684179055905191825285917f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e191015b60405180910390a250505050565b600081604051602001612dce9190615920565b604051602081830303815290604052805190602001209050919050565b60008281526005602052604090205482906001600160a01b031680612e2357604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614612e5757604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff1615612e825760405163769dd35360e11b815260040160405180910390fd5b612e8b84611709565b15612ea957604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b03831660009081526004602090815260408083208784529091529020546001600160401b0316612f05576040516379bfd40160e01b8152600481018590526001600160a01b0384166024820152604401610c03565b600084815260056020908152604080832060020180548251818502810185019093528083529192909190830182828015612f6857602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612f4a575b50505050509050600060018251612f7f9190615d02565b905060005b825181101561308b57856001600160a01b0316838281518110612fa957612fa9615e09565b60200260200101516001600160a01b03161415613079576000838381518110612fd457612fd4615e09565b6020026020010151905080600560008a8152602001908152602001600020600201838154811061300657613006615e09565b600091825260208083209190910180546001600160a01b0319166001600160a01b03949094169390931790925589815260059091526040902060020180548061305157613051615df3565b600082815260209020810160001990810180546001600160a01b03191690550190555061308b565b8061308381615d71565b915050612f84565b506001600160a01b03851660008181526004602090815260408083208a8452825291829020805467ffffffffffffffff19169055905191825287917f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a791016126c9565b600f81815481106130fe57600080fd5b600091825260209091200154905081565b60008281526005602052604090205482906001600160a01b03168061314757604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b0382161461317b57604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff16156131a65760405163769dd35360e11b815260040160405180910390fd5b6000848152600560205260409020600101546001600160a01b03848116911614610e6b5760008481526005602090815260409182902060010180546001600160a01b0319166001600160a01b03871690811790915582513381529182015285917f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a19101612dad565b6000818152600560205260408120548190819081906060906001600160a01b031661326c57604051630fb532db60e11b815260040160405180910390fd5b60008681526006602090815260408083205460058352928190208054600290910180548351818602810186019094528084526001600160601b0380871696600160601b810490911695600160c01b9091046001600160401b0316946001600160a01b039094169391839183018282801561330f57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116132f1575b505050505090509450945094509450945091939590929450565b61333161361c565b6002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561337557600080fd5b505afa158015613389573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133ad91906154c4565b600a549091506001600160601b0316818111156133e7576040516354ced18160e11b81526004810182905260248101839052604401610c03565b81811015611a825760006133fb8284615d02565b60025460405163a9059cbb60e01b81526001600160a01b0387811660048301526024820184905292935091169063a9059cbb90604401602060405180830381600087803b15801561344b57600080fd5b505af115801561345f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613483919061548e565b50604080516001600160a01b0386168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a150505050565b600d54600160301b900460ff16156134f75760405163769dd35360e11b815260040160405180910390fd5b6000818152600560205260409020546001600160a01b031661352c57604051630fb532db60e11b815260040160405180910390fd5b60008181526006602052604090208054600160601b90046001600160601b0316903490600c61355b8385615cad565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b03166135a39190615cad565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f3f1ddc3ab1bdb39001ad76ca51a0e6f57ce6627c69f251d1de41622847721cde8234846135f69190615c6a565b60408051928352602083019190915201612c13565b61361361361c565b610c0c81613f9c565b6000546001600160a01b031633146136765760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610c03565b565b60008061368484613ba4565b60025460405163a9059cbb60e01b81526001600160a01b0387811660048301526001600160601b0385166024830152939550919350919091169063a9059cbb90604401602060405180830381600087803b1580156136e157600080fd5b505af11580156136f5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613719919061548e565b61373657604051631e9acf1760e31b815260040160405180910390fd5b6000836001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d806000811461378c576040519150601f19603f3d011682016040523d82523d6000602084013e613791565b606091505b50509050806137b357604051630dcf35db60e41b815260040160405180910390fd5b604080516001600160a01b03861681526001600160601b038581166020830152841681830152905186917f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c4919081900360600190a25050505050565b6040805160608101825260008082526020820181905291810191909152600061383b8460000151612dbb565b6000818152600e60205260409020549091506001600160a01b03168061387757604051631dfd6e1360e21b815260048101839052602401610c03565b6000828660800151604051602001613899929190918252602082015260400190565b60408051601f19818403018152918152815160209283012060008181526010909352912054909150806138df57604051631b44092560e11b815260040160405180910390fd5b85516020808801516040808a015160608b015160808c015160a08d0151935161390e978a979096959101615ade565b6040516020818303038152906040528051906020012081146139435760405163354a450b60e21b815260040160405180910390fd5b60006139528760000151614046565b905080613a2a578651604051631d2827a760e31b81526001600160401b0390911660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e9413d389060240160206040518083038186803b1580156139c457600080fd5b505afa1580156139d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139fc91906154c4565b905080613a2a57865160405163175dadad60e01b81526001600160401b039091166004820152602401610c03565b6000886080015182604051602001613a4c929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c90506000613a738a83614130565b604080516060810182529889526020890196909652948701949094525093979650505050505050565b60005a611388811015613aae57600080fd5b611388810390508460408204820311613ac657600080fd5b50823b613ad257600080fd5b60008083516020850160008789f190505b9392505050565b60008115613b1857601254613b119086908690640100000000900463ffffffff168661419b565b9050613b32565b601254613b2f908690869063ffffffff1686614205565b90505b949350505050565b6000805b601354811015613b9b57826001600160a01b031660138281548110613b6557613b65615e09565b6000918252602090912001546001600160a01b03161415613b895750600192915050565b80613b9381615d71565b915050613b3e565b50600092915050565b6000818152600560209081526040808320815160608101835281546001600160a01b03908116825260018301541681850152600282018054845181870281018701865281815287968796949594860193919290830182828015613c3057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613c12575b505050919092525050506000858152600660209081526040808320815160608101835290546001600160601b03808216808452600160601b8304909116948301859052600160c01b9091046001600160401b0316928201929092529096509094509192505b826040015151811015613d0d576004600084604001518381518110613cbc57613cbc615e09565b6020908102919091018101516001600160a01b0316825281810192909252604090810160009081208982529092529020805467ffffffffffffffff1916905580613d0581615d71565b915050613c95565b50600085815260056020526040812080546001600160a01b03199081168255600182018054909116905590613d456002830182615091565b5050600085815260066020526040812055613d616008866142f3565b50600a8054859190600090613d809084906001600160601b0316615d19565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555082600a600c8282829054906101000a90046001600160601b0316613dc89190615d19565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050915091565b60408051602081019091526000815281613e1c5750604080516020810190915260008152611355565b63125fa26760e31b613e2e8385615d41565b6001600160e01b03191614613e5657604051632923fee760e11b815260040160405180910390fd5b613e638260048186615c40565b810190613ae391906154dd565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401613ea991511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b60004661a4b1811480613ef6575062066eed81145b15613f735760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b158015613f3557600080fd5b505afa158015613f49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f6d91906154c4565b91505090565b4391505090565b6000613ae383836142ff565b6000611355825490565b6000613ae3838361434e565b6001600160a01b038116331415613ff55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610c03565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60004661a4b181148061405b575062066eed81145b1561412157610100836001600160401b0316614075613ee1565b61407f9190615d02565b118061409b575061408e613ee1565b836001600160401b031610155b156140a95750600092915050565b6040516315a03d4160e11b81526001600160401b0384166004820152606490632b407a829060240160206040518083038186803b1580156140e957600080fd5b505afa1580156140fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ae391906154c4565b50506001600160401b03164090565b60006141648360000151846020015185604001518660600151868860a001518960c001518a60e001518b6101000151614378565b6003836020015160405160200161417c929190615a28565b60408051601f1981840301815291905280516020909101209392505050565b6000806141a66145a3565b905060005a6141b58888615c6a565b6141bf9190615d02565b6141c99085615ce3565b905060006141e263ffffffff871664e8d4a51000615ce3565b9050826141ef8284615c6a565b6141f99190615c6a565b98975050505050505050565b6000806142106145ff565b905060008113614236576040516321ea67b360e11b815260048101829052602401610c03565b60006142406145a3565b9050600082825a6142518b8b615c6a565b61425b9190615d02565b6142659088615ce3565b61426f9190615c6a565b61428190670de0b6b3a7640000615ce3565b61428b9190615ccf565b905060006142a463ffffffff881664e8d4a51000615ce3565b90506142bc816b033b2e3c9fd0803ce8000000615d02565b8211156142dc5760405163e80fa38160e01b815260040160405180910390fd5b6142e68183615c6a565b9998505050505050505050565b6000613ae383836146ce565b600081815260018301602052604081205461434657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611355565b506000611355565b600082600001828154811061436557614365615e09565b9060005260206000200154905092915050565b614381896147c1565b6143cd5760405162461bcd60e51b815260206004820152601a60248201527f7075626c6963206b6579206973206e6f74206f6e2063757276650000000000006044820152606401610c03565b6143d6886147c1565b6144225760405162461bcd60e51b815260206004820152601560248201527f67616d6d61206973206e6f74206f6e20637572766500000000000000000000006044820152606401610c03565b61442b836147c1565b6144775760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e2063757276650000006044820152606401610c03565b614480826147c1565b6144cc5760405162461bcd60e51b815260206004820152601c60248201527f73486173685769746e657373206973206e6f74206f6e206375727665000000006044820152606401610c03565b6144d8878a888761489a565b6145245760405162461bcd60e51b815260206004820152601960248201527f6164647228632a706b2b732a6729213d5f755769746e657373000000000000006044820152606401610c03565b60006145308a876149bd565b90506000614543898b878b868989614a21565b90506000614554838d8d8a86614b41565b9050808a146145955760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610c03565b505050505050505050505050565b60004661a4b18114806145b8575062066eed81145b156145f757606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b815260040160206040518083038186803b158015613f3557600080fd5b600091505090565b600d5460035460408051633fabe5a360e21b81529051600093670100000000000000900463ffffffff169283151592859283926001600160a01b03169163feaf968c9160048083019260a0929190829003018186803b15801561466157600080fd5b505afa158015614675573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614699919061575a565b5094509092508491505080156146bd57506146b48242615d02565b8463ffffffff16105b15613b325750601154949350505050565b600081815260018301602052604081205480156147b75760006146f2600183615d02565b855490915060009061470690600190615d02565b905081811461476b57600086600001828154811061472657614726615e09565b906000526020600020015490508087600001848154811061474957614749615e09565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061477c5761477c615df3565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611355565b6000915050611355565b80516000906401000003d0191161481a5760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420782d6f7264696e61746500000000000000000000000000006044820152606401610c03565b60208201516401000003d019116148735760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420792d6f7264696e61746500000000000000000000000000006044820152606401610c03565b60208201516401000003d0199080096148938360005b6020020151614b81565b1492915050565b60006001600160a01b0382166148e05760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b6044820152606401610c03565b6020840151600090600116156148f757601c6148fa565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe19918203925060009190890987516040805160008082526020820180845287905260ff88169282019290925260608101929092526080820183905291925060019060a0016020604051602081039080840390855afa158015614995573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b6149c56150af565b6149f2600184846040516020016149de939291906158ff565b604051602081830303815290604052614ba5565b90505b6149fe816147c1565b611355578051604080516020810192909252614a1a91016149de565b90506149f5565b614a296150af565b825186516401000003d0199081900691061415614a885760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e637400006044820152606401610c03565b614a93878988614bf3565b614adf5760405162461bcd60e51b815260206004820152601660248201527f4669727374206d756c20636865636b206661696c6564000000000000000000006044820152606401610c03565b614aea848685614bf3565b614b365760405162461bcd60e51b815260206004820152601760248201527f5365636f6e64206d756c20636865636b206661696c65640000000000000000006044820152606401610c03565b6141f9868484614d1b565b600060028686868587604051602001614b5f969594939291906158a0565b60408051601f1981840301815291905280516020909101209695505050505050565b6000806401000003d01980848509840990506401000003d019600782089392505050565b614bad6150af565b614bb682614de2565b8152614bcb614bc6826000614889565b614e1d565b6020820181905260029006600114156122e4576020810180516401000003d019039052919050565b600082614c305760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b6044820152606401610c03565b83516020850151600090614c4690600290615db3565b15614c5257601c614c55565b601b5b9050600070014551231950b75fc4402da1732fc9bebe198387096040805160008082526020820180845281905260ff86169282019290925260608101869052608081018390529192509060019060a0016020604051602081039080840390855afa158015614cc7573d6000803e3d6000fd5b505050602060405103519050600086604051602001614ce6919061588e565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614d236150af565b835160208086015185519186015160009384938493614d4493909190614e3d565b919450925090506401000003d019858209600114614da45760405162461bcd60e51b815260206004820152601960248201527f696e765a206d75737420626520696e7665727365206f66207a000000000000006044820152606401610c03565b60405180604001604052806401000003d01980614dc357614dc3615ddd565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d01981106122e457604080516020808201939093528151808203840181529082019091528051910120614dea565b6000611355826002614e366401000003d0196001615c6a565b901c614f1d565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614e7d83838585614fbf565b9098509050614e8e88828e88614fe3565b9098509050614e9f88828c87614fe3565b90985090506000614eb28d878b85614fe3565b9098509050614ec388828686614fbf565b9098509050614ed488828e89614fe3565b9098509050818114614f09576401000003d019818a0998506401000003d01982890997506401000003d0198183099650614f0d565b8196505b5050505050509450945094915050565b600080614f286150cd565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a0820152614f5a6150eb565b60208160c0846005600019fa925082614fb55760405162461bcd60e51b815260206004820152601260248201527f6269674d6f64457870206661696c7572652100000000000000000000000000006044820152606401610c03565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215615081579160200282015b8281111561508157825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019061504c565b5061508d929150615109565b5090565b5080546000825590600052602060002090810190610c0c9190615109565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b8082111561508d576000815560010161510a565b80356122e481615e35565b806040810183101561135557600080fd5b600082601f83011261514b57600080fd5b615153615bd3565b80838560408601111561516557600080fd5b60005b6002811015615187578135845260209384019390910190600101615168565b509095945050505050565b600082601f8301126151a357600080fd5b81356001600160401b03808211156151bd576151bd615e1f565b604051601f8301601f19908116603f011681019082821181831017156151e5576151e5615e1f565b816040528381528660208588010111156151fe57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060c0828403121561523057600080fd5b615238615bfb565b905081356001600160401b03808216821461525257600080fd5b8183526020840135602084015261526b604085016152d1565b604084015261527c606085016152d1565b606084015261528d6080850161511e565b608084015260a08401359150808211156152a657600080fd5b506152b384828501615192565b60a08301525092915050565b803561ffff811681146122e457600080fd5b803563ffffffff811681146122e457600080fd5b805169ffffffffffffffffffff811681146122e457600080fd5b80356001600160601b03811681146122e457600080fd5b60006020828403121561532857600080fd5b8135613ae381615e35565b6000806040838503121561534657600080fd5b823561535181615e35565b915061535f602084016152ff565b90509250929050565b6000806040838503121561537b57600080fd5b823561538681615e35565b9150602083013561539681615e35565b809150509250929050565b600080606083850312156153b457600080fd5b82356153bf81615e35565b915061535f8460208501615129565b600080600080606085870312156153e457600080fd5b84356153ef81615e35565b93506020850135925060408501356001600160401b038082111561541257600080fd5b818701915087601f83011261542657600080fd5b81358181111561543557600080fd5b88602082850101111561544757600080fd5b95989497505060200194505050565b60006040828403121561546857600080fd5b613ae38383615129565b60006040828403121561548457600080fd5b613ae3838361513a565b6000602082840312156154a057600080fd5b8151613ae381615e4a565b6000602082840312156154bd57600080fd5b5035919050565b6000602082840312156154d657600080fd5b5051919050565b6000602082840312156154ef57600080fd5b604051602081018181106001600160401b038211171561551157615511615e1f565b604052823561551f81615e4a565b81529392505050565b6000808284036101c081121561553d57600080fd5b6101a08082121561554d57600080fd5b615555615c1d565b9150615561868661513a565b8252615570866040870161513a565b60208301526080850135604083015260a0850135606083015260c0850135608083015261559f60e0860161511e565b60a08301526101006155b38782880161513a565b60c08401526155c687610140880161513a565b60e0840152610180860135908301529092508301356001600160401b038111156155ef57600080fd5b6155fb8582860161521e565b9150509250929050565b60006020828403121561561757600080fd5b81356001600160401b0381111561562d57600080fd5b820160c08185031215613ae357600080fd5b60006020828403121561565157600080fd5b613ae3826152bf565b60008060008060008086880360e081121561567457600080fd5b61567d886152bf565b965061568b602089016152d1565b9550615699604089016152d1565b94506156a7606089016152d1565b9350608088013592506040609f19820112156156c257600080fd5b506156cb615bd3565b6156d760a089016152d1565b81526156e560c089016152d1565b6020820152809150509295509295509295565b6000806040838503121561570b57600080fd5b82359150602083013561539681615e35565b6000806040838503121561573057600080fd5b50508035926020909101359150565b60006020828403121561575157600080fd5b613ae3826152d1565b600080600080600060a0868803121561577257600080fd5b61577b866152e5565b945060208601519350604086015192506060860151915061579e608087016152e5565b90509295509295909350565b600081518084526020808501945080840160005b838110156157e35781516001600160a01b0316875295820195908201906001016157be565b509495945050505050565b8060005b6002811015610e6b5781518452602093840193909101906001016157f2565b600081518084526020808501945080840160005b838110156157e357815187529582019590820190600101615825565b6000815180845260005b818110156158675760208185018101518683018201520161584b565b81811115615879576000602083870101525b50601f01601f19169290920160200192915050565b61589881836157ee565b604001919050565b8681526158b060208201876157ee565b6158bd60608201866157ee565b6158ca60a08201856157ee565b6158d760e08201846157ee565b60609190911b6bffffffffffffffffffffffff19166101208201526101340195945050505050565b83815261590f60208201846157ee565b606081019190915260800192915050565b6040810161135582846157ee565b602081526000613ae36020830184615811565b602081526000613ae36020830184615841565b6020815260ff8251166020820152602082015160408201526001600160a01b0360408301511660608201526000606083015160c0608084015261599a60e08401826157aa565b905060808401516001600160601b0380821660a08601528060a08701511660c086015250508091505092915050565b60006060820161ffff86168352602063ffffffff86168185015260606040850152818551808452608086019150828701935060005b81811015615a1a578451835293830193918301916001016159fe565b509098975050505050505050565b82815260608101613ae360208301846157ee565b828152604060208201526000613b326040830184615811565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a08301526141f960c0830184615841565b878152866020820152856040820152600063ffffffff80871660608401528086166080840152506001600160a01b03841660a083015260e060c08301526142e660e0830184615841565b8781526001600160401b0387166020820152856040820152600063ffffffff80871660608401528086166080840152506001600160a01b03841660a083015260e060c08301526142e660e0830184615841565b60006001600160601b0380881683528087166020840152506001600160401b03851660408301526001600160a01b038416606083015260a06080830152615b7b60a08301846157aa565b979650505050505050565b6000808335601e19843603018112615b9d57600080fd5b8301803591506001600160401b03821115615bb757600080fd5b602001915036819003821315615bcc57600080fd5b9250929050565b604080519081016001600160401b0381118282101715615bf557615bf5615e1f565b60405290565b60405160c081016001600160401b0381118282101715615bf557615bf5615e1f565b60405161012081016001600160401b0381118282101715615bf557615bf5615e1f565b60008085851115615c5057600080fd5b83861115615c5d57600080fd5b5050820193919092039150565b60008219821115615c7d57615c7d615dc7565b500190565b60006001600160401b03808316818516808303821115615ca457615ca4615dc7565b01949350505050565b60006001600160601b03808316818516808303821115615ca457615ca4615dc7565b600082615cde57615cde615ddd565b500490565b6000816000190483118215151615615cfd57615cfd615dc7565b500290565b600082821015615d1457615d14615dc7565b500390565b60006001600160601b0383811690831681811015615d3957615d39615dc7565b039392505050565b6001600160e01b03198135818116916004851015615d695780818660040360031b1b83161692505b505092915050565b6000600019821415615d8557615d85615dc7565b5060010190565b60006001600160401b0380831681811415615da957615da9615dc7565b6001019392505050565b600082615dc257615dc2615ddd565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610c0c57600080fd5b8015158114610c0c57600080fdfea164736f6c6343000806000a", } var VRFCoordinatorV2PlusABI = VRFCoordinatorV2PlusMetaData.ABI @@ -338,6 +338,28 @@ func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) MAXREQUESTCONFIR return _VRFCoordinatorV2Plus.Contract.MAXREQUESTCONFIRMATIONS(&_VRFCoordinatorV2Plus.CallOpts) } +func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) GetActiveSubscriptionIds(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + var out []interface{} + err := _VRFCoordinatorV2Plus.contract.Call(opts, &out, "getActiveSubscriptionIds", startIndex, maxCount) + + if err != nil { + return *new([]*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) + + return out0, err + +} + +func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) GetActiveSubscriptionIds(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + return _VRFCoordinatorV2Plus.Contract.GetActiveSubscriptionIds(&_VRFCoordinatorV2Plus.CallOpts, startIndex, maxCount) +} + +func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) GetActiveSubscriptionIds(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + return _VRFCoordinatorV2Plus.Contract.GetActiveSubscriptionIds(&_VRFCoordinatorV2Plus.CallOpts, startIndex, maxCount) +} + func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) GetRequestConfig(opts *bind.CallOpts) (uint16, uint32, [][32]byte, error) { var out []interface{} err := _VRFCoordinatorV2Plus.contract.Call(opts, &out, "getRequestConfig") @@ -375,8 +397,9 @@ func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) GetSubscription(opts *b outstruct.Balance = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) outstruct.EthBalance = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - outstruct.Owner = *abi.ConvertType(out[2], new(common.Address)).(*common.Address) - outstruct.Consumers = *abi.ConvertType(out[3], new([]common.Address)).(*[]common.Address) + outstruct.ReqCount = *abi.ConvertType(out[2], new(uint64)).(*uint64) + outstruct.Owner = *abi.ConvertType(out[3], new(common.Address)).(*common.Address) + outstruct.Consumers = *abi.ConvertType(out[4], new([]common.Address)).(*[]common.Address) return *outstruct, err @@ -495,8 +518,9 @@ func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) SConfig(opts *bind.Call outstruct.MinimumRequestConfirmations = *abi.ConvertType(out[0], new(uint16)).(*uint16) outstruct.MaxGasLimit = *abi.ConvertType(out[1], new(uint32)).(*uint32) - outstruct.StalenessSeconds = *abi.ConvertType(out[2], new(uint32)).(*uint32) - outstruct.GasAfterPaymentCalculation = *abi.ConvertType(out[3], new(uint32)).(*uint32) + outstruct.ReentrancyLock = *abi.ConvertType(out[2], new(bool)).(*bool) + outstruct.StalenessSeconds = *abi.ConvertType(out[3], new(uint32)).(*uint32) + outstruct.GasAfterPaymentCalculation = *abi.ConvertType(out[4], new(uint32)).(*uint32) return *outstruct, err @@ -962,28 +986,16 @@ func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) SetConfig(mi return _VRFCoordinatorV2Plus.Contract.SetConfig(&_VRFCoordinatorV2Plus.TransactOpts, minimumRequestConfirmations, maxGasLimit, stalenessSeconds, gasAfterPaymentCalculation, fallbackWeiPerUnitLink, feeConfig) } -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) SetLINK(opts *bind.TransactOpts, link common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "setLINK", link) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) SetLINK(link common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.SetLINK(&_VRFCoordinatorV2Plus.TransactOpts, link) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) SetLINK(link common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.SetLINK(&_VRFCoordinatorV2Plus.TransactOpts, link) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) SetLinkEthFeed(opts *bind.TransactOpts, linkEthFeed common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "setLinkEthFeed", linkEthFeed) +func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) SetLINKAndLINKETHFeed(opts *bind.TransactOpts, link common.Address, linkEthFeed common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV2Plus.contract.Transact(opts, "setLINKAndLINKETHFeed", link, linkEthFeed) } -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) SetLinkEthFeed(linkEthFeed common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.SetLinkEthFeed(&_VRFCoordinatorV2Plus.TransactOpts, linkEthFeed) +func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) SetLINKAndLINKETHFeed(link common.Address, linkEthFeed common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV2Plus.Contract.SetLINKAndLINKETHFeed(&_VRFCoordinatorV2Plus.TransactOpts, link, linkEthFeed) } -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) SetLinkEthFeed(linkEthFeed common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.SetLinkEthFeed(&_VRFCoordinatorV2Plus.TransactOpts, linkEthFeed) +func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) SetLINKAndLINKETHFeed(link common.Address, linkEthFeed common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV2Plus.Contract.SetLINKAndLINKETHFeed(&_VRFCoordinatorV2Plus.TransactOpts, link, linkEthFeed) } func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { @@ -2299,34 +2311,44 @@ func (it *VRFCoordinatorV2PlusRandomWordsFulfilledIterator) Close() error { type VRFCoordinatorV2PlusRandomWordsFulfilled struct { RequestId *big.Int OutputSeed *big.Int + SubID *big.Int Payment *big.Int - ExtraArgs []byte Success bool Raw types.Log } -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int) (*VRFCoordinatorV2PlusRandomWordsFulfilledIterator, error) { +func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subID []*big.Int) (*VRFCoordinatorV2PlusRandomWordsFulfilledIterator, error) { var requestIdRule []interface{} for _, requestIdItem := range requestId { requestIdRule = append(requestIdRule, requestIdItem) } - logs, sub, err := _VRFCoordinatorV2Plus.contract.FilterLogs(opts, "RandomWordsFulfilled", requestIdRule) + var subIDRule []interface{} + for _, subIDItem := range subID { + subIDRule = append(subIDRule, subIDItem) + } + + logs, sub, err := _VRFCoordinatorV2Plus.contract.FilterLogs(opts, "RandomWordsFulfilled", requestIdRule, subIDRule) if err != nil { return nil, err } return &VRFCoordinatorV2PlusRandomWordsFulfilledIterator{contract: _VRFCoordinatorV2Plus.contract, event: "RandomWordsFulfilled", logs: logs, sub: sub}, nil } -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusRandomWordsFulfilled, requestId []*big.Int) (event.Subscription, error) { +func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusRandomWordsFulfilled, requestId []*big.Int, subID []*big.Int) (event.Subscription, error) { var requestIdRule []interface{} for _, requestIdItem := range requestId { requestIdRule = append(requestIdRule, requestIdItem) } - logs, sub, err := _VRFCoordinatorV2Plus.contract.WatchLogs(opts, "RandomWordsFulfilled", requestIdRule) + var subIDRule []interface{} + for _, subIDItem := range subID { + subIDRule = append(subIDRule, subIDItem) + } + + logs, sub, err := _VRFCoordinatorV2Plus.contract.WatchLogs(opts, "RandomWordsFulfilled", requestIdRule, subIDRule) if err != nil { return nil, err } @@ -3555,12 +3577,14 @@ func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) ParseSubscriptionOwne type GetSubscription struct { Balance *big.Int EthBalance *big.Int + ReqCount uint64 Owner common.Address Consumers []common.Address } type SConfig struct { MinimumRequestConfirmations uint16 MaxGasLimit uint32 + ReentrancyLock bool StalenessSeconds uint32 GasAfterPaymentCalculation uint32 } @@ -3658,7 +3682,7 @@ func (VRFCoordinatorV2PlusProvingKeyRegistered) Topic() common.Hash { } func (VRFCoordinatorV2PlusRandomWordsFulfilled) Topic() common.Hash { - return common.HexToHash("0x2c7b705f67f9ae2cbd3edc06b5b99afb00441ee4aea7bb77f109273bc1f3b5eb") + return common.HexToHash("0x49580fdfd9497e1ed5c1b1cec0495087ae8e3f1267470ec2fb015db32e3d6aa7") } func (VRFCoordinatorV2PlusRandomWordsRequested) Topic() common.Hash { @@ -3714,6 +3738,8 @@ type VRFCoordinatorV2PlusInterface interface { MAXREQUESTCONFIRMATIONS(opts *bind.CallOpts) (uint16, error) + GetActiveSubscriptionIds(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) + GetRequestConfig(opts *bind.CallOpts) (uint16, uint32, [][32]byte, error) GetSubscription(opts *bind.CallOpts, subId *big.Int) (GetSubscription, @@ -3794,9 +3820,7 @@ type VRFCoordinatorV2PlusInterface interface { SetConfig(opts *bind.TransactOpts, minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, feeConfig VRFCoordinatorV2PlusFeeConfig) (*types.Transaction, error) - SetLINK(opts *bind.TransactOpts, link common.Address) (*types.Transaction, error) - - SetLinkEthFeed(opts *bind.TransactOpts, linkEthFeed common.Address) (*types.Transaction, error) + SetLINKAndLINKETHFeed(opts *bind.TransactOpts, link common.Address, linkEthFeed common.Address) (*types.Transaction, error) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) @@ -3860,9 +3884,9 @@ type VRFCoordinatorV2PlusInterface interface { ParseProvingKeyRegistered(log types.Log) (*VRFCoordinatorV2PlusProvingKeyRegistered, error) - FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int) (*VRFCoordinatorV2PlusRandomWordsFulfilledIterator, error) + FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subID []*big.Int) (*VRFCoordinatorV2PlusRandomWordsFulfilledIterator, error) - WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusRandomWordsFulfilled, requestId []*big.Int) (event.Subscription, error) + WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusRandomWordsFulfilled, requestId []*big.Int, subID []*big.Int) (event.Subscription, error) ParseRandomWordsFulfilled(log types.Log) (*VRFCoordinatorV2PlusRandomWordsFulfilled, error) diff --git a/core/gethwrappers/generated/vrf_owner_test_consumer/vrf_owner_test_consumer.go b/core/gethwrappers/generated/vrf_owner_test_consumer/vrf_owner_test_consumer.go new file mode 100644 index 00000000000..e815f5491d9 --- /dev/null +++ b/core/gethwrappers/generated/vrf_owner_test_consumer/vrf_owner_test_consumer.go @@ -0,0 +1,863 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package vrf_owner_test_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 VRFV2OwnerTestConsumerMetaData = &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\"},{\"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\":\"COORDINATOR\",\"outputs\":[{\"internalType\":\"contractVRFCoordinatorV2Interface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"bytes32\",\"name\":\"_keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"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_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\":[],\"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_slowestFulfillment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"subId\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a0604052600060055560006006556103e76007553480156200002157600080fd5b50604051620013ae380380620013ae8339810160408190526200004491620002bf565b6001600160601b0319606082901b166080523380600081620000ad5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000e057620000e08162000213565b5050600280546001600160a01b0319166001600160a01b0384169081179091556040805163288688f960e21b8152905191925063a21a23e49160048083019260209291908290030181600087803b1580156200013b57600080fd5b505af115801562000150573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001769190620002f1565b600280546001600160401b03928316600160a01b908102600160a01b600160e01b03198316811793849055604051631cd0704360e21b81529190930490931660048401523060248401526001600160a01b0391821691161790637341c10c90604401600060405180830381600087803b158015620001f357600080fd5b505af115801562000208573d6000803e3d6000fd5b50505050506200031c565b6001600160a01b0381163314156200026e5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000a4565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620002d257600080fd5b81516001600160a01b0381168114620002ea57600080fd5b9392505050565b6000602082840312156200030457600080fd5b81516001600160401b0381168114620002ea57600080fd5b60805160601c61106c62000342600039600081816103000152610368015261106c6000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c8063a168fa8911610097578063d8a4676f11610066578063d8a4676f14610262578063dc1670db14610287578063eb1d28bb14610290578063f2fde38b146102d557600080fd5b8063a168fa89146101bc578063ad603ea214610227578063b1e217491461023a578063d826f88f1461024357600080fd5b8063737144bc116100d3578063737144bc1461018457806374dba1241461018d57806379ba5097146101965780638da5cb5b1461019e57600080fd5b80631757f11c146101055780631fe543e3146101215780633b2bcbf114610136578063557d2e921461017b575b600080fd5b61010e60065481565b6040519081526020015b60405180910390f35b61013461012f366004610da4565b6102e8565b005b6002546101569073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610118565b61010e60045481565b61010e60055481565b61010e60075481565b6101346103a8565b60005473ffffffffffffffffffffffffffffffffffffffff16610156565b6101fd6101ca366004610d72565b600a602052600090815260409020805460028201546003830154600484015460059094015460ff90931693919290919085565b6040805195151586526020860194909452928401919091526060830152608082015260a001610118565b610134610235366004610d14565b6104a5565b61010e60085481565b6101346000600581905560068190556103e76007556004819055600355565b610275610270366004610d72565b610809565b60405161011896959493929190610e93565b61010e60035481565b6002546102bc9074010000000000000000000000000000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610118565b6101346102e3366004610cd7565b6108ee565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461039a576040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660248201526044015b60405180910390fd5b6103a48282610902565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610429576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610391565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6104ad610a2d565b60005b8161ffff168161ffff1610156106ad576002546040517f5d3b1d300000000000000000000000000000000000000000000000000000000081526004810187905274010000000000000000000000000000000000000000820467ffffffffffffffff16602482015261ffff8816604482015263ffffffff80871660648301528516608482015260009173ffffffffffffffffffffffffffffffffffffffff1690635d3b1d309060a401602060405180830381600087803b15801561057257600080fd5b505af1158015610586573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105aa9190610d8b565b6008819055905060006105bb610ab0565b6040805160c08101825260008082528251818152602080820185528084019182524284860152606084018390526080840186905260a08401839052878352600a815293909120825181547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169015151781559051805194955091939092610649926001850192910190610c4c565b506040820151600282015560608201516003820155608082015160048083019190915560a090920151600590910155805490600061068683610fc8565b909155505060009182526009602052604090912055806106a581610fa6565b9150506104b0565b506002546040517f9f87fad700000000000000000000000000000000000000000000000000000000815274010000000000000000000000000000000000000000820467ffffffffffffffff16600482015230602482015273ffffffffffffffffffffffffffffffffffffffff90911690639f87fad790604401600060405180830381600087803b15801561074057600080fd5b505af1158015610754573d6000803e3d6000fd5b50506002546040517fd7ae1d3000000000000000000000000000000000000000000000000000000000815274010000000000000000000000000000000000000000820467ffffffffffffffff16600482015233602482015273ffffffffffffffffffffffffffffffffffffffff909116925063d7ae1d309150604401600060405180830381600087803b1580156107ea57600080fd5b505af11580156107fe573d6000803e3d6000fd5b505050505050505050565b6000818152600a60209081526040808320815160c081018352815460ff161515815260018201805484518187028101870190955280855260609587958695869586958695919492938584019390929083018282801561088757602002820191906000526020600020905b815481526020019060010190808311610873575b505050505081526020016002820154815260200160038201548152602001600482015481526020016005820154815250509050806000015181602001518260400151836060015184608001518560a001519650965096509650965096505091939550919395565b6108f6610a2d565b6108ff81610b56565b50565b600061090c610ab0565b600084815260096020526040812054919250906109299083610f8f565b9050600061093a82620f4240610f52565b905060065482111561094c5760068290555b600754821061095d5760075461095f565b815b60075560035461096f57806109a2565b60035461097d906001610eff565b8160035460055461098e9190610f52565b6109989190610eff565b6109a29190610f17565b6005556000858152600a6020908152604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117825586516109f4939290910191870190610c4c565b506000858152600a60205260408120426003808301919091556005909101859055805491610a2183610fc8565b91905055505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610aae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610391565b565b60004661a4b1811480610ac5575062066eed81145b15610b4f57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b1157600080fd5b505afa158015610b25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b499190610d8b565b91505090565b4391505090565b73ffffffffffffffffffffffffffffffffffffffff8116331415610bd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610391565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610c87579160200282015b82811115610c87578251825591602001919060010190610c6c565b50610c93929150610c97565b5090565b5b80821115610c935760008155600101610c98565b803561ffff81168114610cbe57600080fd5b919050565b803563ffffffff81168114610cbe57600080fd5b600060208284031215610ce957600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610d0d57600080fd5b9392505050565b600080600080600060a08688031215610d2c57600080fd5b610d3586610cac565b945060208601359350610d4a60408701610cc3565b9250610d5860608701610cc3565b9150610d6660808701610cac565b90509295509295909350565b600060208284031215610d8457600080fd5b5035919050565b600060208284031215610d9d57600080fd5b5051919050565b60008060408385031215610db757600080fd5b8235915060208084013567ffffffffffffffff80821115610dd757600080fd5b818601915086601f830112610deb57600080fd5b813581811115610dfd57610dfd611030565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108582111715610e4057610e40611030565b604052828152858101935084860182860187018b1015610e5f57600080fd5b600095505b83861015610e82578035855260019590950194938601938601610e64565b508096505050505050509250929050565b600060c082018815158352602060c08185015281895180845260e086019150828b01935060005b81811015610ed657845183529383019391830191600101610eba565b505060408501989098525050506060810193909352608083019190915260a09091015292915050565b60008219821115610f1257610f12611001565b500190565b600082610f4d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610f8a57610f8a611001565b500290565b600082821015610fa157610fa1611001565b500390565b600061ffff80831681811415610fbe57610fbe611001565b6001019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610ffa57610ffa611001565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", +} + +var VRFV2OwnerTestConsumerABI = VRFV2OwnerTestConsumerMetaData.ABI + +var VRFV2OwnerTestConsumerBin = VRFV2OwnerTestConsumerMetaData.Bin + +func DeployVRFV2OwnerTestConsumer(auth *bind.TransactOpts, backend bind.ContractBackend, _vrfCoordinator common.Address) (common.Address, *types.Transaction, *VRFV2OwnerTestConsumer, error) { + parsed, err := VRFV2OwnerTestConsumerMetaData.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(VRFV2OwnerTestConsumerBin), backend, _vrfCoordinator) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &VRFV2OwnerTestConsumer{VRFV2OwnerTestConsumerCaller: VRFV2OwnerTestConsumerCaller{contract: contract}, VRFV2OwnerTestConsumerTransactor: VRFV2OwnerTestConsumerTransactor{contract: contract}, VRFV2OwnerTestConsumerFilterer: VRFV2OwnerTestConsumerFilterer{contract: contract}}, nil +} + +type VRFV2OwnerTestConsumer struct { + address common.Address + abi abi.ABI + VRFV2OwnerTestConsumerCaller + VRFV2OwnerTestConsumerTransactor + VRFV2OwnerTestConsumerFilterer +} + +type VRFV2OwnerTestConsumerCaller struct { + contract *bind.BoundContract +} + +type VRFV2OwnerTestConsumerTransactor struct { + contract *bind.BoundContract +} + +type VRFV2OwnerTestConsumerFilterer struct { + contract *bind.BoundContract +} + +type VRFV2OwnerTestConsumerSession struct { + Contract *VRFV2OwnerTestConsumer + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type VRFV2OwnerTestConsumerCallerSession struct { + Contract *VRFV2OwnerTestConsumerCaller + CallOpts bind.CallOpts +} + +type VRFV2OwnerTestConsumerTransactorSession struct { + Contract *VRFV2OwnerTestConsumerTransactor + TransactOpts bind.TransactOpts +} + +type VRFV2OwnerTestConsumerRaw struct { + Contract *VRFV2OwnerTestConsumer +} + +type VRFV2OwnerTestConsumerCallerRaw struct { + Contract *VRFV2OwnerTestConsumerCaller +} + +type VRFV2OwnerTestConsumerTransactorRaw struct { + Contract *VRFV2OwnerTestConsumerTransactor +} + +func NewVRFV2OwnerTestConsumer(address common.Address, backend bind.ContractBackend) (*VRFV2OwnerTestConsumer, error) { + abi, err := abi.JSON(strings.NewReader(VRFV2OwnerTestConsumerABI)) + if err != nil { + return nil, err + } + contract, err := bindVRFV2OwnerTestConsumer(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &VRFV2OwnerTestConsumer{address: address, abi: abi, VRFV2OwnerTestConsumerCaller: VRFV2OwnerTestConsumerCaller{contract: contract}, VRFV2OwnerTestConsumerTransactor: VRFV2OwnerTestConsumerTransactor{contract: contract}, VRFV2OwnerTestConsumerFilterer: VRFV2OwnerTestConsumerFilterer{contract: contract}}, nil +} + +func NewVRFV2OwnerTestConsumerCaller(address common.Address, caller bind.ContractCaller) (*VRFV2OwnerTestConsumerCaller, error) { + contract, err := bindVRFV2OwnerTestConsumer(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &VRFV2OwnerTestConsumerCaller{contract: contract}, nil +} + +func NewVRFV2OwnerTestConsumerTransactor(address common.Address, transactor bind.ContractTransactor) (*VRFV2OwnerTestConsumerTransactor, error) { + contract, err := bindVRFV2OwnerTestConsumer(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &VRFV2OwnerTestConsumerTransactor{contract: contract}, nil +} + +func NewVRFV2OwnerTestConsumerFilterer(address common.Address, filterer bind.ContractFilterer) (*VRFV2OwnerTestConsumerFilterer, error) { + contract, err := bindVRFV2OwnerTestConsumer(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &VRFV2OwnerTestConsumerFilterer{contract: contract}, nil +} + +func bindVRFV2OwnerTestConsumer(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := VRFV2OwnerTestConsumerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VRFV2OwnerTestConsumer.Contract.VRFV2OwnerTestConsumerCaller.contract.Call(opts, result, method, params...) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFV2OwnerTestConsumer.Contract.VRFV2OwnerTestConsumerTransactor.contract.Transfer(opts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VRFV2OwnerTestConsumer.Contract.VRFV2OwnerTestConsumerTransactor.contract.Transact(opts, method, params...) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VRFV2OwnerTestConsumer.Contract.contract.Call(opts, result, method, params...) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFV2OwnerTestConsumer.Contract.contract.Transfer(opts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VRFV2OwnerTestConsumer.Contract.contract.Transact(opts, method, params...) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCaller) COORDINATOR(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFV2OwnerTestConsumer.contract.Call(opts, &out, "COORDINATOR") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerSession) COORDINATOR() (common.Address, error) { + return _VRFV2OwnerTestConsumer.Contract.COORDINATOR(&_VRFV2OwnerTestConsumer.CallOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCallerSession) COORDINATOR() (common.Address, error) { + return _VRFV2OwnerTestConsumer.Contract.COORDINATOR(&_VRFV2OwnerTestConsumer.CallOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCaller) GetRequestStatus(opts *bind.CallOpts, _requestId *big.Int) (GetRequestStatus, + + error) { + var out []interface{} + err := _VRFV2OwnerTestConsumer.contract.Call(opts, &out, "getRequestStatus", _requestId) + + outstruct := new(GetRequestStatus) + if err != nil { + return *outstruct, err + } + + outstruct.Fulfilled = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.RandomWords = *abi.ConvertType(out[1], new([]*big.Int)).(*[]*big.Int) + outstruct.RequestTimestamp = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + outstruct.FulfilmentTimestamp = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.RequestBlockNumber = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + outstruct.FulfilmentBlockNumber = *abi.ConvertType(out[5], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerSession) GetRequestStatus(_requestId *big.Int) (GetRequestStatus, + + error) { + return _VRFV2OwnerTestConsumer.Contract.GetRequestStatus(&_VRFV2OwnerTestConsumer.CallOpts, _requestId) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCallerSession) GetRequestStatus(_requestId *big.Int) (GetRequestStatus, + + error) { + return _VRFV2OwnerTestConsumer.Contract.GetRequestStatus(&_VRFV2OwnerTestConsumer.CallOpts, _requestId) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFV2OwnerTestConsumer.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 (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerSession) Owner() (common.Address, error) { + return _VRFV2OwnerTestConsumer.Contract.Owner(&_VRFV2OwnerTestConsumer.CallOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCallerSession) Owner() (common.Address, error) { + return _VRFV2OwnerTestConsumer.Contract.Owner(&_VRFV2OwnerTestConsumer.CallOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCaller) SAverageFulfillmentInMillions(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFV2OwnerTestConsumer.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 (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerSession) SAverageFulfillmentInMillions() (*big.Int, error) { + return _VRFV2OwnerTestConsumer.Contract.SAverageFulfillmentInMillions(&_VRFV2OwnerTestConsumer.CallOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCallerSession) SAverageFulfillmentInMillions() (*big.Int, error) { + return _VRFV2OwnerTestConsumer.Contract.SAverageFulfillmentInMillions(&_VRFV2OwnerTestConsumer.CallOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCaller) SFastestFulfillment(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFV2OwnerTestConsumer.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 (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerSession) SFastestFulfillment() (*big.Int, error) { + return _VRFV2OwnerTestConsumer.Contract.SFastestFulfillment(&_VRFV2OwnerTestConsumer.CallOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCallerSession) SFastestFulfillment() (*big.Int, error) { + return _VRFV2OwnerTestConsumer.Contract.SFastestFulfillment(&_VRFV2OwnerTestConsumer.CallOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCaller) SLastRequestId(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFV2OwnerTestConsumer.contract.Call(opts, &out, "s_lastRequestId") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerSession) SLastRequestId() (*big.Int, error) { + return _VRFV2OwnerTestConsumer.Contract.SLastRequestId(&_VRFV2OwnerTestConsumer.CallOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCallerSession) SLastRequestId() (*big.Int, error) { + return _VRFV2OwnerTestConsumer.Contract.SLastRequestId(&_VRFV2OwnerTestConsumer.CallOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCaller) SRequestCount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFV2OwnerTestConsumer.contract.Call(opts, &out, "s_requestCount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerSession) SRequestCount() (*big.Int, error) { + return _VRFV2OwnerTestConsumer.Contract.SRequestCount(&_VRFV2OwnerTestConsumer.CallOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCallerSession) SRequestCount() (*big.Int, error) { + return _VRFV2OwnerTestConsumer.Contract.SRequestCount(&_VRFV2OwnerTestConsumer.CallOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCaller) SRequests(opts *bind.CallOpts, arg0 *big.Int) (SRequests, + + error) { + var out []interface{} + err := _VRFV2OwnerTestConsumer.contract.Call(opts, &out, "s_requests", arg0) + + outstruct := new(SRequests) + if err != nil { + return *outstruct, err + } + + outstruct.Fulfilled = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.RequestTimestamp = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.FulfilmentTimestamp = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + outstruct.RequestBlockNumber = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.FulfilmentBlockNumber = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerSession) SRequests(arg0 *big.Int) (SRequests, + + error) { + return _VRFV2OwnerTestConsumer.Contract.SRequests(&_VRFV2OwnerTestConsumer.CallOpts, arg0) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCallerSession) SRequests(arg0 *big.Int) (SRequests, + + error) { + return _VRFV2OwnerTestConsumer.Contract.SRequests(&_VRFV2OwnerTestConsumer.CallOpts, arg0) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCaller) SResponseCount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFV2OwnerTestConsumer.contract.Call(opts, &out, "s_responseCount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerSession) SResponseCount() (*big.Int, error) { + return _VRFV2OwnerTestConsumer.Contract.SResponseCount(&_VRFV2OwnerTestConsumer.CallOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCallerSession) SResponseCount() (*big.Int, error) { + return _VRFV2OwnerTestConsumer.Contract.SResponseCount(&_VRFV2OwnerTestConsumer.CallOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCaller) SSlowestFulfillment(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFV2OwnerTestConsumer.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 (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerSession) SSlowestFulfillment() (*big.Int, error) { + return _VRFV2OwnerTestConsumer.Contract.SSlowestFulfillment(&_VRFV2OwnerTestConsumer.CallOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCallerSession) SSlowestFulfillment() (*big.Int, error) { + return _VRFV2OwnerTestConsumer.Contract.SSlowestFulfillment(&_VRFV2OwnerTestConsumer.CallOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCaller) SubId(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _VRFV2OwnerTestConsumer.contract.Call(opts, &out, "subId") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerSession) SubId() (uint64, error) { + return _VRFV2OwnerTestConsumer.Contract.SubId(&_VRFV2OwnerTestConsumer.CallOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerCallerSession) SubId() (uint64, error) { + return _VRFV2OwnerTestConsumer.Contract.SubId(&_VRFV2OwnerTestConsumer.CallOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFV2OwnerTestConsumer.contract.Transact(opts, "acceptOwnership") +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerSession) AcceptOwnership() (*types.Transaction, error) { + return _VRFV2OwnerTestConsumer.Contract.AcceptOwnership(&_VRFV2OwnerTestConsumer.TransactOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _VRFV2OwnerTestConsumer.Contract.AcceptOwnership(&_VRFV2OwnerTestConsumer.TransactOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerTransactor) RawFulfillRandomWords(opts *bind.TransactOpts, requestId *big.Int, randomWords []*big.Int) (*types.Transaction, error) { + return _VRFV2OwnerTestConsumer.contract.Transact(opts, "rawFulfillRandomWords", requestId, randomWords) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerSession) RawFulfillRandomWords(requestId *big.Int, randomWords []*big.Int) (*types.Transaction, error) { + return _VRFV2OwnerTestConsumer.Contract.RawFulfillRandomWords(&_VRFV2OwnerTestConsumer.TransactOpts, requestId, randomWords) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerTransactorSession) RawFulfillRandomWords(requestId *big.Int, randomWords []*big.Int) (*types.Transaction, error) { + return _VRFV2OwnerTestConsumer.Contract.RawFulfillRandomWords(&_VRFV2OwnerTestConsumer.TransactOpts, requestId, randomWords) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerTransactor) RequestRandomWords(opts *bind.TransactOpts, _requestConfirmations uint16, _keyHash [32]byte, _callbackGasLimit uint32, _numWords uint32, _requestCount uint16) (*types.Transaction, error) { + return _VRFV2OwnerTestConsumer.contract.Transact(opts, "requestRandomWords", _requestConfirmations, _keyHash, _callbackGasLimit, _numWords, _requestCount) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerSession) RequestRandomWords(_requestConfirmations uint16, _keyHash [32]byte, _callbackGasLimit uint32, _numWords uint32, _requestCount uint16) (*types.Transaction, error) { + return _VRFV2OwnerTestConsumer.Contract.RequestRandomWords(&_VRFV2OwnerTestConsumer.TransactOpts, _requestConfirmations, _keyHash, _callbackGasLimit, _numWords, _requestCount) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerTransactorSession) RequestRandomWords(_requestConfirmations uint16, _keyHash [32]byte, _callbackGasLimit uint32, _numWords uint32, _requestCount uint16) (*types.Transaction, error) { + return _VRFV2OwnerTestConsumer.Contract.RequestRandomWords(&_VRFV2OwnerTestConsumer.TransactOpts, _requestConfirmations, _keyHash, _callbackGasLimit, _numWords, _requestCount) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerTransactor) Reset(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFV2OwnerTestConsumer.contract.Transact(opts, "reset") +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerSession) Reset() (*types.Transaction, error) { + return _VRFV2OwnerTestConsumer.Contract.Reset(&_VRFV2OwnerTestConsumer.TransactOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerTransactorSession) Reset() (*types.Transaction, error) { + return _VRFV2OwnerTestConsumer.Contract.Reset(&_VRFV2OwnerTestConsumer.TransactOpts) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _VRFV2OwnerTestConsumer.contract.Transact(opts, "transferOwnership", to) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _VRFV2OwnerTestConsumer.Contract.TransferOwnership(&_VRFV2OwnerTestConsumer.TransactOpts, to) +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _VRFV2OwnerTestConsumer.Contract.TransferOwnership(&_VRFV2OwnerTestConsumer.TransactOpts, to) +} + +type VRFV2OwnerTestConsumerOwnershipTransferRequestedIterator struct { + Event *VRFV2OwnerTestConsumerOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFV2OwnerTestConsumerOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFV2OwnerTestConsumerOwnershipTransferRequested) + 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(VRFV2OwnerTestConsumerOwnershipTransferRequested) + 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 *VRFV2OwnerTestConsumerOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *VRFV2OwnerTestConsumerOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFV2OwnerTestConsumerOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFV2OwnerTestConsumerOwnershipTransferRequestedIterator, 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 := _VRFV2OwnerTestConsumer.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &VRFV2OwnerTestConsumerOwnershipTransferRequestedIterator{contract: _VRFV2OwnerTestConsumer.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFV2OwnerTestConsumerOwnershipTransferRequested, 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 := _VRFV2OwnerTestConsumer.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(VRFV2OwnerTestConsumerOwnershipTransferRequested) + if err := _VRFV2OwnerTestConsumer.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 (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerFilterer) ParseOwnershipTransferRequested(log types.Log) (*VRFV2OwnerTestConsumerOwnershipTransferRequested, error) { + event := new(VRFV2OwnerTestConsumerOwnershipTransferRequested) + if err := _VRFV2OwnerTestConsumer.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFV2OwnerTestConsumerOwnershipTransferredIterator struct { + Event *VRFV2OwnerTestConsumerOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFV2OwnerTestConsumerOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFV2OwnerTestConsumerOwnershipTransferred) + 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(VRFV2OwnerTestConsumerOwnershipTransferred) + 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 *VRFV2OwnerTestConsumerOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *VRFV2OwnerTestConsumerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFV2OwnerTestConsumerOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFV2OwnerTestConsumerOwnershipTransferredIterator, 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 := _VRFV2OwnerTestConsumer.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &VRFV2OwnerTestConsumerOwnershipTransferredIterator{contract: _VRFV2OwnerTestConsumer.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFV2OwnerTestConsumerOwnershipTransferred, 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 := _VRFV2OwnerTestConsumer.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(VRFV2OwnerTestConsumerOwnershipTransferred) + if err := _VRFV2OwnerTestConsumer.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 (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumerFilterer) ParseOwnershipTransferred(log types.Log) (*VRFV2OwnerTestConsumerOwnershipTransferred, error) { + event := new(VRFV2OwnerTestConsumerOwnershipTransferred) + if err := _VRFV2OwnerTestConsumer.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetRequestStatus struct { + Fulfilled bool + RandomWords []*big.Int + RequestTimestamp *big.Int + FulfilmentTimestamp *big.Int + RequestBlockNumber *big.Int + FulfilmentBlockNumber *big.Int +} +type SRequests struct { + Fulfilled bool + RequestTimestamp *big.Int + FulfilmentTimestamp *big.Int + RequestBlockNumber *big.Int + FulfilmentBlockNumber *big.Int +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumer) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _VRFV2OwnerTestConsumer.abi.Events["OwnershipTransferRequested"].ID: + return _VRFV2OwnerTestConsumer.ParseOwnershipTransferRequested(log) + case _VRFV2OwnerTestConsumer.abi.Events["OwnershipTransferred"].ID: + return _VRFV2OwnerTestConsumer.ParseOwnershipTransferred(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (VRFV2OwnerTestConsumerOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (VRFV2OwnerTestConsumerOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (_VRFV2OwnerTestConsumer *VRFV2OwnerTestConsumer) Address() common.Address { + return _VRFV2OwnerTestConsumer.address +} + +type VRFV2OwnerTestConsumerInterface interface { + COORDINATOR(opts *bind.CallOpts) (common.Address, error) + + GetRequestStatus(opts *bind.CallOpts, _requestId *big.Int) (GetRequestStatus, + + error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SAverageFulfillmentInMillions(opts *bind.CallOpts) (*big.Int, error) + + SFastestFulfillment(opts *bind.CallOpts) (*big.Int, error) + + SLastRequestId(opts *bind.CallOpts) (*big.Int, error) + + SRequestCount(opts *bind.CallOpts) (*big.Int, error) + + SRequests(opts *bind.CallOpts, arg0 *big.Int) (SRequests, + + error) + + SResponseCount(opts *bind.CallOpts) (*big.Int, error) + + SSlowestFulfillment(opts *bind.CallOpts) (*big.Int, error) + + SubId(opts *bind.CallOpts) (uint64, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + RawFulfillRandomWords(opts *bind.TransactOpts, requestId *big.Int, randomWords []*big.Int) (*types.Transaction, error) + + RequestRandomWords(opts *bind.TransactOpts, _requestConfirmations uint16, _keyHash [32]byte, _callbackGasLimit uint32, _numWords uint32, _requestCount uint16) (*types.Transaction, error) + + Reset(opts *bind.TransactOpts) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFV2OwnerTestConsumerOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFV2OwnerTestConsumerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*VRFV2OwnerTestConsumerOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFV2OwnerTestConsumerOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFV2OwnerTestConsumerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*VRFV2OwnerTestConsumerOwnershipTransferred, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} 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 350dcd4315b..ce2d4fd13cc 100644 --- a/core/gethwrappers/generated/vrfv2plus_consumer_example/vrfv2plus_consumer_example.go +++ b/core/gethwrappers/generated/vrfv2plus_consumer_example/vrfv2plus_consumer_example.go @@ -31,8 +31,8 @@ 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\":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\":[{\"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_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\":[{\"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: "0x60806040523480156200001157600080fd5b506040516200169b3803806200169b8339810160408190526200003491620001cc565b8133806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000103565b5050600280546001600160a01b03199081166001600160a01b0394851617909155600580548216958416959095179094555060038054909316911617905562000204565b6001600160a01b0381163314156200015e5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001c757600080fd5b919050565b60008060408385031215620001e057600080fd5b620001eb83620001af565b9150620001fb60208401620001af565b90509250929050565b61148780620002146000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80638098004311610097578063cf62c8ab11610066578063cf62c8ab14610283578063de367c8e14610296578063eff27017146102b6578063f2fde38b146102c957600080fd5b806380980043146101c55780638da5cb5b146101d85780638ea98117146101f6578063a168fa891461020957600080fd5b80635d7d53e3116100d35780635d7d53e314610166578063706da1ca1461016f5780637725135b1461017857806379ba5097146101bd57600080fd5b80631fe543e31461010557806329e5d8311461011a5780632fa4e4421461014057806336bfffed14610153575b600080fd5b6101186101133660046110c0565b6102dc565b005b61012d610128366004611164565b610362565b6040519081526020015b60405180910390f35b61011861014e3660046111f1565b61049f565b610118610161366004610fcd565b610558565b61012d60045481565b61012d60065481565b6003546101989073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610137565b610118610690565b6101186101d336600461108e565b600655565b60005473ffffffffffffffffffffffffffffffffffffffff16610198565b610118610204366004610fab565b61078d565b61025161021736600461108e565b6007602052600090815260409020805460019091015460ff821691610100900473ffffffffffffffffffffffffffffffffffffffff169083565b60408051931515845273ffffffffffffffffffffffffffffffffffffffff909216602084015290820152606001610137565b6101186102913660046111f1565b610898565b6005546101989073ffffffffffffffffffffffffffffffffffffffff1681565b6101186102c4366004611186565b610a0f565b6101186102d7366004610fab565b610bfa565b60025473ffffffffffffffffffffffffffffffffffffffff163314610354576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b61035e8282610c0e565b5050565b60008281526007602090815260408083208151608081018352815460ff811615158252610100900473ffffffffffffffffffffffffffffffffffffffff1681850152600182015481840152600282018054845181870281018701909552808552869592946060860193909291908301828280156103fe57602002820191906000526020600020905b8154815260200190600101908083116103ea575b5050505050815250509050806040015160001415610478576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f7272656374000000000000000000604482015260640161034b565b8060600151838151811061048e5761048e61140e565b602002602001015191505092915050565b60035460025460065460408051602081019290925273ffffffffffffffffffffffffffffffffffffffff93841693634000aea09316918591015b6040516020818303038152906040526040518463ffffffff1660e01b81526004016105069392919061128a565b602060405180830381600087803b15801561052057600080fd5b505af1158015610534573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035e9190611071565b6006546105c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f7375624944206e6f742073657400000000000000000000000000000000000000604482015260640161034b565b60005b815181101561035e57600554600654835173ffffffffffffffffffffffffffffffffffffffff9092169163bec4c08c91908590859081106106075761060761140e565b60200260200101516040518363ffffffff1660e01b815260040161064b92919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b15801561066557600080fd5b505af1158015610679573d6000803e3d6000fd5b505050508080610688906113ae565b9150506105c4565b60015473ffffffffffffffffffffffffffffffffffffffff163314610711576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161034b565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906107cd575060025473ffffffffffffffffffffffffffffffffffffffff163314155b1561085157336107f260005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9384166004820152918316602483015291909116604482015260640161034b565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60065461049f57600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a21a23e46040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561090957600080fd5b505af115801561091d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094191906110a7565b60068190556005546040517fbec4c08c000000000000000000000000000000000000000000000000000000008152600481019290925230602483015273ffffffffffffffffffffffffffffffffffffffff169063bec4c08c90604401600060405180830381600087803b1580156109b757600080fd5b505af11580156109cb573d6000803e3d6000fd5b5050505060035460025460065460405173ffffffffffffffffffffffffffffffffffffffff93841693634000aea093169185916104d9919060200190815260200190565b60006040518060c0016040528084815260200160065481526020018661ffff1681526020018763ffffffff1681526020018563ffffffff168152602001610a656040518060200160405280861515815250610cd9565b90526002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925060009173ffffffffffffffffffffffffffffffffffffffff90911690639b1c385e90610ac39085906004016112d6565b602060405180830381600087803b158015610add57600080fd5b505af1158015610af1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1591906110a7565b604080516080810182526000808252336020808401918252838501868152855184815280830187526060860190815287855260078352959093208451815493517fffffffffffffffffffffff0000000000000000000000000000000000000000009094169015157fffffffffffffffffffffff0000000000000000000000000000000000000000ff161761010073ffffffffffffffffffffffffffffffffffffffff9094169390930292909217825591516001820155925180519495509193849392610be8926002850192910190610f0e565b50505060049190915550505050505050565b610c02610d95565b610c0b81610e18565b50565b6004548214610c79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f7272656374000000000000000000604482015260640161034b565b60008281526007602090815260409091208251610c9e92600290920191840190610f0e565b5050600090815260076020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401610d1291511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161034b565b565b73ffffffffffffffffffffffffffffffffffffffff8116331415610e98576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161034b565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610f49579160200282015b82811115610f49578251825591602001919060010190610f2e565b50610f55929150610f59565b5090565b5b80821115610f555760008155600101610f5a565b803573ffffffffffffffffffffffffffffffffffffffff81168114610f9257600080fd5b919050565b803563ffffffff81168114610f9257600080fd5b600060208284031215610fbd57600080fd5b610fc682610f6e565b9392505050565b60006020808385031215610fe057600080fd5b823567ffffffffffffffff811115610ff757600080fd5b8301601f8101851361100857600080fd5b803561101b6110168261138a565b61133b565b80828252848201915084840188868560051b870101111561103b57600080fd5b600094505b838510156110655761105181610f6e565b835260019490940193918501918501611040565b50979650505050505050565b60006020828403121561108357600080fd5b8151610fc68161146c565b6000602082840312156110a057600080fd5b5035919050565b6000602082840312156110b957600080fd5b5051919050565b600080604083850312156110d357600080fd5b8235915060208084013567ffffffffffffffff8111156110f257600080fd5b8401601f8101861361110357600080fd5b80356111116110168261138a565b80828252848201915084840189868560051b870101111561113157600080fd5b600094505b83851015611154578035835260019490940193918501918501611136565b5080955050505050509250929050565b6000806040838503121561117757600080fd5b50508035926020909101359150565b600080600080600060a0868803121561119e57600080fd5b6111a786610f97565b9450602086013561ffff811681146111be57600080fd5b93506111cc60408701610f97565b92506060860135915060808601356111e38161146c565b809150509295509295909350565b60006020828403121561120357600080fd5b81356bffffffffffffffffffffffff81168114610fc657600080fd5b6000815180845260005b8181101561124557602081850181015186830182015201611229565b81811115611257576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff831660208201526060604082015260006112cd606083018461121f565b95945050505050565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c08084015261133360e084018261121f565b949350505050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156113825761138261143d565b604052919050565b600067ffffffffffffffff8211156113a4576113a461143d565b5060051b60200190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611407577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8015158114610c0b57600080fdfea164736f6c6343000806000a", + 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\":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_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: "0x60806040523480156200001157600080fd5b506040516200197e3803806200197e8339810160408190526200003491620001cc565b8133806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000103565b5050600280546001600160a01b03199081166001600160a01b0394851617909155600580548216958416959095179094555060038054909316911617905562000204565b6001600160a01b0381163314156200015e5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001c757600080fd5b919050565b60008060408385031215620001e057600080fd5b620001eb83620001af565b9150620001fb60208401620001af565b90509250929050565b61176a80620002146000396000f3fe6080604052600436106101295760003560e01c806380980043116100a5578063b96dbba711610074578063de367c8e11610059578063de367c8e14610378578063eff27017146103a5578063f2fde38b146103c557600080fd5b8063b96dbba714610350578063cf62c8ab1461035857600080fd5b8063809800431461025e5780638da5cb5b1461027e5780638ea98117146102a9578063a168fa89146102c957600080fd5b806336bfffed116100fc578063706da1ca116100e1578063706da1ca146101e15780637725135b146101f757806379ba50971461024957600080fd5b806336bfffed146101ab5780635d7d53e3146101cb57600080fd5b80631d2b2afd1461012e5780631fe543e31461013857806329e5d831146101585780632fa4e4421461018b575b600080fd5b6101366103e5565b005b34801561014457600080fd5b506101366101533660046113a3565b6104e0565b34801561016457600080fd5b50610178610173366004611447565b610561565b6040519081526020015b60405180910390f35b34801561019757600080fd5b506101366101a63660046114d4565b61069e565b3480156101b757600080fd5b506101366101c63660046112b0565b6107c0565b3480156101d757600080fd5b5061017860045481565b3480156101ed57600080fd5b5061017860065481565b34801561020357600080fd5b506003546102249073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610182565b34801561025557600080fd5b506101366108f8565b34801561026a57600080fd5b50610136610279366004611371565b600655565b34801561028a57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610224565b3480156102b557600080fd5b506101366102c436600461128e565b6109f5565b3480156102d557600080fd5b5061031e6102e4366004611371565b6007602052600090815260409020805460019091015460ff821691610100900473ffffffffffffffffffffffffffffffffffffffff169083565b60408051931515845273ffffffffffffffffffffffffffffffffffffffff909216602084015290820152606001610182565b610136610b00565b34801561036457600080fd5b506101366103733660046114d4565b610b66565b34801561038457600080fd5b506005546102249073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103b157600080fd5b506101366103c0366004611469565b610bad565b3480156103d157600080fd5b506101366103e036600461128e565b610d98565b600654610453576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f737562206e6f742073657400000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6005546006546040517fe8509bff000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff9091169063e8509bff9034906024015b6000604051808303818588803b1580156104c557600080fd5b505af11580156104d9573d6000803e3d6000fd5b5050505050565b60025473ffffffffffffffffffffffffffffffffffffffff163314610553576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161044a565b61055d8282610dac565b5050565b60008281526007602090815260408083208151608081018352815460ff811615158252610100900473ffffffffffffffffffffffffffffffffffffffff1681850152600182015481840152600282018054845181870281018701909552808552869592946060860193909291908301828280156105fd57602002820191906000526020600020905b8154815260200190600101908083116105e9575b5050505050815250509050806040015160001415610677576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f7272656374000000000000000000604482015260640161044a565b8060600151838151811061068d5761068d6116f1565b602002602001015191505092915050565b600654610707576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f737562206e6f7420736574000000000000000000000000000000000000000000604482015260640161044a565b60035460025460065460408051602081019290925273ffffffffffffffffffffffffffffffffffffffff93841693634000aea09316918591015b6040516020818303038152906040526040518463ffffffff1660e01b815260040161076e9392919061156d565b602060405180830381600087803b15801561078857600080fd5b505af115801561079c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061055d9190611354565b600654610829576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f7375624944206e6f742073657400000000000000000000000000000000000000604482015260640161044a565b60005b815181101561055d57600554600654835173ffffffffffffffffffffffffffffffffffffffff9092169163bec4c08c919085908590811061086f5761086f6116f1565b60200260200101516040518363ffffffff1660e01b81526004016108b392919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b1580156108cd57600080fd5b505af11580156108e1573d6000803e3d6000fd5b5050505080806108f090611691565b91505061082c565b60015473ffffffffffffffffffffffffffffffffffffffff163314610979576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161044a565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610a35575060025473ffffffffffffffffffffffffffffffffffffffff163314155b15610ab95733610a5a60005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9384166004820152918316602483015291909116604482015260640161044a565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610b08610e77565b506005546006546040517fe8509bff000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff9091169063e8509bff9034906024016104ac565b610b6e610e77565b5060035460025460065460408051602081019290925273ffffffffffffffffffffffffffffffffffffffff93841693634000aea0931691859101610741565b60006040518060c0016040528084815260200160065481526020018661ffff1681526020018763ffffffff1681526020018563ffffffff168152602001610c036040518060200160405280861515815250610fbc565b90526002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925060009173ffffffffffffffffffffffffffffffffffffffff90911690639b1c385e90610c619085906004016115b9565b602060405180830381600087803b158015610c7b57600080fd5b505af1158015610c8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb3919061138a565b604080516080810182526000808252336020808401918252838501868152855184815280830187526060860190815287855260078352959093208451815493517fffffffffffffffffffffff0000000000000000000000000000000000000000009094169015157fffffffffffffffffffffff0000000000000000000000000000000000000000ff161761010073ffffffffffffffffffffffffffffffffffffffff9094169390930292909217825591516001820155925180519495509193849392610d869260028501929101906111f1565b50505060049190915550505050505050565b610da0611078565b610da9816110fb565b50565b6004548214610e17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f7272656374000000000000000000604482015260640161044a565b60008281526007602090815260409091208251610e3c926002909201918401906111f1565b5050600090815260076020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600060065460001415610fb557600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a21a23e46040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610eee57600080fd5b505af1158015610f02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f26919061138a565b60068190556005546040517fbec4c08c000000000000000000000000000000000000000000000000000000008152600481019290925230602483015273ffffffffffffffffffffffffffffffffffffffff169063bec4c08c90604401600060405180830381600087803b158015610f9c57600080fd5b505af1158015610fb0573d6000803e3d6000fd5b505050505b5060065490565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401610ff591511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146110f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161044a565b565b73ffffffffffffffffffffffffffffffffffffffff811633141561117b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161044a565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b82805482825590600052602060002090810192821561122c579160200282015b8281111561122c578251825591602001919060010190611211565b5061123892915061123c565b5090565b5b80821115611238576000815560010161123d565b803573ffffffffffffffffffffffffffffffffffffffff8116811461127557600080fd5b919050565b803563ffffffff8116811461127557600080fd5b6000602082840312156112a057600080fd5b6112a982611251565b9392505050565b600060208083850312156112c357600080fd5b823567ffffffffffffffff8111156112da57600080fd5b8301601f810185136112eb57600080fd5b80356112fe6112f98261166d565b61161e565b80828252848201915084840188868560051b870101111561131e57600080fd5b600094505b838510156113485761133481611251565b835260019490940193918501918501611323565b50979650505050505050565b60006020828403121561136657600080fd5b81516112a98161174f565b60006020828403121561138357600080fd5b5035919050565b60006020828403121561139c57600080fd5b5051919050565b600080604083850312156113b657600080fd5b8235915060208084013567ffffffffffffffff8111156113d557600080fd5b8401601f810186136113e657600080fd5b80356113f46112f98261166d565b80828252848201915084840189868560051b870101111561141457600080fd5b600094505b83851015611437578035835260019490940193918501918501611419565b5080955050505050509250929050565b6000806040838503121561145a57600080fd5b50508035926020909101359150565b600080600080600060a0868803121561148157600080fd5b61148a8661127a565b9450602086013561ffff811681146114a157600080fd5b93506114af6040870161127a565b92506060860135915060808601356114c68161174f565b809150509295509295909350565b6000602082840312156114e657600080fd5b81356bffffffffffffffffffffffff811681146112a957600080fd5b6000815180845260005b818110156115285760208185018101518683018201520161150c565b8181111561153a576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff831660208201526060604082015260006115b06060830184611502565b95945050505050565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c08084015261161660e0840182611502565b949350505050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561166557611665611720565b604052919050565b600067ffffffffffffffff82111561168757611687611720565b5060051b60200190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156116ea577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8015158114610da957600080fdfea164736f6c6343000806000a", } var VRFV2PlusConsumerExampleABI = VRFV2PlusConsumerExampleMetaData.ABI @@ -358,6 +358,18 @@ func (_VRFV2PlusConsumerExample *VRFV2PlusConsumerExampleTransactorSession) Crea return _VRFV2PlusConsumerExample.Contract.CreateSubscriptionAndFund(&_VRFV2PlusConsumerExample.TransactOpts, amount) } +func (_VRFV2PlusConsumerExample *VRFV2PlusConsumerExampleTransactor) CreateSubscriptionAndFundNative(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFV2PlusConsumerExample.contract.Transact(opts, "createSubscriptionAndFundNative") +} + +func (_VRFV2PlusConsumerExample *VRFV2PlusConsumerExampleSession) CreateSubscriptionAndFundNative() (*types.Transaction, error) { + return _VRFV2PlusConsumerExample.Contract.CreateSubscriptionAndFundNative(&_VRFV2PlusConsumerExample.TransactOpts) +} + +func (_VRFV2PlusConsumerExample *VRFV2PlusConsumerExampleTransactorSession) CreateSubscriptionAndFundNative() (*types.Transaction, error) { + return _VRFV2PlusConsumerExample.Contract.CreateSubscriptionAndFundNative(&_VRFV2PlusConsumerExample.TransactOpts) +} + func (_VRFV2PlusConsumerExample *VRFV2PlusConsumerExampleTransactor) RawFulfillRandomWords(opts *bind.TransactOpts, requestId *big.Int, randomWords []*big.Int) (*types.Transaction, error) { return _VRFV2PlusConsumerExample.contract.Transact(opts, "rawFulfillRandomWords", requestId, randomWords) } @@ -418,6 +430,18 @@ func (_VRFV2PlusConsumerExample *VRFV2PlusConsumerExampleTransactorSession) TopU return _VRFV2PlusConsumerExample.Contract.TopUpSubscription(&_VRFV2PlusConsumerExample.TransactOpts, amount) } +func (_VRFV2PlusConsumerExample *VRFV2PlusConsumerExampleTransactor) TopUpSubscriptionNative(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFV2PlusConsumerExample.contract.Transact(opts, "topUpSubscriptionNative") +} + +func (_VRFV2PlusConsumerExample *VRFV2PlusConsumerExampleSession) TopUpSubscriptionNative() (*types.Transaction, error) { + return _VRFV2PlusConsumerExample.Contract.TopUpSubscriptionNative(&_VRFV2PlusConsumerExample.TransactOpts) +} + +func (_VRFV2PlusConsumerExample *VRFV2PlusConsumerExampleTransactorSession) TopUpSubscriptionNative() (*types.Transaction, error) { + return _VRFV2PlusConsumerExample.Contract.TopUpSubscriptionNative(&_VRFV2PlusConsumerExample.TransactOpts) +} + func (_VRFV2PlusConsumerExample *VRFV2PlusConsumerExampleTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { return _VRFV2PlusConsumerExample.contract.Transact(opts, "transferOwnership", to) } @@ -765,6 +789,8 @@ type VRFV2PlusConsumerExampleInterface interface { CreateSubscriptionAndFund(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) + CreateSubscriptionAndFundNative(opts *bind.TransactOpts) (*types.Transaction, error) + RawFulfillRandomWords(opts *bind.TransactOpts, requestId *big.Int, randomWords []*big.Int) (*types.Transaction, error) RequestRandomWords(opts *bind.TransactOpts, callbackGasLimit uint32, requestConfirmations uint16, numWords uint32, keyHash [32]byte, nativePayment bool) (*types.Transaction, error) @@ -775,6 +801,8 @@ type VRFV2PlusConsumerExampleInterface interface { TopUpSubscription(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) + TopUpSubscriptionNative(opts *bind.TransactOpts) (*types.Transaction, error) + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) UpdateSubscription(opts *bind.TransactOpts, consumers []common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/generation/compile_event_mock_contract.sh b/core/gethwrappers/generation/compile_event_mock_contract.sh index addbc1f178f..a576a16adf6 100755 --- a/core/gethwrappers/generation/compile_event_mock_contract.sh +++ b/core/gethwrappers/generation/compile_event_mock_contract.sh @@ -5,7 +5,7 @@ set -euo pipefail echo "compiling contracts" CDIR="$(dirname "$0")" -COMPILE_COMMAND="$CDIR/../../../contracts/scripts/native_solc_compile_events_mock" +COMPILE_COMMAND="$CDIR/../../../contracts/scripts/native_solc_compile_all_events_mock" # Only print compilation output on failure. 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 e39794e3283..3f602da118c 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 @@ -4,6 +4,8 @@ aggregator_v3_interface: ../../contracts/solc/v0.8.6/AggregatorV3Interface.abi . authorized_forwarder: ../../contracts/solc/v0.7/AuthorizedForwarder.abi ../../contracts/solc/v0.7/AuthorizedForwarder.bin 426d0866a294c77b27a526265f98c688326eb3dec3b7a698180c5f1921ebdf56 authorized_receiver: ../../contracts/solc/v0.7/AuthorizedReceiver.abi ../../contracts/solc/v0.7/AuthorizedReceiver.bin 18e8969ba3234b027e1b16c11a783aca58d0ea5c2361010ec597f134b7bf1c4f automation_consumer_benchmark: ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark.abi ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark.bin f52c76f1aaed4be541d82d97189d70f5aa027fc9838037dd7a7d21910c8c488e +automation_forwarder_logic: ../../contracts/solc/v0.8.16/AutomationForwarderLogic.abi ../../contracts/solc/v0.8.16/AutomationForwarderLogic.bin 15ae0c367297955fdab4b552dbb10e1f2be80a8fde0efec4a4d398693e9d72b5 +automation_registrar_wrapper2_1: ../../contracts/solc/v0.8.16/AutomationRegistrar2_1.abi ../../contracts/solc/v0.8.16/AutomationRegistrar2_1.bin eb06d853aab39d3196c593b03e555851cbe8386e0fe54a74c2479f62d14b3c42 automation_utils_2_1: ../../contracts/solc/v0.8.16/AutomationUtils2_1.abi ../../contracts/solc/v0.8.16/AutomationUtils2_1.bin 0b3006a2a1588916d22bf1ae5429bd3bce24a58904588d5ed3fe1026d64616cf batch_blockhash_store: ../../contracts/solc/v0.8.6/BatchBlockhashStore.abi ../../contracts/solc/v0.8.6/BatchBlockhashStore.bin c5ab26709a01050402615659403f32d5cd1b85f3ad6bb6bfe021692f4233cf19 batch_vrf_coordinator_v2: ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2.abi ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2.bin d0a54963260d8c1f1bbd984b758285e6027cfb5a7e42701bcb562ab123219332 @@ -13,35 +15,34 @@ consumer_wrapper: ../../contracts/solc/v0.7/Consumer.abi ../../contracts/solc/v0 cron_upkeep_factory_wrapper: ../../contracts/solc/v0.8.6/CronUpkeepFactory.abi - dacb0f8cdf54ae9d2781c5e720fc314b32ed5e58eddccff512c75d6067292cd7 cron_upkeep_wrapper: ../../contracts/solc/v0.8.6/CronUpkeep.abi - 362fcfcf30a6ab3acff83095ea4b2b9056dd5e9dcb94bc5411aae58995d22709 derived_price_feed_wrapper: ../../contracts/solc/v0.8.6/DerivedPriceFeed.abi ../../contracts/solc/v0.8.6/DerivedPriceFeed.bin c8542e6c850c2d0fffb79a7f7213dc927ec64e6ddd54e1224cb2fb4a13aabdd0 -feed_lookup_compatible_interface: ../../contracts/solc/v0.8.15/FeedLookupCompatibleInterface.abi ../../contracts/solc/v0.8.15/FeedLookupCompatibleInterface.bin 2c5c2cb669a666ab6f14e7fdbd11ea019997e3860f56ccfaf112156e412f1b15 +dummy_protocol_wrapper: ../../contracts/solc/v0.8.16/DummyProtocol.abi ../../contracts/solc/v0.8.16/DummyProtocol.bin 583a448170b13abf7ed64e406e8177d78c9e55ab44efd141eee60de23a71ee3b +feed_lookup_compatible_interface: ../../contracts/solc/v0.8.16/FeedLookupCompatibleInterface.abi ../../contracts/solc/v0.8.16/FeedLookupCompatibleInterface.bin 2c5c2cb669a666ab6f14e7fdbd11ea019997e3860f56ccfaf112156e412f1b15 flags_wrapper: ../../contracts/solc/v0.6/Flags.abi ../../contracts/solc/v0.6/Flags.bin 2034d1b562ca37a63068851915e3703980276e8d5f7db6db8a3351a49d69fc4a flux_aggregator_wrapper: ../../contracts/solc/v0.6/FluxAggregator.abi ../../contracts/solc/v0.6/FluxAggregator.bin a3b0a6396c4aa3b5ee39b3c4bd45efc89789d4859379a8a92caca3a0496c5794 functions_billing_registry_events_mock: ../../contracts/solc/v0.8.6/FunctionsBillingRegistryEventsMock.abi ../../contracts/solc/v0.8.6/FunctionsBillingRegistryEventsMock.bin 50deeb883bd9c3729702be335c0388f9d8553bab4be5e26ecacac496a89e2b77 functions_oracle_events_mock: ../../contracts/solc/v0.8.6/FunctionsOracleEventsMock.abi ../../contracts/solc/v0.8.6/FunctionsOracleEventsMock.bin 3ca70f966f8fe751987f0ccb50bebb6aa5be77e4a9f835d1ae99e0e9bfb7d52c gas_wrapper: ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.abi ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.bin 4a5dcdac486d18fcd58e3488c15c1710ae76b977556a3f3191bd269a4bc75723 -i_keeper_registry_master_wrapper_2_1: ../../contracts/solc/v0.8.16/IKeeperRegistryMaster.abi ../../contracts/solc/v0.8.16/IKeeperRegistryMaster.bin bae4953d5927956ad355decba4f90b40fe3364b29656ad3eeccbc15b34bdb45e -i_log_automation: ../../contracts/solc/v0.8.16/ILogAutomation.abi ../../contracts/solc/v0.8.16/ILogAutomation.bin 8cc5fbd18810dd2a3dc12871eabdb3bf79634544614e00ee967382767b9dfde3 +gas_wrapper_mock: ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.abi ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.bin a9b08f18da59125c6fc305855710241f3d35161b8b9f3e3f635a7b1d5c6da9c8 +i_keeper_registry_master_wrapper_2_1: ../../contracts/solc/v0.8.16/IKeeperRegistryMaster.abi ../../contracts/solc/v0.8.16/IKeeperRegistryMaster.bin 4426a320baaef8a66692699ec008e371eb7f841b1f9f02ff817c0eee0c63c7b5 +i_log_automation: ../../contracts/solc/v0.8.16/ILogAutomation.abi ../../contracts/solc/v0.8.16/ILogAutomation.bin b9bc273ba34750073874397e7681909794d15b31da8a4449c5aafa0bb5ea1dfc keeper_registrar_wrapper1_2: ../../contracts/solc/v0.8.6/KeeperRegistrar.abi ../../contracts/solc/v0.8.6/KeeperRegistrar.bin e49b2f8b23da17af1ed2209b8ae0968cc04350554d636711e6c24a3ad3118692 +keeper_registrar_wrapper1_2_mock: ../../contracts/solc/v0.8.6/KeeperRegistrar1_2Mock.abi ../../contracts/solc/v0.8.6/KeeperRegistrar1_2Mock.bin 5b155a7cb3def309fd7525de1d7cd364ebf8491bdc3060eac08ea0ff55ab29bc keeper_registrar_wrapper2_0: ../../contracts/solc/v0.8.6/KeeperRegistrar2_0.abi ../../contracts/solc/v0.8.6/KeeperRegistrar2_0.bin 647f125c2f0dafabcdc545cb77b15dc2ec3ea9429357806813179b1fd555c2d2 keeper_registry_logic1_3: ../../contracts/solc/v0.8.6/KeeperRegistryLogic1_3.abi ../../contracts/solc/v0.8.6/KeeperRegistryLogic1_3.bin 0176d7abdb01b370c5bf4f670d9abf85ca10aff53b1f7bdad41f85fabe666020 keeper_registry_logic2_0: ../../contracts/solc/v0.8.6/KeeperRegistryLogic2_0.abi ../../contracts/solc/v0.8.6/KeeperRegistryLogic2_0.bin d69d2bc8e4844293dbc2d45abcddc50b84c88554ecccfa4fa77c0ca45ec80871 -keeper_registry_logic_a_wrapper_2_1: ../../contracts/solc/v0.8.16/KeeperRegistryLogicA2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistryLogicA2_1.bin 41a73c159373257b335e72196b57f0ca4aa2cf83e484943af7b0c8fce3c863de -keeper_registry_logic_b_wrapper_2_1: ../../contracts/solc/v0.8.16/KeeperRegistryLogicB2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistryLogicB2_1.bin 3a1a5efbcd1cf65e6e591b7b8c897f7bf8bde5a43376edfe78dd9e7a7415f40e +keeper_registry_logic_a_wrapper_2_1: ../../contracts/solc/v0.8.16/KeeperRegistryLogicA2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistryLogicA2_1.bin 77481ab75c9aa86a62a7b2a708599b5ea1a6346ed1c0def6d4826e7ae523f1ee +keeper_registry_logic_b_wrapper_2_1: ../../contracts/solc/v0.8.16/KeeperRegistryLogicB2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistryLogicB2_1.bin 467d10741a04601b136553a2b1c6ab37f2a65d809366faf03180a22ff26be215 keeper_registry_wrapper1_1: ../../contracts/solc/v0.7/KeeperRegistry1_1.abi ../../contracts/solc/v0.7/KeeperRegistry1_1.bin 6ce079f2738f015f7374673a2816e8e9787143d00b780ea7652c8aa9ad9e1e20 +keeper_registry_wrapper1_1_mock: ../../contracts/solc/v0.7/KeeperRegistry1_1Mock.abi ../../contracts/solc/v0.7/KeeperRegistry1_1Mock.bin 98ddb3680e86359de3b5d17e648253ba29a84703f087a1b52237824003a8c6df keeper_registry_wrapper1_2: ../../contracts/solc/v0.8.6/KeeperRegistry1_2.abi ../../contracts/solc/v0.8.6/KeeperRegistry1_2.bin c08f903e7ecbdf89bbfea32c6dd334d3bf908ac809ebf63545890798a5f7a4a7 keeper_registry_wrapper1_3: ../../contracts/solc/v0.8.6/KeeperRegistry1_3.abi ../../contracts/solc/v0.8.6/KeeperRegistry1_3.bin 5e1414eacbc1880b7349a4f253b7eca176f7f6300ef3cd834c493ce795a17e25 keeper_registry_wrapper2_0: ../../contracts/solc/v0.8.6/KeeperRegistry2_0.abi ../../contracts/solc/v0.8.6/KeeperRegistry2_0.bin c32dea7d5ef66b7c58ddc84ddf69aa44df1b3ae8601fbc271c95be4ff5853056 -keeper_registry_wrapper_2_1: ../../contracts/solc/v0.8.16/KeeperRegistry2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistry2_1.bin 7c0ef55da830b137a89a6e3d58ffb38385fb1c6ed84d0168eebedef598fd2a0f +keeper_registry_wrapper_2_1: ../../contracts/solc/v0.8.16/KeeperRegistry2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistry2_1.bin 6406f37de79d3d2efa86fb961e1462b62a5a2fff4aeb408bbdb4bc7272d91638 keepers_vrf_consumer: ../../contracts/solc/v0.8.6/KeepersVRFConsumer.abi ../../contracts/solc/v0.8.6/KeepersVRFConsumer.bin fa75572e689c9e84705c63e8dbe1b7b8aa1a8fe82d66356c4873d024bb9166e8 -llo_feeds: ../../contracts/solc/v0.8.16/VerifierProxy.abi ../../contracts/solc/v0.8.16/VerifierProxy.bin 3b69ffe9c694e8551b5375c02b9e960adc985e2390566740e7fea70c89e436f1 -llo_feeds_test: ../../contracts/solc/v0.8.16/ExposedVerifier.abi ../../contracts/solc/v0.8.16/ExposedVerifier.bin 6932cea8f2738e874d3ec9e1a4231d2421704030c071d9e15dd2f7f08482c246 -log_emitter: ../../contracts/solc/v0.8.6/LogEmitter.abi ../../contracts/solc/v0.8.6/LogEmitter.bin 375488d19b6ee1c180d42048be10abea9146e2a58347fd180358850d435cb854 -log_triggered_feed_lookup_wrapper: ../../contracts/solc/v0.8.16/LogTriggeredFeedLookup.abi ../../contracts/solc/v0.8.16/LogTriggeredFeedLookup.bin 0c64df455593bbd4768b28d9794b916fcb4af629c00e4dcd69dc107d41968bd4 -log_upkeep_counter_wrapper: ../../contracts/solc/v0.8.6/LogUpkeepCounter.abi ../../contracts/solc/v0.8.6/LogUpkeepCounter.bin f53538fb7ec780a8d5e18f3a7c11b917ce9eba0020a60f5b113b6bf8b16ddf2f -mercury_exposed_verifier: ../../contracts/solc/v0.8.16/ExposedVerifier.abi ../../contracts/solc/v0.8.16/ExposedVerifier.bin 6932cea8f2738e874d3ec9e1a4231d2421704030c071d9e15dd2f7f08482c246 -mercury_upkeep_wrapper: ../../contracts/solc/v0.8.15/MercuryUpkeep.abi ../../contracts/solc/v0.8.15/MercuryUpkeep.bin c4627433ed9ebe7f8cf6594f577b4a1826ce6f2209271895a885fd4b3017320e -mercury_verifier: ../../contracts/solc/v0.8.16/Verifier.abi ../../contracts/solc/v0.8.16/Verifier.bin 24b2db0d5db8e0198bb7eae2ecde65f2596df4bcc7b17d604d25300546c1694e -mercury_verifier_proxy: ../../contracts/solc/v0.8.16/VerifierProxy.abi ../../contracts/solc/v0.8.16/VerifierProxy.bin 3b69ffe9c694e8551b5375c02b9e960adc985e2390566740e7fea70c89e436f1 +log_emitter: ../../contracts/solc/v0.8.19/LogEmitter.abi ../../contracts/solc/v0.8.19/LogEmitter.bin 244ba13730c036de0b02beef4e3d9c9a96946ce353c27f366baecc7f5be5a6fd +log_triggered_feed_lookup_wrapper: ../../contracts/solc/v0.8.16/LogTriggeredFeedLookup.abi ../../contracts/solc/v0.8.16/LogTriggeredFeedLookup.bin 9678fec51a491bf3f4bfeb582211bf8ab0328b58b2710e45b51be0dde1155933 +log_upkeep_counter_wrapper: ../../contracts/solc/v0.8.6/LogUpkeepCounter.abi ../../contracts/solc/v0.8.6/LogUpkeepCounter.bin 13d6543329f89d06cbf3901d7f9ecdc42acc1a84d8c61db291fcbfdbe1138eb1 +mercury_upkeep_wrapper: ../../contracts/solc/v0.8.16/MercuryUpkeep.abi ../../contracts/solc/v0.8.16/MercuryUpkeep.bin 27a33050249b6c7de7236772d7960f29c69e6f8167cc736409312d0e965508a3 mock_aggregator_proxy: ../../contracts/solc/v0.8.6/MockAggregatorProxy.abi ../../contracts/solc/v0.8.6/MockAggregatorProxy.bin b16c108f3dd384c342ddff5e94da7c0a8d39d1be5e3d8f2cf61ecc7f0e50ff42 mock_ethlink_aggregator_wrapper: ../../contracts/solc/v0.6/MockETHLINKAggregator.abi ../../contracts/solc/v0.6/MockETHLINKAggregator.bin 1c52c24f797b8482aa12b8251dcea1c072827bd5b3426b822621261944b99ca0 mock_gas_aggregator_wrapper: ../../contracts/solc/v0.6/MockGASAggregator.abi ../../contracts/solc/v0.6/MockGASAggregator.bin bacbb1ea4dc6beac0db8a13ca5c75e2fd61b903d70feea9b3b1c8b10fe8df4f3 @@ -59,18 +60,21 @@ solidity_vrf_v08_verifier_wrapper: ../../contracts/solc/v0.8.6/VRFTestHelper.abi solidity_vrf_verifier_wrapper: ../../contracts/solc/v0.6/VRFTestHelper.abi ../../contracts/solc/v0.6/VRFTestHelper.bin 44c2b67d8d2990ab580453deb29d63508c6147a3dc49908a1db563bef06e6474 solidity_vrf_wrapper: ../../contracts/solc/v0.6/VRF.abi ../../contracts/solc/v0.6/VRF.bin 04ede5b83c06ba5b76ef99c081c72928007d8a7aaefcf21449a46a07cbd4bfc2 test_api_consumer_wrapper: ../../contracts/solc/v0.6/TestAPIConsumer.abi ../../contracts/solc/v0.6/TestAPIConsumer.bin ed10893cb18894c18e275302329c955f14ea2de37ee044f84aa1e067ac5ea71e +trusted_blockhash_store: ../../contracts/solc/v0.8.6/TrustedBlockhashStore.abi ../../contracts/solc/v0.8.6/TrustedBlockhashStore.bin a85d2899892aa9fd73fc99852ccba52c3983375113580673e6c5d655bfa79909 type_and_version_interface_wrapper: ../../contracts/solc/v0.8.6/TypeAndVersionInterface.abi ../../contracts/solc/v0.8.6/TypeAndVersionInterface.bin bc9c3a6e73e3ebd5b58754df0deeb3b33f4bb404d5709bb904aed51d32f4b45e upkeep_counter_wrapper: ../../contracts/solc/v0.7/UpkeepCounter.abi ../../contracts/solc/v0.7/UpkeepCounter.bin 901961ebf18906febc1c350f02da85c7ea1c2a68da70cfd94efa27c837a48663 upkeep_perform_counter_restrictive_wrapper: ../../contracts/solc/v0.7/UpkeepPerformCounterRestrictive.abi ../../contracts/solc/v0.7/UpkeepPerformCounterRestrictive.bin 8975a058fba528e16d8414dc6f13946d17a145fcbc66cf25a32449b6fe1ce878 upkeep_transcoder: ../../contracts/solc/v0.8.6/UpkeepTranscoder.abi ../../contracts/solc/v0.8.6/UpkeepTranscoder.bin 336c92a981597be26508455f81a908a0784a817b129a59686c5b2c4afcba730a -verifiable_load_mercury_upkeep_wrapper: ../../contracts/solc/v0.8.6/VerifiableLoadMercuryUpkeep.abi ../../contracts/solc/v0.8.6/VerifiableLoadMercuryUpkeep.bin b922ba0dfc984484d0b3655d1b4a67d27a4b7035f75e73130f4f6e29ff0b53ec -verifiable_load_upkeep_wrapper: ../../contracts/solc/v0.8.6/VerifiableLoadUpkeep.abi ../../contracts/solc/v0.8.6/VerifiableLoadUpkeep.bin dd0b055496b5e4ef14a9925b98abf6759009282dfac21e4f2b083f64a0c41cef +verifiable_load_log_trigger_upkeep_wrapper: ../../contracts/solc/v0.8.16/VerifiableLoadLogTriggerUpkeep.abi ../../contracts/solc/v0.8.16/VerifiableLoadLogTriggerUpkeep.bin 5d46568c3c468563a6e2a01554f42a49d5d39a8d475616723b4a003f8754ebfc +verifiable_load_mercury_upkeep_wrapper: ../../contracts/solc/v0.8.16/VerifiableLoadMercuryUpkeep.abi ../../contracts/solc/v0.8.16/VerifiableLoadMercuryUpkeep.bin 1aff150cf8dfebe9f1bd6e35fdb41a39bb3bcae576a1a2d79a87c92b01b8bbaa +verifiable_load_upkeep_wrapper: ../../contracts/solc/v0.8.16/VerifiableLoadUpkeep.abi ../../contracts/solc/v0.8.16/VerifiableLoadUpkeep.bin 2512e1e5e748bed60bf5a930351acd41c0d355a83126b56bdbf36cc62c5364fd vrf_consumer_v2: ../../contracts/solc/v0.8.6/VRFConsumerV2.abi ../../contracts/solc/v0.8.6/VRFConsumerV2.bin 9ef258bf8e9f8d880fd229ceb145593d91e24fc89366baa0bf19169c5787d15f vrf_consumer_v2_plus_upgradeable_example: ../../contracts/solc/v0.8.6/VRFConsumerV2PlusUpgradeableExample.abi ../../contracts/solc/v0.8.6/VRFConsumerV2PlusUpgradeableExample.bin 3155c611e4d6882e9324b6e975033b31356776ea8b031ca63d63da37589d583b vrf_consumer_v2_upgradeable_example: ../../contracts/solc/v0.8.6/VRFConsumerV2UpgradeableExample.abi ../../contracts/solc/v0.8.6/VRFConsumerV2UpgradeableExample.bin f1790a9a2f2a04c730593e483459709cb89e897f8a19d7a3ac0cfe6a97265e6e vrf_coordinator_mock: ../../contracts/solc/v0.8.6/VRFCoordinatorMock.abi ../../contracts/solc/v0.8.6/VRFCoordinatorMock.bin 5c495cf8df1f46d8736b9150cdf174cce358cb8352f60f0d5bb9581e23920501 vrf_coordinator_v2: ../../contracts/solc/v0.8.6/VRFCoordinatorV2.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2.bin 75c87cf1624a401ac6303df9c8e04896aa8a53849e8b0c3d7340a9d089ef6d4b -vrf_coordinator_v2plus: ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus.bin 8b9603ed36f8ec1cf33c1ee87f51631d06122781d822563cd327ca6fbb42cb7a +vrf_coordinator_v2_plus_v2_example: ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus_V2Example.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus_V2Example.bin 02d0ec25e4f3d72f818e7ebc2b5f5949a94889ab0da091f0d3e7f5e4a20a0bb6 +vrf_coordinator_v2plus: ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus.bin 912a7372a66ed8fd3a38a5b0913c8dca668ddb5d0e2de9d5352a6fac9e60f92b vrf_external_sub_owner_example: ../../contracts/solc/v0.8.6/VRFExternalSubOwnerExample.abi ../../contracts/solc/v0.8.6/VRFExternalSubOwnerExample.bin 14f888eb313930b50233a6f01ea31eba0206b7f41a41f6311670da8bb8a26963 vrf_load_test_external_sub_owner: ../../contracts/solc/v0.8.6/VRFLoadTestExternalSubOwner.abi ../../contracts/solc/v0.8.6/VRFLoadTestExternalSubOwner.bin 2097faa70265e420036cc8a3efb1f1e0836ad2d7323b295b9a26a125dbbe6c7d vrf_load_test_ownerless_consumer: ../../contracts/solc/v0.8.6/VRFLoadTestOwnerlessConsumer.abi ../../contracts/solc/v0.8.6/VRFLoadTestOwnerlessConsumer.bin 74f914843cbc70b9c3079c3e1c709382ce415225e8bb40113e7ac018bfcb0f5c @@ -78,6 +82,7 @@ vrf_load_test_with_metrics: ../../contracts/solc/v0.8.6/VRFV2LoadTestWithMetrics vrf_malicious_consumer_v2: ../../contracts/solc/v0.8.6/VRFMaliciousConsumerV2.abi ../../contracts/solc/v0.8.6/VRFMaliciousConsumerV2.bin 9755fa8ffc7f5f0b337d5d413d77b0c9f6cd6f68c31727d49acdf9d4a51bc522 vrf_malicious_consumer_v2_plus: ../../contracts/solc/v0.8.6/VRFMaliciousConsumerV2Plus.abi ../../contracts/solc/v0.8.6/VRFMaliciousConsumerV2Plus.bin 0c8349f763bf7240127d9d1f788fbd32cae7df22489efda26df02093e3dba97e vrf_owner: ../../contracts/solc/v0.8.6/VRFOwner.abi ../../contracts/solc/v0.8.6/VRFOwner.bin eccfae5ee295b5850e22f61240c469f79752b8d9a3bac5d64aec7ac8def2f6cb +vrf_owner_test_consumer: ../../contracts/solc/v0.8.6/VRFV2OwnerTestConsumer.abi ../../contracts/solc/v0.8.6/VRFV2OwnerTestConsumer.bin 9a53f1f6d23f6f9bd9781284d8406e4b0741d59d13da2bdf4a9e0a8754c88101 vrf_ownerless_consumer_example: ../../contracts/solc/v0.8.6/VRFOwnerlessConsumerExample.abi ../../contracts/solc/v0.8.6/VRFOwnerlessConsumerExample.bin 9893b3805863273917fb282eed32274e32aa3d5c2a67a911510133e1218132be vrf_single_consumer_example: ../../contracts/solc/v0.8.6/VRFSingleConsumerExample.abi ../../contracts/solc/v0.8.6/VRFSingleConsumerExample.bin 892a5ed35da2e933f7fd7835cd6f7f70ef3aa63a9c03a22c5b1fd026711b0ece vrf_v2plus_single_consumer: ../../contracts/solc/v0.8.6/VRFV2PlusSingleConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusSingleConsumerExample.bin ae52552860445980ebe6a6f38277ef2857672d41fff67ea440f4f2e1447ebdeb @@ -89,7 +94,7 @@ vrfv2_wrapper: ../../contracts/solc/v0.8.6/VRFV2Wrapper.abi ../../contracts/solc vrfv2_wrapper_consumer_example: ../../contracts/solc/v0.8.6/VRFV2WrapperConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2WrapperConsumerExample.bin 3c5c9f1c501e697a7e77e959b48767e2a0bb1372393fd7686f7aaef3eb794231 vrfv2_wrapper_interface: ../../contracts/solc/v0.8.6/VRFV2WrapperInterface.abi ../../contracts/solc/v0.8.6/VRFV2WrapperInterface.bin ff8560169de171a68b360b7438d13863682d07040d984fd0fb096b2379421003 vrfv2plus_client: ../../contracts/solc/v0.8.6/VRFV2PlusClient.abi ../../contracts/solc/v0.8.6/VRFV2PlusClient.bin 3ffbfa4971a7e5f46051a26b1722613f265d89ea1867547ecec58500953a9501 -vrfv2plus_consumer_example: ../../contracts/solc/v0.8.6/VRFV2PlusConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusConsumerExample.bin 54a54bd8760e6fa8c6e7ff05c0a7fc883c0b55f5d711d4b5a6cd5b48a51e0bdd +vrfv2plus_consumer_example: ../../contracts/solc/v0.8.6/VRFV2PlusConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusConsumerExample.bin 5cfc2977029d558dc6363a5d4953bb165d94932d248ea003dbb7ebf4b8b938bf vrfv2plus_reverting_example: ../../contracts/solc/v0.8.6/VRFV2PlusRevertingExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusRevertingExample.bin 93e8af756ad31107224560baf3472445af56300a7ad11cb8304c77707a73e082 vrfv2plus_wrapper: ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.bin 06f705f62d5f94c8315dbd680c1eb9ad0e650bfa0292de8eb5757b2fd21edb04 vrfv2plus_wrapper_consumer_example: ../../contracts/solc/v0.8.6/VRFV2PlusWrapperConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapperConsumerExample.bin d4ddf86da21b87c013f551b2563ab68712ea9d4724894664d5778f6b124f4e78 diff --git a/core/gethwrappers/go_generate.go b/core/gethwrappers/go_generate.go index 270ab016e61..6249e3385e0 100644 --- a/core/gethwrappers/go_generate.go +++ b/core/gethwrappers/go_generate.go @@ -30,33 +30,40 @@ package gethwrappers // Automation //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.7/KeeperRegistry1_1.abi ../../contracts/solc/v0.7/KeeperRegistry1_1.bin KeeperRegistry keeper_registry_wrapper1_1 +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.7/KeeperRegistry1_1Mock.abi ../../contracts/solc/v0.7/KeeperRegistry1_1Mock.bin KeeperRegistryMock keeper_registry_wrapper1_1_mock //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.7/UpkeepPerformCounterRestrictive.abi ../../contracts/solc/v0.7/UpkeepPerformCounterRestrictive.bin UpkeepPerformCounterRestrictive upkeep_perform_counter_restrictive_wrapper //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.7/UpkeepCounter.abi ../../contracts/solc/v0.7/UpkeepCounter.bin UpkeepCounter upkeep_counter_wrapper //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/CronUpkeepFactory.abi - CronUpkeepFactory cron_upkeep_factory_wrapper //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/CronUpkeep.abi - CronUpkeep cron_upkeep_wrapper //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/KeeperRegistrar.abi ../../contracts/solc/v0.8.6/KeeperRegistrar.bin KeeperRegistrar keeper_registrar_wrapper1_2 +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/KeeperRegistrar1_2Mock.abi ../../contracts/solc/v0.8.6/KeeperRegistrar1_2Mock.bin KeeperRegistrarMock keeper_registrar_wrapper1_2_mock //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/KeeperRegistry1_2.abi ../../contracts/solc/v0.8.6/KeeperRegistry1_2.bin KeeperRegistry keeper_registry_wrapper1_2 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/TypeAndVersionInterface.abi ../../contracts/solc/v0.8.6/TypeAndVersionInterface.bin TypeAndVersionInterface type_and_version_interface_wrapper //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.abi ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.bin KeeperRegistryCheckUpkeepGasUsageWrapper gas_wrapper +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.abi ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.bin KeeperRegistryCheckUpkeepGasUsageWrapperMock gas_wrapper_mock //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/KeeperRegistry1_3.abi ../../contracts/solc/v0.8.6/KeeperRegistry1_3.bin KeeperRegistry keeper_registry_wrapper1_3 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/KeeperRegistryLogic1_3.abi ../../contracts/solc/v0.8.6/KeeperRegistryLogic1_3.bin KeeperRegistryLogic keeper_registry_logic1_3 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/KeeperRegistrar2_0.abi ../../contracts/solc/v0.8.6/KeeperRegistrar2_0.bin KeeperRegistrar keeper_registrar_wrapper2_0 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/KeeperRegistry2_0.abi ../../contracts/solc/v0.8.6/KeeperRegistry2_0.bin KeeperRegistry keeper_registry_wrapper2_0 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/KeeperRegistryLogic2_0.abi ../../contracts/solc/v0.8.6/KeeperRegistryLogic2_0.bin KeeperRegistryLogic keeper_registry_logic2_0 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/UpkeepTranscoder.abi ../../contracts/solc/v0.8.6/UpkeepTranscoder.bin UpkeepTranscoder upkeep_transcoder -//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VerifiableLoadUpkeep.abi ../../contracts/solc/v0.8.6/VerifiableLoadUpkeep.bin VerifiableLoadUpkeep verifiable_load_upkeep_wrapper -//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VerifiableLoadMercuryUpkeep.abi ../../contracts/solc/v0.8.6/VerifiableLoadMercuryUpkeep.bin VerifiableLoadMercuryUpkeep verifiable_load_mercury_upkeep_wrapper -//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.15/MercuryUpkeep.abi ../../contracts/solc/v0.8.15/MercuryUpkeep.bin MercuryUpkeep mercury_upkeep_wrapper -//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.15/FeedLookupCompatibleInterface.abi ../../contracts/solc/v0.8.15/FeedLookupCompatibleInterface.bin FeedLookupCompatibleInterface feed_lookup_compatible_interface +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/VerifiableLoadUpkeep.abi ../../contracts/solc/v0.8.16/VerifiableLoadUpkeep.bin VerifiableLoadUpkeep verifiable_load_upkeep_wrapper +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/VerifiableLoadMercuryUpkeep.abi ../../contracts/solc/v0.8.16/VerifiableLoadMercuryUpkeep.bin VerifiableLoadMercuryUpkeep verifiable_load_mercury_upkeep_wrapper +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/VerifiableLoadLogTriggerUpkeep.abi ../../contracts/solc/v0.8.16/VerifiableLoadLogTriggerUpkeep.bin VerifiableLoadLogTriggerUpkeep verifiable_load_log_trigger_upkeep_wrapper +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/MercuryUpkeep.abi ../../contracts/solc/v0.8.16/MercuryUpkeep.bin MercuryUpkeep mercury_upkeep_wrapper +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/FeedLookupCompatibleInterface.abi ../../contracts/solc/v0.8.16/FeedLookupCompatibleInterface.bin FeedLookupCompatibleInterface feed_lookup_compatible_interface //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark.abi ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark.bin AutomationConsumerBenchmark automation_consumer_benchmark +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/AutomationRegistrar2_1.abi ../../contracts/solc/v0.8.16/AutomationRegistrar2_1.bin AutomationRegistrar automation_registrar_wrapper2_1 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/KeeperRegistry2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistry2_1.bin KeeperRegistry keeper_registry_wrapper_2_1 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/KeeperRegistryLogicA2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistryLogicA2_1.bin KeeperRegistryLogicA keeper_registry_logic_a_wrapper_2_1 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/KeeperRegistryLogicB2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistryLogicB2_1.bin KeeperRegistryLogicB keeper_registry_logic_b_wrapper_2_1 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/IKeeperRegistryMaster.abi ../../contracts/solc/v0.8.16/IKeeperRegistryMaster.bin IKeeperRegistryMaster i_keeper_registry_master_wrapper_2_1 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/ILogAutomation.abi ../../contracts/solc/v0.8.16/ILogAutomation.bin ILogAutomation i_log_automation //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/AutomationUtils2_1.abi ../../contracts/solc/v0.8.16/AutomationUtils2_1.bin AutomationUtils automation_utils_2_1 +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/AutomationForwarderLogic.abi ../../contracts/solc/v0.8.16/AutomationForwarderLogic.bin AutomationForwarderLogic automation_forwarder_logic //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/LogUpkeepCounter.abi ../../contracts/solc/v0.8.6/LogUpkeepCounter.bin LogUpkeepCounter log_upkeep_counter_wrapper //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/LogTriggeredFeedLookup.abi ../../contracts/solc/v0.8.16/LogTriggeredFeedLookup.bin LogTriggeredFeedLookup log_triggered_feed_lookup_wrapper +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/DummyProtocol.abi ../../contracts/solc/v0.8.16/DummyProtocol.bin DummyProtocol dummy_protocol_wrapper // v0.8.6 VRFConsumer //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFCoordinatorMock.abi ../../contracts/solc/v0.8.6/VRFCoordinatorMock.bin VRFCoordinatorMock vrf_coordinator_mock @@ -66,6 +73,7 @@ package gethwrappers //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFLoadTestOwnerlessConsumer.abi ../../contracts/solc/v0.8.6/VRFLoadTestOwnerlessConsumer.bin VRFLoadTestOwnerlessConsumer vrf_load_test_ownerless_consumer //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFLoadTestExternalSubOwner.abi ../../contracts/solc/v0.8.6/VRFLoadTestExternalSubOwner.bin VRFLoadTestExternalSubOwner vrf_load_test_external_sub_owner //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFV2LoadTestWithMetrics.abi ../../contracts/solc/v0.8.6/VRFV2LoadTestWithMetrics.bin VRFV2LoadTestWithMetrics vrf_load_test_with_metrics +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFV2OwnerTestConsumer.abi ../../contracts/solc/v0.8.6/VRFV2OwnerTestConsumer.bin VRFV2OwnerTestConsumer vrf_owner_test_consumer //go:generate go run ./generation/generate_link/wrap_link.go @@ -109,6 +117,7 @@ package gethwrappers //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFV2PlusRevertingExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusRevertingExample.bin VRFV2PlusRevertingExample vrfv2plus_reverting_example //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFConsumerV2PlusUpgradeableExample.abi ../../contracts/solc/v0.8.6/VRFConsumerV2PlusUpgradeableExample.bin VRFConsumerV2PlusUpgradeableExample vrf_consumer_v2_plus_upgradeable_example //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFV2PlusClient.abi ../../contracts/solc/v0.8.6/VRFV2PlusClient.bin VRFV2PlusClient vrfv2plus_client +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus_V2Example.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus_V2Example.bin VRFCoordinatorV2Plus_V2Example vrf_coordinator_v2_plus_v2_example // Aggregators //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/AggregatorV2V3Interface.abi ../../contracts/solc/v0.8.6/AggregatorV2V3Interface.bin AggregatorV2V3Interface aggregator_v2v3_interface @@ -117,17 +126,24 @@ package gethwrappers //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/MockAggregatorProxy.abi ../../contracts/solc/v0.8.6/MockAggregatorProxy.bin MockAggregatorProxy mock_aggregator_proxy // Log tester -//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/LogEmitter.abi ../../contracts/solc/v0.8.6/LogEmitter.bin LogEmitter log_emitter +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/LogEmitter.abi ../../contracts/solc/v0.8.19/LogEmitter.bin LogEmitter log_emitter // Chainlink Functions //go:generate go generate ./functions // Mercury -//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/Verifier.abi ../../contracts/solc/v0.8.16/Verifier.bin MercuryVerifier mercury_verifier -//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/VerifierProxy.abi ../../contracts/solc/v0.8.16/VerifierProxy.bin MercuryVerifierProxy mercury_verifier_proxy -//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/ExposedVerifier.abi ../../contracts/solc/v0.8.16/ExposedVerifier.bin MercuryExposedVerifier mercury_exposed_verifier +//go:generate go generate ./llo-feeds + +// Shared +//go:generate go generate ./shared // Mocks that contain only events and functions to emit them +// These contracts are used in testing Atlas flows. The contracts contain no logic, only events, structures, and functions to emit them. +// The flow is as follows: +// 1. Compile all non events mock contracts. +// 2. Generate events mock .sol files based on ABI of compiled contracts. +// 3. Compile events mock contracts. ./generation/compile_event_mock_contract.sh calls contracts/scripts/native_solc_compile_all_events_mock to compile events mock contracts. +// 4. Generate wrappers for events mock contracts. //go:generate go run ./generation/generate_events_mock/create_events_mock_contract.go ../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracle.abi ../../contracts/src/v0.8/mocks/FunctionsOracleEventsMock.sol FunctionsOracleEventsMock //go:generate go run ./generation/generate_events_mock/create_events_mock_contract.go ../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsBillingRegistry.abi ../../contracts/src/v0.8/mocks/FunctionsBillingRegistryEventsMock.sol FunctionsBillingRegistryEventsMock //go:generate ./generation/compile_event_mock_contract.sh diff --git a/core/gethwrappers/go_generate_llo.go b/core/gethwrappers/go_generate_llo.go deleted file mode 100644 index 63628fe78de..00000000000 --- a/core/gethwrappers/go_generate_llo.go +++ /dev/null @@ -1,9 +0,0 @@ -// Package gethwrappers provides tools for wrapping solidity contracts with -// golang packages, using abigen. -package gethwrappers - -// Chainlink Functions (OCR2DR) -//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/Verifier.abi ../../contracts/solc/v0.8.16/Verifier.bin LLOVerifier llo_feeds -//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/VerifierProxy.abi ../../contracts/solc/v0.8.16/VerifierProxy.bin LLOVerifierProxy llo_feeds -//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/ErroredVerifier.abi ../../contracts/solc/v0.8.16/ErroredVerifier.bin LLOErroredVerifier llo_feeds_test -//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/ExposedVerifier.abi ../../contracts/solc/v0.8.16/ExposedVerifier.bin LLOExposedVerifier llo_feeds_test diff --git a/core/gethwrappers/go_generate_test.go b/core/gethwrappers/go_generate_test.go index fa19bc437be..9ded44c0785 100644 --- a/core/gethwrappers/go_generate_test.go +++ b/core/gethwrappers/go_generate_test.go @@ -94,7 +94,7 @@ func compareCurrentCompilerArtifactAgainstRecordsAndSoliditySources( t *testing.T, versionInfo ContractVersion, ) { hash := VersionHash(versionInfo.AbiPath, versionInfo.BinaryPath) - recompileCommand := fmt.Sprintf("(cd %s; make go-solidity-wrappers)", rootDir) + 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 %s, @@ -122,7 +122,7 @@ func init() { } fmt.Printf("some solidity artifacts missing (%s); rebuilding...", solidityArtifactsMissing) - // Don't want to run "make go-solidity-wrappers" here, because that would + // Don't want to run "make wrappers-all" here, because that would // result in an infinite loop cmd := exec.Command("bash", "-c", compileCommand) cmd.Stdout = os.Stdout diff --git a/core/gethwrappers/llo-feeds/generated/errored_verifier/errored_verifier.go b/core/gethwrappers/llo-feeds/generated/errored_verifier/errored_verifier.go new file mode 100644 index 00000000000..d6a52b74fd1 --- /dev/null +++ b/core/gethwrappers/llo-feeds/generated/errored_verifier/errored_verifier.go @@ -0,0 +1,415 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package errored_verifier + +import ( + "errors" + "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" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type CommonAddressAndWeight struct { + Addr common.Address + Weight *big.Int +} + +var ErroredVerifierMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"activateConfig\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"activateFeed\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"deactivateConfig\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"deactivateFeed\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"setConfigFromSource\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50610bf9806100206000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c806394d9598011610076578063b70d929d1161005b578063b70d929d146101a9578063ded6307c146101df578063e84f128e146101f257600080fd5b806394d95980146101885780639b103f131461019b57600080fd5b80633dd86430116100a75780633dd864301461014d57806352ba27d614610162578063564a0a7a1461017557600080fd5b806301ffc9a7146100c35780633d3ac1b51461012d575b600080fd5b6101186100d136600461059a565b7fffffffff00000000000000000000000000000000000000000000000000000000167f3d3ac1b5000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b61014061013b366004610741565b610228565b604051610124919061078f565b61016061015b3660046107fb565b610292565b005b6101606101703660046109b4565b6102f4565b6101606101833660046107fb565b610356565b610160610196366004610ab1565b6103b8565b610160610170366004610ad3565b6101bc6101b73660046107fb565b61041a565b604080519315158452602084019290925263ffffffff1690820152606001610124565b6101606101ed366004610ab1565b6104a9565b6102056102003660046107fb565b61050b565b6040805163ffffffff948516815293909216602084015290820152606001610124565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4661696c656420746f207665726966790000000000000000000000000000000060448201526060906064015b60405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4661696c656420746f20616374697661746520666565640000000000000000006044820152606401610289565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4661696c656420746f2073657420636f6e6669670000000000000000000000006044820152606401610289565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4661696c656420746f20646561637469766174652066656564000000000000006044820152606401610289565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4661696c656420746f206465616374697661746520636f6e66696700000000006044820152606401610289565b60008060006040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610289906020808252602c908201527f4661696c656420746f20676574206c617465737420636f6e666967206469676560408201527f737420616e642065706f63680000000000000000000000000000000000000000606082015260800190565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4661696c656420746f20616374697661746520636f6e666967000000000000006044820152606401610289565b60008060006040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102899060208082526023908201527f4661696c656420746f20676574206c617465737420636f6e666967206465746160408201527f696c730000000000000000000000000000000000000000000000000000000000606082015260800190565b6000602082840312156105ac57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146105dc57600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610635576106356105e3565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610682576106826105e3565b604052919050565b600082601f83011261069b57600080fd5b813567ffffffffffffffff8111156106b5576106b56105e3565b6106e660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161063b565b8181528460208386010111156106fb57600080fd5b816020850160208301376000918101602001919091529392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461073c57600080fd5b919050565b6000806040838503121561075457600080fd5b823567ffffffffffffffff81111561076b57600080fd5b6107778582860161068a565b92505061078660208401610718565b90509250929050565b600060208083528351808285015260005b818110156107bc578581018301518582016040015282016107a0565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006020828403121561080d57600080fd5b5035919050565b600067ffffffffffffffff82111561082e5761082e6105e3565b5060051b60200190565b600082601f83011261084957600080fd5b8135602061085e61085983610814565b61063b565b82815260059290921b8401810191818101908684111561087d57600080fd5b8286015b8481101561089f5761089281610718565b8352918301918301610881565b509695505050505050565b600082601f8301126108bb57600080fd5b813560206108cb61085983610814565b82815260059290921b840181019181810190868411156108ea57600080fd5b8286015b8481101561089f57803583529183019183016108ee565b803560ff8116811461073c57600080fd5b803567ffffffffffffffff8116811461073c57600080fd5b600082601f83011261093f57600080fd5b8135602061094f61085983610814565b82815260069290921b8401810191818101908684111561096e57600080fd5b8286015b8481101561089f576040818903121561098b5760008081fd5b610993610612565b61099c82610718565b81528185013585820152835291830191604001610972565b600080600080600080600080610100898b0312156109d157600080fd5b88359750602089013567ffffffffffffffff808211156109f057600080fd5b6109fc8c838d01610838565b985060408b0135915080821115610a1257600080fd5b610a1e8c838d016108aa565b9750610a2c60608c01610905565b965060808b0135915080821115610a4257600080fd5b610a4e8c838d0161068a565b9550610a5c60a08c01610916565b945060c08b0135915080821115610a7257600080fd5b610a7e8c838d0161068a565b935060e08b0135915080821115610a9457600080fd5b50610aa18b828c0161092e565b9150509295985092959890939650565b60008060408385031215610ac457600080fd5b50508035926020909101359150565b6000806000806000806000806000806101408b8d031215610af357600080fd5b8a35995060208b01359850610b0a60408c01610718565b975060608b013567ffffffffffffffff80821115610b2757600080fd5b610b338e838f01610838565b985060808d0135915080821115610b4957600080fd5b610b558e838f016108aa565b9750610b6360a08e01610905565b965060c08d0135915080821115610b7957600080fd5b610b858e838f0161068a565b9550610b9360e08e01610916565b94506101008d0135915080821115610baa57600080fd5b610bb68e838f0161068a565b93506101208d0135915080821115610bcd57600080fd5b50610bda8d828e0161092e565b9150509295989b9194979a509295985056fea164736f6c6343000810000a", +} + +var ErroredVerifierABI = ErroredVerifierMetaData.ABI + +var ErroredVerifierBin = ErroredVerifierMetaData.Bin + +func DeployErroredVerifier(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ErroredVerifier, error) { + parsed, err := ErroredVerifierMetaData.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(ErroredVerifierBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ErroredVerifier{ErroredVerifierCaller: ErroredVerifierCaller{contract: contract}, ErroredVerifierTransactor: ErroredVerifierTransactor{contract: contract}, ErroredVerifierFilterer: ErroredVerifierFilterer{contract: contract}}, nil +} + +type ErroredVerifier struct { + address common.Address + abi abi.ABI + ErroredVerifierCaller + ErroredVerifierTransactor + ErroredVerifierFilterer +} + +type ErroredVerifierCaller struct { + contract *bind.BoundContract +} + +type ErroredVerifierTransactor struct { + contract *bind.BoundContract +} + +type ErroredVerifierFilterer struct { + contract *bind.BoundContract +} + +type ErroredVerifierSession struct { + Contract *ErroredVerifier + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type ErroredVerifierCallerSession struct { + Contract *ErroredVerifierCaller + CallOpts bind.CallOpts +} + +type ErroredVerifierTransactorSession struct { + Contract *ErroredVerifierTransactor + TransactOpts bind.TransactOpts +} + +type ErroredVerifierRaw struct { + Contract *ErroredVerifier +} + +type ErroredVerifierCallerRaw struct { + Contract *ErroredVerifierCaller +} + +type ErroredVerifierTransactorRaw struct { + Contract *ErroredVerifierTransactor +} + +func NewErroredVerifier(address common.Address, backend bind.ContractBackend) (*ErroredVerifier, error) { + abi, err := abi.JSON(strings.NewReader(ErroredVerifierABI)) + if err != nil { + return nil, err + } + contract, err := bindErroredVerifier(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ErroredVerifier{address: address, abi: abi, ErroredVerifierCaller: ErroredVerifierCaller{contract: contract}, ErroredVerifierTransactor: ErroredVerifierTransactor{contract: contract}, ErroredVerifierFilterer: ErroredVerifierFilterer{contract: contract}}, nil +} + +func NewErroredVerifierCaller(address common.Address, caller bind.ContractCaller) (*ErroredVerifierCaller, error) { + contract, err := bindErroredVerifier(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ErroredVerifierCaller{contract: contract}, nil +} + +func NewErroredVerifierTransactor(address common.Address, transactor bind.ContractTransactor) (*ErroredVerifierTransactor, error) { + contract, err := bindErroredVerifier(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ErroredVerifierTransactor{contract: contract}, nil +} + +func NewErroredVerifierFilterer(address common.Address, filterer bind.ContractFilterer) (*ErroredVerifierFilterer, error) { + contract, err := bindErroredVerifier(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ErroredVerifierFilterer{contract: contract}, nil +} + +func bindErroredVerifier(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ErroredVerifierMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_ErroredVerifier *ErroredVerifierRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ErroredVerifier.Contract.ErroredVerifierCaller.contract.Call(opts, result, method, params...) +} + +func (_ErroredVerifier *ErroredVerifierRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ErroredVerifier.Contract.ErroredVerifierTransactor.contract.Transfer(opts) +} + +func (_ErroredVerifier *ErroredVerifierRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ErroredVerifier.Contract.ErroredVerifierTransactor.contract.Transact(opts, method, params...) +} + +func (_ErroredVerifier *ErroredVerifierCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ErroredVerifier.Contract.contract.Call(opts, result, method, params...) +} + +func (_ErroredVerifier *ErroredVerifierTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ErroredVerifier.Contract.contract.Transfer(opts) +} + +func (_ErroredVerifier *ErroredVerifierTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ErroredVerifier.Contract.contract.Transact(opts, method, params...) +} + +func (_ErroredVerifier *ErroredVerifierCaller) ActivateConfig(opts *bind.CallOpts, arg0 [32]byte, arg1 [32]byte) error { + var out []interface{} + err := _ErroredVerifier.contract.Call(opts, &out, "activateConfig", arg0, arg1) + + if err != nil { + return err + } + + return err + +} + +func (_ErroredVerifier *ErroredVerifierSession) ActivateConfig(arg0 [32]byte, arg1 [32]byte) error { + return _ErroredVerifier.Contract.ActivateConfig(&_ErroredVerifier.CallOpts, arg0, arg1) +} + +func (_ErroredVerifier *ErroredVerifierCallerSession) ActivateConfig(arg0 [32]byte, arg1 [32]byte) error { + return _ErroredVerifier.Contract.ActivateConfig(&_ErroredVerifier.CallOpts, arg0, arg1) +} + +func (_ErroredVerifier *ErroredVerifierCaller) ActivateFeed(opts *bind.CallOpts, arg0 [32]byte) error { + var out []interface{} + err := _ErroredVerifier.contract.Call(opts, &out, "activateFeed", arg0) + + if err != nil { + return err + } + + return err + +} + +func (_ErroredVerifier *ErroredVerifierSession) ActivateFeed(arg0 [32]byte) error { + return _ErroredVerifier.Contract.ActivateFeed(&_ErroredVerifier.CallOpts, arg0) +} + +func (_ErroredVerifier *ErroredVerifierCallerSession) ActivateFeed(arg0 [32]byte) error { + return _ErroredVerifier.Contract.ActivateFeed(&_ErroredVerifier.CallOpts, arg0) +} + +func (_ErroredVerifier *ErroredVerifierCaller) DeactivateConfig(opts *bind.CallOpts, arg0 [32]byte, arg1 [32]byte) error { + var out []interface{} + err := _ErroredVerifier.contract.Call(opts, &out, "deactivateConfig", arg0, arg1) + + if err != nil { + return err + } + + return err + +} + +func (_ErroredVerifier *ErroredVerifierSession) DeactivateConfig(arg0 [32]byte, arg1 [32]byte) error { + return _ErroredVerifier.Contract.DeactivateConfig(&_ErroredVerifier.CallOpts, arg0, arg1) +} + +func (_ErroredVerifier *ErroredVerifierCallerSession) DeactivateConfig(arg0 [32]byte, arg1 [32]byte) error { + return _ErroredVerifier.Contract.DeactivateConfig(&_ErroredVerifier.CallOpts, arg0, arg1) +} + +func (_ErroredVerifier *ErroredVerifierCaller) DeactivateFeed(opts *bind.CallOpts, arg0 [32]byte) error { + var out []interface{} + err := _ErroredVerifier.contract.Call(opts, &out, "deactivateFeed", arg0) + + if err != nil { + return err + } + + return err + +} + +func (_ErroredVerifier *ErroredVerifierSession) DeactivateFeed(arg0 [32]byte) error { + return _ErroredVerifier.Contract.DeactivateFeed(&_ErroredVerifier.CallOpts, arg0) +} + +func (_ErroredVerifier *ErroredVerifierCallerSession) DeactivateFeed(arg0 [32]byte) error { + return _ErroredVerifier.Contract.DeactivateFeed(&_ErroredVerifier.CallOpts, arg0) +} + +func (_ErroredVerifier *ErroredVerifierCaller) LatestConfigDetails(opts *bind.CallOpts, arg0 [32]byte) (uint32, uint32, [32]byte, error) { + var out []interface{} + err := _ErroredVerifier.contract.Call(opts, &out, "latestConfigDetails", arg0) + + if err != nil { + return *new(uint32), *new(uint32), *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + out1 := *abi.ConvertType(out[1], new(uint32)).(*uint32) + out2 := *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + + return out0, out1, out2, err + +} + +func (_ErroredVerifier *ErroredVerifierSession) LatestConfigDetails(arg0 [32]byte) (uint32, uint32, [32]byte, error) { + return _ErroredVerifier.Contract.LatestConfigDetails(&_ErroredVerifier.CallOpts, arg0) +} + +func (_ErroredVerifier *ErroredVerifierCallerSession) LatestConfigDetails(arg0 [32]byte) (uint32, uint32, [32]byte, error) { + return _ErroredVerifier.Contract.LatestConfigDetails(&_ErroredVerifier.CallOpts, arg0) +} + +func (_ErroredVerifier *ErroredVerifierCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts, arg0 [32]byte) (bool, [32]byte, uint32, error) { + var out []interface{} + err := _ErroredVerifier.contract.Call(opts, &out, "latestConfigDigestAndEpoch", arg0) + + if err != nil { + return *new(bool), *new([32]byte), *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + out1 := *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + out2 := *abi.ConvertType(out[2], new(uint32)).(*uint32) + + return out0, out1, out2, err + +} + +func (_ErroredVerifier *ErroredVerifierSession) LatestConfigDigestAndEpoch(arg0 [32]byte) (bool, [32]byte, uint32, error) { + return _ErroredVerifier.Contract.LatestConfigDigestAndEpoch(&_ErroredVerifier.CallOpts, arg0) +} + +func (_ErroredVerifier *ErroredVerifierCallerSession) LatestConfigDigestAndEpoch(arg0 [32]byte) (bool, [32]byte, uint32, error) { + return _ErroredVerifier.Contract.LatestConfigDigestAndEpoch(&_ErroredVerifier.CallOpts, arg0) +} + +func (_ErroredVerifier *ErroredVerifierCaller) SetConfig(opts *bind.CallOpts, arg0 [32]byte, arg1 []common.Address, arg2 [][32]byte, arg3 uint8, arg4 []byte, arg5 uint64, arg6 []byte, arg7 []CommonAddressAndWeight) error { + var out []interface{} + err := _ErroredVerifier.contract.Call(opts, &out, "setConfig", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + + if err != nil { + return err + } + + return err + +} + +func (_ErroredVerifier *ErroredVerifierSession) SetConfig(arg0 [32]byte, arg1 []common.Address, arg2 [][32]byte, arg3 uint8, arg4 []byte, arg5 uint64, arg6 []byte, arg7 []CommonAddressAndWeight) error { + return _ErroredVerifier.Contract.SetConfig(&_ErroredVerifier.CallOpts, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +} + +func (_ErroredVerifier *ErroredVerifierCallerSession) SetConfig(arg0 [32]byte, arg1 []common.Address, arg2 [][32]byte, arg3 uint8, arg4 []byte, arg5 uint64, arg6 []byte, arg7 []CommonAddressAndWeight) error { + return _ErroredVerifier.Contract.SetConfig(&_ErroredVerifier.CallOpts, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +} + +func (_ErroredVerifier *ErroredVerifierCaller) SetConfigFromSource(opts *bind.CallOpts, arg0 [32]byte, arg1 *big.Int, arg2 common.Address, arg3 []common.Address, arg4 [][32]byte, arg5 uint8, arg6 []byte, arg7 uint64, arg8 []byte, arg9 []CommonAddressAndWeight) error { + var out []interface{} + err := _ErroredVerifier.contract.Call(opts, &out, "setConfigFromSource", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) + + if err != nil { + return err + } + + return err + +} + +func (_ErroredVerifier *ErroredVerifierSession) SetConfigFromSource(arg0 [32]byte, arg1 *big.Int, arg2 common.Address, arg3 []common.Address, arg4 [][32]byte, arg5 uint8, arg6 []byte, arg7 uint64, arg8 []byte, arg9 []CommonAddressAndWeight) error { + return _ErroredVerifier.Contract.SetConfigFromSource(&_ErroredVerifier.CallOpts, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) +} + +func (_ErroredVerifier *ErroredVerifierCallerSession) SetConfigFromSource(arg0 [32]byte, arg1 *big.Int, arg2 common.Address, arg3 []common.Address, arg4 [][32]byte, arg5 uint8, arg6 []byte, arg7 uint64, arg8 []byte, arg9 []CommonAddressAndWeight) error { + return _ErroredVerifier.Contract.SetConfigFromSource(&_ErroredVerifier.CallOpts, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) +} + +func (_ErroredVerifier *ErroredVerifierCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _ErroredVerifier.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_ErroredVerifier *ErroredVerifierSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _ErroredVerifier.Contract.SupportsInterface(&_ErroredVerifier.CallOpts, interfaceId) +} + +func (_ErroredVerifier *ErroredVerifierCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _ErroredVerifier.Contract.SupportsInterface(&_ErroredVerifier.CallOpts, interfaceId) +} + +func (_ErroredVerifier *ErroredVerifierCaller) Verify(opts *bind.CallOpts, arg0 []byte, arg1 common.Address) ([]byte, error) { + var out []interface{} + err := _ErroredVerifier.contract.Call(opts, &out, "verify", arg0, arg1) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_ErroredVerifier *ErroredVerifierSession) Verify(arg0 []byte, arg1 common.Address) ([]byte, error) { + return _ErroredVerifier.Contract.Verify(&_ErroredVerifier.CallOpts, arg0, arg1) +} + +func (_ErroredVerifier *ErroredVerifierCallerSession) Verify(arg0 []byte, arg1 common.Address) ([]byte, error) { + return _ErroredVerifier.Contract.Verify(&_ErroredVerifier.CallOpts, arg0, arg1) +} + +func (_ErroredVerifier *ErroredVerifier) Address() common.Address { + return _ErroredVerifier.address +} + +type ErroredVerifierInterface interface { + ActivateConfig(opts *bind.CallOpts, arg0 [32]byte, arg1 [32]byte) error + + ActivateFeed(opts *bind.CallOpts, arg0 [32]byte) error + + DeactivateConfig(opts *bind.CallOpts, arg0 [32]byte, arg1 [32]byte) error + + DeactivateFeed(opts *bind.CallOpts, arg0 [32]byte) error + + LatestConfigDetails(opts *bind.CallOpts, arg0 [32]byte) (uint32, uint32, [32]byte, error) + + LatestConfigDigestAndEpoch(opts *bind.CallOpts, arg0 [32]byte) (bool, [32]byte, uint32, error) + + SetConfig(opts *bind.CallOpts, arg0 [32]byte, arg1 []common.Address, arg2 [][32]byte, arg3 uint8, arg4 []byte, arg5 uint64, arg6 []byte, arg7 []CommonAddressAndWeight) error + + SetConfigFromSource(opts *bind.CallOpts, arg0 [32]byte, arg1 *big.Int, arg2 common.Address, arg3 []common.Address, arg4 [][32]byte, arg5 uint8, arg6 []byte, arg7 uint64, arg8 []byte, arg9 []CommonAddressAndWeight) error + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + Verify(opts *bind.CallOpts, arg0 []byte, arg1 common.Address) ([]byte, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/mercury_exposed_verifier/mercury_exposed_verifier.go b/core/gethwrappers/llo-feeds/generated/exposed_verifier/exposed_verifier.go similarity index 51% rename from core/gethwrappers/generated/mercury_exposed_verifier/mercury_exposed_verifier.go rename to core/gethwrappers/llo-feeds/generated/exposed_verifier/exposed_verifier.go index 68aa9f0b907..2ca74b7cf3d 100644 --- a/core/gethwrappers/generated/mercury_exposed_verifier/mercury_exposed_verifier.go +++ b/core/gethwrappers/llo-feeds/generated/exposed_verifier/exposed_verifier.go @@ -1,7 +1,7 @@ // Code generated - DO NOT EDIT. // This file is a generated binding and any manual changes will be lost. -package mercury_exposed_verifier +package exposed_verifier import ( "errors" @@ -28,17 +28,17 @@ var ( _ = abi.ConvertType ) -var MercuryExposedVerifierMetaData = &bind.MetaData{ +var ExposedVerifierMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_feedId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"_configCount\",\"type\":\"uint64\"},{\"internalType\":\"address[]\",\"name\":\"_signers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"_offchainTransmitters\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"_f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"_encodedConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"_encodedConfig\",\"type\":\"bytes\"}],\"name\":\"exposedConfigDigestFromConfigData\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", Bin: "0x608060405234801561001057600080fd5b50610696806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80630ebd702314610030575b600080fd5b61004361003e3660046103f7565b610055565b60405190815260200160405180910390f35b60006100a18c8c8c8c8c8c8c8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92508d91506100b19050565b9c9b505050505050505050505050565b6000808b8b8b8b8b8b8b8b8b8b6040516020016100d79a999897969594939291906105a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e06000000000000000000000000000000000000000000000000000000000000179150509a9950505050505050505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461018357600080fd5b919050565b803567ffffffffffffffff8116811461018357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610216576102166101a0565b604052919050565b600067ffffffffffffffff821115610238576102386101a0565b5060051b60200190565b600082601f83011261025357600080fd5b813560206102686102638361021e565b6101cf565b82815260059290921b8401810191818101908684111561028757600080fd5b8286015b848110156102a95761029c8161015f565b835291830191830161028b565b509695505050505050565b600082601f8301126102c557600080fd5b813560206102d56102638361021e565b82815260059290921b840181019181810190868411156102f457600080fd5b8286015b848110156102a957803583529183019183016102f8565b803560ff8116811461018357600080fd5b60008083601f84011261033257600080fd5b50813567ffffffffffffffff81111561034a57600080fd5b60208301915083602082850101111561036257600080fd5b9250929050565b600082601f83011261037a57600080fd5b813567ffffffffffffffff811115610394576103946101a0565b6103c560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016101cf565b8181528460208386010111156103da57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060008060008060006101408c8e03121561041957600080fd5b8b359a5060208c0135995061043060408d0161015f565b985061043e60608d01610188565b975067ffffffffffffffff8060808e0135111561045a57600080fd5b61046a8e60808f01358f01610242565b97508060a08e0135111561047d57600080fd5b61048d8e60a08f01358f016102b4565b965061049b60c08e0161030f565b95508060e08e013511156104ae57600080fd5b6104be8e60e08f01358f01610320565b90955093506104d06101008e01610188565b9250806101208e013511156104e457600080fd5b506104f68d6101208e01358e01610369565b90509295989b509295989b9093969950565b600081518084526020808501945080840160005b838110156105385781518752958201959082019060010161051c565b509495945050505050565b6000815180845260005b818110156105695760208185018101518683018201520161054d565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b8a815260208082018b905273ffffffffffffffffffffffffffffffffffffffff8a8116604084015267ffffffffffffffff8a1660608401526101406080840181905289519084018190526000926101608501928b820192855b8181101561061e578451831686529483019493830193600101610600565b505050505082810360a08401526106358189610508565b60ff881660c0850152905082810360e08401526106528187610543565b67ffffffffffffffff861661010085015290508281036101208401526106788185610543565b9d9c5050505050505050505050505056fea164736f6c6343000810000a", } -var MercuryExposedVerifierABI = MercuryExposedVerifierMetaData.ABI +var ExposedVerifierABI = ExposedVerifierMetaData.ABI -var MercuryExposedVerifierBin = MercuryExposedVerifierMetaData.Bin +var ExposedVerifierBin = ExposedVerifierMetaData.Bin -func DeployMercuryExposedVerifier(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *MercuryExposedVerifier, error) { - parsed, err := MercuryExposedVerifierMetaData.GetAbi() +func DeployExposedVerifier(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ExposedVerifier, error) { + parsed, err := ExposedVerifierMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -46,132 +46,132 @@ func DeployMercuryExposedVerifier(auth *bind.TransactOpts, backend bind.Contract return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MercuryExposedVerifierBin), backend) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ExposedVerifierBin), backend) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &MercuryExposedVerifier{MercuryExposedVerifierCaller: MercuryExposedVerifierCaller{contract: contract}, MercuryExposedVerifierTransactor: MercuryExposedVerifierTransactor{contract: contract}, MercuryExposedVerifierFilterer: MercuryExposedVerifierFilterer{contract: contract}}, nil + return address, tx, &ExposedVerifier{ExposedVerifierCaller: ExposedVerifierCaller{contract: contract}, ExposedVerifierTransactor: ExposedVerifierTransactor{contract: contract}, ExposedVerifierFilterer: ExposedVerifierFilterer{contract: contract}}, nil } -type MercuryExposedVerifier struct { +type ExposedVerifier struct { address common.Address abi abi.ABI - MercuryExposedVerifierCaller - MercuryExposedVerifierTransactor - MercuryExposedVerifierFilterer + ExposedVerifierCaller + ExposedVerifierTransactor + ExposedVerifierFilterer } -type MercuryExposedVerifierCaller struct { +type ExposedVerifierCaller struct { contract *bind.BoundContract } -type MercuryExposedVerifierTransactor struct { +type ExposedVerifierTransactor struct { contract *bind.BoundContract } -type MercuryExposedVerifierFilterer struct { +type ExposedVerifierFilterer struct { contract *bind.BoundContract } -type MercuryExposedVerifierSession struct { - Contract *MercuryExposedVerifier +type ExposedVerifierSession struct { + Contract *ExposedVerifier CallOpts bind.CallOpts TransactOpts bind.TransactOpts } -type MercuryExposedVerifierCallerSession struct { - Contract *MercuryExposedVerifierCaller +type ExposedVerifierCallerSession struct { + Contract *ExposedVerifierCaller CallOpts bind.CallOpts } -type MercuryExposedVerifierTransactorSession struct { - Contract *MercuryExposedVerifierTransactor +type ExposedVerifierTransactorSession struct { + Contract *ExposedVerifierTransactor TransactOpts bind.TransactOpts } -type MercuryExposedVerifierRaw struct { - Contract *MercuryExposedVerifier +type ExposedVerifierRaw struct { + Contract *ExposedVerifier } -type MercuryExposedVerifierCallerRaw struct { - Contract *MercuryExposedVerifierCaller +type ExposedVerifierCallerRaw struct { + Contract *ExposedVerifierCaller } -type MercuryExposedVerifierTransactorRaw struct { - Contract *MercuryExposedVerifierTransactor +type ExposedVerifierTransactorRaw struct { + Contract *ExposedVerifierTransactor } -func NewMercuryExposedVerifier(address common.Address, backend bind.ContractBackend) (*MercuryExposedVerifier, error) { - abi, err := abi.JSON(strings.NewReader(MercuryExposedVerifierABI)) +func NewExposedVerifier(address common.Address, backend bind.ContractBackend) (*ExposedVerifier, error) { + abi, err := abi.JSON(strings.NewReader(ExposedVerifierABI)) if err != nil { return nil, err } - contract, err := bindMercuryExposedVerifier(address, backend, backend, backend) + contract, err := bindExposedVerifier(address, backend, backend, backend) if err != nil { return nil, err } - return &MercuryExposedVerifier{address: address, abi: abi, MercuryExposedVerifierCaller: MercuryExposedVerifierCaller{contract: contract}, MercuryExposedVerifierTransactor: MercuryExposedVerifierTransactor{contract: contract}, MercuryExposedVerifierFilterer: MercuryExposedVerifierFilterer{contract: contract}}, nil + return &ExposedVerifier{address: address, abi: abi, ExposedVerifierCaller: ExposedVerifierCaller{contract: contract}, ExposedVerifierTransactor: ExposedVerifierTransactor{contract: contract}, ExposedVerifierFilterer: ExposedVerifierFilterer{contract: contract}}, nil } -func NewMercuryExposedVerifierCaller(address common.Address, caller bind.ContractCaller) (*MercuryExposedVerifierCaller, error) { - contract, err := bindMercuryExposedVerifier(address, caller, nil, nil) +func NewExposedVerifierCaller(address common.Address, caller bind.ContractCaller) (*ExposedVerifierCaller, error) { + contract, err := bindExposedVerifier(address, caller, nil, nil) if err != nil { return nil, err } - return &MercuryExposedVerifierCaller{contract: contract}, nil + return &ExposedVerifierCaller{contract: contract}, nil } -func NewMercuryExposedVerifierTransactor(address common.Address, transactor bind.ContractTransactor) (*MercuryExposedVerifierTransactor, error) { - contract, err := bindMercuryExposedVerifier(address, nil, transactor, nil) +func NewExposedVerifierTransactor(address common.Address, transactor bind.ContractTransactor) (*ExposedVerifierTransactor, error) { + contract, err := bindExposedVerifier(address, nil, transactor, nil) if err != nil { return nil, err } - return &MercuryExposedVerifierTransactor{contract: contract}, nil + return &ExposedVerifierTransactor{contract: contract}, nil } -func NewMercuryExposedVerifierFilterer(address common.Address, filterer bind.ContractFilterer) (*MercuryExposedVerifierFilterer, error) { - contract, err := bindMercuryExposedVerifier(address, nil, nil, filterer) +func NewExposedVerifierFilterer(address common.Address, filterer bind.ContractFilterer) (*ExposedVerifierFilterer, error) { + contract, err := bindExposedVerifier(address, nil, nil, filterer) if err != nil { return nil, err } - return &MercuryExposedVerifierFilterer{contract: contract}, nil + return &ExposedVerifierFilterer{contract: contract}, nil } -func bindMercuryExposedVerifier(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := MercuryExposedVerifierMetaData.GetAbi() +func bindExposedVerifier(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ExposedVerifierMetaData.GetAbi() if err != nil { return nil, err } return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } -func (_MercuryExposedVerifier *MercuryExposedVerifierRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _MercuryExposedVerifier.Contract.MercuryExposedVerifierCaller.contract.Call(opts, result, method, params...) +func (_ExposedVerifier *ExposedVerifierRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ExposedVerifier.Contract.ExposedVerifierCaller.contract.Call(opts, result, method, params...) } -func (_MercuryExposedVerifier *MercuryExposedVerifierRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _MercuryExposedVerifier.Contract.MercuryExposedVerifierTransactor.contract.Transfer(opts) +func (_ExposedVerifier *ExposedVerifierRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ExposedVerifier.Contract.ExposedVerifierTransactor.contract.Transfer(opts) } -func (_MercuryExposedVerifier *MercuryExposedVerifierRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _MercuryExposedVerifier.Contract.MercuryExposedVerifierTransactor.contract.Transact(opts, method, params...) +func (_ExposedVerifier *ExposedVerifierRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ExposedVerifier.Contract.ExposedVerifierTransactor.contract.Transact(opts, method, params...) } -func (_MercuryExposedVerifier *MercuryExposedVerifierCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _MercuryExposedVerifier.Contract.contract.Call(opts, result, method, params...) +func (_ExposedVerifier *ExposedVerifierCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ExposedVerifier.Contract.contract.Call(opts, result, method, params...) } -func (_MercuryExposedVerifier *MercuryExposedVerifierTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _MercuryExposedVerifier.Contract.contract.Transfer(opts) +func (_ExposedVerifier *ExposedVerifierTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ExposedVerifier.Contract.contract.Transfer(opts) } -func (_MercuryExposedVerifier *MercuryExposedVerifierTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _MercuryExposedVerifier.Contract.contract.Transact(opts, method, params...) +func (_ExposedVerifier *ExposedVerifierTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ExposedVerifier.Contract.contract.Transact(opts, method, params...) } -func (_MercuryExposedVerifier *MercuryExposedVerifierCaller) ExposedConfigDigestFromConfigData(opts *bind.CallOpts, _feedId [32]byte, _chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) { +func (_ExposedVerifier *ExposedVerifierCaller) ExposedConfigDigestFromConfigData(opts *bind.CallOpts, _feedId [32]byte, _chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) { var out []interface{} - err := _MercuryExposedVerifier.contract.Call(opts, &out, "exposedConfigDigestFromConfigData", _feedId, _chainId, _contractAddress, _configCount, _signers, _offchainTransmitters, _f, _onchainConfig, _encodedConfigVersion, _encodedConfig) + err := _ExposedVerifier.contract.Call(opts, &out, "exposedConfigDigestFromConfigData", _feedId, _chainId, _contractAddress, _configCount, _signers, _offchainTransmitters, _f, _onchainConfig, _encodedConfigVersion, _encodedConfig) if err != nil { return *new([32]byte), err @@ -183,19 +183,19 @@ func (_MercuryExposedVerifier *MercuryExposedVerifierCaller) ExposedConfigDigest } -func (_MercuryExposedVerifier *MercuryExposedVerifierSession) ExposedConfigDigestFromConfigData(_feedId [32]byte, _chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) { - return _MercuryExposedVerifier.Contract.ExposedConfigDigestFromConfigData(&_MercuryExposedVerifier.CallOpts, _feedId, _chainId, _contractAddress, _configCount, _signers, _offchainTransmitters, _f, _onchainConfig, _encodedConfigVersion, _encodedConfig) +func (_ExposedVerifier *ExposedVerifierSession) ExposedConfigDigestFromConfigData(_feedId [32]byte, _chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) { + return _ExposedVerifier.Contract.ExposedConfigDigestFromConfigData(&_ExposedVerifier.CallOpts, _feedId, _chainId, _contractAddress, _configCount, _signers, _offchainTransmitters, _f, _onchainConfig, _encodedConfigVersion, _encodedConfig) } -func (_MercuryExposedVerifier *MercuryExposedVerifierCallerSession) ExposedConfigDigestFromConfigData(_feedId [32]byte, _chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) { - return _MercuryExposedVerifier.Contract.ExposedConfigDigestFromConfigData(&_MercuryExposedVerifier.CallOpts, _feedId, _chainId, _contractAddress, _configCount, _signers, _offchainTransmitters, _f, _onchainConfig, _encodedConfigVersion, _encodedConfig) +func (_ExposedVerifier *ExposedVerifierCallerSession) ExposedConfigDigestFromConfigData(_feedId [32]byte, _chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) { + return _ExposedVerifier.Contract.ExposedConfigDigestFromConfigData(&_ExposedVerifier.CallOpts, _feedId, _chainId, _contractAddress, _configCount, _signers, _offchainTransmitters, _f, _onchainConfig, _encodedConfigVersion, _encodedConfig) } -func (_MercuryExposedVerifier *MercuryExposedVerifier) Address() common.Address { - return _MercuryExposedVerifier.address +func (_ExposedVerifier *ExposedVerifier) Address() common.Address { + return _ExposedVerifier.address } -type MercuryExposedVerifierInterface interface { +type ExposedVerifierInterface interface { ExposedConfigDigestFromConfigData(opts *bind.CallOpts, _feedId [32]byte, _chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) Address() common.Address diff --git a/core/gethwrappers/llo-feeds/generated/fee_manager/fee_manager.go b/core/gethwrappers/llo-feeds/generated/fee_manager/fee_manager.go new file mode 100644 index 00000000000..31c0a0b1a06 --- /dev/null +++ b/core/gethwrappers/llo-feeds/generated/fee_manager/fee_manager.go @@ -0,0 +1,1496 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package fee_manager + +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 CommonAddressAndWeight struct { + Addr common.Address + Weight *big.Int +} + +type CommonAsset struct { + AssetAddress common.Address + Amount *big.Int +} + +type IFeeManagerQuote struct { + QuoteAddress common.Address +} + +var FeeManagerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_linkAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_nativeAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_proxyAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_rewardManagerAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ExpiredReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDeposit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDiscount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidQuote\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSurcharge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroDeficit\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"linkQuantity\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nativeQuantity\",\"type\":\"uint256\"}],\"name\":\"InsufficientLink\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"linkQuantity\",\"type\":\"uint256\"}],\"name\":\"LinkDeficitCleared\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSurcharge\",\"type\":\"uint256\"}],\"name\":\"NativeSurchargeUpdated\",\"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\":\"subscriber\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"discount\",\"type\":\"uint256\"}],\"name\":\"SubscriberDiscountUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"name\":\"Withdraw\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"quoteAddress\",\"type\":\"address\"}],\"internalType\":\"structIFeeManager.Quote\",\"name\":\"quote\",\"type\":\"tuple\"}],\"name\":\"getFeeAndReward\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"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\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"payLinkDeficit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"}],\"name\":\"processFee\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_linkDeficit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_nativeSurcharge\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_subscriberDiscounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"rewardRecipientAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setFeeRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"surcharge\",\"type\":\"uint256\"}],\"name\":\"setNativeSurcharge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"discount\",\"type\":\"uint256\"}],\"name\":\"updateSubscriberDiscount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b506040516200296d3803806200296d833981016040819052620000359162000288565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001c0565b5050506001600160a01b0384161580620000e057506001600160a01b038316155b80620000f357506001600160a01b038216155b806200010657506001600160a01b038116155b15620001255760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b03848116608081905284821660a05283821660c05290821660e081905260405163095ea7b360e01b81526004810191909152600019602482015263095ea7b3906044016020604051808303816000875af11580156200018f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001b59190620002e5565b505050505062000310565b336001600160a01b038216036200021a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146200028357600080fd5b919050565b600080600080608085870312156200029f57600080fd5b620002aa856200026b565b9350620002ba602086016200026b565b9250620002ca604086016200026b565b9150620002da606086016200026b565b905092959194509250565b600060208284031215620002f857600080fd5b815180151581146200030957600080fd5b9392505050565b60805160a05160c05160e0516125ba620003b36000396000818161047e01528181610bc00152818161101d01526112230152600081816103e70152610caa015260008181610716015281816107690152818161095d01528181610e1501528181610edc015261138f01526000818161073b015281816107c4015281816108e801528181610a9d01528181610f9c015281816110e3015261133801526125ba6000f3fe6080604052600436106100f35760003560e01c80638da5cb5b1161008a578063f1387e1611610059578063f1387e1614610339578063f237f1a81461034c578063f2fde38b1461036c578063f3fef3a31461038c57600080fd5b80638da5cb5b146102a1578063c541cbde146102d6578063d09dc33914610304578063e389d9a41461031957600080fd5b806369fd2b34116100c657806369fd2b341461020c5780636b54d8a61461022e57806379ba50971461024e57806387d6d8431461026357600080fd5b8063013f542b146100f857806301ffc9a714610138578063181f5a77146101aa57806332f5f746146101f6575b600080fd5b34801561010457600080fd5b50610125610113366004611bb8565b60036020526000908152604090205481565b6040519081526020015b60405180910390f35b34801561014457600080fd5b5061019a610153366004611bd1565b7fffffffff00000000000000000000000000000000000000000000000000000000167ff1387e16000000000000000000000000000000000000000000000000000000001490565b604051901515815260200161012f565b3480156101b657600080fd5b50604080518082018252601081527f4665654d616e6167657220302e302e31000000000000000000000000000000006020820152905161012f9190611c37565b34801561020257600080fd5b5061012560045481565b34801561021857600080fd5b5061022c610227366004611c88565b6103ac565b005b34801561023a57600080fd5b5061022c610249366004611bb8565b6104ee565b34801561025a57600080fd5b5061022c610573565b34801561026f57600080fd5b5061012561027e366004611d29565b600260209081526000938452604080852082529284528284209052825290205481565b3480156102ad57600080fd5b5060005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161012f565b3480156102e257600080fd5b506102f66102f1366004611ea0565b610675565b60405161012f929190611f41565b34801561031057600080fd5b50610125610a6c565b34801561032557600080fd5b5061022c610334366004611bb8565b610b22565b61022c610347366004611f95565b610c6f565b34801561035857600080fd5b5061022c61036736600461200d565b6112ec565b34801561037857600080fd5b5061022c610387366004612055565b611493565b34801561039857600080fd5b5061022c6103a7366004612072565b6114a7565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061040a57503373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614155b15610441576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f633b5f6e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063633b5f6e906104b79086908690869060040161209e565b600060405180830381600087803b1580156104d157600080fd5b505af11580156104e5573d6000803e3d6000fd5b50505050505050565b6104f66115af565b670de0b6b3a7640000811115610538576040517f05e8ac2900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60048190556040518181527fa320ddc8288125050af9b9b75fd872443f8c722e70b14fc8475dbd630a4916e19060200160405180910390a150565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b604080518082019091526000808252602082015260408051808201909152600080825260208201526040805180820190915260008082526020820152604080518082019091526000808252602082015260006106d08761210d565b90507fffff00000000000000000000000000000000000000000000000000000000000080821690810161076757505073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811683527f00000000000000000000000000000000000000000000000000000000000000001681529092509050610a64565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16876000015173ffffffffffffffffffffffffffffffffffffffff161415801561081757507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16876000015173ffffffffffffffffffffffffffffffffffffffff1614155b1561084e576040517ff861803000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008a8060200190518101906108679190612193565b77ffffffffffffffffffffffffffffffffffffffffffffffff92831699509116965063ffffffff16945050504283101591506108d19050576040517fb6c405f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116808852602088018590528b519091160361094657855173ffffffffffffffffffffffffffffffffffffffff168752602080870151908801526109b6565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001687526004546109b09061099890670de0b6b3a7640000612249565b6109a2908461225c565b670de0b6b3a7640000611632565b60208801525b73ffffffffffffffffffffffffffffffffffffffff808d16600090815260026020908152604080832089845282528083208e5190941683529281529190205490880151670de0b6b3a764000090610a0e90839061225c565b610a189190612299565b8860200151610a2791906122d4565b886020018181525050610a438188602001516109a2919061225c565b8760200151610a5291906122d4565b60208801525095975093955050505050505b935093915050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610af9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1d91906122e7565b905090565b610b2a6115af565b60008181526003602052604081205490819003610b73576040517f03aad31200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526003602052604080822091909155517fefb03fe900000000000000000000000000000000000000000000000000000000815260048101839052306024820152604481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063efb03fe990606401600060405180830381600087803b158015610c1957600080fd5b505af1158015610c2d573d6000803e3d6000fd5b50505050817f843f0b103e50b42b08f9d30f12f961845a6d02623730872e24644899c0dd989582604051610c6391815260200190565b60405180910390a25050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610ccd57503373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614155b15610d04576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff821603610d53576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d618385018561236e565b915050600081610d709061210d565b6040805160208101909152600081529091507e010000000000000000000000000000000000000000000000000000000000007fffff000000000000000000000000000000000000000000000000000000000000831614610df7576000610dd88688018861243d565b9550505050505080806020019051810190610df39190612505565b9150505b600080610e05338685610675565b91509150600034600014610f69577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614610e9c576040517fb2e532de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3483602001511115610eda576040517fb2e532de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db084602001516040518263ffffffff1660e01b81526004016000604051808303818588803b158015610f4657600080fd5b505af1158015610f5a573d6000803e3d6000fd5b50505050508260200151340390505b6000610f75898b612533565b9050836020015160001461129557835173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081169116036110805760208301516040517fefb03fe90000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff8a8116602483015260448201929092527f00000000000000000000000000000000000000000000000000000000000000009091169063efb03fe990606401600060405180830381600087803b15801561106357600080fd5b505af1158015611077573d6000803e3d6000fd5b50505050611295565b346000036110b557602084015184516110b59173ffffffffffffffffffffffffffffffffffffffff909116908a90309061166c565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561113f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116391906122e7565b836020015111156111e15782602001516003600083815260200190815260200160002060008282546111959190612249565b909155505060208381015185820151604080519283529282015282917feb6f22018570d97db6df12dc94f202b4e2b2888a6a5d4bd179422c91b29dcdf7910160405180910390a2611295565b60208301516040517fefb03fe90000000000000000000000000000000000000000000000000000000081526004810183905230602482015260448101919091527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063efb03fe990606401600060405180830381600087803b15801561127c57600080fd5b505af1158015611290573d6000803e3d6000fd5b505050505b81156112e05760405173ffffffffffffffffffffffffffffffffffffffff89169083156108fc029084906000818181858888f193505050501580156112de573d6000803e3d6000fd5b505b50505050505050505050565b6112f46115af565b670de0b6b3a7640000811115611336576040517f997ea36000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156113de57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15611415576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84811660008181526002602090815260408083208884528252808320948716808452948252918290208590558151938452830184905285927f41eb9ccd292d5906dc1f0ec108bed3e2b966e3071e033df938f7215f6d30ca84910160405180910390a350505050565b61149b6115af565b6114a48161174e565b50565b6114af6115af565b73ffffffffffffffffffffffffffffffffffffffff8216611515576000805460405173ffffffffffffffffffffffffffffffffffffffff9091169183156108fc02918491818181858888f19350505050158015611510573d6000803e3d6000fd5b505050565b61155561153760005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff84169083611843565b6040805133815273ffffffffffffffffffffffffffffffffffffffff841660208201529081018290527f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb9060600160405180910390a15050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611630576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016105f0565b565b6000821561166057816116466001856122d4565b6116509190612299565b61165b906001612249565b611663565b60005b90505b92915050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526117489085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611899565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036117cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016105f0565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526115109084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064016116c6565b60006118fb826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119a59092919063ffffffff16565b8051909150156115105780806020019051810190611919919061256f565b611510576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016105f0565b60606119b484846000856119be565b90505b9392505050565b606082471015611a50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016105f0565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611a799190612591565b60006040518083038185875af1925050503d8060008114611ab6576040519150601f19603f3d011682016040523d82523d6000602084013e611abb565b606091505b5091509150611acc87838387611ad9565b925050505b949350505050565b60608315611b6f578251600003611b685773ffffffffffffffffffffffffffffffffffffffff85163b611b68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105f0565b5081611ad1565b611ad18383815115611b845781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105f09190611c37565b600060208284031215611bca57600080fd5b5035919050565b600060208284031215611be357600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146119b757600080fd5b60005b83811015611c2e578181015183820152602001611c16565b50506000910152565b6020815260008251806020840152611c56816040850160208701611c13565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600080600060408486031215611c9d57600080fd5b83359250602084013567ffffffffffffffff80821115611cbc57600080fd5b818601915086601f830112611cd057600080fd5b813581811115611cdf57600080fd5b8760208260061b8501011115611cf457600080fd5b6020830194508093505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff811681146114a457600080fd5b600080600060608486031215611d3e57600080fd5b8335611d4981611d07565b9250602084013591506040840135611d6081611d07565b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516020810167ffffffffffffffff81118282101715611dbd57611dbd611d6b565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611e0a57611e0a611d6b565b604052919050565b600082601f830112611e2357600080fd5b813567ffffffffffffffff811115611e3d57611e3d611d6b565b611e6e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611dc3565b818152846020838601011115611e8357600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008385036060811215611eb657600080fd5b8435611ec181611d07565b9350602085013567ffffffffffffffff811115611edd57600080fd5b611ee987828801611e12565b93505060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc082011215611f1c57600080fd5b50611f25611d9a565b6040850135611f3381611d07565b815292959194509192509050565b825173ffffffffffffffffffffffffffffffffffffffff1681526020808401519082015260808101825173ffffffffffffffffffffffffffffffffffffffff166040830152602083015160608301526119b7565b600080600060408486031215611faa57600080fd5b833567ffffffffffffffff80821115611fc257600080fd5b818601915086601f830112611fd657600080fd5b813581811115611fe557600080fd5b876020828501011115611ff757600080fd5b60209283019550935050840135611d6081611d07565b6000806000806080858703121561202357600080fd5b843561202e81611d07565b935060208501359250604085013561204581611d07565b9396929550929360600135925050565b60006020828403121561206757600080fd5b81356119b781611d07565b6000806040838503121561208557600080fd5b823561209081611d07565b946020939093013593505050565b8381526040602080830182905282820184905260009190859060608501845b878110156121005783356120d081611d07565b73ffffffffffffffffffffffffffffffffffffffff168252838301358383015292840192908401906001016120bd565b5098975050505050505050565b8051602080830151919081101561214c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b805163ffffffff8116811461216657600080fd5b919050565b805177ffffffffffffffffffffffffffffffffffffffffffffffff8116811461216657600080fd5b600080600080600080600060e0888a0312156121ae57600080fd5b875196506121be60208901612152565b95506121cc60408901612152565b945060608801518060170b81146121e257600080fd5b93506121f06080890161216b565b92506121fe60a0890161216b565b915061220c60c08901612152565b905092959891949750929550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156116665761166661221a565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156122945761229461221a565b500290565b6000826122cf577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b818103818111156116665761166661221a565b6000602082840312156122f957600080fd5b5051919050565b600082601f83011261231157600080fd5b6040516060810181811067ffffffffffffffff8211171561233457612334611d6b565b60405280606084018581111561234957600080fd5b845b8181101561236357803583526020928301920161234b565b509195945050505050565b6000806080838503121561238157600080fd5b61238b8484612300565b9150606083013567ffffffffffffffff8111156123a757600080fd5b6123b385828601611e12565b9150509250929050565b600082601f8301126123ce57600080fd5b8135602067ffffffffffffffff8211156123ea576123ea611d6b565b8160051b6123f9828201611dc3565b928352848101820192828101908785111561241357600080fd5b83870192505b8483101561243257823582529183019190830190612419565b979650505050505050565b600080600080600080610100878903121561245757600080fd5b6124618888612300565b9550606087013567ffffffffffffffff8082111561247e57600080fd5b61248a8a838b01611e12565b965060808901359150808211156124a057600080fd5b6124ac8a838b016123bd565b955060a08901359150808211156124c257600080fd5b6124ce8a838b016123bd565b945060c0890135935060e08901359150808211156124eb57600080fd5b506124f889828a01611e12565b9150509295509295509295565b60006020828403121561251757600080fd5b61251f611d9a565b825161252a81611d07565b81529392505050565b80356020831015611666577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b60006020828403121561258157600080fd5b815180151581146119b757600080fd5b600082516125a3818460208701611c13565b919091019291505056fea164736f6c6343000810000a", +} + +var FeeManagerABI = FeeManagerMetaData.ABI + +var FeeManagerBin = FeeManagerMetaData.Bin + +func DeployFeeManager(auth *bind.TransactOpts, backend bind.ContractBackend, _linkAddress common.Address, _nativeAddress common.Address, _proxyAddress common.Address, _rewardManagerAddress common.Address) (common.Address, *types.Transaction, *FeeManager, error) { + parsed, err := FeeManagerMetaData.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(FeeManagerBin), backend, _linkAddress, _nativeAddress, _proxyAddress, _rewardManagerAddress) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &FeeManager{FeeManagerCaller: FeeManagerCaller{contract: contract}, FeeManagerTransactor: FeeManagerTransactor{contract: contract}, FeeManagerFilterer: FeeManagerFilterer{contract: contract}}, nil +} + +type FeeManager struct { + address common.Address + abi abi.ABI + FeeManagerCaller + FeeManagerTransactor + FeeManagerFilterer +} + +type FeeManagerCaller struct { + contract *bind.BoundContract +} + +type FeeManagerTransactor struct { + contract *bind.BoundContract +} + +type FeeManagerFilterer struct { + contract *bind.BoundContract +} + +type FeeManagerSession struct { + Contract *FeeManager + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type FeeManagerCallerSession struct { + Contract *FeeManagerCaller + CallOpts bind.CallOpts +} + +type FeeManagerTransactorSession struct { + Contract *FeeManagerTransactor + TransactOpts bind.TransactOpts +} + +type FeeManagerRaw struct { + Contract *FeeManager +} + +type FeeManagerCallerRaw struct { + Contract *FeeManagerCaller +} + +type FeeManagerTransactorRaw struct { + Contract *FeeManagerTransactor +} + +func NewFeeManager(address common.Address, backend bind.ContractBackend) (*FeeManager, error) { + abi, err := abi.JSON(strings.NewReader(FeeManagerABI)) + if err != nil { + return nil, err + } + contract, err := bindFeeManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &FeeManager{address: address, abi: abi, FeeManagerCaller: FeeManagerCaller{contract: contract}, FeeManagerTransactor: FeeManagerTransactor{contract: contract}, FeeManagerFilterer: FeeManagerFilterer{contract: contract}}, nil +} + +func NewFeeManagerCaller(address common.Address, caller bind.ContractCaller) (*FeeManagerCaller, error) { + contract, err := bindFeeManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &FeeManagerCaller{contract: contract}, nil +} + +func NewFeeManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*FeeManagerTransactor, error) { + contract, err := bindFeeManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &FeeManagerTransactor{contract: contract}, nil +} + +func NewFeeManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*FeeManagerFilterer, error) { + contract, err := bindFeeManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &FeeManagerFilterer{contract: contract}, nil +} + +func bindFeeManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := FeeManagerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_FeeManager *FeeManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _FeeManager.Contract.FeeManagerCaller.contract.Call(opts, result, method, params...) +} + +func (_FeeManager *FeeManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _FeeManager.Contract.FeeManagerTransactor.contract.Transfer(opts) +} + +func (_FeeManager *FeeManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _FeeManager.Contract.FeeManagerTransactor.contract.Transact(opts, method, params...) +} + +func (_FeeManager *FeeManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _FeeManager.Contract.contract.Call(opts, result, method, params...) +} + +func (_FeeManager *FeeManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _FeeManager.Contract.contract.Transfer(opts) +} + +func (_FeeManager *FeeManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _FeeManager.Contract.contract.Transact(opts, method, params...) +} + +func (_FeeManager *FeeManagerCaller) GetFeeAndReward(opts *bind.CallOpts, subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, error) { + var out []interface{} + err := _FeeManager.contract.Call(opts, &out, "getFeeAndReward", subscriber, report, quote) + + if err != nil { + return *new(CommonAsset), *new(CommonAsset), err + } + + out0 := *abi.ConvertType(out[0], new(CommonAsset)).(*CommonAsset) + out1 := *abi.ConvertType(out[1], new(CommonAsset)).(*CommonAsset) + + return out0, out1, err + +} + +func (_FeeManager *FeeManagerSession) GetFeeAndReward(subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, error) { + return _FeeManager.Contract.GetFeeAndReward(&_FeeManager.CallOpts, subscriber, report, quote) +} + +func (_FeeManager *FeeManagerCallerSession) GetFeeAndReward(subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, error) { + return _FeeManager.Contract.GetFeeAndReward(&_FeeManager.CallOpts, subscriber, report, quote) +} + +func (_FeeManager *FeeManagerCaller) LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _FeeManager.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 (_FeeManager *FeeManagerSession) LinkAvailableForPayment() (*big.Int, error) { + return _FeeManager.Contract.LinkAvailableForPayment(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCallerSession) LinkAvailableForPayment() (*big.Int, error) { + return _FeeManager.Contract.LinkAvailableForPayment(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _FeeManager.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 (_FeeManager *FeeManagerSession) Owner() (common.Address, error) { + return _FeeManager.Contract.Owner(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCallerSession) Owner() (common.Address, error) { + return _FeeManager.Contract.Owner(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCaller) SLinkDeficit(opts *bind.CallOpts, arg0 [32]byte) (*big.Int, error) { + var out []interface{} + err := _FeeManager.contract.Call(opts, &out, "s_linkDeficit", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_FeeManager *FeeManagerSession) SLinkDeficit(arg0 [32]byte) (*big.Int, error) { + return _FeeManager.Contract.SLinkDeficit(&_FeeManager.CallOpts, arg0) +} + +func (_FeeManager *FeeManagerCallerSession) SLinkDeficit(arg0 [32]byte) (*big.Int, error) { + return _FeeManager.Contract.SLinkDeficit(&_FeeManager.CallOpts, arg0) +} + +func (_FeeManager *FeeManagerCaller) SNativeSurcharge(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _FeeManager.contract.Call(opts, &out, "s_nativeSurcharge") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_FeeManager *FeeManagerSession) SNativeSurcharge() (*big.Int, error) { + return _FeeManager.Contract.SNativeSurcharge(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCallerSession) SNativeSurcharge() (*big.Int, error) { + return _FeeManager.Contract.SNativeSurcharge(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCaller) SSubscriberDiscounts(opts *bind.CallOpts, arg0 common.Address, arg1 [32]byte, arg2 common.Address) (*big.Int, error) { + var out []interface{} + err := _FeeManager.contract.Call(opts, &out, "s_subscriberDiscounts", arg0, arg1, arg2) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_FeeManager *FeeManagerSession) SSubscriberDiscounts(arg0 common.Address, arg1 [32]byte, arg2 common.Address) (*big.Int, error) { + return _FeeManager.Contract.SSubscriberDiscounts(&_FeeManager.CallOpts, arg0, arg1, arg2) +} + +func (_FeeManager *FeeManagerCallerSession) SSubscriberDiscounts(arg0 common.Address, arg1 [32]byte, arg2 common.Address) (*big.Int, error) { + return _FeeManager.Contract.SSubscriberDiscounts(&_FeeManager.CallOpts, arg0, arg1, arg2) +} + +func (_FeeManager *FeeManagerCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _FeeManager.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_FeeManager *FeeManagerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _FeeManager.Contract.SupportsInterface(&_FeeManager.CallOpts, interfaceId) +} + +func (_FeeManager *FeeManagerCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _FeeManager.Contract.SupportsInterface(&_FeeManager.CallOpts, interfaceId) +} + +func (_FeeManager *FeeManagerCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _FeeManager.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_FeeManager *FeeManagerSession) TypeAndVersion() (string, error) { + return _FeeManager.Contract.TypeAndVersion(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCallerSession) TypeAndVersion() (string, error) { + return _FeeManager.Contract.TypeAndVersion(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _FeeManager.contract.Transact(opts, "acceptOwnership") +} + +func (_FeeManager *FeeManagerSession) AcceptOwnership() (*types.Transaction, error) { + return _FeeManager.Contract.AcceptOwnership(&_FeeManager.TransactOpts) +} + +func (_FeeManager *FeeManagerTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _FeeManager.Contract.AcceptOwnership(&_FeeManager.TransactOpts) +} + +func (_FeeManager *FeeManagerTransactor) PayLinkDeficit(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) { + return _FeeManager.contract.Transact(opts, "payLinkDeficit", configDigest) +} + +func (_FeeManager *FeeManagerSession) PayLinkDeficit(configDigest [32]byte) (*types.Transaction, error) { + return _FeeManager.Contract.PayLinkDeficit(&_FeeManager.TransactOpts, configDigest) +} + +func (_FeeManager *FeeManagerTransactorSession) PayLinkDeficit(configDigest [32]byte) (*types.Transaction, error) { + return _FeeManager.Contract.PayLinkDeficit(&_FeeManager.TransactOpts, configDigest) +} + +func (_FeeManager *FeeManagerTransactor) ProcessFee(opts *bind.TransactOpts, payload []byte, subscriber common.Address) (*types.Transaction, error) { + return _FeeManager.contract.Transact(opts, "processFee", payload, subscriber) +} + +func (_FeeManager *FeeManagerSession) ProcessFee(payload []byte, subscriber common.Address) (*types.Transaction, error) { + return _FeeManager.Contract.ProcessFee(&_FeeManager.TransactOpts, payload, subscriber) +} + +func (_FeeManager *FeeManagerTransactorSession) ProcessFee(payload []byte, subscriber common.Address) (*types.Transaction, error) { + return _FeeManager.Contract.ProcessFee(&_FeeManager.TransactOpts, payload, subscriber) +} + +func (_FeeManager *FeeManagerTransactor) SetFeeRecipients(opts *bind.TransactOpts, configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _FeeManager.contract.Transact(opts, "setFeeRecipients", configDigest, rewardRecipientAndWeights) +} + +func (_FeeManager *FeeManagerSession) SetFeeRecipients(configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _FeeManager.Contract.SetFeeRecipients(&_FeeManager.TransactOpts, configDigest, rewardRecipientAndWeights) +} + +func (_FeeManager *FeeManagerTransactorSession) SetFeeRecipients(configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _FeeManager.Contract.SetFeeRecipients(&_FeeManager.TransactOpts, configDigest, rewardRecipientAndWeights) +} + +func (_FeeManager *FeeManagerTransactor) SetNativeSurcharge(opts *bind.TransactOpts, surcharge *big.Int) (*types.Transaction, error) { + return _FeeManager.contract.Transact(opts, "setNativeSurcharge", surcharge) +} + +func (_FeeManager *FeeManagerSession) SetNativeSurcharge(surcharge *big.Int) (*types.Transaction, error) { + return _FeeManager.Contract.SetNativeSurcharge(&_FeeManager.TransactOpts, surcharge) +} + +func (_FeeManager *FeeManagerTransactorSession) SetNativeSurcharge(surcharge *big.Int) (*types.Transaction, error) { + return _FeeManager.Contract.SetNativeSurcharge(&_FeeManager.TransactOpts, surcharge) +} + +func (_FeeManager *FeeManagerTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _FeeManager.contract.Transact(opts, "transferOwnership", to) +} + +func (_FeeManager *FeeManagerSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _FeeManager.Contract.TransferOwnership(&_FeeManager.TransactOpts, to) +} + +func (_FeeManager *FeeManagerTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _FeeManager.Contract.TransferOwnership(&_FeeManager.TransactOpts, to) +} + +func (_FeeManager *FeeManagerTransactor) UpdateSubscriberDiscount(opts *bind.TransactOpts, subscriber common.Address, feedId [32]byte, token common.Address, discount *big.Int) (*types.Transaction, error) { + return _FeeManager.contract.Transact(opts, "updateSubscriberDiscount", subscriber, feedId, token, discount) +} + +func (_FeeManager *FeeManagerSession) UpdateSubscriberDiscount(subscriber common.Address, feedId [32]byte, token common.Address, discount *big.Int) (*types.Transaction, error) { + return _FeeManager.Contract.UpdateSubscriberDiscount(&_FeeManager.TransactOpts, subscriber, feedId, token, discount) +} + +func (_FeeManager *FeeManagerTransactorSession) UpdateSubscriberDiscount(subscriber common.Address, feedId [32]byte, token common.Address, discount *big.Int) (*types.Transaction, error) { + return _FeeManager.Contract.UpdateSubscriberDiscount(&_FeeManager.TransactOpts, subscriber, feedId, token, discount) +} + +func (_FeeManager *FeeManagerTransactor) Withdraw(opts *bind.TransactOpts, assetAddress common.Address, quantity *big.Int) (*types.Transaction, error) { + return _FeeManager.contract.Transact(opts, "withdraw", assetAddress, quantity) +} + +func (_FeeManager *FeeManagerSession) Withdraw(assetAddress common.Address, quantity *big.Int) (*types.Transaction, error) { + return _FeeManager.Contract.Withdraw(&_FeeManager.TransactOpts, assetAddress, quantity) +} + +func (_FeeManager *FeeManagerTransactorSession) Withdraw(assetAddress common.Address, quantity *big.Int) (*types.Transaction, error) { + return _FeeManager.Contract.Withdraw(&_FeeManager.TransactOpts, assetAddress, quantity) +} + +type FeeManagerInsufficientLinkIterator struct { + Event *FeeManagerInsufficientLink + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *FeeManagerInsufficientLinkIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(FeeManagerInsufficientLink) + 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(FeeManagerInsufficientLink) + 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 *FeeManagerInsufficientLinkIterator) Error() error { + return it.fail +} + +func (it *FeeManagerInsufficientLinkIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type FeeManagerInsufficientLink struct { + ConfigDigest [32]byte + LinkQuantity *big.Int + NativeQuantity *big.Int + Raw types.Log +} + +func (_FeeManager *FeeManagerFilterer) FilterInsufficientLink(opts *bind.FilterOpts, configDigest [][32]byte) (*FeeManagerInsufficientLinkIterator, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + + logs, sub, err := _FeeManager.contract.FilterLogs(opts, "InsufficientLink", configDigestRule) + if err != nil { + return nil, err + } + return &FeeManagerInsufficientLinkIterator{contract: _FeeManager.contract, event: "InsufficientLink", logs: logs, sub: sub}, nil +} + +func (_FeeManager *FeeManagerFilterer) WatchInsufficientLink(opts *bind.WatchOpts, sink chan<- *FeeManagerInsufficientLink, configDigest [][32]byte) (event.Subscription, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + + logs, sub, err := _FeeManager.contract.WatchLogs(opts, "InsufficientLink", configDigestRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(FeeManagerInsufficientLink) + if err := _FeeManager.contract.UnpackLog(event, "InsufficientLink", 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 (_FeeManager *FeeManagerFilterer) ParseInsufficientLink(log types.Log) (*FeeManagerInsufficientLink, error) { + event := new(FeeManagerInsufficientLink) + if err := _FeeManager.contract.UnpackLog(event, "InsufficientLink", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type FeeManagerLinkDeficitClearedIterator struct { + Event *FeeManagerLinkDeficitCleared + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *FeeManagerLinkDeficitClearedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(FeeManagerLinkDeficitCleared) + 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(FeeManagerLinkDeficitCleared) + 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 *FeeManagerLinkDeficitClearedIterator) Error() error { + return it.fail +} + +func (it *FeeManagerLinkDeficitClearedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type FeeManagerLinkDeficitCleared struct { + ConfigDigest [32]byte + LinkQuantity *big.Int + Raw types.Log +} + +func (_FeeManager *FeeManagerFilterer) FilterLinkDeficitCleared(opts *bind.FilterOpts, configDigest [][32]byte) (*FeeManagerLinkDeficitClearedIterator, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + + logs, sub, err := _FeeManager.contract.FilterLogs(opts, "LinkDeficitCleared", configDigestRule) + if err != nil { + return nil, err + } + return &FeeManagerLinkDeficitClearedIterator{contract: _FeeManager.contract, event: "LinkDeficitCleared", logs: logs, sub: sub}, nil +} + +func (_FeeManager *FeeManagerFilterer) WatchLinkDeficitCleared(opts *bind.WatchOpts, sink chan<- *FeeManagerLinkDeficitCleared, configDigest [][32]byte) (event.Subscription, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + + logs, sub, err := _FeeManager.contract.WatchLogs(opts, "LinkDeficitCleared", configDigestRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(FeeManagerLinkDeficitCleared) + if err := _FeeManager.contract.UnpackLog(event, "LinkDeficitCleared", 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 (_FeeManager *FeeManagerFilterer) ParseLinkDeficitCleared(log types.Log) (*FeeManagerLinkDeficitCleared, error) { + event := new(FeeManagerLinkDeficitCleared) + if err := _FeeManager.contract.UnpackLog(event, "LinkDeficitCleared", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type FeeManagerNativeSurchargeUpdatedIterator struct { + Event *FeeManagerNativeSurchargeUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *FeeManagerNativeSurchargeUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(FeeManagerNativeSurchargeUpdated) + 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(FeeManagerNativeSurchargeUpdated) + 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 *FeeManagerNativeSurchargeUpdatedIterator) Error() error { + return it.fail +} + +func (it *FeeManagerNativeSurchargeUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type FeeManagerNativeSurchargeUpdated struct { + NewSurcharge *big.Int + Raw types.Log +} + +func (_FeeManager *FeeManagerFilterer) FilterNativeSurchargeUpdated(opts *bind.FilterOpts) (*FeeManagerNativeSurchargeUpdatedIterator, error) { + + logs, sub, err := _FeeManager.contract.FilterLogs(opts, "NativeSurchargeUpdated") + if err != nil { + return nil, err + } + return &FeeManagerNativeSurchargeUpdatedIterator{contract: _FeeManager.contract, event: "NativeSurchargeUpdated", logs: logs, sub: sub}, nil +} + +func (_FeeManager *FeeManagerFilterer) WatchNativeSurchargeUpdated(opts *bind.WatchOpts, sink chan<- *FeeManagerNativeSurchargeUpdated) (event.Subscription, error) { + + logs, sub, err := _FeeManager.contract.WatchLogs(opts, "NativeSurchargeUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(FeeManagerNativeSurchargeUpdated) + if err := _FeeManager.contract.UnpackLog(event, "NativeSurchargeUpdated", 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 (_FeeManager *FeeManagerFilterer) ParseNativeSurchargeUpdated(log types.Log) (*FeeManagerNativeSurchargeUpdated, error) { + event := new(FeeManagerNativeSurchargeUpdated) + if err := _FeeManager.contract.UnpackLog(event, "NativeSurchargeUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type FeeManagerOwnershipTransferRequestedIterator struct { + Event *FeeManagerOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *FeeManagerOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(FeeManagerOwnershipTransferRequested) + 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(FeeManagerOwnershipTransferRequested) + 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 *FeeManagerOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *FeeManagerOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type FeeManagerOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_FeeManager *FeeManagerFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FeeManagerOwnershipTransferRequestedIterator, 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 := _FeeManager.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &FeeManagerOwnershipTransferRequestedIterator{contract: _FeeManager.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_FeeManager *FeeManagerFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FeeManagerOwnershipTransferRequested, 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 := _FeeManager.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(FeeManagerOwnershipTransferRequested) + if err := _FeeManager.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 (_FeeManager *FeeManagerFilterer) ParseOwnershipTransferRequested(log types.Log) (*FeeManagerOwnershipTransferRequested, error) { + event := new(FeeManagerOwnershipTransferRequested) + if err := _FeeManager.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type FeeManagerOwnershipTransferredIterator struct { + Event *FeeManagerOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *FeeManagerOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(FeeManagerOwnershipTransferred) + 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(FeeManagerOwnershipTransferred) + 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 *FeeManagerOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *FeeManagerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type FeeManagerOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_FeeManager *FeeManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FeeManagerOwnershipTransferredIterator, 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 := _FeeManager.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &FeeManagerOwnershipTransferredIterator{contract: _FeeManager.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_FeeManager *FeeManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *FeeManagerOwnershipTransferred, 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 := _FeeManager.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(FeeManagerOwnershipTransferred) + if err := _FeeManager.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 (_FeeManager *FeeManagerFilterer) ParseOwnershipTransferred(log types.Log) (*FeeManagerOwnershipTransferred, error) { + event := new(FeeManagerOwnershipTransferred) + if err := _FeeManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type FeeManagerSubscriberDiscountUpdatedIterator struct { + Event *FeeManagerSubscriberDiscountUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *FeeManagerSubscriberDiscountUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(FeeManagerSubscriberDiscountUpdated) + 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(FeeManagerSubscriberDiscountUpdated) + 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 *FeeManagerSubscriberDiscountUpdatedIterator) Error() error { + return it.fail +} + +func (it *FeeManagerSubscriberDiscountUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type FeeManagerSubscriberDiscountUpdated struct { + Subscriber common.Address + FeedId [32]byte + Token common.Address + Discount *big.Int + Raw types.Log +} + +func (_FeeManager *FeeManagerFilterer) FilterSubscriberDiscountUpdated(opts *bind.FilterOpts, subscriber []common.Address, feedId [][32]byte) (*FeeManagerSubscriberDiscountUpdatedIterator, error) { + + var subscriberRule []interface{} + for _, subscriberItem := range subscriber { + subscriberRule = append(subscriberRule, subscriberItem) + } + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _FeeManager.contract.FilterLogs(opts, "SubscriberDiscountUpdated", subscriberRule, feedIdRule) + if err != nil { + return nil, err + } + return &FeeManagerSubscriberDiscountUpdatedIterator{contract: _FeeManager.contract, event: "SubscriberDiscountUpdated", logs: logs, sub: sub}, nil +} + +func (_FeeManager *FeeManagerFilterer) WatchSubscriberDiscountUpdated(opts *bind.WatchOpts, sink chan<- *FeeManagerSubscriberDiscountUpdated, subscriber []common.Address, feedId [][32]byte) (event.Subscription, error) { + + var subscriberRule []interface{} + for _, subscriberItem := range subscriber { + subscriberRule = append(subscriberRule, subscriberItem) + } + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _FeeManager.contract.WatchLogs(opts, "SubscriberDiscountUpdated", subscriberRule, feedIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(FeeManagerSubscriberDiscountUpdated) + if err := _FeeManager.contract.UnpackLog(event, "SubscriberDiscountUpdated", 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 (_FeeManager *FeeManagerFilterer) ParseSubscriberDiscountUpdated(log types.Log) (*FeeManagerSubscriberDiscountUpdated, error) { + event := new(FeeManagerSubscriberDiscountUpdated) + if err := _FeeManager.contract.UnpackLog(event, "SubscriberDiscountUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type FeeManagerWithdrawIterator struct { + Event *FeeManagerWithdraw + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *FeeManagerWithdrawIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(FeeManagerWithdraw) + 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(FeeManagerWithdraw) + 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 *FeeManagerWithdrawIterator) Error() error { + return it.fail +} + +func (it *FeeManagerWithdrawIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type FeeManagerWithdraw struct { + AdminAddress common.Address + AssetAddress common.Address + Quantity *big.Int + Raw types.Log +} + +func (_FeeManager *FeeManagerFilterer) FilterWithdraw(opts *bind.FilterOpts) (*FeeManagerWithdrawIterator, error) { + + logs, sub, err := _FeeManager.contract.FilterLogs(opts, "Withdraw") + if err != nil { + return nil, err + } + return &FeeManagerWithdrawIterator{contract: _FeeManager.contract, event: "Withdraw", logs: logs, sub: sub}, nil +} + +func (_FeeManager *FeeManagerFilterer) WatchWithdraw(opts *bind.WatchOpts, sink chan<- *FeeManagerWithdraw) (event.Subscription, error) { + + logs, sub, err := _FeeManager.contract.WatchLogs(opts, "Withdraw") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(FeeManagerWithdraw) + if err := _FeeManager.contract.UnpackLog(event, "Withdraw", 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 (_FeeManager *FeeManagerFilterer) ParseWithdraw(log types.Log) (*FeeManagerWithdraw, error) { + event := new(FeeManagerWithdraw) + if err := _FeeManager.contract.UnpackLog(event, "Withdraw", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_FeeManager *FeeManager) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _FeeManager.abi.Events["InsufficientLink"].ID: + return _FeeManager.ParseInsufficientLink(log) + case _FeeManager.abi.Events["LinkDeficitCleared"].ID: + return _FeeManager.ParseLinkDeficitCleared(log) + case _FeeManager.abi.Events["NativeSurchargeUpdated"].ID: + return _FeeManager.ParseNativeSurchargeUpdated(log) + case _FeeManager.abi.Events["OwnershipTransferRequested"].ID: + return _FeeManager.ParseOwnershipTransferRequested(log) + case _FeeManager.abi.Events["OwnershipTransferred"].ID: + return _FeeManager.ParseOwnershipTransferred(log) + case _FeeManager.abi.Events["SubscriberDiscountUpdated"].ID: + return _FeeManager.ParseSubscriberDiscountUpdated(log) + case _FeeManager.abi.Events["Withdraw"].ID: + return _FeeManager.ParseWithdraw(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (FeeManagerInsufficientLink) Topic() common.Hash { + return common.HexToHash("0xeb6f22018570d97db6df12dc94f202b4e2b2888a6a5d4bd179422c91b29dcdf7") +} + +func (FeeManagerLinkDeficitCleared) Topic() common.Hash { + return common.HexToHash("0x843f0b103e50b42b08f9d30f12f961845a6d02623730872e24644899c0dd9895") +} + +func (FeeManagerNativeSurchargeUpdated) Topic() common.Hash { + return common.HexToHash("0xa320ddc8288125050af9b9b75fd872443f8c722e70b14fc8475dbd630a4916e1") +} + +func (FeeManagerOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (FeeManagerOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (FeeManagerSubscriberDiscountUpdated) Topic() common.Hash { + return common.HexToHash("0x41eb9ccd292d5906dc1f0ec108bed3e2b966e3071e033df938f7215f6d30ca84") +} + +func (FeeManagerWithdraw) Topic() common.Hash { + return common.HexToHash("0x9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb") +} + +func (_FeeManager *FeeManager) Address() common.Address { + return _FeeManager.address +} + +type FeeManagerInterface interface { + GetFeeAndReward(opts *bind.CallOpts, subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, error) + + LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SLinkDeficit(opts *bind.CallOpts, arg0 [32]byte) (*big.Int, error) + + SNativeSurcharge(opts *bind.CallOpts) (*big.Int, error) + + SSubscriberDiscounts(opts *bind.CallOpts, arg0 common.Address, arg1 [32]byte, arg2 common.Address) (*big.Int, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + PayLinkDeficit(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) + + ProcessFee(opts *bind.TransactOpts, payload []byte, subscriber common.Address) (*types.Transaction, error) + + SetFeeRecipients(opts *bind.TransactOpts, configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) + + SetNativeSurcharge(opts *bind.TransactOpts, surcharge *big.Int) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + UpdateSubscriberDiscount(opts *bind.TransactOpts, subscriber common.Address, feedId [32]byte, token common.Address, discount *big.Int) (*types.Transaction, error) + + Withdraw(opts *bind.TransactOpts, assetAddress common.Address, quantity *big.Int) (*types.Transaction, error) + + FilterInsufficientLink(opts *bind.FilterOpts, configDigest [][32]byte) (*FeeManagerInsufficientLinkIterator, error) + + WatchInsufficientLink(opts *bind.WatchOpts, sink chan<- *FeeManagerInsufficientLink, configDigest [][32]byte) (event.Subscription, error) + + ParseInsufficientLink(log types.Log) (*FeeManagerInsufficientLink, error) + + FilterLinkDeficitCleared(opts *bind.FilterOpts, configDigest [][32]byte) (*FeeManagerLinkDeficitClearedIterator, error) + + WatchLinkDeficitCleared(opts *bind.WatchOpts, sink chan<- *FeeManagerLinkDeficitCleared, configDigest [][32]byte) (event.Subscription, error) + + ParseLinkDeficitCleared(log types.Log) (*FeeManagerLinkDeficitCleared, error) + + FilterNativeSurchargeUpdated(opts *bind.FilterOpts) (*FeeManagerNativeSurchargeUpdatedIterator, error) + + WatchNativeSurchargeUpdated(opts *bind.WatchOpts, sink chan<- *FeeManagerNativeSurchargeUpdated) (event.Subscription, error) + + ParseNativeSurchargeUpdated(log types.Log) (*FeeManagerNativeSurchargeUpdated, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FeeManagerOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FeeManagerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*FeeManagerOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FeeManagerOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *FeeManagerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*FeeManagerOwnershipTransferred, error) + + FilterSubscriberDiscountUpdated(opts *bind.FilterOpts, subscriber []common.Address, feedId [][32]byte) (*FeeManagerSubscriberDiscountUpdatedIterator, error) + + WatchSubscriberDiscountUpdated(opts *bind.WatchOpts, sink chan<- *FeeManagerSubscriberDiscountUpdated, subscriber []common.Address, feedId [][32]byte) (event.Subscription, error) + + ParseSubscriberDiscountUpdated(log types.Log) (*FeeManagerSubscriberDiscountUpdated, error) + + FilterWithdraw(opts *bind.FilterOpts) (*FeeManagerWithdrawIterator, error) + + WatchWithdraw(opts *bind.WatchOpts, sink chan<- *FeeManagerWithdraw) (event.Subscription, error) + + ParseWithdraw(log types.Log) (*FeeManagerWithdraw, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/llo-feeds/generated/llo_feeds/llo_feeds.go b/core/gethwrappers/llo-feeds/generated/llo_feeds/llo_feeds.go new file mode 100644 index 00000000000..0cf53356440 --- /dev/null +++ b/core/gethwrappers/llo-feeds/generated/llo_feeds/llo_feeds.go @@ -0,0 +1,1318 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package llo_feeds + +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 CommonAddressAndWeight struct { + Addr common.Address + Weight *big.Int +} + +type CommonAsset struct { + AssetAddress common.Address + Amount *big.Int +} + +type IFeeManagerQuote struct { + QuoteAddress common.Address +} + +var LLOFeeManagerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_linkAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_nativeAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_proxyAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_rewardManagerAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ExpiredReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDeposit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDiscount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidQuote\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSurcharge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"linkQuantity\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nativeQuantity\",\"type\":\"uint256\"}],\"name\":\"InsufficientLink\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSurcharge\",\"type\":\"uint256\"}],\"name\":\"NativeSurchargeSet\",\"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\":\"subscriber\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"discount\",\"type\":\"uint256\"}],\"name\":\"SubscriberDiscountUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"name\":\"Withdraw\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"quoteAddress\",\"type\":\"address\"}],\"internalType\":\"structIFeeManager.Quote\",\"name\":\"quote\",\"type\":\"tuple\"}],\"name\":\"getFeeAndReward\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nativeSurcharge\",\"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\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"}],\"name\":\"processFee\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"rewardRecipientAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setFeeRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"surcharge\",\"type\":\"uint256\"}],\"name\":\"setNativeSurcharge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"subscriberDiscounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"discount\",\"type\":\"uint256\"}],\"name\":\"updateSubscriberDiscount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b50604051620024d4380380620024d4833981016040819052620000359162000288565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001c0565b5050506001600160a01b0384161580620000e057506001600160a01b038316155b80620000f357506001600160a01b038216155b806200010657506001600160a01b038116155b15620001255760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b03848116608081905284821660a05283821660c05290821660e081905260405163095ea7b360e01b81526004810191909152600019602482015263095ea7b3906044016020604051808303816000875af11580156200018f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001b59190620002e5565b505050505062000310565b336001600160a01b038216036200021a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146200028357600080fd5b919050565b600080600080608085870312156200029f57600080fd5b620002aa856200026b565b9350620002ba602086016200026b565b9250620002ca604086016200026b565b9150620002da606086016200026b565b905092959194509250565b600060208284031215620002f857600080fd5b815180151581146200030957600080fd5b9392505050565b60805160a05160c05160e051612128620003ac6000396000818161044c01528181610e5401526110b20152600081816103820152610b1b0152600081816106af015281816107020152818161090f01528181610c6901528181610d3001526112170152600081816106d40152818161075d0152818161089a01528181610a5d01528181610def01528181610fa301526111c001526121286000f3fe6080604052600436106100dd5760003560e01c806393798be71161007f578063f1387e1611610059578063f1387e16146102d6578063f237f1a8146102e9578063f2fde38b14610309578063f3fef3a31461032957600080fd5b806393798be714610255578063c541cbde14610293578063d09dc339146102c157600080fd5b80636b54d8a6116100bb5780636b54d8a6146101c757806379ba5097146101e75780637d75cc49146101fc5780638da5cb5b1461022057600080fd5b806301ffc9a7146100e2578063181f5a771461015957806369fd2b34146101a5575b600080fd5b3480156100ee57600080fd5b506101446100fd36600461167b565b7fffffffff00000000000000000000000000000000000000000000000000000000167ff1387e16000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b34801561016557600080fd5b50604080518082018252601081527f4665654d616e6167657220302e302e31000000000000000000000000000000006020820152905161015091906116c4565b3480156101b157600080fd5b506101c56101c0366004611730565b610349565b005b3480156101d357600080fd5b506101c56101e23660046117af565b6104bc565b3480156101f357600080fd5b506101c5610541565b34801561020857600080fd5b5061021260035481565b604051908152602001610150565b34801561022c57600080fd5b5060005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610150565b34801561026157600080fd5b506102126102703660046117ea565b600260209081526000938452604080852082529284528284209052825290205481565b34801561029f57600080fd5b506102b36102ae366004611961565b61063e565b604051610150929190611a02565b3480156102cd57600080fd5b50610212610a2c565b6101c56102e4366004611a56565b610ae2565b3480156102f557600080fd5b506101c5610304366004611ace565b611174565b34801561031557600080fd5b506101c5610324366004611b16565b61131b565b34801561033557600080fd5b506101c5610344366004611b33565b61132f565b60005473ffffffffffffffffffffffffffffffffffffffff163314806103a457503373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016145b61040f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4f6e6c79206f776e6572206f722070726f78790000000000000000000000000060448201526064015b60405180910390fd5b6040517f633b5f6e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063633b5f6e9061048590869086908690600401611b5f565b600060405180830381600087803b15801561049f57600080fd5b505af11580156104b3573d6000803e3d6000fd5b50505050505050565b6104c46114c9565b670de0b6b3a7640000811115610506576040517f05e8ac2900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60038190556040518181527f4fbcc2b7f4cb5518be923bd7c7c887e29e07b001e2a4a0fdd47c494696d8a1479060200160405180910390a150565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610406565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60408051808201909152600080825260208201526040805180820190915260008082526020820152604080518082019091526000808252602082015260408051808201909152600080825260208201528551610120106107005773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811683527f00000000000000000000000000000000000000000000000000000000000000001681529092509050610a24565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16856000015173ffffffffffffffffffffffffffffffffffffffff16141580156107b057507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16856000015173ffffffffffffffffffffffffffffffffffffffff1614155b156107e7576040517ff861803000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000888060200190518101906108009190611c39565b63ffffffff169b5077ffffffffffffffffffffffffffffffffffffffffffffffff169b5077ffffffffffffffffffffffffffffffffffffffffffffffff169b5050505050505050505042811015610883576040517fb6c405f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116808652602086018590528951909116036108f857835173ffffffffffffffffffffffffffffffffffffffff16855260208085015190860152610968565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001685526003546109629061094a90670de0b6b3a7640000611d36565b6109549084611d49565b670de0b6b3a764000061154c565b60208601525b60006109738a611d86565b73ffffffffffffffffffffffffffffffffffffffff808d16600090815260026020908152604080832085845282528083208e519094168352928152919020549088015191925090670de0b6b3a7640000906109cf908390611d49565b6109d99190611dcb565b87602001516109e89190611e06565b876020018181525050610a048187602001516109549190611d49565b8660200151610a139190611e06565b602087015250949650929450505050505b935093915050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610ab9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610add9190611e19565b905090565b60005473ffffffffffffffffffffffffffffffffffffffff16331480610b3d57503373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016145b610ba3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4f6e6c79206f776e6572206f722070726f7879000000000000000000000000006044820152606401610406565b3073ffffffffffffffffffffffffffffffffffffffff821603610bf2576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610c0083850185611ea0565b604080516020810190915260008152909250905081516101201015610c4c576000610c2d85870187611f6f565b9550505050505080806020019051810190610c489190612037565b9150505b600080610c5a33858561063e565b909250905060003415610dbd577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614610cf0576040517fb2e532de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3483602001511115610d2e576040517fb2e532de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db084602001516040518263ffffffff1660e01b81526004016000604051808303818588803b158015610d9a57600080fd5b505af1158015610dae573d6000803e3d6000fd5b50505050508260200151340390505b6000610dc9888a612065565b60208501519091501561111e57835173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116911603610ec4576040517f84afb76e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906384afb76e90610e8d9084908b9088906004016120a1565b600060405180830381600087803b158015610ea757600080fd5b505af1158015610ebb573d6000803e3d6000fd5b5050505061111e565b34600003610f7557835160208501516040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a8116600483015230602483015260448201929092529116906323b872dd906064016020604051808303816000875af1158015610f4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7391906120f9565b505b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610fff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110239190611e19565b836020015111156110755760208084015185820151604080519283529282015282917feb6f22018570d97db6df12dc94f202b4e2b2888a6a5d4bd179422c91b29dcdf7910160405180910390a261111e565b6040517f84afb76e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906384afb76e906110eb908490309088906004016120a1565b600060405180830381600087803b15801561110557600080fd5b505af1158015611119573d6000803e3d6000fd5b505050505b81156111695760405173ffffffffffffffffffffffffffffffffffffffff88169083156108fc029084906000818181858888f19350505050158015611167573d6000803e3d6000fd5b505b505050505050505050565b61117c6114c9565b670de0b6b3a76400008111156111be576040517f997ea36000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561126657507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b1561129d576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84811660008181526002602090815260408083208884528252808320948716808452948252918290208590558151938452830184905285927f41eb9ccd292d5906dc1f0ec108bed3e2b966e3071e033df938f7215f6d30ca84910160405180910390a350505050565b6113236114c9565b61132c81611586565b50565b6113376114c9565b73ffffffffffffffffffffffffffffffffffffffff821661139d576000805460405173ffffffffffffffffffffffffffffffffffffffff9091169183156108fc02918491818181858888f19350505050158015611398573d6000803e3d6000fd5b505050565b8173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6113d860005473ffffffffffffffffffffffffffffffffffffffff1690565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602481018490526044016020604051808303816000875af115801561144a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061146e91906120f9565b506040805133815273ffffffffffffffffffffffffffffffffffffffff841660208201529081018290527f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb9060600160405180910390a15050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461154a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610406565b565b6000821561157a5781611560600185611e06565b61156a9190611dcb565b611575906001611d36565b61157d565b60005b90505b92915050565b3373ffffffffffffffffffffffffffffffffffffffff821603611605576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610406565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006020828403121561168d57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146116bd57600080fd5b9392505050565b600060208083528351808285015260005b818110156116f1578581018301518582016040015282016116d5565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60008060006040848603121561174557600080fd5b83359250602084013567ffffffffffffffff8082111561176457600080fd5b818601915086601f83011261177857600080fd5b81358181111561178757600080fd5b8760208260061b850101111561179c57600080fd5b6020830194508093505050509250925092565b6000602082840312156117c157600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461132c57600080fd5b6000806000606084860312156117ff57600080fd5b833561180a816117c8565b9250602084013591506040840135611821816117c8565b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516020810167ffffffffffffffff8111828210171561187e5761187e61182c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156118cb576118cb61182c565b604052919050565b600082601f8301126118e457600080fd5b813567ffffffffffffffff8111156118fe576118fe61182c565b61192f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611884565b81815284602083860101111561194457600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000838503606081121561197757600080fd5b8435611982816117c8565b9350602085013567ffffffffffffffff81111561199e57600080fd5b6119aa878288016118d3565b93505060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0820112156119dd57600080fd5b506119e661185b565b60408501356119f4816117c8565b815292959194509192509050565b825173ffffffffffffffffffffffffffffffffffffffff1681526020808401519082015260808101825173ffffffffffffffffffffffffffffffffffffffff166040830152602083015160608301526116bd565b600080600060408486031215611a6b57600080fd5b833567ffffffffffffffff80821115611a8357600080fd5b818601915086601f830112611a9757600080fd5b813581811115611aa657600080fd5b876020828501011115611ab857600080fd5b60209283019550935050840135611821816117c8565b60008060008060808587031215611ae457600080fd5b8435611aef816117c8565b9350602085013592506040850135611b06816117c8565b9396929550929360600135925050565b600060208284031215611b2857600080fd5b81356116bd816117c8565b60008060408385031215611b4657600080fd5b8235611b51816117c8565b946020939093013593505050565b8381526040602080830182905282820184905260009190859060608501845b87811015611bc1578335611b91816117c8565b73ffffffffffffffffffffffffffffffffffffffff16825283830135838301529284019290840190600101611b7e565b5098975050505050505050565b805163ffffffff81168114611be257600080fd5b919050565b8051601781900b8114611be257600080fd5b805167ffffffffffffffff81168114611be257600080fd5b805177ffffffffffffffffffffffffffffffffffffffffffffffff81168114611be257600080fd5b6000806000806000806000806000806000806101808d8f031215611c5c57600080fd5b8c519b50611c6c60208e01611bce565b9a50611c7a60408e01611be7565b9950611c8860608e01611be7565b9850611c9660808e01611be7565b9750611ca460a08e01611bf9565b965060c08d01519550611cb960e08e01611bf9565b9450611cc86101008e01611bf9565b9350611cd76101208e01611c11565b9250611ce66101408e01611c11565b9150611cf56101608e01611bce565b90509295989b509295989b509295989b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561158057611580611d07565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611d8157611d81611d07565b500290565b80516020808301519190811015611dc5577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b600082611e01577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b8181038181111561158057611580611d07565b600060208284031215611e2b57600080fd5b5051919050565b600082601f830112611e4357600080fd5b6040516060810181811067ffffffffffffffff82111715611e6657611e6661182c565b604052806060840185811115611e7b57600080fd5b845b81811015611e95578035835260209283019201611e7d565b509195945050505050565b60008060808385031215611eb357600080fd5b611ebd8484611e32565b9150606083013567ffffffffffffffff811115611ed957600080fd5b611ee5858286016118d3565b9150509250929050565b600082601f830112611f0057600080fd5b8135602067ffffffffffffffff821115611f1c57611f1c61182c565b8160051b611f2b828201611884565b9283528481018201928281019087851115611f4557600080fd5b83870192505b84831015611f6457823582529183019190830190611f4b565b979650505050505050565b6000806000806000806101008789031215611f8957600080fd5b611f938888611e32565b9550606087013567ffffffffffffffff80821115611fb057600080fd5b611fbc8a838b016118d3565b96506080890135915080821115611fd257600080fd5b611fde8a838b01611eef565b955060a0890135915080821115611ff457600080fd5b6120008a838b01611eef565b945060c0890135935060e089013591508082111561201d57600080fd5b5061202a89828a016118d3565b9150509295509295509295565b60006020828403121561204957600080fd5b61205161185b565b825161205c816117c8565b81529392505050565b80356020831015611580577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b83815273ffffffffffffffffffffffffffffffffffffffff83166020820152608081016120f16040830184805173ffffffffffffffffffffffffffffffffffffffff168252602090810151910152565b949350505050565b60006020828403121561210b57600080fd5b815180151581146116bd57600080fdfea164736f6c6343000810000a", +} + +var LLOFeeManagerABI = LLOFeeManagerMetaData.ABI + +var LLOFeeManagerBin = LLOFeeManagerMetaData.Bin + +func DeployLLOFeeManager(auth *bind.TransactOpts, backend bind.ContractBackend, _linkAddress common.Address, _nativeAddress common.Address, _proxyAddress common.Address, _rewardManagerAddress common.Address) (common.Address, *types.Transaction, *LLOFeeManager, error) { + parsed, err := LLOFeeManagerMetaData.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(LLOFeeManagerBin), backend, _linkAddress, _nativeAddress, _proxyAddress, _rewardManagerAddress) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &LLOFeeManager{LLOFeeManagerCaller: LLOFeeManagerCaller{contract: contract}, LLOFeeManagerTransactor: LLOFeeManagerTransactor{contract: contract}, LLOFeeManagerFilterer: LLOFeeManagerFilterer{contract: contract}}, nil +} + +type LLOFeeManager struct { + address common.Address + abi abi.ABI + LLOFeeManagerCaller + LLOFeeManagerTransactor + LLOFeeManagerFilterer +} + +type LLOFeeManagerCaller struct { + contract *bind.BoundContract +} + +type LLOFeeManagerTransactor struct { + contract *bind.BoundContract +} + +type LLOFeeManagerFilterer struct { + contract *bind.BoundContract +} + +type LLOFeeManagerSession struct { + Contract *LLOFeeManager + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type LLOFeeManagerCallerSession struct { + Contract *LLOFeeManagerCaller + CallOpts bind.CallOpts +} + +type LLOFeeManagerTransactorSession struct { + Contract *LLOFeeManagerTransactor + TransactOpts bind.TransactOpts +} + +type LLOFeeManagerRaw struct { + Contract *LLOFeeManager +} + +type LLOFeeManagerCallerRaw struct { + Contract *LLOFeeManagerCaller +} + +type LLOFeeManagerTransactorRaw struct { + Contract *LLOFeeManagerTransactor +} + +func NewLLOFeeManager(address common.Address, backend bind.ContractBackend) (*LLOFeeManager, error) { + abi, err := abi.JSON(strings.NewReader(LLOFeeManagerABI)) + if err != nil { + return nil, err + } + contract, err := bindLLOFeeManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &LLOFeeManager{address: address, abi: abi, LLOFeeManagerCaller: LLOFeeManagerCaller{contract: contract}, LLOFeeManagerTransactor: LLOFeeManagerTransactor{contract: contract}, LLOFeeManagerFilterer: LLOFeeManagerFilterer{contract: contract}}, nil +} + +func NewLLOFeeManagerCaller(address common.Address, caller bind.ContractCaller) (*LLOFeeManagerCaller, error) { + contract, err := bindLLOFeeManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &LLOFeeManagerCaller{contract: contract}, nil +} + +func NewLLOFeeManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*LLOFeeManagerTransactor, error) { + contract, err := bindLLOFeeManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &LLOFeeManagerTransactor{contract: contract}, nil +} + +func NewLLOFeeManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*LLOFeeManagerFilterer, error) { + contract, err := bindLLOFeeManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &LLOFeeManagerFilterer{contract: contract}, nil +} + +func bindLLOFeeManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := LLOFeeManagerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_LLOFeeManager *LLOFeeManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LLOFeeManager.Contract.LLOFeeManagerCaller.contract.Call(opts, result, method, params...) +} + +func (_LLOFeeManager *LLOFeeManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LLOFeeManager.Contract.LLOFeeManagerTransactor.contract.Transfer(opts) +} + +func (_LLOFeeManager *LLOFeeManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LLOFeeManager.Contract.LLOFeeManagerTransactor.contract.Transact(opts, method, params...) +} + +func (_LLOFeeManager *LLOFeeManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LLOFeeManager.Contract.contract.Call(opts, result, method, params...) +} + +func (_LLOFeeManager *LLOFeeManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LLOFeeManager.Contract.contract.Transfer(opts) +} + +func (_LLOFeeManager *LLOFeeManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LLOFeeManager.Contract.contract.Transact(opts, method, params...) +} + +func (_LLOFeeManager *LLOFeeManagerCaller) GetFeeAndReward(opts *bind.CallOpts, subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, error) { + var out []interface{} + err := _LLOFeeManager.contract.Call(opts, &out, "getFeeAndReward", subscriber, report, quote) + + if err != nil { + return *new(CommonAsset), *new(CommonAsset), err + } + + out0 := *abi.ConvertType(out[0], new(CommonAsset)).(*CommonAsset) + out1 := *abi.ConvertType(out[1], new(CommonAsset)).(*CommonAsset) + + return out0, out1, err + +} + +func (_LLOFeeManager *LLOFeeManagerSession) GetFeeAndReward(subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, error) { + return _LLOFeeManager.Contract.GetFeeAndReward(&_LLOFeeManager.CallOpts, subscriber, report, quote) +} + +func (_LLOFeeManager *LLOFeeManagerCallerSession) GetFeeAndReward(subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, error) { + return _LLOFeeManager.Contract.GetFeeAndReward(&_LLOFeeManager.CallOpts, subscriber, report, quote) +} + +func (_LLOFeeManager *LLOFeeManagerCaller) LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _LLOFeeManager.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 (_LLOFeeManager *LLOFeeManagerSession) LinkAvailableForPayment() (*big.Int, error) { + return _LLOFeeManager.Contract.LinkAvailableForPayment(&_LLOFeeManager.CallOpts) +} + +func (_LLOFeeManager *LLOFeeManagerCallerSession) LinkAvailableForPayment() (*big.Int, error) { + return _LLOFeeManager.Contract.LinkAvailableForPayment(&_LLOFeeManager.CallOpts) +} + +func (_LLOFeeManager *LLOFeeManagerCaller) NativeSurcharge(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _LLOFeeManager.contract.Call(opts, &out, "nativeSurcharge") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LLOFeeManager *LLOFeeManagerSession) NativeSurcharge() (*big.Int, error) { + return _LLOFeeManager.Contract.NativeSurcharge(&_LLOFeeManager.CallOpts) +} + +func (_LLOFeeManager *LLOFeeManagerCallerSession) NativeSurcharge() (*big.Int, error) { + return _LLOFeeManager.Contract.NativeSurcharge(&_LLOFeeManager.CallOpts) +} + +func (_LLOFeeManager *LLOFeeManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LLOFeeManager.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 (_LLOFeeManager *LLOFeeManagerSession) Owner() (common.Address, error) { + return _LLOFeeManager.Contract.Owner(&_LLOFeeManager.CallOpts) +} + +func (_LLOFeeManager *LLOFeeManagerCallerSession) Owner() (common.Address, error) { + return _LLOFeeManager.Contract.Owner(&_LLOFeeManager.CallOpts) +} + +func (_LLOFeeManager *LLOFeeManagerCaller) SubscriberDiscounts(opts *bind.CallOpts, arg0 common.Address, arg1 [32]byte, arg2 common.Address) (*big.Int, error) { + var out []interface{} + err := _LLOFeeManager.contract.Call(opts, &out, "subscriberDiscounts", arg0, arg1, arg2) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LLOFeeManager *LLOFeeManagerSession) SubscriberDiscounts(arg0 common.Address, arg1 [32]byte, arg2 common.Address) (*big.Int, error) { + return _LLOFeeManager.Contract.SubscriberDiscounts(&_LLOFeeManager.CallOpts, arg0, arg1, arg2) +} + +func (_LLOFeeManager *LLOFeeManagerCallerSession) SubscriberDiscounts(arg0 common.Address, arg1 [32]byte, arg2 common.Address) (*big.Int, error) { + return _LLOFeeManager.Contract.SubscriberDiscounts(&_LLOFeeManager.CallOpts, arg0, arg1, arg2) +} + +func (_LLOFeeManager *LLOFeeManagerCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _LLOFeeManager.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LLOFeeManager *LLOFeeManagerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _LLOFeeManager.Contract.SupportsInterface(&_LLOFeeManager.CallOpts, interfaceId) +} + +func (_LLOFeeManager *LLOFeeManagerCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _LLOFeeManager.Contract.SupportsInterface(&_LLOFeeManager.CallOpts, interfaceId) +} + +func (_LLOFeeManager *LLOFeeManagerCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _LLOFeeManager.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_LLOFeeManager *LLOFeeManagerSession) TypeAndVersion() (string, error) { + return _LLOFeeManager.Contract.TypeAndVersion(&_LLOFeeManager.CallOpts) +} + +func (_LLOFeeManager *LLOFeeManagerCallerSession) TypeAndVersion() (string, error) { + return _LLOFeeManager.Contract.TypeAndVersion(&_LLOFeeManager.CallOpts) +} + +func (_LLOFeeManager *LLOFeeManagerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LLOFeeManager.contract.Transact(opts, "acceptOwnership") +} + +func (_LLOFeeManager *LLOFeeManagerSession) AcceptOwnership() (*types.Transaction, error) { + return _LLOFeeManager.Contract.AcceptOwnership(&_LLOFeeManager.TransactOpts) +} + +func (_LLOFeeManager *LLOFeeManagerTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _LLOFeeManager.Contract.AcceptOwnership(&_LLOFeeManager.TransactOpts) +} + +func (_LLOFeeManager *LLOFeeManagerTransactor) ProcessFee(opts *bind.TransactOpts, payload []byte, subscriber common.Address) (*types.Transaction, error) { + return _LLOFeeManager.contract.Transact(opts, "processFee", payload, subscriber) +} + +func (_LLOFeeManager *LLOFeeManagerSession) ProcessFee(payload []byte, subscriber common.Address) (*types.Transaction, error) { + return _LLOFeeManager.Contract.ProcessFee(&_LLOFeeManager.TransactOpts, payload, subscriber) +} + +func (_LLOFeeManager *LLOFeeManagerTransactorSession) ProcessFee(payload []byte, subscriber common.Address) (*types.Transaction, error) { + return _LLOFeeManager.Contract.ProcessFee(&_LLOFeeManager.TransactOpts, payload, subscriber) +} + +func (_LLOFeeManager *LLOFeeManagerTransactor) SetFeeRecipients(opts *bind.TransactOpts, configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _LLOFeeManager.contract.Transact(opts, "setFeeRecipients", configDigest, rewardRecipientAndWeights) +} + +func (_LLOFeeManager *LLOFeeManagerSession) SetFeeRecipients(configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _LLOFeeManager.Contract.SetFeeRecipients(&_LLOFeeManager.TransactOpts, configDigest, rewardRecipientAndWeights) +} + +func (_LLOFeeManager *LLOFeeManagerTransactorSession) SetFeeRecipients(configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _LLOFeeManager.Contract.SetFeeRecipients(&_LLOFeeManager.TransactOpts, configDigest, rewardRecipientAndWeights) +} + +func (_LLOFeeManager *LLOFeeManagerTransactor) SetNativeSurcharge(opts *bind.TransactOpts, surcharge *big.Int) (*types.Transaction, error) { + return _LLOFeeManager.contract.Transact(opts, "setNativeSurcharge", surcharge) +} + +func (_LLOFeeManager *LLOFeeManagerSession) SetNativeSurcharge(surcharge *big.Int) (*types.Transaction, error) { + return _LLOFeeManager.Contract.SetNativeSurcharge(&_LLOFeeManager.TransactOpts, surcharge) +} + +func (_LLOFeeManager *LLOFeeManagerTransactorSession) SetNativeSurcharge(surcharge *big.Int) (*types.Transaction, error) { + return _LLOFeeManager.Contract.SetNativeSurcharge(&_LLOFeeManager.TransactOpts, surcharge) +} + +func (_LLOFeeManager *LLOFeeManagerTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _LLOFeeManager.contract.Transact(opts, "transferOwnership", to) +} + +func (_LLOFeeManager *LLOFeeManagerSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _LLOFeeManager.Contract.TransferOwnership(&_LLOFeeManager.TransactOpts, to) +} + +func (_LLOFeeManager *LLOFeeManagerTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _LLOFeeManager.Contract.TransferOwnership(&_LLOFeeManager.TransactOpts, to) +} + +func (_LLOFeeManager *LLOFeeManagerTransactor) UpdateSubscriberDiscount(opts *bind.TransactOpts, subscriber common.Address, feedId [32]byte, token common.Address, discount *big.Int) (*types.Transaction, error) { + return _LLOFeeManager.contract.Transact(opts, "updateSubscriberDiscount", subscriber, feedId, token, discount) +} + +func (_LLOFeeManager *LLOFeeManagerSession) UpdateSubscriberDiscount(subscriber common.Address, feedId [32]byte, token common.Address, discount *big.Int) (*types.Transaction, error) { + return _LLOFeeManager.Contract.UpdateSubscriberDiscount(&_LLOFeeManager.TransactOpts, subscriber, feedId, token, discount) +} + +func (_LLOFeeManager *LLOFeeManagerTransactorSession) UpdateSubscriberDiscount(subscriber common.Address, feedId [32]byte, token common.Address, discount *big.Int) (*types.Transaction, error) { + return _LLOFeeManager.Contract.UpdateSubscriberDiscount(&_LLOFeeManager.TransactOpts, subscriber, feedId, token, discount) +} + +func (_LLOFeeManager *LLOFeeManagerTransactor) Withdraw(opts *bind.TransactOpts, assetAddress common.Address, quantity *big.Int) (*types.Transaction, error) { + return _LLOFeeManager.contract.Transact(opts, "withdraw", assetAddress, quantity) +} + +func (_LLOFeeManager *LLOFeeManagerSession) Withdraw(assetAddress common.Address, quantity *big.Int) (*types.Transaction, error) { + return _LLOFeeManager.Contract.Withdraw(&_LLOFeeManager.TransactOpts, assetAddress, quantity) +} + +func (_LLOFeeManager *LLOFeeManagerTransactorSession) Withdraw(assetAddress common.Address, quantity *big.Int) (*types.Transaction, error) { + return _LLOFeeManager.Contract.Withdraw(&_LLOFeeManager.TransactOpts, assetAddress, quantity) +} + +type LLOFeeManagerInsufficientLinkIterator struct { + Event *LLOFeeManagerInsufficientLink + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LLOFeeManagerInsufficientLinkIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LLOFeeManagerInsufficientLink) + 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(LLOFeeManagerInsufficientLink) + 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 *LLOFeeManagerInsufficientLinkIterator) Error() error { + return it.fail +} + +func (it *LLOFeeManagerInsufficientLinkIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LLOFeeManagerInsufficientLink struct { + ConfigDigest [32]byte + LinkQuantity *big.Int + NativeQuantity *big.Int + Raw types.Log +} + +func (_LLOFeeManager *LLOFeeManagerFilterer) FilterInsufficientLink(opts *bind.FilterOpts, configDigest [][32]byte) (*LLOFeeManagerInsufficientLinkIterator, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + + logs, sub, err := _LLOFeeManager.contract.FilterLogs(opts, "InsufficientLink", configDigestRule) + if err != nil { + return nil, err + } + return &LLOFeeManagerInsufficientLinkIterator{contract: _LLOFeeManager.contract, event: "InsufficientLink", logs: logs, sub: sub}, nil +} + +func (_LLOFeeManager *LLOFeeManagerFilterer) WatchInsufficientLink(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerInsufficientLink, configDigest [][32]byte) (event.Subscription, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + + logs, sub, err := _LLOFeeManager.contract.WatchLogs(opts, "InsufficientLink", configDigestRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LLOFeeManagerInsufficientLink) + if err := _LLOFeeManager.contract.UnpackLog(event, "InsufficientLink", 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 (_LLOFeeManager *LLOFeeManagerFilterer) ParseInsufficientLink(log types.Log) (*LLOFeeManagerInsufficientLink, error) { + event := new(LLOFeeManagerInsufficientLink) + if err := _LLOFeeManager.contract.UnpackLog(event, "InsufficientLink", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LLOFeeManagerNativeSurchargeSetIterator struct { + Event *LLOFeeManagerNativeSurchargeSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LLOFeeManagerNativeSurchargeSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LLOFeeManagerNativeSurchargeSet) + 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(LLOFeeManagerNativeSurchargeSet) + 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 *LLOFeeManagerNativeSurchargeSetIterator) Error() error { + return it.fail +} + +func (it *LLOFeeManagerNativeSurchargeSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LLOFeeManagerNativeSurchargeSet struct { + NewSurcharge *big.Int + Raw types.Log +} + +func (_LLOFeeManager *LLOFeeManagerFilterer) FilterNativeSurchargeSet(opts *bind.FilterOpts) (*LLOFeeManagerNativeSurchargeSetIterator, error) { + + logs, sub, err := _LLOFeeManager.contract.FilterLogs(opts, "NativeSurchargeSet") + if err != nil { + return nil, err + } + return &LLOFeeManagerNativeSurchargeSetIterator{contract: _LLOFeeManager.contract, event: "NativeSurchargeSet", logs: logs, sub: sub}, nil +} + +func (_LLOFeeManager *LLOFeeManagerFilterer) WatchNativeSurchargeSet(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerNativeSurchargeSet) (event.Subscription, error) { + + logs, sub, err := _LLOFeeManager.contract.WatchLogs(opts, "NativeSurchargeSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LLOFeeManagerNativeSurchargeSet) + if err := _LLOFeeManager.contract.UnpackLog(event, "NativeSurchargeSet", 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 (_LLOFeeManager *LLOFeeManagerFilterer) ParseNativeSurchargeSet(log types.Log) (*LLOFeeManagerNativeSurchargeSet, error) { + event := new(LLOFeeManagerNativeSurchargeSet) + if err := _LLOFeeManager.contract.UnpackLog(event, "NativeSurchargeSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LLOFeeManagerOwnershipTransferRequestedIterator struct { + Event *LLOFeeManagerOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LLOFeeManagerOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LLOFeeManagerOwnershipTransferRequested) + 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(LLOFeeManagerOwnershipTransferRequested) + 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 *LLOFeeManagerOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *LLOFeeManagerOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LLOFeeManagerOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_LLOFeeManager *LLOFeeManagerFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LLOFeeManagerOwnershipTransferRequestedIterator, 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 := _LLOFeeManager.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &LLOFeeManagerOwnershipTransferRequestedIterator{contract: _LLOFeeManager.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_LLOFeeManager *LLOFeeManagerFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerOwnershipTransferRequested, 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 := _LLOFeeManager.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(LLOFeeManagerOwnershipTransferRequested) + if err := _LLOFeeManager.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 (_LLOFeeManager *LLOFeeManagerFilterer) ParseOwnershipTransferRequested(log types.Log) (*LLOFeeManagerOwnershipTransferRequested, error) { + event := new(LLOFeeManagerOwnershipTransferRequested) + if err := _LLOFeeManager.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LLOFeeManagerOwnershipTransferredIterator struct { + Event *LLOFeeManagerOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LLOFeeManagerOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LLOFeeManagerOwnershipTransferred) + 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(LLOFeeManagerOwnershipTransferred) + 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 *LLOFeeManagerOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *LLOFeeManagerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LLOFeeManagerOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_LLOFeeManager *LLOFeeManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LLOFeeManagerOwnershipTransferredIterator, 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 := _LLOFeeManager.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &LLOFeeManagerOwnershipTransferredIterator{contract: _LLOFeeManager.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_LLOFeeManager *LLOFeeManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerOwnershipTransferred, 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 := _LLOFeeManager.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(LLOFeeManagerOwnershipTransferred) + if err := _LLOFeeManager.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 (_LLOFeeManager *LLOFeeManagerFilterer) ParseOwnershipTransferred(log types.Log) (*LLOFeeManagerOwnershipTransferred, error) { + event := new(LLOFeeManagerOwnershipTransferred) + if err := _LLOFeeManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LLOFeeManagerSubscriberDiscountUpdatedIterator struct { + Event *LLOFeeManagerSubscriberDiscountUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LLOFeeManagerSubscriberDiscountUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LLOFeeManagerSubscriberDiscountUpdated) + 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(LLOFeeManagerSubscriberDiscountUpdated) + 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 *LLOFeeManagerSubscriberDiscountUpdatedIterator) Error() error { + return it.fail +} + +func (it *LLOFeeManagerSubscriberDiscountUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LLOFeeManagerSubscriberDiscountUpdated struct { + Subscriber common.Address + FeedId [32]byte + Token common.Address + Discount *big.Int + Raw types.Log +} + +func (_LLOFeeManager *LLOFeeManagerFilterer) FilterSubscriberDiscountUpdated(opts *bind.FilterOpts, subscriber []common.Address, feedId [][32]byte) (*LLOFeeManagerSubscriberDiscountUpdatedIterator, error) { + + var subscriberRule []interface{} + for _, subscriberItem := range subscriber { + subscriberRule = append(subscriberRule, subscriberItem) + } + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _LLOFeeManager.contract.FilterLogs(opts, "SubscriberDiscountUpdated", subscriberRule, feedIdRule) + if err != nil { + return nil, err + } + return &LLOFeeManagerSubscriberDiscountUpdatedIterator{contract: _LLOFeeManager.contract, event: "SubscriberDiscountUpdated", logs: logs, sub: sub}, nil +} + +func (_LLOFeeManager *LLOFeeManagerFilterer) WatchSubscriberDiscountUpdated(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerSubscriberDiscountUpdated, subscriber []common.Address, feedId [][32]byte) (event.Subscription, error) { + + var subscriberRule []interface{} + for _, subscriberItem := range subscriber { + subscriberRule = append(subscriberRule, subscriberItem) + } + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _LLOFeeManager.contract.WatchLogs(opts, "SubscriberDiscountUpdated", subscriberRule, feedIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LLOFeeManagerSubscriberDiscountUpdated) + if err := _LLOFeeManager.contract.UnpackLog(event, "SubscriberDiscountUpdated", 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 (_LLOFeeManager *LLOFeeManagerFilterer) ParseSubscriberDiscountUpdated(log types.Log) (*LLOFeeManagerSubscriberDiscountUpdated, error) { + event := new(LLOFeeManagerSubscriberDiscountUpdated) + if err := _LLOFeeManager.contract.UnpackLog(event, "SubscriberDiscountUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LLOFeeManagerWithdrawIterator struct { + Event *LLOFeeManagerWithdraw + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LLOFeeManagerWithdrawIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LLOFeeManagerWithdraw) + 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(LLOFeeManagerWithdraw) + 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 *LLOFeeManagerWithdrawIterator) Error() error { + return it.fail +} + +func (it *LLOFeeManagerWithdrawIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LLOFeeManagerWithdraw struct { + AdminAddress common.Address + AssetAddress common.Address + Quantity *big.Int + Raw types.Log +} + +func (_LLOFeeManager *LLOFeeManagerFilterer) FilterWithdraw(opts *bind.FilterOpts) (*LLOFeeManagerWithdrawIterator, error) { + + logs, sub, err := _LLOFeeManager.contract.FilterLogs(opts, "Withdraw") + if err != nil { + return nil, err + } + return &LLOFeeManagerWithdrawIterator{contract: _LLOFeeManager.contract, event: "Withdraw", logs: logs, sub: sub}, nil +} + +func (_LLOFeeManager *LLOFeeManagerFilterer) WatchWithdraw(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerWithdraw) (event.Subscription, error) { + + logs, sub, err := _LLOFeeManager.contract.WatchLogs(opts, "Withdraw") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LLOFeeManagerWithdraw) + if err := _LLOFeeManager.contract.UnpackLog(event, "Withdraw", 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 (_LLOFeeManager *LLOFeeManagerFilterer) ParseWithdraw(log types.Log) (*LLOFeeManagerWithdraw, error) { + event := new(LLOFeeManagerWithdraw) + if err := _LLOFeeManager.contract.UnpackLog(event, "Withdraw", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_LLOFeeManager *LLOFeeManager) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _LLOFeeManager.abi.Events["InsufficientLink"].ID: + return _LLOFeeManager.ParseInsufficientLink(log) + case _LLOFeeManager.abi.Events["NativeSurchargeSet"].ID: + return _LLOFeeManager.ParseNativeSurchargeSet(log) + case _LLOFeeManager.abi.Events["OwnershipTransferRequested"].ID: + return _LLOFeeManager.ParseOwnershipTransferRequested(log) + case _LLOFeeManager.abi.Events["OwnershipTransferred"].ID: + return _LLOFeeManager.ParseOwnershipTransferred(log) + case _LLOFeeManager.abi.Events["SubscriberDiscountUpdated"].ID: + return _LLOFeeManager.ParseSubscriberDiscountUpdated(log) + case _LLOFeeManager.abi.Events["Withdraw"].ID: + return _LLOFeeManager.ParseWithdraw(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (LLOFeeManagerInsufficientLink) Topic() common.Hash { + return common.HexToHash("0xeb6f22018570d97db6df12dc94f202b4e2b2888a6a5d4bd179422c91b29dcdf7") +} + +func (LLOFeeManagerNativeSurchargeSet) Topic() common.Hash { + return common.HexToHash("0x4fbcc2b7f4cb5518be923bd7c7c887e29e07b001e2a4a0fdd47c494696d8a147") +} + +func (LLOFeeManagerOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (LLOFeeManagerOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (LLOFeeManagerSubscriberDiscountUpdated) Topic() common.Hash { + return common.HexToHash("0x41eb9ccd292d5906dc1f0ec108bed3e2b966e3071e033df938f7215f6d30ca84") +} + +func (LLOFeeManagerWithdraw) Topic() common.Hash { + return common.HexToHash("0x9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb") +} + +func (_LLOFeeManager *LLOFeeManager) Address() common.Address { + return _LLOFeeManager.address +} + +type LLOFeeManagerInterface interface { + GetFeeAndReward(opts *bind.CallOpts, subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, error) + + LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) + + NativeSurcharge(opts *bind.CallOpts) (*big.Int, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SubscriberDiscounts(opts *bind.CallOpts, arg0 common.Address, arg1 [32]byte, arg2 common.Address) (*big.Int, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ProcessFee(opts *bind.TransactOpts, payload []byte, subscriber common.Address) (*types.Transaction, error) + + SetFeeRecipients(opts *bind.TransactOpts, configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) + + SetNativeSurcharge(opts *bind.TransactOpts, surcharge *big.Int) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + UpdateSubscriberDiscount(opts *bind.TransactOpts, subscriber common.Address, feedId [32]byte, token common.Address, discount *big.Int) (*types.Transaction, error) + + Withdraw(opts *bind.TransactOpts, assetAddress common.Address, quantity *big.Int) (*types.Transaction, error) + + FilterInsufficientLink(opts *bind.FilterOpts, configDigest [][32]byte) (*LLOFeeManagerInsufficientLinkIterator, error) + + WatchInsufficientLink(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerInsufficientLink, configDigest [][32]byte) (event.Subscription, error) + + ParseInsufficientLink(log types.Log) (*LLOFeeManagerInsufficientLink, error) + + FilterNativeSurchargeSet(opts *bind.FilterOpts) (*LLOFeeManagerNativeSurchargeSetIterator, error) + + WatchNativeSurchargeSet(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerNativeSurchargeSet) (event.Subscription, error) + + ParseNativeSurchargeSet(log types.Log) (*LLOFeeManagerNativeSurchargeSet, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LLOFeeManagerOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*LLOFeeManagerOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LLOFeeManagerOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*LLOFeeManagerOwnershipTransferred, error) + + FilterSubscriberDiscountUpdated(opts *bind.FilterOpts, subscriber []common.Address, feedId [][32]byte) (*LLOFeeManagerSubscriberDiscountUpdatedIterator, error) + + WatchSubscriberDiscountUpdated(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerSubscriberDiscountUpdated, subscriber []common.Address, feedId [][32]byte) (event.Subscription, error) + + ParseSubscriberDiscountUpdated(log types.Log) (*LLOFeeManagerSubscriberDiscountUpdated, error) + + FilterWithdraw(opts *bind.FilterOpts) (*LLOFeeManagerWithdrawIterator, error) + + WatchWithdraw(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerWithdraw) (event.Subscription, error) + + ParseWithdraw(log types.Log) (*LLOFeeManagerWithdraw, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/llo-feeds/generated/llo_feeds_test/llo_feeds_test.go b/core/gethwrappers/llo-feeds/generated/llo_feeds_test/llo_feeds_test.go new file mode 100644 index 00000000000..51f0f6e462e --- /dev/null +++ b/core/gethwrappers/llo-feeds/generated/llo_feeds_test/llo_feeds_test.go @@ -0,0 +1,202 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package llo_feeds_test + +import ( + "errors" + "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" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var LLOExposedVerifierMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_feedId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"_configCount\",\"type\":\"uint64\"},{\"internalType\":\"address[]\",\"name\":\"_signers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"_offchainTransmitters\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"_f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"_encodedConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"_encodedConfig\",\"type\":\"bytes\"}],\"name\":\"exposedConfigDigestFromConfigData\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50610696806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80630ebd702314610030575b600080fd5b61004361003e3660046103f7565b610055565b60405190815260200160405180910390f35b60006100a18c8c8c8c8c8c8c8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92508d91506100b19050565b9c9b505050505050505050505050565b6000808b8b8b8b8b8b8b8b8b8b6040516020016100d79a999897969594939291906105a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e06000000000000000000000000000000000000000000000000000000000000179150509a9950505050505050505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461018357600080fd5b919050565b803567ffffffffffffffff8116811461018357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610216576102166101a0565b604052919050565b600067ffffffffffffffff821115610238576102386101a0565b5060051b60200190565b600082601f83011261025357600080fd5b813560206102686102638361021e565b6101cf565b82815260059290921b8401810191818101908684111561028757600080fd5b8286015b848110156102a95761029c8161015f565b835291830191830161028b565b509695505050505050565b600082601f8301126102c557600080fd5b813560206102d56102638361021e565b82815260059290921b840181019181810190868411156102f457600080fd5b8286015b848110156102a957803583529183019183016102f8565b803560ff8116811461018357600080fd5b60008083601f84011261033257600080fd5b50813567ffffffffffffffff81111561034a57600080fd5b60208301915083602082850101111561036257600080fd5b9250929050565b600082601f83011261037a57600080fd5b813567ffffffffffffffff811115610394576103946101a0565b6103c560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016101cf565b8181528460208386010111156103da57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060008060008060006101408c8e03121561041957600080fd5b8b359a5060208c0135995061043060408d0161015f565b985061043e60608d01610188565b975067ffffffffffffffff8060808e0135111561045a57600080fd5b61046a8e60808f01358f01610242565b97508060a08e0135111561047d57600080fd5b61048d8e60a08f01358f016102b4565b965061049b60c08e0161030f565b95508060e08e013511156104ae57600080fd5b6104be8e60e08f01358f01610320565b90955093506104d06101008e01610188565b9250806101208e013511156104e457600080fd5b506104f68d6101208e01358e01610369565b90509295989b509295989b9093969950565b600081518084526020808501945080840160005b838110156105385781518752958201959082019060010161051c565b509495945050505050565b6000815180845260005b818110156105695760208185018101518683018201520161054d565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b8a815260208082018b905273ffffffffffffffffffffffffffffffffffffffff8a8116604084015267ffffffffffffffff8a1660608401526101406080840181905289519084018190526000926101608501928b820192855b8181101561061e578451831686529483019493830193600101610600565b505050505082810360a08401526106358189610508565b60ff881660c0850152905082810360e08401526106528187610543565b67ffffffffffffffff861661010085015290508281036101208401526106788185610543565b9d9c5050505050505050505050505056fea164736f6c6343000810000a", +} + +var LLOExposedVerifierABI = LLOExposedVerifierMetaData.ABI + +var LLOExposedVerifierBin = LLOExposedVerifierMetaData.Bin + +func DeployLLOExposedVerifier(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *LLOExposedVerifier, error) { + parsed, err := LLOExposedVerifierMetaData.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(LLOExposedVerifierBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &LLOExposedVerifier{LLOExposedVerifierCaller: LLOExposedVerifierCaller{contract: contract}, LLOExposedVerifierTransactor: LLOExposedVerifierTransactor{contract: contract}, LLOExposedVerifierFilterer: LLOExposedVerifierFilterer{contract: contract}}, nil +} + +type LLOExposedVerifier struct { + address common.Address + abi abi.ABI + LLOExposedVerifierCaller + LLOExposedVerifierTransactor + LLOExposedVerifierFilterer +} + +type LLOExposedVerifierCaller struct { + contract *bind.BoundContract +} + +type LLOExposedVerifierTransactor struct { + contract *bind.BoundContract +} + +type LLOExposedVerifierFilterer struct { + contract *bind.BoundContract +} + +type LLOExposedVerifierSession struct { + Contract *LLOExposedVerifier + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type LLOExposedVerifierCallerSession struct { + Contract *LLOExposedVerifierCaller + CallOpts bind.CallOpts +} + +type LLOExposedVerifierTransactorSession struct { + Contract *LLOExposedVerifierTransactor + TransactOpts bind.TransactOpts +} + +type LLOExposedVerifierRaw struct { + Contract *LLOExposedVerifier +} + +type LLOExposedVerifierCallerRaw struct { + Contract *LLOExposedVerifierCaller +} + +type LLOExposedVerifierTransactorRaw struct { + Contract *LLOExposedVerifierTransactor +} + +func NewLLOExposedVerifier(address common.Address, backend bind.ContractBackend) (*LLOExposedVerifier, error) { + abi, err := abi.JSON(strings.NewReader(LLOExposedVerifierABI)) + if err != nil { + return nil, err + } + contract, err := bindLLOExposedVerifier(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &LLOExposedVerifier{address: address, abi: abi, LLOExposedVerifierCaller: LLOExposedVerifierCaller{contract: contract}, LLOExposedVerifierTransactor: LLOExposedVerifierTransactor{contract: contract}, LLOExposedVerifierFilterer: LLOExposedVerifierFilterer{contract: contract}}, nil +} + +func NewLLOExposedVerifierCaller(address common.Address, caller bind.ContractCaller) (*LLOExposedVerifierCaller, error) { + contract, err := bindLLOExposedVerifier(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &LLOExposedVerifierCaller{contract: contract}, nil +} + +func NewLLOExposedVerifierTransactor(address common.Address, transactor bind.ContractTransactor) (*LLOExposedVerifierTransactor, error) { + contract, err := bindLLOExposedVerifier(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &LLOExposedVerifierTransactor{contract: contract}, nil +} + +func NewLLOExposedVerifierFilterer(address common.Address, filterer bind.ContractFilterer) (*LLOExposedVerifierFilterer, error) { + contract, err := bindLLOExposedVerifier(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &LLOExposedVerifierFilterer{contract: contract}, nil +} + +func bindLLOExposedVerifier(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := LLOExposedVerifierMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_LLOExposedVerifier *LLOExposedVerifierRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LLOExposedVerifier.Contract.LLOExposedVerifierCaller.contract.Call(opts, result, method, params...) +} + +func (_LLOExposedVerifier *LLOExposedVerifierRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LLOExposedVerifier.Contract.LLOExposedVerifierTransactor.contract.Transfer(opts) +} + +func (_LLOExposedVerifier *LLOExposedVerifierRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LLOExposedVerifier.Contract.LLOExposedVerifierTransactor.contract.Transact(opts, method, params...) +} + +func (_LLOExposedVerifier *LLOExposedVerifierCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LLOExposedVerifier.Contract.contract.Call(opts, result, method, params...) +} + +func (_LLOExposedVerifier *LLOExposedVerifierTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LLOExposedVerifier.Contract.contract.Transfer(opts) +} + +func (_LLOExposedVerifier *LLOExposedVerifierTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LLOExposedVerifier.Contract.contract.Transact(opts, method, params...) +} + +func (_LLOExposedVerifier *LLOExposedVerifierCaller) ExposedConfigDigestFromConfigData(opts *bind.CallOpts, _feedId [32]byte, _chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) { + var out []interface{} + err := _LLOExposedVerifier.contract.Call(opts, &out, "exposedConfigDigestFromConfigData", _feedId, _chainId, _contractAddress, _configCount, _signers, _offchainTransmitters, _f, _onchainConfig, _encodedConfigVersion, _encodedConfig) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_LLOExposedVerifier *LLOExposedVerifierSession) ExposedConfigDigestFromConfigData(_feedId [32]byte, _chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) { + return _LLOExposedVerifier.Contract.ExposedConfigDigestFromConfigData(&_LLOExposedVerifier.CallOpts, _feedId, _chainId, _contractAddress, _configCount, _signers, _offchainTransmitters, _f, _onchainConfig, _encodedConfigVersion, _encodedConfig) +} + +func (_LLOExposedVerifier *LLOExposedVerifierCallerSession) ExposedConfigDigestFromConfigData(_feedId [32]byte, _chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) { + return _LLOExposedVerifier.Contract.ExposedConfigDigestFromConfigData(&_LLOExposedVerifier.CallOpts, _feedId, _chainId, _contractAddress, _configCount, _signers, _offchainTransmitters, _f, _onchainConfig, _encodedConfigVersion, _encodedConfig) +} + +func (_LLOExposedVerifier *LLOExposedVerifier) Address() common.Address { + return _LLOExposedVerifier.address +} + +type LLOExposedVerifierInterface interface { + ExposedConfigDigestFromConfigData(opts *bind.CallOpts, _feedId [32]byte, _chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) + + Address() common.Address +} diff --git a/core/gethwrappers/llo-feeds/generated/reward_manager/reward_manager.go b/core/gethwrappers/llo-feeds/generated/reward_manager/reward_manager.go new file mode 100644 index 00000000000..3ea1bee3e8b --- /dev/null +++ b/core/gethwrappers/llo-feeds/generated/reward_manager/reward_manager.go @@ -0,0 +1,1344 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package reward_manager + +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 CommonAddressAndWeight struct { + Addr common.Address + Weight *big.Int +} + +var RewardManagerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"linkAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPoolId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWeights\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newFeeManagerAddress\",\"type\":\"address\"}],\"name\":\"FeeManagerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"name\":\"FeePaid\",\"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\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"newRewardRecipients\",\"type\":\"tuple[]\"}],\"name\":\"RewardRecipientsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"name\":\"RewardsClaimed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"poolIds\",\"type\":\"bytes32[]\"}],\"name\":\"claimRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"getAvailableRewardPoolIds\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"onFeePaid\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"recipients\",\"type\":\"address[]\"}],\"name\":\"payRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_feeManagerAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_registeredPoolIds\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_rewardRecipientWeights\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_totalRewardRecipientFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newFeeManagerAddress\",\"type\":\"address\"}],\"name\":\"setFeeManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"rewardRecipientAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setRewardRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"newRewardRecipients\",\"type\":\"tuple[]\"}],\"name\":\"updateRewardRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b5060405162001d5338038062001d538339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e95760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b608051611b58620001fb600039600081816109b90152610d2a0152611b586000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80636992922f11610097578063cd5f729211610066578063cd5f7292146102e0578063efb03fe9146102f3578063f2fde38b14610306578063f34517aa1461031957600080fd5b80636992922f1461026f57806379ba50971461028f5780638ac85a5c146102975780638da5cb5b146102c257600080fd5b806339ee81e1116100d357806339ee81e114610208578063472d35b9146102365780634d32208414610249578063633b5f6e1461025c57600080fd5b806301ffc9a7146101055780630f3c34d11461016f578063181f5a7714610184578063276e7660146101c3575b600080fd5b61015a6101133660046115da565b7fffffffff00000000000000000000000000000000000000000000000000000000167fefb03fe9000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b61018261017d36600461169a565b61032c565b005b604080518082018252601381527f5265776172644d616e6167657220302e302e3100000000000000000000000000602082015290516101669190611764565b6007546101e39073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610166565b6102286102163660046117b5565b60026020526000908152604090205481565b604051908152602001610166565b6101826102443660046117f7565b61033a565b610182610257366004611819565b610408565b61018261026a366004611898565b61053f565b61028261027d3660046117f7565b6106f5565b6040516101669190611904565b6101826107f1565b6102286102a5366004611948565b600460209081526000928352604080842090915290825290205481565b60005473ffffffffffffffffffffffffffffffffffffffff166101e3565b6102286102ee3660046117b5565b6108f3565b610182610301366004611974565b610914565b6101826103143660046117f7565b610a3c565b610182610327366004611898565b610a50565b6103363382610bca565b5050565b610342610d5a565b73ffffffffffffffffffffffffffffffffffffffff811661038f576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fe45f5e140399b0a7e12971ab020724b828fbed8ac408c420884dc7d1bbe506b49060200160405180910390a150565b8261042860005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415801561047a57506000818152600460209081526040808320338452909152902054155b156104b1576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160018082528183019092526000916020808301908036833701905050905084816000815181106104e7576104e76119a9565b60200260200101818152505060005b838110156105375761052e858583818110610513576105136119a9565b905060200201602081019061052891906117f7565b83610bca565b506001016104f6565b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061057f575060075473ffffffffffffffffffffffffffffffffffffffff163314155b156105b6576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008190036105f1576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526005602052604090205460ff161561063a576040517f0afa7ee800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006805460018181019092557ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01849055600084815260056020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690911790556106b6838383670de0b6b3a7640000610ddd565b827fe5ca4131deaeb848b5d6a9c0f85795efc54e8a0252eb38d3e77a1efc2b38419683836040516106e89291906119d8565b60405180910390a2505050565b60065460609060008167ffffffffffffffff8111156107165761071661161c565b60405190808252806020026020018201604052801561073f578160200160208202803683370190505b5090506000805b838110156107e757600060068281548110610763576107636119a9565b600091825260208083209091015480835260048252604080842073ffffffffffffffffffffffffffffffffffffffff8c168552909252912054909150156107de57600081815260026020526040902054156107de57808484815181106107cb576107cb6119a9565b6020026020010181815250508260010192505b50600101610746565b5090949350505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6006818154811061090357600080fd5b600091825260209091200154905081565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610954575060075473ffffffffffffffffffffffffffffffffffffffff163314155b1561098b576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526002602052604090208054820190556109e173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016833084610fd6565b6040805184815273ffffffffffffffffffffffffffffffffffffffff841660208201529081018290527f0ae7c9bfbc7dfc3426a34852f9a1cdd2f750abec8190abbff0bbe13d8118c30c9060600160405180910390a1505050565b610a44610d5a565b610a4d816110b8565b50565b610a58610d5a565b604080516001808252818301909252600091602080830190803683370190505090508381600081518110610a8e57610a8e6119a9565b6020026020010181815250506000805b83811015610b7c576000858583818110610aba57610aba6119a9565b610ad092602060409092020190810191506117f7565b600088815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152812054919250819003610b3c576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b6d878785818110610b5157610b516119a9565b610b6792602060409092020190810191506117f7565b86610bca565b50929092019150600101610a9e565b50610b8985858584610ddd565b847fe5ca4131deaeb848b5d6a9c0f85795efc54e8a0252eb38d3e77a1efc2b3841968585604051610bbb9291906119d8565b60405180910390a25050505050565b60008060005b8351811015610d09576000848281518110610bed57610bed6119a9565b6020908102919091018101516000818152600283526040808220546003855281832073ffffffffffffffffffffffffffffffffffffffff8c16808552908652828420548585526004875283852091855295529082205492945092830391670de0b6b3a76400009083020490819003610c685750505050610cf9565b600084815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8d168085529252909120849055885196820196899087908110610cb357610cb36119a9565b60200260200101517ffec539b3c42d74cd492c3ecf7966bf014b327beef98e935cdc3ec5e54a6901c783604051610cec91815260200190565b60405180910390a3505050505b610d0281611a6b565b9050610bd0565b508015610d5157610d5173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001685836111ad565b90505b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ddb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161086e565b565b610e388383808060200260200160405190810160405280939291908181526020016000905b82821015610e2e57610e1f60408302860136819003810190611aa3565b81526020019060010190610e02565b5050505050611208565b15610e6f576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b83811015610f95576000858583818110610e8f57610e8f6119a9565b9050604002016020013590506000868684818110610eaf57610eaf6119a9565b610ec592602060409092020190810191506117f7565b905073ffffffffffffffffffffffffffffffffffffffff8116610f14576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81600003610f4e576040517f84677ce800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff9094168352929052208190559190910190610f8e81611a6b565b9050610e73565b50818114610fcf576040517f84677ce800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526110b29085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526112bf565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff821603611137576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161086e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112039084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401611030565b505050565b6000805b82518110156112b6576000611222826001611afa565b90505b83518110156112ad57838181518110611240576112406119a9565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16848381518110611274576112746119a9565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036112a5575060019392505050565b600101611225565b5060010161120c565b50600092915050565b6000611321826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166113cb9092919063ffffffff16565b805190915015611203578080602001905181019061133f9190611b0d565b611203576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161086e565b60606113da84846000856113e2565b949350505050565b606082471015611474576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161086e565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161149d9190611b2f565b60006040518083038185875af1925050503d80600081146114da576040519150601f19603f3d011682016040523d82523d6000602084013e6114df565b606091505b50915091506114f0878383876114fb565b979650505050505050565b6060831561159157825160000361158a5773ffffffffffffffffffffffffffffffffffffffff85163b61158a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161086e565b50816113da565b6113da83838151156115a65781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161086e9190611764565b6000602082840312156115ec57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610d5157600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156116925761169261161c565b604052919050565b600060208083850312156116ad57600080fd5b823567ffffffffffffffff808211156116c557600080fd5b818501915085601f8301126116d957600080fd5b8135818111156116eb576116eb61161c565b8060051b91506116fc84830161164b565b818152918301840191848101908884111561171657600080fd5b938501935b838510156117345784358252938501939085019061171b565b98975050505050505050565b60005b8381101561175b578181015183820152602001611743565b50506000910152565b6020815260008251806020840152611783816040850160208701611740565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000602082840312156117c757600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff811681146117f257600080fd5b919050565b60006020828403121561180957600080fd5b611812826117ce565b9392505050565b60008060006040848603121561182e57600080fd5b83359250602084013567ffffffffffffffff8082111561184d57600080fd5b818601915086601f83011261186157600080fd5b81358181111561187057600080fd5b8760208260051b850101111561188557600080fd5b6020830194508093505050509250925092565b6000806000604084860312156118ad57600080fd5b83359250602084013567ffffffffffffffff808211156118cc57600080fd5b818601915086601f8301126118e057600080fd5b8135818111156118ef57600080fd5b8760208260061b850101111561188557600080fd5b6020808252825182820181905260009190848201906040850190845b8181101561193c57835183529284019291840191600101611920565b50909695505050505050565b6000806040838503121561195b57600080fd5b8235915061196b602084016117ce565b90509250929050565b60008060006060848603121561198957600080fd5b83359250611999602085016117ce565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020808252818101839052600090604080840186845b87811015611a2f5773ffffffffffffffffffffffffffffffffffffffff611a14836117ce565b168352818501358584015291830191908301906001016119ee565b5090979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611a9c57611a9c611a3c565b5060010190565b600060408284031215611ab557600080fd5b6040516040810181811067ffffffffffffffff82111715611ad857611ad861161c565b604052611ae4836117ce565b8152602083013560208201528091505092915050565b80820180821115610d5457610d54611a3c565b600060208284031215611b1f57600080fd5b81518015158114610d5157600080fd5b60008251611b41818460208701611740565b919091019291505056fea164736f6c6343000810000a", +} + +var RewardManagerABI = RewardManagerMetaData.ABI + +var RewardManagerBin = RewardManagerMetaData.Bin + +func DeployRewardManager(auth *bind.TransactOpts, backend bind.ContractBackend, linkAddress common.Address) (common.Address, *types.Transaction, *RewardManager, error) { + parsed, err := RewardManagerMetaData.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(RewardManagerBin), backend, linkAddress) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &RewardManager{RewardManagerCaller: RewardManagerCaller{contract: contract}, RewardManagerTransactor: RewardManagerTransactor{contract: contract}, RewardManagerFilterer: RewardManagerFilterer{contract: contract}}, nil +} + +type RewardManager struct { + address common.Address + abi abi.ABI + RewardManagerCaller + RewardManagerTransactor + RewardManagerFilterer +} + +type RewardManagerCaller struct { + contract *bind.BoundContract +} + +type RewardManagerTransactor struct { + contract *bind.BoundContract +} + +type RewardManagerFilterer struct { + contract *bind.BoundContract +} + +type RewardManagerSession struct { + Contract *RewardManager + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type RewardManagerCallerSession struct { + Contract *RewardManagerCaller + CallOpts bind.CallOpts +} + +type RewardManagerTransactorSession struct { + Contract *RewardManagerTransactor + TransactOpts bind.TransactOpts +} + +type RewardManagerRaw struct { + Contract *RewardManager +} + +type RewardManagerCallerRaw struct { + Contract *RewardManagerCaller +} + +type RewardManagerTransactorRaw struct { + Contract *RewardManagerTransactor +} + +func NewRewardManager(address common.Address, backend bind.ContractBackend) (*RewardManager, error) { + abi, err := abi.JSON(strings.NewReader(RewardManagerABI)) + if err != nil { + return nil, err + } + contract, err := bindRewardManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &RewardManager{address: address, abi: abi, RewardManagerCaller: RewardManagerCaller{contract: contract}, RewardManagerTransactor: RewardManagerTransactor{contract: contract}, RewardManagerFilterer: RewardManagerFilterer{contract: contract}}, nil +} + +func NewRewardManagerCaller(address common.Address, caller bind.ContractCaller) (*RewardManagerCaller, error) { + contract, err := bindRewardManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &RewardManagerCaller{contract: contract}, nil +} + +func NewRewardManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*RewardManagerTransactor, error) { + contract, err := bindRewardManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &RewardManagerTransactor{contract: contract}, nil +} + +func NewRewardManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*RewardManagerFilterer, error) { + contract, err := bindRewardManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &RewardManagerFilterer{contract: contract}, nil +} + +func bindRewardManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := RewardManagerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_RewardManager *RewardManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _RewardManager.Contract.RewardManagerCaller.contract.Call(opts, result, method, params...) +} + +func (_RewardManager *RewardManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RewardManager.Contract.RewardManagerTransactor.contract.Transfer(opts) +} + +func (_RewardManager *RewardManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _RewardManager.Contract.RewardManagerTransactor.contract.Transact(opts, method, params...) +} + +func (_RewardManager *RewardManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _RewardManager.Contract.contract.Call(opts, result, method, params...) +} + +func (_RewardManager *RewardManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RewardManager.Contract.contract.Transfer(opts) +} + +func (_RewardManager *RewardManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _RewardManager.Contract.contract.Transact(opts, method, params...) +} + +func (_RewardManager *RewardManagerCaller) GetAvailableRewardPoolIds(opts *bind.CallOpts, recipient common.Address) ([][32]byte, error) { + var out []interface{} + err := _RewardManager.contract.Call(opts, &out, "getAvailableRewardPoolIds", recipient) + + if err != nil { + return *new([][32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([][32]byte)).(*[][32]byte) + + return out0, err + +} + +func (_RewardManager *RewardManagerSession) GetAvailableRewardPoolIds(recipient common.Address) ([][32]byte, error) { + return _RewardManager.Contract.GetAvailableRewardPoolIds(&_RewardManager.CallOpts, recipient) +} + +func (_RewardManager *RewardManagerCallerSession) GetAvailableRewardPoolIds(recipient common.Address) ([][32]byte, error) { + return _RewardManager.Contract.GetAvailableRewardPoolIds(&_RewardManager.CallOpts, recipient) +} + +func (_RewardManager *RewardManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _RewardManager.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 (_RewardManager *RewardManagerSession) Owner() (common.Address, error) { + return _RewardManager.Contract.Owner(&_RewardManager.CallOpts) +} + +func (_RewardManager *RewardManagerCallerSession) Owner() (common.Address, error) { + return _RewardManager.Contract.Owner(&_RewardManager.CallOpts) +} + +func (_RewardManager *RewardManagerCaller) SFeeManagerAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _RewardManager.contract.Call(opts, &out, "s_feeManagerAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_RewardManager *RewardManagerSession) SFeeManagerAddress() (common.Address, error) { + return _RewardManager.Contract.SFeeManagerAddress(&_RewardManager.CallOpts) +} + +func (_RewardManager *RewardManagerCallerSession) SFeeManagerAddress() (common.Address, error) { + return _RewardManager.Contract.SFeeManagerAddress(&_RewardManager.CallOpts) +} + +func (_RewardManager *RewardManagerCaller) SRegisteredPoolIds(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { + var out []interface{} + err := _RewardManager.contract.Call(opts, &out, "s_registeredPoolIds", arg0) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_RewardManager *RewardManagerSession) SRegisteredPoolIds(arg0 *big.Int) ([32]byte, error) { + return _RewardManager.Contract.SRegisteredPoolIds(&_RewardManager.CallOpts, arg0) +} + +func (_RewardManager *RewardManagerCallerSession) SRegisteredPoolIds(arg0 *big.Int) ([32]byte, error) { + return _RewardManager.Contract.SRegisteredPoolIds(&_RewardManager.CallOpts, arg0) +} + +func (_RewardManager *RewardManagerCaller) SRewardRecipientWeights(opts *bind.CallOpts, arg0 [32]byte, arg1 common.Address) (*big.Int, error) { + var out []interface{} + err := _RewardManager.contract.Call(opts, &out, "s_rewardRecipientWeights", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_RewardManager *RewardManagerSession) SRewardRecipientWeights(arg0 [32]byte, arg1 common.Address) (*big.Int, error) { + return _RewardManager.Contract.SRewardRecipientWeights(&_RewardManager.CallOpts, arg0, arg1) +} + +func (_RewardManager *RewardManagerCallerSession) SRewardRecipientWeights(arg0 [32]byte, arg1 common.Address) (*big.Int, error) { + return _RewardManager.Contract.SRewardRecipientWeights(&_RewardManager.CallOpts, arg0, arg1) +} + +func (_RewardManager *RewardManagerCaller) STotalRewardRecipientFees(opts *bind.CallOpts, arg0 [32]byte) (*big.Int, error) { + var out []interface{} + err := _RewardManager.contract.Call(opts, &out, "s_totalRewardRecipientFees", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_RewardManager *RewardManagerSession) STotalRewardRecipientFees(arg0 [32]byte) (*big.Int, error) { + return _RewardManager.Contract.STotalRewardRecipientFees(&_RewardManager.CallOpts, arg0) +} + +func (_RewardManager *RewardManagerCallerSession) STotalRewardRecipientFees(arg0 [32]byte) (*big.Int, error) { + return _RewardManager.Contract.STotalRewardRecipientFees(&_RewardManager.CallOpts, arg0) +} + +func (_RewardManager *RewardManagerCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _RewardManager.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_RewardManager *RewardManagerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _RewardManager.Contract.SupportsInterface(&_RewardManager.CallOpts, interfaceId) +} + +func (_RewardManager *RewardManagerCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _RewardManager.Contract.SupportsInterface(&_RewardManager.CallOpts, interfaceId) +} + +func (_RewardManager *RewardManagerCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _RewardManager.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_RewardManager *RewardManagerSession) TypeAndVersion() (string, error) { + return _RewardManager.Contract.TypeAndVersion(&_RewardManager.CallOpts) +} + +func (_RewardManager *RewardManagerCallerSession) TypeAndVersion() (string, error) { + return _RewardManager.Contract.TypeAndVersion(&_RewardManager.CallOpts) +} + +func (_RewardManager *RewardManagerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RewardManager.contract.Transact(opts, "acceptOwnership") +} + +func (_RewardManager *RewardManagerSession) AcceptOwnership() (*types.Transaction, error) { + return _RewardManager.Contract.AcceptOwnership(&_RewardManager.TransactOpts) +} + +func (_RewardManager *RewardManagerTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _RewardManager.Contract.AcceptOwnership(&_RewardManager.TransactOpts) +} + +func (_RewardManager *RewardManagerTransactor) ClaimRewards(opts *bind.TransactOpts, poolIds [][32]byte) (*types.Transaction, error) { + return _RewardManager.contract.Transact(opts, "claimRewards", poolIds) +} + +func (_RewardManager *RewardManagerSession) ClaimRewards(poolIds [][32]byte) (*types.Transaction, error) { + return _RewardManager.Contract.ClaimRewards(&_RewardManager.TransactOpts, poolIds) +} + +func (_RewardManager *RewardManagerTransactorSession) ClaimRewards(poolIds [][32]byte) (*types.Transaction, error) { + return _RewardManager.Contract.ClaimRewards(&_RewardManager.TransactOpts, poolIds) +} + +func (_RewardManager *RewardManagerTransactor) OnFeePaid(opts *bind.TransactOpts, poolId [32]byte, payee common.Address, amount *big.Int) (*types.Transaction, error) { + return _RewardManager.contract.Transact(opts, "onFeePaid", poolId, payee, amount) +} + +func (_RewardManager *RewardManagerSession) OnFeePaid(poolId [32]byte, payee common.Address, amount *big.Int) (*types.Transaction, error) { + return _RewardManager.Contract.OnFeePaid(&_RewardManager.TransactOpts, poolId, payee, amount) +} + +func (_RewardManager *RewardManagerTransactorSession) OnFeePaid(poolId [32]byte, payee common.Address, amount *big.Int) (*types.Transaction, error) { + return _RewardManager.Contract.OnFeePaid(&_RewardManager.TransactOpts, poolId, payee, amount) +} + +func (_RewardManager *RewardManagerTransactor) PayRecipients(opts *bind.TransactOpts, poolId [32]byte, recipients []common.Address) (*types.Transaction, error) { + return _RewardManager.contract.Transact(opts, "payRecipients", poolId, recipients) +} + +func (_RewardManager *RewardManagerSession) PayRecipients(poolId [32]byte, recipients []common.Address) (*types.Transaction, error) { + return _RewardManager.Contract.PayRecipients(&_RewardManager.TransactOpts, poolId, recipients) +} + +func (_RewardManager *RewardManagerTransactorSession) PayRecipients(poolId [32]byte, recipients []common.Address) (*types.Transaction, error) { + return _RewardManager.Contract.PayRecipients(&_RewardManager.TransactOpts, poolId, recipients) +} + +func (_RewardManager *RewardManagerTransactor) SetFeeManager(opts *bind.TransactOpts, newFeeManagerAddress common.Address) (*types.Transaction, error) { + return _RewardManager.contract.Transact(opts, "setFeeManager", newFeeManagerAddress) +} + +func (_RewardManager *RewardManagerSession) SetFeeManager(newFeeManagerAddress common.Address) (*types.Transaction, error) { + return _RewardManager.Contract.SetFeeManager(&_RewardManager.TransactOpts, newFeeManagerAddress) +} + +func (_RewardManager *RewardManagerTransactorSession) SetFeeManager(newFeeManagerAddress common.Address) (*types.Transaction, error) { + return _RewardManager.Contract.SetFeeManager(&_RewardManager.TransactOpts, newFeeManagerAddress) +} + +func (_RewardManager *RewardManagerTransactor) SetRewardRecipients(opts *bind.TransactOpts, poolId [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _RewardManager.contract.Transact(opts, "setRewardRecipients", poolId, rewardRecipientAndWeights) +} + +func (_RewardManager *RewardManagerSession) SetRewardRecipients(poolId [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _RewardManager.Contract.SetRewardRecipients(&_RewardManager.TransactOpts, poolId, rewardRecipientAndWeights) +} + +func (_RewardManager *RewardManagerTransactorSession) SetRewardRecipients(poolId [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _RewardManager.Contract.SetRewardRecipients(&_RewardManager.TransactOpts, poolId, rewardRecipientAndWeights) +} + +func (_RewardManager *RewardManagerTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _RewardManager.contract.Transact(opts, "transferOwnership", to) +} + +func (_RewardManager *RewardManagerSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _RewardManager.Contract.TransferOwnership(&_RewardManager.TransactOpts, to) +} + +func (_RewardManager *RewardManagerTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _RewardManager.Contract.TransferOwnership(&_RewardManager.TransactOpts, to) +} + +func (_RewardManager *RewardManagerTransactor) UpdateRewardRecipients(opts *bind.TransactOpts, poolId [32]byte, newRewardRecipients []CommonAddressAndWeight) (*types.Transaction, error) { + return _RewardManager.contract.Transact(opts, "updateRewardRecipients", poolId, newRewardRecipients) +} + +func (_RewardManager *RewardManagerSession) UpdateRewardRecipients(poolId [32]byte, newRewardRecipients []CommonAddressAndWeight) (*types.Transaction, error) { + return _RewardManager.Contract.UpdateRewardRecipients(&_RewardManager.TransactOpts, poolId, newRewardRecipients) +} + +func (_RewardManager *RewardManagerTransactorSession) UpdateRewardRecipients(poolId [32]byte, newRewardRecipients []CommonAddressAndWeight) (*types.Transaction, error) { + return _RewardManager.Contract.UpdateRewardRecipients(&_RewardManager.TransactOpts, poolId, newRewardRecipients) +} + +type RewardManagerFeeManagerUpdatedIterator struct { + Event *RewardManagerFeeManagerUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RewardManagerFeeManagerUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RewardManagerFeeManagerUpdated) + 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(RewardManagerFeeManagerUpdated) + 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 *RewardManagerFeeManagerUpdatedIterator) Error() error { + return it.fail +} + +func (it *RewardManagerFeeManagerUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RewardManagerFeeManagerUpdated struct { + NewFeeManagerAddress common.Address + Raw types.Log +} + +func (_RewardManager *RewardManagerFilterer) FilterFeeManagerUpdated(opts *bind.FilterOpts) (*RewardManagerFeeManagerUpdatedIterator, error) { + + logs, sub, err := _RewardManager.contract.FilterLogs(opts, "FeeManagerUpdated") + if err != nil { + return nil, err + } + return &RewardManagerFeeManagerUpdatedIterator{contract: _RewardManager.contract, event: "FeeManagerUpdated", logs: logs, sub: sub}, nil +} + +func (_RewardManager *RewardManagerFilterer) WatchFeeManagerUpdated(opts *bind.WatchOpts, sink chan<- *RewardManagerFeeManagerUpdated) (event.Subscription, error) { + + logs, sub, err := _RewardManager.contract.WatchLogs(opts, "FeeManagerUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(RewardManagerFeeManagerUpdated) + if err := _RewardManager.contract.UnpackLog(event, "FeeManagerUpdated", 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 (_RewardManager *RewardManagerFilterer) ParseFeeManagerUpdated(log types.Log) (*RewardManagerFeeManagerUpdated, error) { + event := new(RewardManagerFeeManagerUpdated) + if err := _RewardManager.contract.UnpackLog(event, "FeeManagerUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type RewardManagerFeePaidIterator struct { + Event *RewardManagerFeePaid + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RewardManagerFeePaidIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RewardManagerFeePaid) + 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(RewardManagerFeePaid) + 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 *RewardManagerFeePaidIterator) Error() error { + return it.fail +} + +func (it *RewardManagerFeePaidIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RewardManagerFeePaid struct { + PoolId [32]byte + Payee common.Address + Quantity *big.Int + Raw types.Log +} + +func (_RewardManager *RewardManagerFilterer) FilterFeePaid(opts *bind.FilterOpts) (*RewardManagerFeePaidIterator, error) { + + logs, sub, err := _RewardManager.contract.FilterLogs(opts, "FeePaid") + if err != nil { + return nil, err + } + return &RewardManagerFeePaidIterator{contract: _RewardManager.contract, event: "FeePaid", logs: logs, sub: sub}, nil +} + +func (_RewardManager *RewardManagerFilterer) WatchFeePaid(opts *bind.WatchOpts, sink chan<- *RewardManagerFeePaid) (event.Subscription, error) { + + logs, sub, err := _RewardManager.contract.WatchLogs(opts, "FeePaid") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(RewardManagerFeePaid) + if err := _RewardManager.contract.UnpackLog(event, "FeePaid", 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 (_RewardManager *RewardManagerFilterer) ParseFeePaid(log types.Log) (*RewardManagerFeePaid, error) { + event := new(RewardManagerFeePaid) + if err := _RewardManager.contract.UnpackLog(event, "FeePaid", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type RewardManagerOwnershipTransferRequestedIterator struct { + Event *RewardManagerOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RewardManagerOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RewardManagerOwnershipTransferRequested) + 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(RewardManagerOwnershipTransferRequested) + 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 *RewardManagerOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *RewardManagerOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RewardManagerOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_RewardManager *RewardManagerFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RewardManagerOwnershipTransferRequestedIterator, 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 := _RewardManager.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &RewardManagerOwnershipTransferRequestedIterator{contract: _RewardManager.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_RewardManager *RewardManagerFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *RewardManagerOwnershipTransferRequested, 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 := _RewardManager.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(RewardManagerOwnershipTransferRequested) + if err := _RewardManager.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 (_RewardManager *RewardManagerFilterer) ParseOwnershipTransferRequested(log types.Log) (*RewardManagerOwnershipTransferRequested, error) { + event := new(RewardManagerOwnershipTransferRequested) + if err := _RewardManager.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type RewardManagerOwnershipTransferredIterator struct { + Event *RewardManagerOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RewardManagerOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RewardManagerOwnershipTransferred) + 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(RewardManagerOwnershipTransferred) + 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 *RewardManagerOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *RewardManagerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RewardManagerOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_RewardManager *RewardManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RewardManagerOwnershipTransferredIterator, 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 := _RewardManager.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &RewardManagerOwnershipTransferredIterator{contract: _RewardManager.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_RewardManager *RewardManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *RewardManagerOwnershipTransferred, 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 := _RewardManager.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(RewardManagerOwnershipTransferred) + if err := _RewardManager.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 (_RewardManager *RewardManagerFilterer) ParseOwnershipTransferred(log types.Log) (*RewardManagerOwnershipTransferred, error) { + event := new(RewardManagerOwnershipTransferred) + if err := _RewardManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type RewardManagerRewardRecipientsUpdatedIterator struct { + Event *RewardManagerRewardRecipientsUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RewardManagerRewardRecipientsUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RewardManagerRewardRecipientsUpdated) + 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(RewardManagerRewardRecipientsUpdated) + 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 *RewardManagerRewardRecipientsUpdatedIterator) Error() error { + return it.fail +} + +func (it *RewardManagerRewardRecipientsUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RewardManagerRewardRecipientsUpdated struct { + PoolId [32]byte + NewRewardRecipients []CommonAddressAndWeight + Raw types.Log +} + +func (_RewardManager *RewardManagerFilterer) FilterRewardRecipientsUpdated(opts *bind.FilterOpts, poolId [][32]byte) (*RewardManagerRewardRecipientsUpdatedIterator, error) { + + var poolIdRule []interface{} + for _, poolIdItem := range poolId { + poolIdRule = append(poolIdRule, poolIdItem) + } + + logs, sub, err := _RewardManager.contract.FilterLogs(opts, "RewardRecipientsUpdated", poolIdRule) + if err != nil { + return nil, err + } + return &RewardManagerRewardRecipientsUpdatedIterator{contract: _RewardManager.contract, event: "RewardRecipientsUpdated", logs: logs, sub: sub}, nil +} + +func (_RewardManager *RewardManagerFilterer) WatchRewardRecipientsUpdated(opts *bind.WatchOpts, sink chan<- *RewardManagerRewardRecipientsUpdated, poolId [][32]byte) (event.Subscription, error) { + + var poolIdRule []interface{} + for _, poolIdItem := range poolId { + poolIdRule = append(poolIdRule, poolIdItem) + } + + logs, sub, err := _RewardManager.contract.WatchLogs(opts, "RewardRecipientsUpdated", poolIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(RewardManagerRewardRecipientsUpdated) + if err := _RewardManager.contract.UnpackLog(event, "RewardRecipientsUpdated", 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 (_RewardManager *RewardManagerFilterer) ParseRewardRecipientsUpdated(log types.Log) (*RewardManagerRewardRecipientsUpdated, error) { + event := new(RewardManagerRewardRecipientsUpdated) + if err := _RewardManager.contract.UnpackLog(event, "RewardRecipientsUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type RewardManagerRewardsClaimedIterator struct { + Event *RewardManagerRewardsClaimed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RewardManagerRewardsClaimedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RewardManagerRewardsClaimed) + 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(RewardManagerRewardsClaimed) + 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 *RewardManagerRewardsClaimedIterator) Error() error { + return it.fail +} + +func (it *RewardManagerRewardsClaimedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RewardManagerRewardsClaimed struct { + PoolId [32]byte + Recipient common.Address + Quantity *big.Int + Raw types.Log +} + +func (_RewardManager *RewardManagerFilterer) FilterRewardsClaimed(opts *bind.FilterOpts, poolId [][32]byte, recipient []common.Address) (*RewardManagerRewardsClaimedIterator, error) { + + var poolIdRule []interface{} + for _, poolIdItem := range poolId { + poolIdRule = append(poolIdRule, poolIdItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _RewardManager.contract.FilterLogs(opts, "RewardsClaimed", poolIdRule, recipientRule) + if err != nil { + return nil, err + } + return &RewardManagerRewardsClaimedIterator{contract: _RewardManager.contract, event: "RewardsClaimed", logs: logs, sub: sub}, nil +} + +func (_RewardManager *RewardManagerFilterer) WatchRewardsClaimed(opts *bind.WatchOpts, sink chan<- *RewardManagerRewardsClaimed, poolId [][32]byte, recipient []common.Address) (event.Subscription, error) { + + var poolIdRule []interface{} + for _, poolIdItem := range poolId { + poolIdRule = append(poolIdRule, poolIdItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _RewardManager.contract.WatchLogs(opts, "RewardsClaimed", poolIdRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(RewardManagerRewardsClaimed) + if err := _RewardManager.contract.UnpackLog(event, "RewardsClaimed", 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 (_RewardManager *RewardManagerFilterer) ParseRewardsClaimed(log types.Log) (*RewardManagerRewardsClaimed, error) { + event := new(RewardManagerRewardsClaimed) + if err := _RewardManager.contract.UnpackLog(event, "RewardsClaimed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_RewardManager *RewardManager) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _RewardManager.abi.Events["FeeManagerUpdated"].ID: + return _RewardManager.ParseFeeManagerUpdated(log) + case _RewardManager.abi.Events["FeePaid"].ID: + return _RewardManager.ParseFeePaid(log) + case _RewardManager.abi.Events["OwnershipTransferRequested"].ID: + return _RewardManager.ParseOwnershipTransferRequested(log) + case _RewardManager.abi.Events["OwnershipTransferred"].ID: + return _RewardManager.ParseOwnershipTransferred(log) + case _RewardManager.abi.Events["RewardRecipientsUpdated"].ID: + return _RewardManager.ParseRewardRecipientsUpdated(log) + case _RewardManager.abi.Events["RewardsClaimed"].ID: + return _RewardManager.ParseRewardsClaimed(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (RewardManagerFeeManagerUpdated) Topic() common.Hash { + return common.HexToHash("0xe45f5e140399b0a7e12971ab020724b828fbed8ac408c420884dc7d1bbe506b4") +} + +func (RewardManagerFeePaid) Topic() common.Hash { + return common.HexToHash("0x0ae7c9bfbc7dfc3426a34852f9a1cdd2f750abec8190abbff0bbe13d8118c30c") +} + +func (RewardManagerOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (RewardManagerOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (RewardManagerRewardRecipientsUpdated) Topic() common.Hash { + return common.HexToHash("0xe5ca4131deaeb848b5d6a9c0f85795efc54e8a0252eb38d3e77a1efc2b384196") +} + +func (RewardManagerRewardsClaimed) Topic() common.Hash { + return common.HexToHash("0xfec539b3c42d74cd492c3ecf7966bf014b327beef98e935cdc3ec5e54a6901c7") +} + +func (_RewardManager *RewardManager) Address() common.Address { + return _RewardManager.address +} + +type RewardManagerInterface interface { + GetAvailableRewardPoolIds(opts *bind.CallOpts, recipient common.Address) ([][32]byte, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SFeeManagerAddress(opts *bind.CallOpts) (common.Address, error) + + SRegisteredPoolIds(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) + + SRewardRecipientWeights(opts *bind.CallOpts, arg0 [32]byte, arg1 common.Address) (*big.Int, error) + + STotalRewardRecipientFees(opts *bind.CallOpts, arg0 [32]byte) (*big.Int, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ClaimRewards(opts *bind.TransactOpts, poolIds [][32]byte) (*types.Transaction, error) + + OnFeePaid(opts *bind.TransactOpts, poolId [32]byte, payee common.Address, amount *big.Int) (*types.Transaction, error) + + PayRecipients(opts *bind.TransactOpts, poolId [32]byte, recipients []common.Address) (*types.Transaction, error) + + SetFeeManager(opts *bind.TransactOpts, newFeeManagerAddress common.Address) (*types.Transaction, error) + + SetRewardRecipients(opts *bind.TransactOpts, poolId [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + UpdateRewardRecipients(opts *bind.TransactOpts, poolId [32]byte, newRewardRecipients []CommonAddressAndWeight) (*types.Transaction, error) + + FilterFeeManagerUpdated(opts *bind.FilterOpts) (*RewardManagerFeeManagerUpdatedIterator, error) + + WatchFeeManagerUpdated(opts *bind.WatchOpts, sink chan<- *RewardManagerFeeManagerUpdated) (event.Subscription, error) + + ParseFeeManagerUpdated(log types.Log) (*RewardManagerFeeManagerUpdated, error) + + FilterFeePaid(opts *bind.FilterOpts) (*RewardManagerFeePaidIterator, error) + + WatchFeePaid(opts *bind.WatchOpts, sink chan<- *RewardManagerFeePaid) (event.Subscription, error) + + ParseFeePaid(log types.Log) (*RewardManagerFeePaid, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RewardManagerOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *RewardManagerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*RewardManagerOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RewardManagerOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *RewardManagerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*RewardManagerOwnershipTransferred, error) + + FilterRewardRecipientsUpdated(opts *bind.FilterOpts, poolId [][32]byte) (*RewardManagerRewardRecipientsUpdatedIterator, error) + + WatchRewardRecipientsUpdated(opts *bind.WatchOpts, sink chan<- *RewardManagerRewardRecipientsUpdated, poolId [][32]byte) (event.Subscription, error) + + ParseRewardRecipientsUpdated(log types.Log) (*RewardManagerRewardRecipientsUpdated, error) + + FilterRewardsClaimed(opts *bind.FilterOpts, poolId [][32]byte, recipient []common.Address) (*RewardManagerRewardsClaimedIterator, error) + + WatchRewardsClaimed(opts *bind.WatchOpts, sink chan<- *RewardManagerRewardsClaimed, poolId [][32]byte, recipient []common.Address) (event.Subscription, error) + + ParseRewardsClaimed(log types.Log) (*RewardManagerRewardsClaimed, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/llo-feeds/generated/verifier/verifier.go b/core/gethwrappers/llo-feeds/generated/verifier/verifier.go new file mode 100644 index 00000000000..7830951f646 --- /dev/null +++ b/core/gethwrappers/llo-feeds/generated/verifier/verifier.go @@ -0,0 +1,1616 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package verifier + +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 CommonAddressAndWeight struct { + Addr common.Address + Weight *big.Int +} + +var VerifierMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierProxyAddr\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadVerification\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"CannotDeactivateLatestConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DigestEmpty\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"DigestInactive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"DigestNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSigners\",\"type\":\"uint256\"}],\"name\":\"ExcessSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FaultToleranceMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FeedIdEmpty\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"InactiveFeed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expectedNumSigners\",\"type\":\"uint256\"}],\"name\":\"IncorrectSignatureCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minSigners\",\"type\":\"uint256\"}],\"name\":\"InsufficientSigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"rsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ssLength\",\"type\":\"uint256\"}],\"name\":\"MismatchedSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigDeactivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"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\":\"bytes32[]\",\"name\":\"offchainTransmitters\",\"type\":\"bytes32[]\"},{\"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\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"FeedActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"FeedDeactivated\",\"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\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"name\":\"ReportVerified\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"activateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"activateFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"deactivateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"deactivateFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"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\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"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\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"offchainTransmitters\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"recipientAddressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"sourceChainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sourceAddress\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"offchainTransmitters\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"recipientAddressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setConfigFromSource\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isVerifier\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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\":\"bytes\",\"name\":\"signedReport\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b5060405162002362380380620023628339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e95760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b608051612167620001fb6000396000818161033b01526112cf01526121676000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80638da5cb5b1161008c578063b70d929d11610066578063b70d929d1461023f578063ded6307c1461029e578063e84f128e146102b1578063f2fde38b1461030e57600080fd5b80638da5cb5b146101f157806394d95980146102195780639b103f131461022c57600080fd5b80633dd86430116100c85780633dd86430146101ae57806352ba27d6146101c3578063564a0a7a146101d657806379ba5097146101e957600080fd5b806301ffc9a7146100ef578063181f5a77146101595780633d3ac1b51461019b575b600080fd5b6101446100fd366004611580565b7fffffffff00000000000000000000000000000000000000000000000000000000167f3d3ac1b5000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b60408051808201909152600e81527f566572696669657220312e312e3000000000000000000000000000000000000060208201525b604051610150919061162d565b61018e6101a9366004611669565b610321565b6101c16101bc3660046116ea565b6104bb565b005b6101c16101d13660046119fb565b61056d565b6101c16101e43660046116ea565b61067b565b6101c161073c565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610150565b6101c1610227366004611af8565b610839565b6101c161023a366004611b1a565b61099a565b61027b61024d3660046116ea565b6000908152600260205260408120600181015490549192909168010000000000000000900463ffffffff1690565b604080519315158452602084019290925263ffffffff1690820152606001610150565b6101c16102ac366004611af8565b610a64565b6102eb6102bf3660046116ea565b6000908152600260205260409020805460019091015463ffffffff808316936401000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610150565b6101c161031c366004611c33565b610b75565b60603373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610392576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808080806103a4888a018a611c4e565b945094509450945094506000846103ba90611d29565b60008181526002602052604090208054919250906c01000000000000000000000000900460ff1615610420576040517f36dbe748000000000000000000000000000000000000000000000000000000008152600481018390526024015b60405180910390fd5b86516000818152600283016020526040902061043f8483898985610b89565b6104498984610c85565b8751602089012061045e818b8a8a8a87610ced565b60405173ffffffffffffffffffffffffffffffffffffffff8d16815285907f58ca9502e98a536e06e72d680fcc251e5d10b72291a281665a2c2dc0ac30fcc59060200160405180910390a250969c9b505050505050505050505050565b6104c3610f69565b60008181526002602052604081208054909163ffffffff9091169003610518576040517fa25b0b9600000000000000000000000000000000000000000000000000000000815260048101839052602401610417565b80547fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff16815560405182907ff438564f793525caa89c6e3a26d41e16aa39d1e589747595751e3f3df75cb2b490600090a25050565b86518560ff16806000036105ad576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f8211156105f2576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f6024820152604401610417565b6105fd816003611dcc565b8211610655578161060f826003611dcc565b61061a906001611e09565b6040517f9dd9e6d800000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401610417565b61065d610f69565b61066f8a46308c8c8c8c8c8c8c610fec565b50505050505050505050565b610683610f69565b60008181526002602052604081208054909163ffffffff90911690036106d8576040517fa25b0b9600000000000000000000000000000000000000000000000000000000815260048101839052602401610417565b80547fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff166c0100000000000000000000000017815560405182907ffc4f79b8c65b6be1773063461984c0974400d1e99654c79477a092ace83fd06190600090a25050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146107bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610417565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610841610f69565b600082815260026020526040902081610886576040517fe332262700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260028201602052604081205460ff1690036108dc576040517f8bca63110000000000000000000000000000000000000000000000000000000081526004810184905260248101839052604401610417565b80600101548203610923576040517fa403c0160000000000000000000000000000000000000000000000000000000081526004810184905260248101839052604401610417565b60008281526002820160205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555183907f0e173bea63a8c59ec70bf87043f2a729693790183f16a1a54b705de9e989cc4c9061098d9085815260200190565b60405180910390a2505050565b86518560ff16806000036109da576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f821115610a1f576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f6024820152604401610417565b610a2a816003611dcc565b8211610a3c578161060f826003611dcc565b610a44610f69565b610a568c8c8c8c8c8c8c8c8c8c610fec565b505050505050505050505050565b610a6c610f69565b600082815260026020526040902081610ab1576040517fe332262700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260028201602052604081205460ff169003610b07576040517f8bca63110000000000000000000000000000000000000000000000000000000081526004810184905260248101839052604401610417565b60008281526002820160205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555183907f54f8872b9b94ebea6577f33576d55847bd8ea22641ccc886b965f6e50bfe77469061098d9085815260200190565b610b7d610f69565b610b86816113dd565b50565b8054600090610b9c9060ff166001611e22565b8254909150610100900460ff16610be9576040517ffc10a2830000000000000000000000000000000000000000000000000000000081526004810187905260248101869052604401610417565b8060ff16845114610c355783516040517f5348a282000000000000000000000000000000000000000000000000000000008152600481019190915260ff82166024820152604401610417565b8251845114610c7d57835183516040517ff0d3140800000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401610417565b505050505050565b6020820151815463ffffffff600883901c81169168010000000000000000900416811115610ce75782547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff166801000000000000000063ffffffff8316021783555b50505050565b60008686604051602001610d02929190611e3b565b6040516020818303038152906040528051906020012090506000610d36604080518082019091526000808252602082015290565b8651600090815b81811015610f0157600186898360208110610d5a57610d5a611d6e565b610d6791901a601b611e22565b8c8481518110610d7957610d79611d6e565b60200260200101518c8581518110610d9357610d93611d6e565b602002602001015160405160008152602001604052604051610dd1949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015610df3573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526001808d01602090815291859020848601909552845460ff808216865293995093955090850192610100900490911690811115610e7857610e78611e77565b6001811115610e8957610e89611e77565b9052509350600184602001516001811115610ea657610ea6611e77565b14610edd576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836000015160080260ff166001901b8501945080610efa90611ea6565b9050610d3d565b50837e01010101010101010101010101010101010101010101010101010101010101851614610f5c576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610fea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610417565b565b60008a81526002602052604081208054909163ffffffff90911690829061101283611ede565b82546101009290920a63ffffffff81810219909316918316021790915582546000925061104b918e918e918e91168d8d8d8d8d8d6114d2565b6000818152600284016020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8b16176101001790559091505b89518160ff16101561128c5760008a8260ff16815181106110b1576110b1611d6e565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611121576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000858152600287016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452600190810190925290912054610100900460ff169081111561117457611174611e77565b14801591506111af576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff8416815260208101600190526000858152600287016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684526001908101835292208351815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00821681178355928501519193919284927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216179061010090849081111561127157611271611e77565b021790555090505050508061128590611f01565b905061108e565b5060018201546040517f589ede2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169163589ede2891611307919085908890600401611f20565b600060405180830381600087803b15801561132157600080fd5b505af1158015611335573d6000803e3d6000fd5b505083546040518f93507fa23a88453230b183877098801ff5a8f771a120e2573eea559ce6c4c2e305a4da925061138e9163ffffffff6401000000008204811692879291909116908f908f908f908f908f908f90612017565b60405180910390a281547fffffffffffffffffffffffffffffffffffffffff0000000000000000ffffffff1664010000000063ffffffff43160217825560019091015550505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361145c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610417565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000808b8b8b8b8b8b8b8b8b8b6040516020016114f89a999897969594939291906120ad565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e06000000000000000000000000000000000000000000000000000000000000179150509a9950505050505050505050565b60006020828403121561159257600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146115c257600080fd5b9392505050565b6000815180845260005b818110156115ef576020818501810151868301820152016115d3565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006115c260208301846115c9565b803573ffffffffffffffffffffffffffffffffffffffff8116811461166457600080fd5b919050565b60008060006040848603121561167e57600080fd5b833567ffffffffffffffff8082111561169657600080fd5b818601915086601f8301126116aa57600080fd5b8135818111156116b957600080fd5b8760208285010111156116cb57600080fd5b6020928301955093506116e19186019050611640565b90509250925092565b6000602082840312156116fc57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561175557611755611703565b60405290565b6040516060810167ffffffffffffffff8111828210171561175557611755611703565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156117c5576117c5611703565b604052919050565b600067ffffffffffffffff8211156117e7576117e7611703565b5060051b60200190565b600082601f83011261180257600080fd5b81356020611817611812836117cd565b61177e565b82815260059290921b8401810191818101908684111561183657600080fd5b8286015b848110156118585761184b81611640565b835291830191830161183a565b509695505050505050565b600082601f83011261187457600080fd5b81356020611884611812836117cd565b82815260059290921b840181019181810190868411156118a357600080fd5b8286015b8481101561185857803583529183019183016118a7565b803560ff8116811461166457600080fd5b600082601f8301126118e057600080fd5b813567ffffffffffffffff8111156118fa576118fa611703565b61192b60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161177e565b81815284602083860101111561194057600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff8116811461166457600080fd5b600082601f83011261198657600080fd5b81356020611996611812836117cd565b82815260069290921b840181019181810190868411156119b557600080fd5b8286015b8481101561185857604081890312156119d25760008081fd5b6119da611732565b6119e382611640565b815281850135858201528352918301916040016119b9565b600080600080600080600080610100898b031215611a1857600080fd5b88359750602089013567ffffffffffffffff80821115611a3757600080fd5b611a438c838d016117f1565b985060408b0135915080821115611a5957600080fd5b611a658c838d01611863565b9750611a7360608c016118be565b965060808b0135915080821115611a8957600080fd5b611a958c838d016118cf565b9550611aa360a08c0161195d565b945060c08b0135915080821115611ab957600080fd5b611ac58c838d016118cf565b935060e08b0135915080821115611adb57600080fd5b50611ae88b828c01611975565b9150509295985092959890939650565b60008060408385031215611b0b57600080fd5b50508035926020909101359150565b6000806000806000806000806000806101408b8d031215611b3a57600080fd5b8a35995060208b01359850611b5160408c01611640565b975060608b013567ffffffffffffffff80821115611b6e57600080fd5b611b7a8e838f016117f1565b985060808d0135915080821115611b9057600080fd5b611b9c8e838f01611863565b9750611baa60a08e016118be565b965060c08d0135915080821115611bc057600080fd5b611bcc8e838f016118cf565b9550611bda60e08e0161195d565b94506101008d0135915080821115611bf157600080fd5b611bfd8e838f016118cf565b93506101208d0135915080821115611c1457600080fd5b50611c218d828e01611975565b9150509295989b9194979a5092959850565b600060208284031215611c4557600080fd5b6115c282611640565b600080600080600060e08688031215611c6657600080fd5b86601f870112611c7557600080fd5b611c7d61175b565b806060880189811115611c8f57600080fd5b885b81811015611ca9578035845260209384019301611c91565b5090965035905067ffffffffffffffff80821115611cc657600080fd5b611cd289838a016118cf565b95506080880135915080821115611ce857600080fd5b611cf489838a01611863565b945060a0880135915080821115611d0a57600080fd5b50611d1788828901611863565b9598949750929560c001359392505050565b80516020808301519190811015611d68577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611e0457611e04611d9d565b500290565b80820180821115611e1c57611e1c611d9d565b92915050565b60ff8181168382160190811115611e1c57611e1c611d9d565b828152600060208083018460005b6003811015611e6657815183529183019190830190600101611e49565b505050506080820190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611ed757611ed7611d9d565b5060010190565b600063ffffffff808316818103611ef757611ef7611d9d565b6001019392505050565b600060ff821660ff8103611f1757611f17611d9d565b60010192915050565b600060608201858352602085818501526040606081860152828651808552608087019150838801945060005b81811015611f87578551805173ffffffffffffffffffffffffffffffffffffffff168452850151858401529484019491830191600101611f4c565b50909998505050505050505050565b600081518084526020808501945080840160005b83811015611fdc57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101611faa565b509495945050505050565b600081518084526020808501945080840160005b83811015611fdc57815187529582019590820190600101611ffb565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526120478184018a611f96565b9050828103608084015261205b8189611fe7565b905060ff871660a084015282810360c084015261207881876115c9565b905067ffffffffffffffff851660e084015282810361010084015261209d81856115c9565b9c9b505050505050505050505050565b60006101408c83528b602084015273ffffffffffffffffffffffffffffffffffffffff8b16604084015267ffffffffffffffff808b1660608501528160808501526120fa8285018b611f96565b915083820360a085015261210e828a611fe7565b915060ff881660c085015283820360e085015261212b82886115c9565b908616610100850152838103610120850152905061214981856115c9565b9d9c5050505050505050505050505056fea164736f6c6343000810000a", +} + +var VerifierABI = VerifierMetaData.ABI + +var VerifierBin = VerifierMetaData.Bin + +func DeployVerifier(auth *bind.TransactOpts, backend bind.ContractBackend, verifierProxyAddr common.Address) (common.Address, *types.Transaction, *Verifier, error) { + parsed, err := VerifierMetaData.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(VerifierBin), backend, verifierProxyAddr) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Verifier{VerifierCaller: VerifierCaller{contract: contract}, VerifierTransactor: VerifierTransactor{contract: contract}, VerifierFilterer: VerifierFilterer{contract: contract}}, nil +} + +type Verifier struct { + address common.Address + abi abi.ABI + VerifierCaller + VerifierTransactor + VerifierFilterer +} + +type VerifierCaller struct { + contract *bind.BoundContract +} + +type VerifierTransactor struct { + contract *bind.BoundContract +} + +type VerifierFilterer struct { + contract *bind.BoundContract +} + +type VerifierSession struct { + Contract *Verifier + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type VerifierCallerSession struct { + Contract *VerifierCaller + CallOpts bind.CallOpts +} + +type VerifierTransactorSession struct { + Contract *VerifierTransactor + TransactOpts bind.TransactOpts +} + +type VerifierRaw struct { + Contract *Verifier +} + +type VerifierCallerRaw struct { + Contract *VerifierCaller +} + +type VerifierTransactorRaw struct { + Contract *VerifierTransactor +} + +func NewVerifier(address common.Address, backend bind.ContractBackend) (*Verifier, error) { + abi, err := abi.JSON(strings.NewReader(VerifierABI)) + if err != nil { + return nil, err + } + contract, err := bindVerifier(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Verifier{address: address, abi: abi, VerifierCaller: VerifierCaller{contract: contract}, VerifierTransactor: VerifierTransactor{contract: contract}, VerifierFilterer: VerifierFilterer{contract: contract}}, nil +} + +func NewVerifierCaller(address common.Address, caller bind.ContractCaller) (*VerifierCaller, error) { + contract, err := bindVerifier(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &VerifierCaller{contract: contract}, nil +} + +func NewVerifierTransactor(address common.Address, transactor bind.ContractTransactor) (*VerifierTransactor, error) { + contract, err := bindVerifier(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &VerifierTransactor{contract: contract}, nil +} + +func NewVerifierFilterer(address common.Address, filterer bind.ContractFilterer) (*VerifierFilterer, error) { + contract, err := bindVerifier(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &VerifierFilterer{contract: contract}, nil +} + +func bindVerifier(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := VerifierMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_Verifier *VerifierRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Verifier.Contract.VerifierCaller.contract.Call(opts, result, method, params...) +} + +func (_Verifier *VerifierRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Verifier.Contract.VerifierTransactor.contract.Transfer(opts) +} + +func (_Verifier *VerifierRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Verifier.Contract.VerifierTransactor.contract.Transact(opts, method, params...) +} + +func (_Verifier *VerifierCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Verifier.Contract.contract.Call(opts, result, method, params...) +} + +func (_Verifier *VerifierTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Verifier.Contract.contract.Transfer(opts) +} + +func (_Verifier *VerifierTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Verifier.Contract.contract.Transact(opts, method, params...) +} + +func (_Verifier *VerifierCaller) LatestConfigDetails(opts *bind.CallOpts, feedId [32]byte) (LatestConfigDetails, + + error) { + var out []interface{} + err := _Verifier.contract.Call(opts, &out, "latestConfigDetails", feedId) + + 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 (_Verifier *VerifierSession) LatestConfigDetails(feedId [32]byte) (LatestConfigDetails, + + error) { + return _Verifier.Contract.LatestConfigDetails(&_Verifier.CallOpts, feedId) +} + +func (_Verifier *VerifierCallerSession) LatestConfigDetails(feedId [32]byte) (LatestConfigDetails, + + error) { + return _Verifier.Contract.LatestConfigDetails(&_Verifier.CallOpts, feedId) +} + +func (_Verifier *VerifierCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts, feedId [32]byte) (LatestConfigDigestAndEpoch, + + error) { + var out []interface{} + err := _Verifier.contract.Call(opts, &out, "latestConfigDigestAndEpoch", feedId) + + 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 (_Verifier *VerifierSession) LatestConfigDigestAndEpoch(feedId [32]byte) (LatestConfigDigestAndEpoch, + + error) { + return _Verifier.Contract.LatestConfigDigestAndEpoch(&_Verifier.CallOpts, feedId) +} + +func (_Verifier *VerifierCallerSession) LatestConfigDigestAndEpoch(feedId [32]byte) (LatestConfigDigestAndEpoch, + + error) { + return _Verifier.Contract.LatestConfigDigestAndEpoch(&_Verifier.CallOpts, feedId) +} + +func (_Verifier *VerifierCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Verifier.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 (_Verifier *VerifierSession) Owner() (common.Address, error) { + return _Verifier.Contract.Owner(&_Verifier.CallOpts) +} + +func (_Verifier *VerifierCallerSession) Owner() (common.Address, error) { + return _Verifier.Contract.Owner(&_Verifier.CallOpts) +} + +func (_Verifier *VerifierCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _Verifier.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_Verifier *VerifierSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _Verifier.Contract.SupportsInterface(&_Verifier.CallOpts, interfaceId) +} + +func (_Verifier *VerifierCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _Verifier.Contract.SupportsInterface(&_Verifier.CallOpts, interfaceId) +} + +func (_Verifier *VerifierCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _Verifier.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_Verifier *VerifierSession) TypeAndVersion() (string, error) { + return _Verifier.Contract.TypeAndVersion(&_Verifier.CallOpts) +} + +func (_Verifier *VerifierCallerSession) TypeAndVersion() (string, error) { + return _Verifier.Contract.TypeAndVersion(&_Verifier.CallOpts) +} + +func (_Verifier *VerifierTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Verifier.contract.Transact(opts, "acceptOwnership") +} + +func (_Verifier *VerifierSession) AcceptOwnership() (*types.Transaction, error) { + return _Verifier.Contract.AcceptOwnership(&_Verifier.TransactOpts) +} + +func (_Verifier *VerifierTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _Verifier.Contract.AcceptOwnership(&_Verifier.TransactOpts) +} + +func (_Verifier *VerifierTransactor) ActivateConfig(opts *bind.TransactOpts, feedId [32]byte, configDigest [32]byte) (*types.Transaction, error) { + return _Verifier.contract.Transact(opts, "activateConfig", feedId, configDigest) +} + +func (_Verifier *VerifierSession) ActivateConfig(feedId [32]byte, configDigest [32]byte) (*types.Transaction, error) { + return _Verifier.Contract.ActivateConfig(&_Verifier.TransactOpts, feedId, configDigest) +} + +func (_Verifier *VerifierTransactorSession) ActivateConfig(feedId [32]byte, configDigest [32]byte) (*types.Transaction, error) { + return _Verifier.Contract.ActivateConfig(&_Verifier.TransactOpts, feedId, configDigest) +} + +func (_Verifier *VerifierTransactor) ActivateFeed(opts *bind.TransactOpts, feedId [32]byte) (*types.Transaction, error) { + return _Verifier.contract.Transact(opts, "activateFeed", feedId) +} + +func (_Verifier *VerifierSession) ActivateFeed(feedId [32]byte) (*types.Transaction, error) { + return _Verifier.Contract.ActivateFeed(&_Verifier.TransactOpts, feedId) +} + +func (_Verifier *VerifierTransactorSession) ActivateFeed(feedId [32]byte) (*types.Transaction, error) { + return _Verifier.Contract.ActivateFeed(&_Verifier.TransactOpts, feedId) +} + +func (_Verifier *VerifierTransactor) DeactivateConfig(opts *bind.TransactOpts, feedId [32]byte, configDigest [32]byte) (*types.Transaction, error) { + return _Verifier.contract.Transact(opts, "deactivateConfig", feedId, configDigest) +} + +func (_Verifier *VerifierSession) DeactivateConfig(feedId [32]byte, configDigest [32]byte) (*types.Transaction, error) { + return _Verifier.Contract.DeactivateConfig(&_Verifier.TransactOpts, feedId, configDigest) +} + +func (_Verifier *VerifierTransactorSession) DeactivateConfig(feedId [32]byte, configDigest [32]byte) (*types.Transaction, error) { + return _Verifier.Contract.DeactivateConfig(&_Verifier.TransactOpts, feedId, configDigest) +} + +func (_Verifier *VerifierTransactor) DeactivateFeed(opts *bind.TransactOpts, feedId [32]byte) (*types.Transaction, error) { + return _Verifier.contract.Transact(opts, "deactivateFeed", feedId) +} + +func (_Verifier *VerifierSession) DeactivateFeed(feedId [32]byte) (*types.Transaction, error) { + return _Verifier.Contract.DeactivateFeed(&_Verifier.TransactOpts, feedId) +} + +func (_Verifier *VerifierTransactorSession) DeactivateFeed(feedId [32]byte) (*types.Transaction, error) { + return _Verifier.Contract.DeactivateFeed(&_Verifier.TransactOpts, feedId) +} + +func (_Verifier *VerifierTransactor) SetConfig(opts *bind.TransactOpts, feedId [32]byte, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _Verifier.contract.Transact(opts, "setConfig", feedId, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights) +} + +func (_Verifier *VerifierSession) SetConfig(feedId [32]byte, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _Verifier.Contract.SetConfig(&_Verifier.TransactOpts, feedId, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights) +} + +func (_Verifier *VerifierTransactorSession) SetConfig(feedId [32]byte, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _Verifier.Contract.SetConfig(&_Verifier.TransactOpts, feedId, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights) +} + +func (_Verifier *VerifierTransactor) SetConfigFromSource(opts *bind.TransactOpts, feedId [32]byte, sourceChainId *big.Int, sourceAddress common.Address, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _Verifier.contract.Transact(opts, "setConfigFromSource", feedId, sourceChainId, sourceAddress, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights) +} + +func (_Verifier *VerifierSession) SetConfigFromSource(feedId [32]byte, sourceChainId *big.Int, sourceAddress common.Address, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _Verifier.Contract.SetConfigFromSource(&_Verifier.TransactOpts, feedId, sourceChainId, sourceAddress, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights) +} + +func (_Verifier *VerifierTransactorSession) SetConfigFromSource(feedId [32]byte, sourceChainId *big.Int, sourceAddress common.Address, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _Verifier.Contract.SetConfigFromSource(&_Verifier.TransactOpts, feedId, sourceChainId, sourceAddress, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights) +} + +func (_Verifier *VerifierTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _Verifier.contract.Transact(opts, "transferOwnership", to) +} + +func (_Verifier *VerifierSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _Verifier.Contract.TransferOwnership(&_Verifier.TransactOpts, to) +} + +func (_Verifier *VerifierTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _Verifier.Contract.TransferOwnership(&_Verifier.TransactOpts, to) +} + +func (_Verifier *VerifierTransactor) Verify(opts *bind.TransactOpts, signedReport []byte, sender common.Address) (*types.Transaction, error) { + return _Verifier.contract.Transact(opts, "verify", signedReport, sender) +} + +func (_Verifier *VerifierSession) Verify(signedReport []byte, sender common.Address) (*types.Transaction, error) { + return _Verifier.Contract.Verify(&_Verifier.TransactOpts, signedReport, sender) +} + +func (_Verifier *VerifierTransactorSession) Verify(signedReport []byte, sender common.Address) (*types.Transaction, error) { + return _Verifier.Contract.Verify(&_Verifier.TransactOpts, signedReport, sender) +} + +type VerifierConfigActivatedIterator struct { + Event *VerifierConfigActivated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierConfigActivatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierConfigActivated) + 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(VerifierConfigActivated) + 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 *VerifierConfigActivatedIterator) Error() error { + return it.fail +} + +func (it *VerifierConfigActivatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierConfigActivated struct { + FeedId [32]byte + ConfigDigest [32]byte + Raw types.Log +} + +func (_Verifier *VerifierFilterer) FilterConfigActivated(opts *bind.FilterOpts, feedId [][32]byte) (*VerifierConfigActivatedIterator, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _Verifier.contract.FilterLogs(opts, "ConfigActivated", feedIdRule) + if err != nil { + return nil, err + } + return &VerifierConfigActivatedIterator{contract: _Verifier.contract, event: "ConfigActivated", logs: logs, sub: sub}, nil +} + +func (_Verifier *VerifierFilterer) WatchConfigActivated(opts *bind.WatchOpts, sink chan<- *VerifierConfigActivated, feedId [][32]byte) (event.Subscription, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _Verifier.contract.WatchLogs(opts, "ConfigActivated", feedIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierConfigActivated) + if err := _Verifier.contract.UnpackLog(event, "ConfigActivated", 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 (_Verifier *VerifierFilterer) ParseConfigActivated(log types.Log) (*VerifierConfigActivated, error) { + event := new(VerifierConfigActivated) + if err := _Verifier.contract.UnpackLog(event, "ConfigActivated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierConfigDeactivatedIterator struct { + Event *VerifierConfigDeactivated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierConfigDeactivatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierConfigDeactivated) + 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(VerifierConfigDeactivated) + 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 *VerifierConfigDeactivatedIterator) Error() error { + return it.fail +} + +func (it *VerifierConfigDeactivatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierConfigDeactivated struct { + FeedId [32]byte + ConfigDigest [32]byte + Raw types.Log +} + +func (_Verifier *VerifierFilterer) FilterConfigDeactivated(opts *bind.FilterOpts, feedId [][32]byte) (*VerifierConfigDeactivatedIterator, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _Verifier.contract.FilterLogs(opts, "ConfigDeactivated", feedIdRule) + if err != nil { + return nil, err + } + return &VerifierConfigDeactivatedIterator{contract: _Verifier.contract, event: "ConfigDeactivated", logs: logs, sub: sub}, nil +} + +func (_Verifier *VerifierFilterer) WatchConfigDeactivated(opts *bind.WatchOpts, sink chan<- *VerifierConfigDeactivated, feedId [][32]byte) (event.Subscription, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _Verifier.contract.WatchLogs(opts, "ConfigDeactivated", feedIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierConfigDeactivated) + if err := _Verifier.contract.UnpackLog(event, "ConfigDeactivated", 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 (_Verifier *VerifierFilterer) ParseConfigDeactivated(log types.Log) (*VerifierConfigDeactivated, error) { + event := new(VerifierConfigDeactivated) + if err := _Verifier.contract.UnpackLog(event, "ConfigDeactivated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierConfigSetIterator struct { + Event *VerifierConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierConfigSet) + 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(VerifierConfigSet) + 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 *VerifierConfigSetIterator) Error() error { + return it.fail +} + +func (it *VerifierConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierConfigSet struct { + FeedId [32]byte + PreviousConfigBlockNumber uint32 + ConfigDigest [32]byte + ConfigCount uint64 + Signers []common.Address + OffchainTransmitters [][32]byte + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte + Raw types.Log +} + +func (_Verifier *VerifierFilterer) FilterConfigSet(opts *bind.FilterOpts, feedId [][32]byte) (*VerifierConfigSetIterator, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _Verifier.contract.FilterLogs(opts, "ConfigSet", feedIdRule) + if err != nil { + return nil, err + } + return &VerifierConfigSetIterator{contract: _Verifier.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_Verifier *VerifierFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *VerifierConfigSet, feedId [][32]byte) (event.Subscription, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _Verifier.contract.WatchLogs(opts, "ConfigSet", feedIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierConfigSet) + if err := _Verifier.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 (_Verifier *VerifierFilterer) ParseConfigSet(log types.Log) (*VerifierConfigSet, error) { + event := new(VerifierConfigSet) + if err := _Verifier.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierFeedActivatedIterator struct { + Event *VerifierFeedActivated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierFeedActivatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierFeedActivated) + 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(VerifierFeedActivated) + 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 *VerifierFeedActivatedIterator) Error() error { + return it.fail +} + +func (it *VerifierFeedActivatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierFeedActivated struct { + FeedId [32]byte + Raw types.Log +} + +func (_Verifier *VerifierFilterer) FilterFeedActivated(opts *bind.FilterOpts, feedId [][32]byte) (*VerifierFeedActivatedIterator, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _Verifier.contract.FilterLogs(opts, "FeedActivated", feedIdRule) + if err != nil { + return nil, err + } + return &VerifierFeedActivatedIterator{contract: _Verifier.contract, event: "FeedActivated", logs: logs, sub: sub}, nil +} + +func (_Verifier *VerifierFilterer) WatchFeedActivated(opts *bind.WatchOpts, sink chan<- *VerifierFeedActivated, feedId [][32]byte) (event.Subscription, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _Verifier.contract.WatchLogs(opts, "FeedActivated", feedIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierFeedActivated) + if err := _Verifier.contract.UnpackLog(event, "FeedActivated", 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 (_Verifier *VerifierFilterer) ParseFeedActivated(log types.Log) (*VerifierFeedActivated, error) { + event := new(VerifierFeedActivated) + if err := _Verifier.contract.UnpackLog(event, "FeedActivated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierFeedDeactivatedIterator struct { + Event *VerifierFeedDeactivated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierFeedDeactivatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierFeedDeactivated) + 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(VerifierFeedDeactivated) + 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 *VerifierFeedDeactivatedIterator) Error() error { + return it.fail +} + +func (it *VerifierFeedDeactivatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierFeedDeactivated struct { + FeedId [32]byte + Raw types.Log +} + +func (_Verifier *VerifierFilterer) FilterFeedDeactivated(opts *bind.FilterOpts, feedId [][32]byte) (*VerifierFeedDeactivatedIterator, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _Verifier.contract.FilterLogs(opts, "FeedDeactivated", feedIdRule) + if err != nil { + return nil, err + } + return &VerifierFeedDeactivatedIterator{contract: _Verifier.contract, event: "FeedDeactivated", logs: logs, sub: sub}, nil +} + +func (_Verifier *VerifierFilterer) WatchFeedDeactivated(opts *bind.WatchOpts, sink chan<- *VerifierFeedDeactivated, feedId [][32]byte) (event.Subscription, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _Verifier.contract.WatchLogs(opts, "FeedDeactivated", feedIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierFeedDeactivated) + if err := _Verifier.contract.UnpackLog(event, "FeedDeactivated", 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 (_Verifier *VerifierFilterer) ParseFeedDeactivated(log types.Log) (*VerifierFeedDeactivated, error) { + event := new(VerifierFeedDeactivated) + if err := _Verifier.contract.UnpackLog(event, "FeedDeactivated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierOwnershipTransferRequestedIterator struct { + Event *VerifierOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierOwnershipTransferRequested) + 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(VerifierOwnershipTransferRequested) + 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 *VerifierOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *VerifierOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_Verifier *VerifierFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifierOwnershipTransferRequestedIterator, 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 := _Verifier.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &VerifierOwnershipTransferRequestedIterator{contract: _Verifier.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_Verifier *VerifierFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifierOwnershipTransferRequested, 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 := _Verifier.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(VerifierOwnershipTransferRequested) + if err := _Verifier.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 (_Verifier *VerifierFilterer) ParseOwnershipTransferRequested(log types.Log) (*VerifierOwnershipTransferRequested, error) { + event := new(VerifierOwnershipTransferRequested) + if err := _Verifier.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierOwnershipTransferredIterator struct { + Event *VerifierOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierOwnershipTransferred) + 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(VerifierOwnershipTransferred) + 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 *VerifierOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *VerifierOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_Verifier *VerifierFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifierOwnershipTransferredIterator, 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 := _Verifier.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &VerifierOwnershipTransferredIterator{contract: _Verifier.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_Verifier *VerifierFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifierOwnershipTransferred, 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 := _Verifier.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(VerifierOwnershipTransferred) + if err := _Verifier.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 (_Verifier *VerifierFilterer) ParseOwnershipTransferred(log types.Log) (*VerifierOwnershipTransferred, error) { + event := new(VerifierOwnershipTransferred) + if err := _Verifier.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierReportVerifiedIterator struct { + Event *VerifierReportVerified + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierReportVerifiedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierReportVerified) + 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(VerifierReportVerified) + 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 *VerifierReportVerifiedIterator) Error() error { + return it.fail +} + +func (it *VerifierReportVerifiedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierReportVerified struct { + FeedId [32]byte + Requester common.Address + Raw types.Log +} + +func (_Verifier *VerifierFilterer) FilterReportVerified(opts *bind.FilterOpts, feedId [][32]byte) (*VerifierReportVerifiedIterator, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _Verifier.contract.FilterLogs(opts, "ReportVerified", feedIdRule) + if err != nil { + return nil, err + } + return &VerifierReportVerifiedIterator{contract: _Verifier.contract, event: "ReportVerified", logs: logs, sub: sub}, nil +} + +func (_Verifier *VerifierFilterer) WatchReportVerified(opts *bind.WatchOpts, sink chan<- *VerifierReportVerified, feedId [][32]byte) (event.Subscription, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _Verifier.contract.WatchLogs(opts, "ReportVerified", feedIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierReportVerified) + if err := _Verifier.contract.UnpackLog(event, "ReportVerified", 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 (_Verifier *VerifierFilterer) ParseReportVerified(log types.Log) (*VerifierReportVerified, error) { + event := new(VerifierReportVerified) + if err := _Verifier.contract.UnpackLog(event, "ReportVerified", 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 (_Verifier *Verifier) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _Verifier.abi.Events["ConfigActivated"].ID: + return _Verifier.ParseConfigActivated(log) + case _Verifier.abi.Events["ConfigDeactivated"].ID: + return _Verifier.ParseConfigDeactivated(log) + case _Verifier.abi.Events["ConfigSet"].ID: + return _Verifier.ParseConfigSet(log) + case _Verifier.abi.Events["FeedActivated"].ID: + return _Verifier.ParseFeedActivated(log) + case _Verifier.abi.Events["FeedDeactivated"].ID: + return _Verifier.ParseFeedDeactivated(log) + case _Verifier.abi.Events["OwnershipTransferRequested"].ID: + return _Verifier.ParseOwnershipTransferRequested(log) + case _Verifier.abi.Events["OwnershipTransferred"].ID: + return _Verifier.ParseOwnershipTransferred(log) + case _Verifier.abi.Events["ReportVerified"].ID: + return _Verifier.ParseReportVerified(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (VerifierConfigActivated) Topic() common.Hash { + return common.HexToHash("0x54f8872b9b94ebea6577f33576d55847bd8ea22641ccc886b965f6e50bfe7746") +} + +func (VerifierConfigDeactivated) Topic() common.Hash { + return common.HexToHash("0x0e173bea63a8c59ec70bf87043f2a729693790183f16a1a54b705de9e989cc4c") +} + +func (VerifierConfigSet) Topic() common.Hash { + return common.HexToHash("0xa23a88453230b183877098801ff5a8f771a120e2573eea559ce6c4c2e305a4da") +} + +func (VerifierFeedActivated) Topic() common.Hash { + return common.HexToHash("0xf438564f793525caa89c6e3a26d41e16aa39d1e589747595751e3f3df75cb2b4") +} + +func (VerifierFeedDeactivated) Topic() common.Hash { + return common.HexToHash("0xfc4f79b8c65b6be1773063461984c0974400d1e99654c79477a092ace83fd061") +} + +func (VerifierOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (VerifierOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (VerifierReportVerified) Topic() common.Hash { + return common.HexToHash("0x58ca9502e98a536e06e72d680fcc251e5d10b72291a281665a2c2dc0ac30fcc5") +} + +func (_Verifier *Verifier) Address() common.Address { + return _Verifier.address +} + +type VerifierInterface interface { + LatestConfigDetails(opts *bind.CallOpts, feedId [32]byte) (LatestConfigDetails, + + error) + + LatestConfigDigestAndEpoch(opts *bind.CallOpts, feedId [32]byte) (LatestConfigDigestAndEpoch, + + error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ActivateConfig(opts *bind.TransactOpts, feedId [32]byte, configDigest [32]byte) (*types.Transaction, error) + + ActivateFeed(opts *bind.TransactOpts, feedId [32]byte) (*types.Transaction, error) + + DeactivateConfig(opts *bind.TransactOpts, feedId [32]byte, configDigest [32]byte) (*types.Transaction, error) + + DeactivateFeed(opts *bind.TransactOpts, feedId [32]byte) (*types.Transaction, error) + + SetConfig(opts *bind.TransactOpts, feedId [32]byte, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) + + SetConfigFromSource(opts *bind.TransactOpts, feedId [32]byte, sourceChainId *big.Int, sourceAddress common.Address, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Verify(opts *bind.TransactOpts, signedReport []byte, sender common.Address) (*types.Transaction, error) + + FilterConfigActivated(opts *bind.FilterOpts, feedId [][32]byte) (*VerifierConfigActivatedIterator, error) + + WatchConfigActivated(opts *bind.WatchOpts, sink chan<- *VerifierConfigActivated, feedId [][32]byte) (event.Subscription, error) + + ParseConfigActivated(log types.Log) (*VerifierConfigActivated, error) + + FilterConfigDeactivated(opts *bind.FilterOpts, feedId [][32]byte) (*VerifierConfigDeactivatedIterator, error) + + WatchConfigDeactivated(opts *bind.WatchOpts, sink chan<- *VerifierConfigDeactivated, feedId [][32]byte) (event.Subscription, error) + + ParseConfigDeactivated(log types.Log) (*VerifierConfigDeactivated, error) + + FilterConfigSet(opts *bind.FilterOpts, feedId [][32]byte) (*VerifierConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *VerifierConfigSet, feedId [][32]byte) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*VerifierConfigSet, error) + + FilterFeedActivated(opts *bind.FilterOpts, feedId [][32]byte) (*VerifierFeedActivatedIterator, error) + + WatchFeedActivated(opts *bind.WatchOpts, sink chan<- *VerifierFeedActivated, feedId [][32]byte) (event.Subscription, error) + + ParseFeedActivated(log types.Log) (*VerifierFeedActivated, error) + + FilterFeedDeactivated(opts *bind.FilterOpts, feedId [][32]byte) (*VerifierFeedDeactivatedIterator, error) + + WatchFeedDeactivated(opts *bind.WatchOpts, sink chan<- *VerifierFeedDeactivated, feedId [][32]byte) (event.Subscription, error) + + ParseFeedDeactivated(log types.Log) (*VerifierFeedDeactivated, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifierOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifierOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*VerifierOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifierOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifierOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*VerifierOwnershipTransferred, error) + + FilterReportVerified(opts *bind.FilterOpts, feedId [][32]byte) (*VerifierReportVerifiedIterator, error) + + WatchReportVerified(opts *bind.WatchOpts, sink chan<- *VerifierReportVerified, feedId [][32]byte) (event.Subscription, error) + + ParseReportVerified(log types.Log) (*VerifierReportVerified, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/llo-feeds/generated/verifier_proxy/verifier_proxy.go b/core/gethwrappers/llo-feeds/generated/verifier_proxy/verifier_proxy.go new file mode 100644 index 00000000000..40a6d24221b --- /dev/null +++ b/core/gethwrappers/llo-feeds/generated/verifier_proxy/verifier_proxy.go @@ -0,0 +1,1373 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package verifier_proxy + +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 CommonAddressAndWeight struct { + Addr common.Address + Weight *big.Int +} + +var VerifierProxyMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"accessController\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadVerification\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"verifier\",\"type\":\"address\"}],\"name\":\"ConfigDigestAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifier\",\"type\":\"address\"}],\"name\":\"VerifierAlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerifierInvalid\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"VerifierNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessController\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessController\",\"type\":\"address\"}],\"name\":\"AccessControllerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldFeeManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newFeeManager\",\"type\":\"address\"}],\"name\":\"FeeManagerSet\",\"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\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"oldConfigDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"newConfigDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierUnset\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"getVerifier\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"initializeVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_accessController\",\"outputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_feeManager\",\"outputs\":[{\"internalType\":\"contractIVerifierFeeManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"accessController\",\"type\":\"address\"}],\"name\":\"setAccessController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIVerifierFeeManager\",\"name\":\"feeManager\",\"type\":\"address\"}],\"name\":\"setFeeManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"currentConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"newConfigDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"addressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setVerifier\",\"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\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"unsetVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"verifierResponse\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50604051620015333803806200153383398101604081905261003191610189565b33806000816100875760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156100b7576100b7816100e0565b5050600480546001600160a01b0319166001600160a01b039390931692909217909155506101b9565b336001600160a01b038216036101385760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161007e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006020828403121561019b57600080fd5b81516001600160a01b03811681146101b257600080fd5b9392505050565b61136a80620001c96000396000f3fe6080604052600436106100d25760003560e01c80638c2a4d531161007f57806394ba28461161005957806394ba284614610256578063eeb7b24814610283578063f08391d8146102c6578063f2fde38b146102e657600080fd5b80638c2a4d53146101f85780638da5cb5b146102185780638e760afe1461024357600080fd5b8063589ede28116100b0578063589ede28146101a35780636e914094146101c357806379ba5097146101e357600080fd5b8063181f5a77146100d757806338416b5b1461012f578063472d35b914610181575b600080fd5b3480156100e357600080fd5b5060408051808201909152601381527f566572696669657250726f787920312e312e300000000000000000000000000060208201525b6040516101269190610f7d565b60405180910390f35b34801561013b57600080fd5b5060055461015c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610126565b34801561018d57600080fd5b506101a161019c366004610fb9565b610306565b005b3480156101af57600080fd5b506101a16101be366004610fd6565b6103e2565b3480156101cf57600080fd5b506101a16101de366004611059565b61060d565b3480156101ef57600080fd5b506101a16106f9565b34801561020457600080fd5b506101a1610213366004610fb9565b6107f6565b34801561022457600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff1661015c565b610119610251366004611072565b610a27565b34801561026257600080fd5b5060045461015c9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561028f57600080fd5b5061015c61029e366004611059565b60009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b3480156102d257600080fd5b506101a16102e1366004610fb9565b610cfc565b3480156102f257600080fd5b506101a1610301366004610fb9565b610d83565b61030e610d97565b73ffffffffffffffffffffffffffffffffffffffff811661035b576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f04628abcaa6b1674651352125cb94b65b289145bc2bc4d67720bb7d966372f0391015b60405180910390a15050565b600083815260036020526040902054839073ffffffffffffffffffffffffffffffffffffffff168015610465576040517f375d1fe60000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff821660248201526044015b60405180910390fd5b3360009081526002602052604090205460ff166104ae576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260036020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317905582156105c65760055473ffffffffffffffffffffffffffffffffffffffff16610539576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546040517f69fd2b3400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906369fd2b3490610593908890889088906004016110e4565b600060405180830381600087803b1580156105ad57600080fd5b505af11580156105c1573d6000803e3d6000fd5b505050505b6040805187815260208101879052338183015290517fbeb513e532542a562ac35699e7cd9ae7d198dcd3eee15bada6c857d28ceaddcf9181900360600190a1505050505050565b610615610d97565b60008181526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1680610674576040517fb151802b0000000000000000000000000000000000000000000000000000000081526004810183905260240161045c565b6000828152600360205260409081902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055517f11dc15c4b8ac2b183166cc8427e5385a5ece8308217a4217338c6a7614845c4c906103d6908490849091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60015473ffffffffffffffffffffffffffffffffffffffff16331461077a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161045c565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6107fe610d97565b8073ffffffffffffffffffffffffffffffffffffffff811661084c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f3d3ac1b500000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa1580156108d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108fa9190611153565b610930576040517f75b0527a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090205460ff16156109a8576040517f4e01ccfd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015260240161045c565b73ffffffffffffffffffffffffffffffffffffffff821660008181526002602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590519182527f1f2cd7c97f4d801b5efe26cc409617c1fd6c5ef786e79aacb90af40923e4e8e991016103d6565b60045460609073ffffffffffffffffffffffffffffffffffffffff168015801590610ae757506040517f6b14daf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690636b14daf890610aa490339060009036906004016111be565b602060405180830381865afa158015610ac1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae59190611153565b155b15610b1e576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610b2a84866111f7565b60008181526003602052604090205490915073ffffffffffffffffffffffffffffffffffffffff1680610b8c576040517fb151802b0000000000000000000000000000000000000000000000000000000081526004810183905260240161045c565b60055473ffffffffffffffffffffffffffffffffffffffff168015610c36576040517ff1387e1600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063f1387e16903490610c03908b908b903390600401611234565b6000604051808303818588803b158015610c1c57600080fd5b505af1158015610c30573d6000803e3d6000fd5b50505050505b6040517f3d3ac1b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831690633d3ac1b590610c8c908a908a903390600401611234565b6000604051808303816000875af1158015610cab573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610cf1919081019061129d565b979650505050505050565b610d04610d97565b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f953e92b1a6442e9c3242531154a3f6f6eb00b4e9c719ba8118fa6235e4ce89b691016103d6565b610d8b610d97565b610d9481610e1a565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161045c565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610e99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161045c565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b83811015610f2a578181015183820152602001610f12565b50506000910152565b60008151808452610f4b816020860160208601610f0f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610f906020830184610f33565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610d9457600080fd5b600060208284031215610fcb57600080fd5b8135610f9081610f97565b60008060008060608587031215610fec57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561101257600080fd5b818701915087601f83011261102657600080fd5b81358181111561103557600080fd5b8860208260061b850101111561104a57600080fd5b95989497505060200194505050565b60006020828403121561106b57600080fd5b5035919050565b6000806020838503121561108557600080fd5b823567ffffffffffffffff8082111561109d57600080fd5b818501915085601f8301126110b157600080fd5b8135818111156110c057600080fd5b8660208285010111156110d257600080fd5b60209290920196919550909350505050565b8381526040602080830182905282820184905260009190859060608501845b8781101561114657833561111681610f97565b73ffffffffffffffffffffffffffffffffffffffff16825283830135838301529284019290840190600101611103565b5098975050505050505050565b60006020828403121561116557600080fd5b81518015158114610f9057600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff841681526040602082015260006111ee604083018486611175565b95945050505050565b8035602083101561122e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b165b92915050565b604081526000611248604083018587611175565b905073ffffffffffffffffffffffffffffffffffffffff83166020830152949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156112af57600080fd5b815167ffffffffffffffff808211156112c757600080fd5b818401915084601f8301126112db57600080fd5b8151818111156112ed576112ed61126e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156113335761133361126e565b8160405282815287602084870101111561134c57600080fd5b610cf1836020830160208801610f0f56fea164736f6c6343000810000a", +} + +var VerifierProxyABI = VerifierProxyMetaData.ABI + +var VerifierProxyBin = VerifierProxyMetaData.Bin + +func DeployVerifierProxy(auth *bind.TransactOpts, backend bind.ContractBackend, accessController common.Address) (common.Address, *types.Transaction, *VerifierProxy, error) { + parsed, err := VerifierProxyMetaData.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(VerifierProxyBin), backend, accessController) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &VerifierProxy{VerifierProxyCaller: VerifierProxyCaller{contract: contract}, VerifierProxyTransactor: VerifierProxyTransactor{contract: contract}, VerifierProxyFilterer: VerifierProxyFilterer{contract: contract}}, nil +} + +type VerifierProxy struct { + address common.Address + abi abi.ABI + VerifierProxyCaller + VerifierProxyTransactor + VerifierProxyFilterer +} + +type VerifierProxyCaller struct { + contract *bind.BoundContract +} + +type VerifierProxyTransactor struct { + contract *bind.BoundContract +} + +type VerifierProxyFilterer struct { + contract *bind.BoundContract +} + +type VerifierProxySession struct { + Contract *VerifierProxy + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type VerifierProxyCallerSession struct { + Contract *VerifierProxyCaller + CallOpts bind.CallOpts +} + +type VerifierProxyTransactorSession struct { + Contract *VerifierProxyTransactor + TransactOpts bind.TransactOpts +} + +type VerifierProxyRaw struct { + Contract *VerifierProxy +} + +type VerifierProxyCallerRaw struct { + Contract *VerifierProxyCaller +} + +type VerifierProxyTransactorRaw struct { + Contract *VerifierProxyTransactor +} + +func NewVerifierProxy(address common.Address, backend bind.ContractBackend) (*VerifierProxy, error) { + abi, err := abi.JSON(strings.NewReader(VerifierProxyABI)) + if err != nil { + return nil, err + } + contract, err := bindVerifierProxy(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &VerifierProxy{address: address, abi: abi, VerifierProxyCaller: VerifierProxyCaller{contract: contract}, VerifierProxyTransactor: VerifierProxyTransactor{contract: contract}, VerifierProxyFilterer: VerifierProxyFilterer{contract: contract}}, nil +} + +func NewVerifierProxyCaller(address common.Address, caller bind.ContractCaller) (*VerifierProxyCaller, error) { + contract, err := bindVerifierProxy(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &VerifierProxyCaller{contract: contract}, nil +} + +func NewVerifierProxyTransactor(address common.Address, transactor bind.ContractTransactor) (*VerifierProxyTransactor, error) { + contract, err := bindVerifierProxy(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &VerifierProxyTransactor{contract: contract}, nil +} + +func NewVerifierProxyFilterer(address common.Address, filterer bind.ContractFilterer) (*VerifierProxyFilterer, error) { + contract, err := bindVerifierProxy(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &VerifierProxyFilterer{contract: contract}, nil +} + +func bindVerifierProxy(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := VerifierProxyMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_VerifierProxy *VerifierProxyRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VerifierProxy.Contract.VerifierProxyCaller.contract.Call(opts, result, method, params...) +} + +func (_VerifierProxy *VerifierProxyRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VerifierProxy.Contract.VerifierProxyTransactor.contract.Transfer(opts) +} + +func (_VerifierProxy *VerifierProxyRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VerifierProxy.Contract.VerifierProxyTransactor.contract.Transact(opts, method, params...) +} + +func (_VerifierProxy *VerifierProxyCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VerifierProxy.Contract.contract.Call(opts, result, method, params...) +} + +func (_VerifierProxy *VerifierProxyTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VerifierProxy.Contract.contract.Transfer(opts) +} + +func (_VerifierProxy *VerifierProxyTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VerifierProxy.Contract.contract.Transact(opts, method, params...) +} + +func (_VerifierProxy *VerifierProxyCaller) GetVerifier(opts *bind.CallOpts, configDigest [32]byte) (common.Address, error) { + var out []interface{} + err := _VerifierProxy.contract.Call(opts, &out, "getVerifier", configDigest) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VerifierProxy *VerifierProxySession) GetVerifier(configDigest [32]byte) (common.Address, error) { + return _VerifierProxy.Contract.GetVerifier(&_VerifierProxy.CallOpts, configDigest) +} + +func (_VerifierProxy *VerifierProxyCallerSession) GetVerifier(configDigest [32]byte) (common.Address, error) { + return _VerifierProxy.Contract.GetVerifier(&_VerifierProxy.CallOpts, configDigest) +} + +func (_VerifierProxy *VerifierProxyCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VerifierProxy.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 (_VerifierProxy *VerifierProxySession) Owner() (common.Address, error) { + return _VerifierProxy.Contract.Owner(&_VerifierProxy.CallOpts) +} + +func (_VerifierProxy *VerifierProxyCallerSession) Owner() (common.Address, error) { + return _VerifierProxy.Contract.Owner(&_VerifierProxy.CallOpts) +} + +func (_VerifierProxy *VerifierProxyCaller) SAccessController(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VerifierProxy.contract.Call(opts, &out, "s_accessController") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VerifierProxy *VerifierProxySession) SAccessController() (common.Address, error) { + return _VerifierProxy.Contract.SAccessController(&_VerifierProxy.CallOpts) +} + +func (_VerifierProxy *VerifierProxyCallerSession) SAccessController() (common.Address, error) { + return _VerifierProxy.Contract.SAccessController(&_VerifierProxy.CallOpts) +} + +func (_VerifierProxy *VerifierProxyCaller) SFeeManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VerifierProxy.contract.Call(opts, &out, "s_feeManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VerifierProxy *VerifierProxySession) SFeeManager() (common.Address, error) { + return _VerifierProxy.Contract.SFeeManager(&_VerifierProxy.CallOpts) +} + +func (_VerifierProxy *VerifierProxyCallerSession) SFeeManager() (common.Address, error) { + return _VerifierProxy.Contract.SFeeManager(&_VerifierProxy.CallOpts) +} + +func (_VerifierProxy *VerifierProxyCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _VerifierProxy.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_VerifierProxy *VerifierProxySession) TypeAndVersion() (string, error) { + return _VerifierProxy.Contract.TypeAndVersion(&_VerifierProxy.CallOpts) +} + +func (_VerifierProxy *VerifierProxyCallerSession) TypeAndVersion() (string, error) { + return _VerifierProxy.Contract.TypeAndVersion(&_VerifierProxy.CallOpts) +} + +func (_VerifierProxy *VerifierProxyTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VerifierProxy.contract.Transact(opts, "acceptOwnership") +} + +func (_VerifierProxy *VerifierProxySession) AcceptOwnership() (*types.Transaction, error) { + return _VerifierProxy.Contract.AcceptOwnership(&_VerifierProxy.TransactOpts) +} + +func (_VerifierProxy *VerifierProxyTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _VerifierProxy.Contract.AcceptOwnership(&_VerifierProxy.TransactOpts) +} + +func (_VerifierProxy *VerifierProxyTransactor) InitializeVerifier(opts *bind.TransactOpts, verifierAddress common.Address) (*types.Transaction, error) { + return _VerifierProxy.contract.Transact(opts, "initializeVerifier", verifierAddress) +} + +func (_VerifierProxy *VerifierProxySession) InitializeVerifier(verifierAddress common.Address) (*types.Transaction, error) { + return _VerifierProxy.Contract.InitializeVerifier(&_VerifierProxy.TransactOpts, verifierAddress) +} + +func (_VerifierProxy *VerifierProxyTransactorSession) InitializeVerifier(verifierAddress common.Address) (*types.Transaction, error) { + return _VerifierProxy.Contract.InitializeVerifier(&_VerifierProxy.TransactOpts, verifierAddress) +} + +func (_VerifierProxy *VerifierProxyTransactor) SetAccessController(opts *bind.TransactOpts, accessController common.Address) (*types.Transaction, error) { + return _VerifierProxy.contract.Transact(opts, "setAccessController", accessController) +} + +func (_VerifierProxy *VerifierProxySession) SetAccessController(accessController common.Address) (*types.Transaction, error) { + return _VerifierProxy.Contract.SetAccessController(&_VerifierProxy.TransactOpts, accessController) +} + +func (_VerifierProxy *VerifierProxyTransactorSession) SetAccessController(accessController common.Address) (*types.Transaction, error) { + return _VerifierProxy.Contract.SetAccessController(&_VerifierProxy.TransactOpts, accessController) +} + +func (_VerifierProxy *VerifierProxyTransactor) SetFeeManager(opts *bind.TransactOpts, feeManager common.Address) (*types.Transaction, error) { + return _VerifierProxy.contract.Transact(opts, "setFeeManager", feeManager) +} + +func (_VerifierProxy *VerifierProxySession) SetFeeManager(feeManager common.Address) (*types.Transaction, error) { + return _VerifierProxy.Contract.SetFeeManager(&_VerifierProxy.TransactOpts, feeManager) +} + +func (_VerifierProxy *VerifierProxyTransactorSession) SetFeeManager(feeManager common.Address) (*types.Transaction, error) { + return _VerifierProxy.Contract.SetFeeManager(&_VerifierProxy.TransactOpts, feeManager) +} + +func (_VerifierProxy *VerifierProxyTransactor) SetVerifier(opts *bind.TransactOpts, currentConfigDigest [32]byte, newConfigDigest [32]byte, addressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _VerifierProxy.contract.Transact(opts, "setVerifier", currentConfigDigest, newConfigDigest, addressesAndWeights) +} + +func (_VerifierProxy *VerifierProxySession) SetVerifier(currentConfigDigest [32]byte, newConfigDigest [32]byte, addressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _VerifierProxy.Contract.SetVerifier(&_VerifierProxy.TransactOpts, currentConfigDigest, newConfigDigest, addressesAndWeights) +} + +func (_VerifierProxy *VerifierProxyTransactorSession) SetVerifier(currentConfigDigest [32]byte, newConfigDigest [32]byte, addressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _VerifierProxy.Contract.SetVerifier(&_VerifierProxy.TransactOpts, currentConfigDigest, newConfigDigest, addressesAndWeights) +} + +func (_VerifierProxy *VerifierProxyTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _VerifierProxy.contract.Transact(opts, "transferOwnership", to) +} + +func (_VerifierProxy *VerifierProxySession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _VerifierProxy.Contract.TransferOwnership(&_VerifierProxy.TransactOpts, to) +} + +func (_VerifierProxy *VerifierProxyTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _VerifierProxy.Contract.TransferOwnership(&_VerifierProxy.TransactOpts, to) +} + +func (_VerifierProxy *VerifierProxyTransactor) UnsetVerifier(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) { + return _VerifierProxy.contract.Transact(opts, "unsetVerifier", configDigest) +} + +func (_VerifierProxy *VerifierProxySession) UnsetVerifier(configDigest [32]byte) (*types.Transaction, error) { + return _VerifierProxy.Contract.UnsetVerifier(&_VerifierProxy.TransactOpts, configDigest) +} + +func (_VerifierProxy *VerifierProxyTransactorSession) UnsetVerifier(configDigest [32]byte) (*types.Transaction, error) { + return _VerifierProxy.Contract.UnsetVerifier(&_VerifierProxy.TransactOpts, configDigest) +} + +func (_VerifierProxy *VerifierProxyTransactor) Verify(opts *bind.TransactOpts, payload []byte) (*types.Transaction, error) { + return _VerifierProxy.contract.Transact(opts, "verify", payload) +} + +func (_VerifierProxy *VerifierProxySession) Verify(payload []byte) (*types.Transaction, error) { + return _VerifierProxy.Contract.Verify(&_VerifierProxy.TransactOpts, payload) +} + +func (_VerifierProxy *VerifierProxyTransactorSession) Verify(payload []byte) (*types.Transaction, error) { + return _VerifierProxy.Contract.Verify(&_VerifierProxy.TransactOpts, payload) +} + +type VerifierProxyAccessControllerSetIterator struct { + Event *VerifierProxyAccessControllerSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierProxyAccessControllerSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierProxyAccessControllerSet) + 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(VerifierProxyAccessControllerSet) + 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 *VerifierProxyAccessControllerSetIterator) Error() error { + return it.fail +} + +func (it *VerifierProxyAccessControllerSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierProxyAccessControllerSet struct { + OldAccessController common.Address + NewAccessController common.Address + Raw types.Log +} + +func (_VerifierProxy *VerifierProxyFilterer) FilterAccessControllerSet(opts *bind.FilterOpts) (*VerifierProxyAccessControllerSetIterator, error) { + + logs, sub, err := _VerifierProxy.contract.FilterLogs(opts, "AccessControllerSet") + if err != nil { + return nil, err + } + return &VerifierProxyAccessControllerSetIterator{contract: _VerifierProxy.contract, event: "AccessControllerSet", logs: logs, sub: sub}, nil +} + +func (_VerifierProxy *VerifierProxyFilterer) WatchAccessControllerSet(opts *bind.WatchOpts, sink chan<- *VerifierProxyAccessControllerSet) (event.Subscription, error) { + + logs, sub, err := _VerifierProxy.contract.WatchLogs(opts, "AccessControllerSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierProxyAccessControllerSet) + if err := _VerifierProxy.contract.UnpackLog(event, "AccessControllerSet", 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 (_VerifierProxy *VerifierProxyFilterer) ParseAccessControllerSet(log types.Log) (*VerifierProxyAccessControllerSet, error) { + event := new(VerifierProxyAccessControllerSet) + if err := _VerifierProxy.contract.UnpackLog(event, "AccessControllerSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierProxyFeeManagerSetIterator struct { + Event *VerifierProxyFeeManagerSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierProxyFeeManagerSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierProxyFeeManagerSet) + 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(VerifierProxyFeeManagerSet) + 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 *VerifierProxyFeeManagerSetIterator) Error() error { + return it.fail +} + +func (it *VerifierProxyFeeManagerSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierProxyFeeManagerSet struct { + OldFeeManager common.Address + NewFeeManager common.Address + Raw types.Log +} + +func (_VerifierProxy *VerifierProxyFilterer) FilterFeeManagerSet(opts *bind.FilterOpts) (*VerifierProxyFeeManagerSetIterator, error) { + + logs, sub, err := _VerifierProxy.contract.FilterLogs(opts, "FeeManagerSet") + if err != nil { + return nil, err + } + return &VerifierProxyFeeManagerSetIterator{contract: _VerifierProxy.contract, event: "FeeManagerSet", logs: logs, sub: sub}, nil +} + +func (_VerifierProxy *VerifierProxyFilterer) WatchFeeManagerSet(opts *bind.WatchOpts, sink chan<- *VerifierProxyFeeManagerSet) (event.Subscription, error) { + + logs, sub, err := _VerifierProxy.contract.WatchLogs(opts, "FeeManagerSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierProxyFeeManagerSet) + if err := _VerifierProxy.contract.UnpackLog(event, "FeeManagerSet", 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 (_VerifierProxy *VerifierProxyFilterer) ParseFeeManagerSet(log types.Log) (*VerifierProxyFeeManagerSet, error) { + event := new(VerifierProxyFeeManagerSet) + if err := _VerifierProxy.contract.UnpackLog(event, "FeeManagerSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierProxyOwnershipTransferRequestedIterator struct { + Event *VerifierProxyOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierProxyOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierProxyOwnershipTransferRequested) + 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(VerifierProxyOwnershipTransferRequested) + 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 *VerifierProxyOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *VerifierProxyOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierProxyOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_VerifierProxy *VerifierProxyFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifierProxyOwnershipTransferRequestedIterator, 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 := _VerifierProxy.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &VerifierProxyOwnershipTransferRequestedIterator{contract: _VerifierProxy.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_VerifierProxy *VerifierProxyFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifierProxyOwnershipTransferRequested, 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 := _VerifierProxy.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(VerifierProxyOwnershipTransferRequested) + if err := _VerifierProxy.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 (_VerifierProxy *VerifierProxyFilterer) ParseOwnershipTransferRequested(log types.Log) (*VerifierProxyOwnershipTransferRequested, error) { + event := new(VerifierProxyOwnershipTransferRequested) + if err := _VerifierProxy.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierProxyOwnershipTransferredIterator struct { + Event *VerifierProxyOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierProxyOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierProxyOwnershipTransferred) + 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(VerifierProxyOwnershipTransferred) + 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 *VerifierProxyOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *VerifierProxyOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierProxyOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_VerifierProxy *VerifierProxyFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifierProxyOwnershipTransferredIterator, 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 := _VerifierProxy.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &VerifierProxyOwnershipTransferredIterator{contract: _VerifierProxy.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_VerifierProxy *VerifierProxyFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifierProxyOwnershipTransferred, 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 := _VerifierProxy.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(VerifierProxyOwnershipTransferred) + if err := _VerifierProxy.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 (_VerifierProxy *VerifierProxyFilterer) ParseOwnershipTransferred(log types.Log) (*VerifierProxyOwnershipTransferred, error) { + event := new(VerifierProxyOwnershipTransferred) + if err := _VerifierProxy.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierProxyVerifierInitializedIterator struct { + Event *VerifierProxyVerifierInitialized + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierProxyVerifierInitializedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierProxyVerifierInitialized) + 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(VerifierProxyVerifierInitialized) + 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 *VerifierProxyVerifierInitializedIterator) Error() error { + return it.fail +} + +func (it *VerifierProxyVerifierInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierProxyVerifierInitialized struct { + VerifierAddress common.Address + Raw types.Log +} + +func (_VerifierProxy *VerifierProxyFilterer) FilterVerifierInitialized(opts *bind.FilterOpts) (*VerifierProxyVerifierInitializedIterator, error) { + + logs, sub, err := _VerifierProxy.contract.FilterLogs(opts, "VerifierInitialized") + if err != nil { + return nil, err + } + return &VerifierProxyVerifierInitializedIterator{contract: _VerifierProxy.contract, event: "VerifierInitialized", logs: logs, sub: sub}, nil +} + +func (_VerifierProxy *VerifierProxyFilterer) WatchVerifierInitialized(opts *bind.WatchOpts, sink chan<- *VerifierProxyVerifierInitialized) (event.Subscription, error) { + + logs, sub, err := _VerifierProxy.contract.WatchLogs(opts, "VerifierInitialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierProxyVerifierInitialized) + if err := _VerifierProxy.contract.UnpackLog(event, "VerifierInitialized", 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 (_VerifierProxy *VerifierProxyFilterer) ParseVerifierInitialized(log types.Log) (*VerifierProxyVerifierInitialized, error) { + event := new(VerifierProxyVerifierInitialized) + if err := _VerifierProxy.contract.UnpackLog(event, "VerifierInitialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierProxyVerifierSetIterator struct { + Event *VerifierProxyVerifierSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierProxyVerifierSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierProxyVerifierSet) + 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(VerifierProxyVerifierSet) + 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 *VerifierProxyVerifierSetIterator) Error() error { + return it.fail +} + +func (it *VerifierProxyVerifierSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierProxyVerifierSet struct { + OldConfigDigest [32]byte + NewConfigDigest [32]byte + VerifierAddress common.Address + Raw types.Log +} + +func (_VerifierProxy *VerifierProxyFilterer) FilterVerifierSet(opts *bind.FilterOpts) (*VerifierProxyVerifierSetIterator, error) { + + logs, sub, err := _VerifierProxy.contract.FilterLogs(opts, "VerifierSet") + if err != nil { + return nil, err + } + return &VerifierProxyVerifierSetIterator{contract: _VerifierProxy.contract, event: "VerifierSet", logs: logs, sub: sub}, nil +} + +func (_VerifierProxy *VerifierProxyFilterer) WatchVerifierSet(opts *bind.WatchOpts, sink chan<- *VerifierProxyVerifierSet) (event.Subscription, error) { + + logs, sub, err := _VerifierProxy.contract.WatchLogs(opts, "VerifierSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierProxyVerifierSet) + if err := _VerifierProxy.contract.UnpackLog(event, "VerifierSet", 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 (_VerifierProxy *VerifierProxyFilterer) ParseVerifierSet(log types.Log) (*VerifierProxyVerifierSet, error) { + event := new(VerifierProxyVerifierSet) + if err := _VerifierProxy.contract.UnpackLog(event, "VerifierSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierProxyVerifierUnsetIterator struct { + Event *VerifierProxyVerifierUnset + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierProxyVerifierUnsetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierProxyVerifierUnset) + 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(VerifierProxyVerifierUnset) + 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 *VerifierProxyVerifierUnsetIterator) Error() error { + return it.fail +} + +func (it *VerifierProxyVerifierUnsetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierProxyVerifierUnset struct { + ConfigDigest [32]byte + VerifierAddress common.Address + Raw types.Log +} + +func (_VerifierProxy *VerifierProxyFilterer) FilterVerifierUnset(opts *bind.FilterOpts) (*VerifierProxyVerifierUnsetIterator, error) { + + logs, sub, err := _VerifierProxy.contract.FilterLogs(opts, "VerifierUnset") + if err != nil { + return nil, err + } + return &VerifierProxyVerifierUnsetIterator{contract: _VerifierProxy.contract, event: "VerifierUnset", logs: logs, sub: sub}, nil +} + +func (_VerifierProxy *VerifierProxyFilterer) WatchVerifierUnset(opts *bind.WatchOpts, sink chan<- *VerifierProxyVerifierUnset) (event.Subscription, error) { + + logs, sub, err := _VerifierProxy.contract.WatchLogs(opts, "VerifierUnset") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierProxyVerifierUnset) + if err := _VerifierProxy.contract.UnpackLog(event, "VerifierUnset", 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 (_VerifierProxy *VerifierProxyFilterer) ParseVerifierUnset(log types.Log) (*VerifierProxyVerifierUnset, error) { + event := new(VerifierProxyVerifierUnset) + if err := _VerifierProxy.contract.UnpackLog(event, "VerifierUnset", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_VerifierProxy *VerifierProxy) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _VerifierProxy.abi.Events["AccessControllerSet"].ID: + return _VerifierProxy.ParseAccessControllerSet(log) + case _VerifierProxy.abi.Events["FeeManagerSet"].ID: + return _VerifierProxy.ParseFeeManagerSet(log) + case _VerifierProxy.abi.Events["OwnershipTransferRequested"].ID: + return _VerifierProxy.ParseOwnershipTransferRequested(log) + case _VerifierProxy.abi.Events["OwnershipTransferred"].ID: + return _VerifierProxy.ParseOwnershipTransferred(log) + case _VerifierProxy.abi.Events["VerifierInitialized"].ID: + return _VerifierProxy.ParseVerifierInitialized(log) + case _VerifierProxy.abi.Events["VerifierSet"].ID: + return _VerifierProxy.ParseVerifierSet(log) + case _VerifierProxy.abi.Events["VerifierUnset"].ID: + return _VerifierProxy.ParseVerifierUnset(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (VerifierProxyAccessControllerSet) Topic() common.Hash { + return common.HexToHash("0x953e92b1a6442e9c3242531154a3f6f6eb00b4e9c719ba8118fa6235e4ce89b6") +} + +func (VerifierProxyFeeManagerSet) Topic() common.Hash { + return common.HexToHash("0x04628abcaa6b1674651352125cb94b65b289145bc2bc4d67720bb7d966372f03") +} + +func (VerifierProxyOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (VerifierProxyOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (VerifierProxyVerifierInitialized) Topic() common.Hash { + return common.HexToHash("0x1f2cd7c97f4d801b5efe26cc409617c1fd6c5ef786e79aacb90af40923e4e8e9") +} + +func (VerifierProxyVerifierSet) Topic() common.Hash { + return common.HexToHash("0xbeb513e532542a562ac35699e7cd9ae7d198dcd3eee15bada6c857d28ceaddcf") +} + +func (VerifierProxyVerifierUnset) Topic() common.Hash { + return common.HexToHash("0x11dc15c4b8ac2b183166cc8427e5385a5ece8308217a4217338c6a7614845c4c") +} + +func (_VerifierProxy *VerifierProxy) Address() common.Address { + return _VerifierProxy.address +} + +type VerifierProxyInterface interface { + GetVerifier(opts *bind.CallOpts, configDigest [32]byte) (common.Address, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SAccessController(opts *bind.CallOpts) (common.Address, error) + + SFeeManager(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + InitializeVerifier(opts *bind.TransactOpts, verifierAddress common.Address) (*types.Transaction, error) + + SetAccessController(opts *bind.TransactOpts, accessController common.Address) (*types.Transaction, error) + + SetFeeManager(opts *bind.TransactOpts, feeManager common.Address) (*types.Transaction, error) + + SetVerifier(opts *bind.TransactOpts, currentConfigDigest [32]byte, newConfigDigest [32]byte, addressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + UnsetVerifier(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) + + Verify(opts *bind.TransactOpts, payload []byte) (*types.Transaction, error) + + FilterAccessControllerSet(opts *bind.FilterOpts) (*VerifierProxyAccessControllerSetIterator, error) + + WatchAccessControllerSet(opts *bind.WatchOpts, sink chan<- *VerifierProxyAccessControllerSet) (event.Subscription, error) + + ParseAccessControllerSet(log types.Log) (*VerifierProxyAccessControllerSet, error) + + FilterFeeManagerSet(opts *bind.FilterOpts) (*VerifierProxyFeeManagerSetIterator, error) + + WatchFeeManagerSet(opts *bind.WatchOpts, sink chan<- *VerifierProxyFeeManagerSet) (event.Subscription, error) + + ParseFeeManagerSet(log types.Log) (*VerifierProxyFeeManagerSet, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifierProxyOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifierProxyOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*VerifierProxyOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifierProxyOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifierProxyOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*VerifierProxyOwnershipTransferred, error) + + FilterVerifierInitialized(opts *bind.FilterOpts) (*VerifierProxyVerifierInitializedIterator, error) + + WatchVerifierInitialized(opts *bind.WatchOpts, sink chan<- *VerifierProxyVerifierInitialized) (event.Subscription, error) + + ParseVerifierInitialized(log types.Log) (*VerifierProxyVerifierInitialized, error) + + FilterVerifierSet(opts *bind.FilterOpts) (*VerifierProxyVerifierSetIterator, error) + + WatchVerifierSet(opts *bind.WatchOpts, sink chan<- *VerifierProxyVerifierSet) (event.Subscription, error) + + ParseVerifierSet(log types.Log) (*VerifierProxyVerifierSet, error) + + FilterVerifierUnset(opts *bind.FilterOpts) (*VerifierProxyVerifierUnsetIterator, error) + + WatchVerifierUnset(opts *bind.WatchOpts, sink chan<- *VerifierProxyVerifierUnset) (event.Subscription, error) + + ParseVerifierUnset(log types.Log) (*VerifierProxyVerifierUnset, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt new file mode 100644 index 00000000000..13b0f9ba040 --- /dev/null +++ b/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -0,0 +1,9 @@ +GETH_VERSION: 1.12.0 +errored_verifier: ../../../contracts/solc/v0.8.16/ErroredVerifier.abi ../../../contracts/solc/v0.8.16/ErroredVerifier.bin 1b0a03b90137d31fceb340b80ade65a4ed52fa63c5caf24183ce3f63567d818f +exposed_verifier: ../../../contracts/solc/v0.8.16/ExposedVerifier.abi ../../../contracts/solc/v0.8.16/ExposedVerifier.bin 6932cea8f2738e874d3ec9e1a4231d2421704030c071d9e15dd2f7f08482c246 +fee_manager: ../../../contracts/solc/v0.8.16/FeeManager.abi ../../../contracts/solc/v0.8.16/FeeManager.bin 0fca974f9243402e60e1420382efe594a4eed910a849711a86b76bde01bba184 +llo_feeds: ../../../contracts/solc/v0.8.16/FeeManager.abi ../../../contracts/solc/v0.8.16/FeeManager.bin cb71e018f67e49d7bc0e194c822204dfd59f79ff42e4fc8fd8ab63f3acd71361 +llo_feeds_test: ../../../contracts/solc/v0.8.16/ExposedVerifier.abi ../../../contracts/solc/v0.8.16/ExposedVerifier.bin 6932cea8f2738e874d3ec9e1a4231d2421704030c071d9e15dd2f7f08482c246 +reward_manager: ../../../contracts/solc/v0.8.16/RewardManager.abi ../../../contracts/solc/v0.8.16/RewardManager.bin b8a37ed1b1eb92004a5e9d6936877bf7254d04799c594824764bab5e52233d2c +verifier: ../../../contracts/solc/v0.8.16/Verifier.abi ../../../contracts/solc/v0.8.16/Verifier.bin 3c9b047bd96056a8bf85c0a1e928044c1166c58c4bd6986975100877ff43f1ec +verifier_proxy: ../../../contracts/solc/v0.8.16/VerifierProxy.abi ../../../contracts/solc/v0.8.16/VerifierProxy.bin 64c61227ccc947171c35c5cd5dc664c492fbe2139fdfee70d4941a0109261341 diff --git a/core/gethwrappers/llo-feeds/go_generate.go b/core/gethwrappers/llo-feeds/go_generate.go new file mode 100644 index 00000000000..8d9e3be0493 --- /dev/null +++ b/core/gethwrappers/llo-feeds/go_generate.go @@ -0,0 +1,11 @@ +// Package gethwrappers provides tools for wrapping solidity contracts with +// golang packages, using abigen. +package gethwrappers + +// Chainlink LLO +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.16/Verifier.abi ../../../contracts/solc/v0.8.16/Verifier.bin Verifier verifier +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.16/VerifierProxy.abi ../../../contracts/solc/v0.8.16/VerifierProxy.bin VerifierProxy verifier_proxy +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.16/ErroredVerifier.abi ../../../contracts/solc/v0.8.16/ErroredVerifier.bin ErroredVerifier errored_verifier +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.16/ExposedVerifier.abi ../../../contracts/solc/v0.8.16/ExposedVerifier.bin ExposedVerifier exposed_verifier +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.16/RewardManager.abi ../../../contracts/solc/v0.8.16/RewardManager.bin RewardManager reward_manager +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.16/FeeManager.abi ../../../contracts/solc/v0.8.16/FeeManager.bin FeeManager fee_manager diff --git a/core/gethwrappers/shared/generated/burn_mint_erc677/burn_mint_erc677.go b/core/gethwrappers/shared/generated/burn_mint_erc677/burn_mint_erc677.go new file mode 100644 index 00000000000..f138b3b1f00 --- /dev/null +++ b/core/gethwrappers/shared/generated/burn_mint_erc677/burn_mint_erc677.go @@ -0,0 +1,2068 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package burn_mint_erc677 + +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 BurnMintERC677MetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"decimals_\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"maxSupply_\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"supplyAfterMint\",\"type\":\"uint256\"}],\"name\":\"MaxSupplyExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotBurner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotMinter\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"BurnAccessGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"BurnAccessRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MintAccessGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MintAccessRevoked\",\"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\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseApproval\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBurners\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMinters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"grantBurnRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burnAndMinter\",\"type\":\"address\"}],\"name\":\"grantMintAndBurnRoles\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"grantMintRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"isBurner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"revokeBurnRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"revokeMintRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"transferAndCall\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60c06040523480156200001157600080fd5b50604051620022dd380380620022dd833981016040819052620000349162000277565b338060008686818160036200004a838262000391565b50600462000059828262000391565b5050506001600160a01b0384169150620000bc90505760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600580546001600160a01b0319166001600160a01b0384811691909117909155811615620000ef57620000ef8162000106565b50505060ff90911660805260a052506200045d9050565b336001600160a01b03821603620001605760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000b3565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001da57600080fd5b81516001600160401b0380821115620001f757620001f7620001b2565b604051601f8301601f19908116603f01168101908282118183101715620002225762000222620001b2565b816040528381526020925086838588010111156200023f57600080fd5b600091505b8382101562000263578582018301518183018401529082019062000244565b600093810190920192909252949350505050565b600080600080608085870312156200028e57600080fd5b84516001600160401b0380821115620002a657600080fd5b620002b488838901620001c8565b95506020870151915080821115620002cb57600080fd5b50620002da87828801620001c8565b935050604085015160ff81168114620002f257600080fd5b6060959095015193969295505050565b600181811c908216806200031757607f821691505b6020821081036200033857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038c57600081815260208120601f850160051c81016020861015620003675750805b601f850160051c820191505b81811015620003885782815560010162000373565b5050505b505050565b81516001600160401b03811115620003ad57620003ad620001b2565b620003c581620003be845462000302565b846200033e565b602080601f831160018114620003fd5760008415620003e45750858301515b600019600386901b1c1916600185901b17855562000388565b600085815260208120601f198616915b828110156200042e578886015182559484019460019091019084016200040d565b50858210156200044d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a051611e4c6200049160003960008181610447015281816108c301526108ed015260006102710152611e4c6000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c806379cc67901161010f578063c2e3273d116100a2578063d73dd62311610071578063d73dd6231461046b578063dd62ed3e1461047e578063f2fde38b146104c4578063f81094f3146104d757600080fd5b8063c2e3273d1461040c578063c630948d1461041f578063c64d0ebc14610432578063d5abeb011461044557600080fd5b80639dc29fac116100de5780639dc29fac146103c0578063a457c2d7146103d3578063a9059cbb146103e6578063aa271e1a146103f957600080fd5b806379cc67901461037557806386fe8b43146103885780638da5cb5b1461039057806395d89b41146103b857600080fd5b806340c10f19116101875780636618846311610156578063661884631461030f5780636b32810b1461032257806370a082311461033757806379ba50971461036d57600080fd5b806340c10f19146102c157806342966c68146102d65780634334614a146102e95780634f5632f8146102fc57600080fd5b806323b872dd116101c357806323b872dd14610257578063313ce5671461026a578063395093511461029b5780634000aea0146102ae57600080fd5b806301ffc9a7146101f557806306fdde031461021d578063095ea7b31461023257806318160ddd14610245575b600080fd5b6102086102033660046119b9565b6104ea565b60405190151581526020015b60405180910390f35b61022561061b565b6040516102149190611a5f565b610208610240366004611a9b565b6106ad565b6002545b604051908152602001610214565b610208610265366004611ac5565b6106c5565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610214565b6102086102a9366004611a9b565b6106e9565b6102086102bc366004611b30565b610735565b6102d46102cf366004611a9b565b610858565b005b6102d46102e4366004611c19565b61097f565b6102086102f7366004611c32565b6109cc565b6102d461030a366004611c32565b6109d9565b61020861031d366004611a9b565b610a35565b61032a610a48565b6040516102149190611c4d565b610249610345366004611c32565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6102d4610a59565b6102d4610383366004611a9b565b610b5a565b61032a610ba9565b60055460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b610225610bb5565b6102d46103ce366004611a9b565b610bc4565b6102086103e1366004611a9b565b610bce565b6102086103f4366004611a9b565b610c9f565b610208610407366004611c32565b610cad565b6102d461041a366004611c32565b610cba565b6102d461042d366004611c32565b610d16565b6102d4610440366004611c32565b610d24565b7f0000000000000000000000000000000000000000000000000000000000000000610249565b6102d4610479366004611a9b565b610d80565b61024961048c366004611ca7565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6102d46104d2366004611c32565b610d8a565b6102d46104e5366004611c32565b610d9b565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f36372b0700000000000000000000000000000000000000000000000000000000148061057d57507fffffffff0000000000000000000000000000000000000000000000000000000082167f4000aea000000000000000000000000000000000000000000000000000000000145b806105c957507fffffffff0000000000000000000000000000000000000000000000000000000082167fe6599b4d00000000000000000000000000000000000000000000000000000000145b8061061557507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b60606003805461062a90611cda565b80601f016020809104026020016040519081016040528092919081815260200182805461065690611cda565b80156106a35780601f10610678576101008083540402835291602001916106a3565b820191906000526020600020905b81548152906001019060200180831161068657829003601f168201915b5050505050905090565b6000336106bb818585610df7565b5060019392505050565b6000336106d3858285610e2b565b6106de858585610efc565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906106bb9082908690610730908790611d5c565b610df7565b60006107418484610c9f565b508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c1685856040516107a1929190611d6f565b60405180910390a373ffffffffffffffffffffffffffffffffffffffff84163b156106bb576040517fa4c0ed3600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063a4c0ed369061081c90339087908790600401611d90565b600060405180830381600087803b15801561083657600080fd5b505af115801561084a573d6000803e3d6000fd5b505050505060019392505050565b61086133610cad565b61089e576040517fe2c8c9d50000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b813073ffffffffffffffffffffffffffffffffffffffff8216036108c157600080fd5b7f00000000000000000000000000000000000000000000000000000000000000001580159061092257507f00000000000000000000000000000000000000000000000000000000000000008261091660025490565b6109209190611d5c565b115b15610970578161093160025490565b61093b9190611d5c565b6040517fcbbf111300000000000000000000000000000000000000000000000000000000815260040161089591815260200190565b61097a8383610f2a565b505050565b610988336109cc565b6109c0576040517fc820b10b000000000000000000000000000000000000000000000000000000008152336004820152602401610895565b6109c98161101d565b50565b6000610615600983611027565b6109e1611056565b6109ec6009826110d9565b156109c95760405173ffffffffffffffffffffffffffffffffffffffff8216907f0a675452746933cefe3d74182e78db7afe57ba60eaa4234b5d85e9aa41b0610c90600090a250565b6000610a418383610bce565b9392505050565b6060610a5460076110fb565b905090565b60065473ffffffffffffffffffffffffffffffffffffffff163314610ada576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610895565b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560068054909116905560405173ffffffffffffffffffffffffffffffffffffffff909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b610b63336109cc565b610b9b576040517fc820b10b000000000000000000000000000000000000000000000000000000008152336004820152602401610895565b610ba58282611108565b5050565b6060610a5460096110fb565b60606004805461062a90611cda565b610ba58282610b5a565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610c92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610895565b6106de8286868403610df7565b6000336106bb818585610efc565b6000610615600783611027565b610cc2611056565b610ccd60078261111d565b156109c95760405173ffffffffffffffffffffffffffffffffffffffff8216907fe46fef8bbff1389d9010703cf8ebb363fb3daf5bf56edc27080b67bc8d9251ea90600090a250565b610d1f81610cba565b6109c9815b610d2c611056565b610d3760098261111d565b156109c95760405173ffffffffffffffffffffffffffffffffffffffff8216907f92308bb7573b2a3d17ddb868b39d8ebec433f3194421abc22d084f89658c9bad90600090a250565b61097a82826106e9565b610d92611056565b6109c98161113f565b610da3611056565b610dae6007826110d9565b156109c95760405173ffffffffffffffffffffffffffffffffffffffff8216907fed998b960f6340d045f620c119730f7aa7995e7425c2401d3a5b64ff998a59e990600090a250565b813073ffffffffffffffffffffffffffffffffffffffff821603610e1a57600080fd5b610e25848484611235565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610e255781811015610eef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610895565b610e258484848403610df7565b813073ffffffffffffffffffffffffffffffffffffffff821603610f1f57600080fd5b610e258484846113e8565b73ffffffffffffffffffffffffffffffffffffffff8216610fa7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610895565b8060026000828254610fb99190611d5c565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6109c93382611657565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610a41565b60055473ffffffffffffffffffffffffffffffffffffffff1633146110d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610895565b565b6000610a418373ffffffffffffffffffffffffffffffffffffffff841661181b565b60606000610a418361190e565b611113823383610e2b565b610ba58282611657565b6000610a418373ffffffffffffffffffffffffffffffffffffffff841661196a565b3373ffffffffffffffffffffffffffffffffffffffff8216036111be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610895565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b73ffffffffffffffffffffffffffffffffffffffff83166112d7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff821661137a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff831661148b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff821661152e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040902054818110156115e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610e25565b73ffffffffffffffffffffffffffffffffffffffff82166116fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156117b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6000818152600183016020526040812054801561190457600061183f600183611dce565b855490915060009061185390600190611dce565b90508181146118b857600086600001828154811061187357611873611de1565b906000526020600020015490508087600001848154811061189657611896611de1565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806118c9576118c9611e10565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610615565b6000915050610615565b60608160000180548060200260200160405190810160405280929190818152602001828054801561195e57602002820191906000526020600020905b81548152602001906001019080831161194a575b50505050509050919050565b60008181526001830160205260408120546119b157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610615565b506000610615565b6000602082840312156119cb57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610a4157600080fd5b6000815180845260005b81811015611a2157602081850181015186830182015201611a05565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610a4160208301846119fb565b803573ffffffffffffffffffffffffffffffffffffffff81168114611a9657600080fd5b919050565b60008060408385031215611aae57600080fd5b611ab783611a72565b946020939093013593505050565b600080600060608486031215611ada57600080fd5b611ae384611a72565b9250611af160208501611a72565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080600060608486031215611b4557600080fd5b611b4e84611a72565b925060208401359150604084013567ffffffffffffffff80821115611b7257600080fd5b818601915086601f830112611b8657600080fd5b813581811115611b9857611b98611b01565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611bde57611bde611b01565b81604052828152896020848701011115611bf757600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b600060208284031215611c2b57600080fd5b5035919050565b600060208284031215611c4457600080fd5b610a4182611a72565b6020808252825182820181905260009190848201906040850190845b81811015611c9b57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611c69565b50909695505050505050565b60008060408385031215611cba57600080fd5b611cc383611a72565b9150611cd160208401611a72565b90509250929050565b600181811c90821680611cee57607f821691505b602082108103611d27577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561061557610615611d2d565b828152604060208201526000611d8860408301846119fb565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000611dc560608301846119fb565b95945050505050565b8181038181111561061557610615611d2d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", +} + +var BurnMintERC677ABI = BurnMintERC677MetaData.ABI + +var BurnMintERC677Bin = BurnMintERC677MetaData.Bin + +func DeployBurnMintERC677(auth *bind.TransactOpts, backend bind.ContractBackend, name string, symbol string, decimals_ uint8, maxSupply_ *big.Int) (common.Address, *types.Transaction, *BurnMintERC677, error) { + parsed, err := BurnMintERC677MetaData.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(BurnMintERC677Bin), backend, name, symbol, decimals_, maxSupply_) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &BurnMintERC677{BurnMintERC677Caller: BurnMintERC677Caller{contract: contract}, BurnMintERC677Transactor: BurnMintERC677Transactor{contract: contract}, BurnMintERC677Filterer: BurnMintERC677Filterer{contract: contract}}, nil +} + +type BurnMintERC677 struct { + address common.Address + abi abi.ABI + BurnMintERC677Caller + BurnMintERC677Transactor + BurnMintERC677Filterer +} + +type BurnMintERC677Caller struct { + contract *bind.BoundContract +} + +type BurnMintERC677Transactor struct { + contract *bind.BoundContract +} + +type BurnMintERC677Filterer struct { + contract *bind.BoundContract +} + +type BurnMintERC677Session struct { + Contract *BurnMintERC677 + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type BurnMintERC677CallerSession struct { + Contract *BurnMintERC677Caller + CallOpts bind.CallOpts +} + +type BurnMintERC677TransactorSession struct { + Contract *BurnMintERC677Transactor + TransactOpts bind.TransactOpts +} + +type BurnMintERC677Raw struct { + Contract *BurnMintERC677 +} + +type BurnMintERC677CallerRaw struct { + Contract *BurnMintERC677Caller +} + +type BurnMintERC677TransactorRaw struct { + Contract *BurnMintERC677Transactor +} + +func NewBurnMintERC677(address common.Address, backend bind.ContractBackend) (*BurnMintERC677, error) { + abi, err := abi.JSON(strings.NewReader(BurnMintERC677ABI)) + if err != nil { + return nil, err + } + contract, err := bindBurnMintERC677(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &BurnMintERC677{address: address, abi: abi, BurnMintERC677Caller: BurnMintERC677Caller{contract: contract}, BurnMintERC677Transactor: BurnMintERC677Transactor{contract: contract}, BurnMintERC677Filterer: BurnMintERC677Filterer{contract: contract}}, nil +} + +func NewBurnMintERC677Caller(address common.Address, caller bind.ContractCaller) (*BurnMintERC677Caller, error) { + contract, err := bindBurnMintERC677(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &BurnMintERC677Caller{contract: contract}, nil +} + +func NewBurnMintERC677Transactor(address common.Address, transactor bind.ContractTransactor) (*BurnMintERC677Transactor, error) { + contract, err := bindBurnMintERC677(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &BurnMintERC677Transactor{contract: contract}, nil +} + +func NewBurnMintERC677Filterer(address common.Address, filterer bind.ContractFilterer) (*BurnMintERC677Filterer, error) { + contract, err := bindBurnMintERC677(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &BurnMintERC677Filterer{contract: contract}, nil +} + +func bindBurnMintERC677(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := BurnMintERC677MetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_BurnMintERC677 *BurnMintERC677Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _BurnMintERC677.Contract.BurnMintERC677Caller.contract.Call(opts, result, method, params...) +} + +func (_BurnMintERC677 *BurnMintERC677Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnMintERC677.Contract.BurnMintERC677Transactor.contract.Transfer(opts) +} + +func (_BurnMintERC677 *BurnMintERC677Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _BurnMintERC677.Contract.BurnMintERC677Transactor.contract.Transact(opts, method, params...) +} + +func (_BurnMintERC677 *BurnMintERC677CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _BurnMintERC677.Contract.contract.Call(opts, result, method, params...) +} + +func (_BurnMintERC677 *BurnMintERC677TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnMintERC677.Contract.contract.Transfer(opts) +} + +func (_BurnMintERC677 *BurnMintERC677TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _BurnMintERC677.Contract.contract.Transact(opts, method, params...) +} + +func (_BurnMintERC677 *BurnMintERC677Caller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) { + var out []interface{} + err := _BurnMintERC677.contract.Call(opts, &out, "allowance", owner, spender) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_BurnMintERC677 *BurnMintERC677Session) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _BurnMintERC677.Contract.Allowance(&_BurnMintERC677.CallOpts, owner, spender) +} + +func (_BurnMintERC677 *BurnMintERC677CallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _BurnMintERC677.Contract.Allowance(&_BurnMintERC677.CallOpts, owner, spender) +} + +func (_BurnMintERC677 *BurnMintERC677Caller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) { + var out []interface{} + err := _BurnMintERC677.contract.Call(opts, &out, "balanceOf", account) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_BurnMintERC677 *BurnMintERC677Session) BalanceOf(account common.Address) (*big.Int, error) { + return _BurnMintERC677.Contract.BalanceOf(&_BurnMintERC677.CallOpts, account) +} + +func (_BurnMintERC677 *BurnMintERC677CallerSession) BalanceOf(account common.Address) (*big.Int, error) { + return _BurnMintERC677.Contract.BalanceOf(&_BurnMintERC677.CallOpts, account) +} + +func (_BurnMintERC677 *BurnMintERC677Caller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _BurnMintERC677.contract.Call(opts, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_BurnMintERC677 *BurnMintERC677Session) Decimals() (uint8, error) { + return _BurnMintERC677.Contract.Decimals(&_BurnMintERC677.CallOpts) +} + +func (_BurnMintERC677 *BurnMintERC677CallerSession) Decimals() (uint8, error) { + return _BurnMintERC677.Contract.Decimals(&_BurnMintERC677.CallOpts) +} + +func (_BurnMintERC677 *BurnMintERC677Caller) GetBurners(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _BurnMintERC677.contract.Call(opts, &out, "getBurners") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_BurnMintERC677 *BurnMintERC677Session) GetBurners() ([]common.Address, error) { + return _BurnMintERC677.Contract.GetBurners(&_BurnMintERC677.CallOpts) +} + +func (_BurnMintERC677 *BurnMintERC677CallerSession) GetBurners() ([]common.Address, error) { + return _BurnMintERC677.Contract.GetBurners(&_BurnMintERC677.CallOpts) +} + +func (_BurnMintERC677 *BurnMintERC677Caller) GetMinters(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _BurnMintERC677.contract.Call(opts, &out, "getMinters") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_BurnMintERC677 *BurnMintERC677Session) GetMinters() ([]common.Address, error) { + return _BurnMintERC677.Contract.GetMinters(&_BurnMintERC677.CallOpts) +} + +func (_BurnMintERC677 *BurnMintERC677CallerSession) GetMinters() ([]common.Address, error) { + return _BurnMintERC677.Contract.GetMinters(&_BurnMintERC677.CallOpts) +} + +func (_BurnMintERC677 *BurnMintERC677Caller) IsBurner(opts *bind.CallOpts, burner common.Address) (bool, error) { + var out []interface{} + err := _BurnMintERC677.contract.Call(opts, &out, "isBurner", burner) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnMintERC677 *BurnMintERC677Session) IsBurner(burner common.Address) (bool, error) { + return _BurnMintERC677.Contract.IsBurner(&_BurnMintERC677.CallOpts, burner) +} + +func (_BurnMintERC677 *BurnMintERC677CallerSession) IsBurner(burner common.Address) (bool, error) { + return _BurnMintERC677.Contract.IsBurner(&_BurnMintERC677.CallOpts, burner) +} + +func (_BurnMintERC677 *BurnMintERC677Caller) IsMinter(opts *bind.CallOpts, minter common.Address) (bool, error) { + var out []interface{} + err := _BurnMintERC677.contract.Call(opts, &out, "isMinter", minter) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnMintERC677 *BurnMintERC677Session) IsMinter(minter common.Address) (bool, error) { + return _BurnMintERC677.Contract.IsMinter(&_BurnMintERC677.CallOpts, minter) +} + +func (_BurnMintERC677 *BurnMintERC677CallerSession) IsMinter(minter common.Address) (bool, error) { + return _BurnMintERC677.Contract.IsMinter(&_BurnMintERC677.CallOpts, minter) +} + +func (_BurnMintERC677 *BurnMintERC677Caller) MaxSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _BurnMintERC677.contract.Call(opts, &out, "maxSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_BurnMintERC677 *BurnMintERC677Session) MaxSupply() (*big.Int, error) { + return _BurnMintERC677.Contract.MaxSupply(&_BurnMintERC677.CallOpts) +} + +func (_BurnMintERC677 *BurnMintERC677CallerSession) MaxSupply() (*big.Int, error) { + return _BurnMintERC677.Contract.MaxSupply(&_BurnMintERC677.CallOpts) +} + +func (_BurnMintERC677 *BurnMintERC677Caller) Name(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _BurnMintERC677.contract.Call(opts, &out, "name") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_BurnMintERC677 *BurnMintERC677Session) Name() (string, error) { + return _BurnMintERC677.Contract.Name(&_BurnMintERC677.CallOpts) +} + +func (_BurnMintERC677 *BurnMintERC677CallerSession) Name() (string, error) { + return _BurnMintERC677.Contract.Name(&_BurnMintERC677.CallOpts) +} + +func (_BurnMintERC677 *BurnMintERC677Caller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BurnMintERC677.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 (_BurnMintERC677 *BurnMintERC677Session) Owner() (common.Address, error) { + return _BurnMintERC677.Contract.Owner(&_BurnMintERC677.CallOpts) +} + +func (_BurnMintERC677 *BurnMintERC677CallerSession) Owner() (common.Address, error) { + return _BurnMintERC677.Contract.Owner(&_BurnMintERC677.CallOpts) +} + +func (_BurnMintERC677 *BurnMintERC677Caller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _BurnMintERC677.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnMintERC677 *BurnMintERC677Session) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _BurnMintERC677.Contract.SupportsInterface(&_BurnMintERC677.CallOpts, interfaceId) +} + +func (_BurnMintERC677 *BurnMintERC677CallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _BurnMintERC677.Contract.SupportsInterface(&_BurnMintERC677.CallOpts, interfaceId) +} + +func (_BurnMintERC677 *BurnMintERC677Caller) Symbol(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _BurnMintERC677.contract.Call(opts, &out, "symbol") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_BurnMintERC677 *BurnMintERC677Session) Symbol() (string, error) { + return _BurnMintERC677.Contract.Symbol(&_BurnMintERC677.CallOpts) +} + +func (_BurnMintERC677 *BurnMintERC677CallerSession) Symbol() (string, error) { + return _BurnMintERC677.Contract.Symbol(&_BurnMintERC677.CallOpts) +} + +func (_BurnMintERC677 *BurnMintERC677Caller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _BurnMintERC677.contract.Call(opts, &out, "totalSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_BurnMintERC677 *BurnMintERC677Session) TotalSupply() (*big.Int, error) { + return _BurnMintERC677.Contract.TotalSupply(&_BurnMintERC677.CallOpts) +} + +func (_BurnMintERC677 *BurnMintERC677CallerSession) TotalSupply() (*big.Int, error) { + return _BurnMintERC677.Contract.TotalSupply(&_BurnMintERC677.CallOpts) +} + +func (_BurnMintERC677 *BurnMintERC677Transactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BurnMintERC677.contract.Transact(opts, "acceptOwnership") +} + +func (_BurnMintERC677 *BurnMintERC677Session) AcceptOwnership() (*types.Transaction, error) { + return _BurnMintERC677.Contract.AcceptOwnership(&_BurnMintERC677.TransactOpts) +} + +func (_BurnMintERC677 *BurnMintERC677TransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _BurnMintERC677.Contract.AcceptOwnership(&_BurnMintERC677.TransactOpts) +} + +func (_BurnMintERC677 *BurnMintERC677Transactor) Approve(opts *bind.TransactOpts, spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.contract.Transact(opts, "approve", spender, amount) +} + +func (_BurnMintERC677 *BurnMintERC677Session) Approve(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.Approve(&_BurnMintERC677.TransactOpts, spender, amount) +} + +func (_BurnMintERC677 *BurnMintERC677TransactorSession) Approve(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.Approve(&_BurnMintERC677.TransactOpts, spender, amount) +} + +func (_BurnMintERC677 *BurnMintERC677Transactor) Burn(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.contract.Transact(opts, "burn", amount) +} + +func (_BurnMintERC677 *BurnMintERC677Session) Burn(amount *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.Burn(&_BurnMintERC677.TransactOpts, amount) +} + +func (_BurnMintERC677 *BurnMintERC677TransactorSession) Burn(amount *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.Burn(&_BurnMintERC677.TransactOpts, amount) +} + +func (_BurnMintERC677 *BurnMintERC677Transactor) Burn0(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.contract.Transact(opts, "burn0", account, amount) +} + +func (_BurnMintERC677 *BurnMintERC677Session) Burn0(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.Burn0(&_BurnMintERC677.TransactOpts, account, amount) +} + +func (_BurnMintERC677 *BurnMintERC677TransactorSession) Burn0(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.Burn0(&_BurnMintERC677.TransactOpts, account, amount) +} + +func (_BurnMintERC677 *BurnMintERC677Transactor) BurnFrom(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.contract.Transact(opts, "burnFrom", account, amount) +} + +func (_BurnMintERC677 *BurnMintERC677Session) BurnFrom(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.BurnFrom(&_BurnMintERC677.TransactOpts, account, amount) +} + +func (_BurnMintERC677 *BurnMintERC677TransactorSession) BurnFrom(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.BurnFrom(&_BurnMintERC677.TransactOpts, account, amount) +} + +func (_BurnMintERC677 *BurnMintERC677Transactor) DecreaseAllowance(opts *bind.TransactOpts, spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.contract.Transact(opts, "decreaseAllowance", spender, subtractedValue) +} + +func (_BurnMintERC677 *BurnMintERC677Session) DecreaseAllowance(spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.DecreaseAllowance(&_BurnMintERC677.TransactOpts, spender, subtractedValue) +} + +func (_BurnMintERC677 *BurnMintERC677TransactorSession) DecreaseAllowance(spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.DecreaseAllowance(&_BurnMintERC677.TransactOpts, spender, subtractedValue) +} + +func (_BurnMintERC677 *BurnMintERC677Transactor) DecreaseApproval(opts *bind.TransactOpts, spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.contract.Transact(opts, "decreaseApproval", spender, subtractedValue) +} + +func (_BurnMintERC677 *BurnMintERC677Session) DecreaseApproval(spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.DecreaseApproval(&_BurnMintERC677.TransactOpts, spender, subtractedValue) +} + +func (_BurnMintERC677 *BurnMintERC677TransactorSession) DecreaseApproval(spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.DecreaseApproval(&_BurnMintERC677.TransactOpts, spender, subtractedValue) +} + +func (_BurnMintERC677 *BurnMintERC677Transactor) GrantBurnRole(opts *bind.TransactOpts, burner common.Address) (*types.Transaction, error) { + return _BurnMintERC677.contract.Transact(opts, "grantBurnRole", burner) +} + +func (_BurnMintERC677 *BurnMintERC677Session) GrantBurnRole(burner common.Address) (*types.Transaction, error) { + return _BurnMintERC677.Contract.GrantBurnRole(&_BurnMintERC677.TransactOpts, burner) +} + +func (_BurnMintERC677 *BurnMintERC677TransactorSession) GrantBurnRole(burner common.Address) (*types.Transaction, error) { + return _BurnMintERC677.Contract.GrantBurnRole(&_BurnMintERC677.TransactOpts, burner) +} + +func (_BurnMintERC677 *BurnMintERC677Transactor) GrantMintAndBurnRoles(opts *bind.TransactOpts, burnAndMinter common.Address) (*types.Transaction, error) { + return _BurnMintERC677.contract.Transact(opts, "grantMintAndBurnRoles", burnAndMinter) +} + +func (_BurnMintERC677 *BurnMintERC677Session) GrantMintAndBurnRoles(burnAndMinter common.Address) (*types.Transaction, error) { + return _BurnMintERC677.Contract.GrantMintAndBurnRoles(&_BurnMintERC677.TransactOpts, burnAndMinter) +} + +func (_BurnMintERC677 *BurnMintERC677TransactorSession) GrantMintAndBurnRoles(burnAndMinter common.Address) (*types.Transaction, error) { + return _BurnMintERC677.Contract.GrantMintAndBurnRoles(&_BurnMintERC677.TransactOpts, burnAndMinter) +} + +func (_BurnMintERC677 *BurnMintERC677Transactor) GrantMintRole(opts *bind.TransactOpts, minter common.Address) (*types.Transaction, error) { + return _BurnMintERC677.contract.Transact(opts, "grantMintRole", minter) +} + +func (_BurnMintERC677 *BurnMintERC677Session) GrantMintRole(minter common.Address) (*types.Transaction, error) { + return _BurnMintERC677.Contract.GrantMintRole(&_BurnMintERC677.TransactOpts, minter) +} + +func (_BurnMintERC677 *BurnMintERC677TransactorSession) GrantMintRole(minter common.Address) (*types.Transaction, error) { + return _BurnMintERC677.Contract.GrantMintRole(&_BurnMintERC677.TransactOpts, minter) +} + +func (_BurnMintERC677 *BurnMintERC677Transactor) IncreaseAllowance(opts *bind.TransactOpts, spender common.Address, addedValue *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.contract.Transact(opts, "increaseAllowance", spender, addedValue) +} + +func (_BurnMintERC677 *BurnMintERC677Session) IncreaseAllowance(spender common.Address, addedValue *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.IncreaseAllowance(&_BurnMintERC677.TransactOpts, spender, addedValue) +} + +func (_BurnMintERC677 *BurnMintERC677TransactorSession) IncreaseAllowance(spender common.Address, addedValue *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.IncreaseAllowance(&_BurnMintERC677.TransactOpts, spender, addedValue) +} + +func (_BurnMintERC677 *BurnMintERC677Transactor) IncreaseApproval(opts *bind.TransactOpts, spender common.Address, addedValue *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.contract.Transact(opts, "increaseApproval", spender, addedValue) +} + +func (_BurnMintERC677 *BurnMintERC677Session) IncreaseApproval(spender common.Address, addedValue *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.IncreaseApproval(&_BurnMintERC677.TransactOpts, spender, addedValue) +} + +func (_BurnMintERC677 *BurnMintERC677TransactorSession) IncreaseApproval(spender common.Address, addedValue *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.IncreaseApproval(&_BurnMintERC677.TransactOpts, spender, addedValue) +} + +func (_BurnMintERC677 *BurnMintERC677Transactor) Mint(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.contract.Transact(opts, "mint", account, amount) +} + +func (_BurnMintERC677 *BurnMintERC677Session) Mint(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.Mint(&_BurnMintERC677.TransactOpts, account, amount) +} + +func (_BurnMintERC677 *BurnMintERC677TransactorSession) Mint(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.Mint(&_BurnMintERC677.TransactOpts, account, amount) +} + +func (_BurnMintERC677 *BurnMintERC677Transactor) RevokeBurnRole(opts *bind.TransactOpts, burner common.Address) (*types.Transaction, error) { + return _BurnMintERC677.contract.Transact(opts, "revokeBurnRole", burner) +} + +func (_BurnMintERC677 *BurnMintERC677Session) RevokeBurnRole(burner common.Address) (*types.Transaction, error) { + return _BurnMintERC677.Contract.RevokeBurnRole(&_BurnMintERC677.TransactOpts, burner) +} + +func (_BurnMintERC677 *BurnMintERC677TransactorSession) RevokeBurnRole(burner common.Address) (*types.Transaction, error) { + return _BurnMintERC677.Contract.RevokeBurnRole(&_BurnMintERC677.TransactOpts, burner) +} + +func (_BurnMintERC677 *BurnMintERC677Transactor) RevokeMintRole(opts *bind.TransactOpts, minter common.Address) (*types.Transaction, error) { + return _BurnMintERC677.contract.Transact(opts, "revokeMintRole", minter) +} + +func (_BurnMintERC677 *BurnMintERC677Session) RevokeMintRole(minter common.Address) (*types.Transaction, error) { + return _BurnMintERC677.Contract.RevokeMintRole(&_BurnMintERC677.TransactOpts, minter) +} + +func (_BurnMintERC677 *BurnMintERC677TransactorSession) RevokeMintRole(minter common.Address) (*types.Transaction, error) { + return _BurnMintERC677.Contract.RevokeMintRole(&_BurnMintERC677.TransactOpts, minter) +} + +func (_BurnMintERC677 *BurnMintERC677Transactor) Transfer(opts *bind.TransactOpts, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.contract.Transact(opts, "transfer", to, amount) +} + +func (_BurnMintERC677 *BurnMintERC677Session) Transfer(to common.Address, amount *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.Transfer(&_BurnMintERC677.TransactOpts, to, amount) +} + +func (_BurnMintERC677 *BurnMintERC677TransactorSession) Transfer(to common.Address, amount *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.Transfer(&_BurnMintERC677.TransactOpts, to, amount) +} + +func (_BurnMintERC677 *BurnMintERC677Transactor) TransferAndCall(opts *bind.TransactOpts, to common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _BurnMintERC677.contract.Transact(opts, "transferAndCall", to, amount, data) +} + +func (_BurnMintERC677 *BurnMintERC677Session) TransferAndCall(to common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _BurnMintERC677.Contract.TransferAndCall(&_BurnMintERC677.TransactOpts, to, amount, data) +} + +func (_BurnMintERC677 *BurnMintERC677TransactorSession) TransferAndCall(to common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _BurnMintERC677.Contract.TransferAndCall(&_BurnMintERC677.TransactOpts, to, amount, data) +} + +func (_BurnMintERC677 *BurnMintERC677Transactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.contract.Transact(opts, "transferFrom", from, to, amount) +} + +func (_BurnMintERC677 *BurnMintERC677Session) TransferFrom(from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.TransferFrom(&_BurnMintERC677.TransactOpts, from, to, amount) +} + +func (_BurnMintERC677 *BurnMintERC677TransactorSession) TransferFrom(from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _BurnMintERC677.Contract.TransferFrom(&_BurnMintERC677.TransactOpts, from, to, amount) +} + +func (_BurnMintERC677 *BurnMintERC677Transactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _BurnMintERC677.contract.Transact(opts, "transferOwnership", to) +} + +func (_BurnMintERC677 *BurnMintERC677Session) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _BurnMintERC677.Contract.TransferOwnership(&_BurnMintERC677.TransactOpts, to) +} + +func (_BurnMintERC677 *BurnMintERC677TransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _BurnMintERC677.Contract.TransferOwnership(&_BurnMintERC677.TransactOpts, to) +} + +type BurnMintERC677ApprovalIterator struct { + Event *BurnMintERC677Approval + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintERC677ApprovalIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintERC677Approval) + 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(BurnMintERC677Approval) + 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 *BurnMintERC677ApprovalIterator) Error() error { + return it.fail +} + +func (it *BurnMintERC677ApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintERC677Approval struct { + Owner common.Address + Spender common.Address + Value *big.Int + Raw types.Log +} + +func (_BurnMintERC677 *BurnMintERC677Filterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*BurnMintERC677ApprovalIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _BurnMintERC677.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return &BurnMintERC677ApprovalIterator{contract: _BurnMintERC677.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +func (_BurnMintERC677 *BurnMintERC677Filterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *BurnMintERC677Approval, owner []common.Address, spender []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _BurnMintERC677.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintERC677Approval) + if err := _BurnMintERC677.contract.UnpackLog(event, "Approval", 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 (_BurnMintERC677 *BurnMintERC677Filterer) ParseApproval(log types.Log) (*BurnMintERC677Approval, error) { + event := new(BurnMintERC677Approval) + if err := _BurnMintERC677.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintERC677BurnAccessGrantedIterator struct { + Event *BurnMintERC677BurnAccessGranted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintERC677BurnAccessGrantedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintERC677BurnAccessGranted) + 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(BurnMintERC677BurnAccessGranted) + 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 *BurnMintERC677BurnAccessGrantedIterator) Error() error { + return it.fail +} + +func (it *BurnMintERC677BurnAccessGrantedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintERC677BurnAccessGranted struct { + Burner common.Address + Raw types.Log +} + +func (_BurnMintERC677 *BurnMintERC677Filterer) FilterBurnAccessGranted(opts *bind.FilterOpts, burner []common.Address) (*BurnMintERC677BurnAccessGrantedIterator, error) { + + var burnerRule []interface{} + for _, burnerItem := range burner { + burnerRule = append(burnerRule, burnerItem) + } + + logs, sub, err := _BurnMintERC677.contract.FilterLogs(opts, "BurnAccessGranted", burnerRule) + if err != nil { + return nil, err + } + return &BurnMintERC677BurnAccessGrantedIterator{contract: _BurnMintERC677.contract, event: "BurnAccessGranted", logs: logs, sub: sub}, nil +} + +func (_BurnMintERC677 *BurnMintERC677Filterer) WatchBurnAccessGranted(opts *bind.WatchOpts, sink chan<- *BurnMintERC677BurnAccessGranted, burner []common.Address) (event.Subscription, error) { + + var burnerRule []interface{} + for _, burnerItem := range burner { + burnerRule = append(burnerRule, burnerItem) + } + + logs, sub, err := _BurnMintERC677.contract.WatchLogs(opts, "BurnAccessGranted", burnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintERC677BurnAccessGranted) + if err := _BurnMintERC677.contract.UnpackLog(event, "BurnAccessGranted", 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 (_BurnMintERC677 *BurnMintERC677Filterer) ParseBurnAccessGranted(log types.Log) (*BurnMintERC677BurnAccessGranted, error) { + event := new(BurnMintERC677BurnAccessGranted) + if err := _BurnMintERC677.contract.UnpackLog(event, "BurnAccessGranted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintERC677BurnAccessRevokedIterator struct { + Event *BurnMintERC677BurnAccessRevoked + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintERC677BurnAccessRevokedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintERC677BurnAccessRevoked) + 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(BurnMintERC677BurnAccessRevoked) + 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 *BurnMintERC677BurnAccessRevokedIterator) Error() error { + return it.fail +} + +func (it *BurnMintERC677BurnAccessRevokedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintERC677BurnAccessRevoked struct { + Burner common.Address + Raw types.Log +} + +func (_BurnMintERC677 *BurnMintERC677Filterer) FilterBurnAccessRevoked(opts *bind.FilterOpts, burner []common.Address) (*BurnMintERC677BurnAccessRevokedIterator, error) { + + var burnerRule []interface{} + for _, burnerItem := range burner { + burnerRule = append(burnerRule, burnerItem) + } + + logs, sub, err := _BurnMintERC677.contract.FilterLogs(opts, "BurnAccessRevoked", burnerRule) + if err != nil { + return nil, err + } + return &BurnMintERC677BurnAccessRevokedIterator{contract: _BurnMintERC677.contract, event: "BurnAccessRevoked", logs: logs, sub: sub}, nil +} + +func (_BurnMintERC677 *BurnMintERC677Filterer) WatchBurnAccessRevoked(opts *bind.WatchOpts, sink chan<- *BurnMintERC677BurnAccessRevoked, burner []common.Address) (event.Subscription, error) { + + var burnerRule []interface{} + for _, burnerItem := range burner { + burnerRule = append(burnerRule, burnerItem) + } + + logs, sub, err := _BurnMintERC677.contract.WatchLogs(opts, "BurnAccessRevoked", burnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintERC677BurnAccessRevoked) + if err := _BurnMintERC677.contract.UnpackLog(event, "BurnAccessRevoked", 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 (_BurnMintERC677 *BurnMintERC677Filterer) ParseBurnAccessRevoked(log types.Log) (*BurnMintERC677BurnAccessRevoked, error) { + event := new(BurnMintERC677BurnAccessRevoked) + if err := _BurnMintERC677.contract.UnpackLog(event, "BurnAccessRevoked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintERC677MintAccessGrantedIterator struct { + Event *BurnMintERC677MintAccessGranted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintERC677MintAccessGrantedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintERC677MintAccessGranted) + 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(BurnMintERC677MintAccessGranted) + 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 *BurnMintERC677MintAccessGrantedIterator) Error() error { + return it.fail +} + +func (it *BurnMintERC677MintAccessGrantedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintERC677MintAccessGranted struct { + Minter common.Address + Raw types.Log +} + +func (_BurnMintERC677 *BurnMintERC677Filterer) FilterMintAccessGranted(opts *bind.FilterOpts, minter []common.Address) (*BurnMintERC677MintAccessGrantedIterator, error) { + + var minterRule []interface{} + for _, minterItem := range minter { + minterRule = append(minterRule, minterItem) + } + + logs, sub, err := _BurnMintERC677.contract.FilterLogs(opts, "MintAccessGranted", minterRule) + if err != nil { + return nil, err + } + return &BurnMintERC677MintAccessGrantedIterator{contract: _BurnMintERC677.contract, event: "MintAccessGranted", logs: logs, sub: sub}, nil +} + +func (_BurnMintERC677 *BurnMintERC677Filterer) WatchMintAccessGranted(opts *bind.WatchOpts, sink chan<- *BurnMintERC677MintAccessGranted, minter []common.Address) (event.Subscription, error) { + + var minterRule []interface{} + for _, minterItem := range minter { + minterRule = append(minterRule, minterItem) + } + + logs, sub, err := _BurnMintERC677.contract.WatchLogs(opts, "MintAccessGranted", minterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintERC677MintAccessGranted) + if err := _BurnMintERC677.contract.UnpackLog(event, "MintAccessGranted", 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 (_BurnMintERC677 *BurnMintERC677Filterer) ParseMintAccessGranted(log types.Log) (*BurnMintERC677MintAccessGranted, error) { + event := new(BurnMintERC677MintAccessGranted) + if err := _BurnMintERC677.contract.UnpackLog(event, "MintAccessGranted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintERC677MintAccessRevokedIterator struct { + Event *BurnMintERC677MintAccessRevoked + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintERC677MintAccessRevokedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintERC677MintAccessRevoked) + 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(BurnMintERC677MintAccessRevoked) + 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 *BurnMintERC677MintAccessRevokedIterator) Error() error { + return it.fail +} + +func (it *BurnMintERC677MintAccessRevokedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintERC677MintAccessRevoked struct { + Minter common.Address + Raw types.Log +} + +func (_BurnMintERC677 *BurnMintERC677Filterer) FilterMintAccessRevoked(opts *bind.FilterOpts, minter []common.Address) (*BurnMintERC677MintAccessRevokedIterator, error) { + + var minterRule []interface{} + for _, minterItem := range minter { + minterRule = append(minterRule, minterItem) + } + + logs, sub, err := _BurnMintERC677.contract.FilterLogs(opts, "MintAccessRevoked", minterRule) + if err != nil { + return nil, err + } + return &BurnMintERC677MintAccessRevokedIterator{contract: _BurnMintERC677.contract, event: "MintAccessRevoked", logs: logs, sub: sub}, nil +} + +func (_BurnMintERC677 *BurnMintERC677Filterer) WatchMintAccessRevoked(opts *bind.WatchOpts, sink chan<- *BurnMintERC677MintAccessRevoked, minter []common.Address) (event.Subscription, error) { + + var minterRule []interface{} + for _, minterItem := range minter { + minterRule = append(minterRule, minterItem) + } + + logs, sub, err := _BurnMintERC677.contract.WatchLogs(opts, "MintAccessRevoked", minterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintERC677MintAccessRevoked) + if err := _BurnMintERC677.contract.UnpackLog(event, "MintAccessRevoked", 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 (_BurnMintERC677 *BurnMintERC677Filterer) ParseMintAccessRevoked(log types.Log) (*BurnMintERC677MintAccessRevoked, error) { + event := new(BurnMintERC677MintAccessRevoked) + if err := _BurnMintERC677.contract.UnpackLog(event, "MintAccessRevoked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintERC677OwnershipTransferRequestedIterator struct { + Event *BurnMintERC677OwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintERC677OwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintERC677OwnershipTransferRequested) + 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(BurnMintERC677OwnershipTransferRequested) + 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 *BurnMintERC677OwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *BurnMintERC677OwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintERC677OwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_BurnMintERC677 *BurnMintERC677Filterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintERC677OwnershipTransferRequestedIterator, 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 := _BurnMintERC677.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &BurnMintERC677OwnershipTransferRequestedIterator{contract: _BurnMintERC677.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_BurnMintERC677 *BurnMintERC677Filterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *BurnMintERC677OwnershipTransferRequested, 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 := _BurnMintERC677.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(BurnMintERC677OwnershipTransferRequested) + if err := _BurnMintERC677.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 (_BurnMintERC677 *BurnMintERC677Filterer) ParseOwnershipTransferRequested(log types.Log) (*BurnMintERC677OwnershipTransferRequested, error) { + event := new(BurnMintERC677OwnershipTransferRequested) + if err := _BurnMintERC677.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintERC677OwnershipTransferredIterator struct { + Event *BurnMintERC677OwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintERC677OwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintERC677OwnershipTransferred) + 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(BurnMintERC677OwnershipTransferred) + 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 *BurnMintERC677OwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *BurnMintERC677OwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintERC677OwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_BurnMintERC677 *BurnMintERC677Filterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintERC677OwnershipTransferredIterator, 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 := _BurnMintERC677.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &BurnMintERC677OwnershipTransferredIterator{contract: _BurnMintERC677.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_BurnMintERC677 *BurnMintERC677Filterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *BurnMintERC677OwnershipTransferred, 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 := _BurnMintERC677.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(BurnMintERC677OwnershipTransferred) + if err := _BurnMintERC677.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 (_BurnMintERC677 *BurnMintERC677Filterer) ParseOwnershipTransferred(log types.Log) (*BurnMintERC677OwnershipTransferred, error) { + event := new(BurnMintERC677OwnershipTransferred) + if err := _BurnMintERC677.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintERC677TransferIterator struct { + Event *BurnMintERC677Transfer + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintERC677TransferIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintERC677Transfer) + 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(BurnMintERC677Transfer) + 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 *BurnMintERC677TransferIterator) Error() error { + return it.fail +} + +func (it *BurnMintERC677TransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintERC677Transfer struct { + From common.Address + To common.Address + Value *big.Int + Raw types.Log +} + +func (_BurnMintERC677 *BurnMintERC677Filterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintERC677TransferIterator, 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 := _BurnMintERC677.contract.FilterLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return &BurnMintERC677TransferIterator{contract: _BurnMintERC677.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +func (_BurnMintERC677 *BurnMintERC677Filterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *BurnMintERC677Transfer, 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 := _BurnMintERC677.contract.WatchLogs(opts, "Transfer", 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(BurnMintERC677Transfer) + if err := _BurnMintERC677.contract.UnpackLog(event, "Transfer", 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 (_BurnMintERC677 *BurnMintERC677Filterer) ParseTransfer(log types.Log) (*BurnMintERC677Transfer, error) { + event := new(BurnMintERC677Transfer) + if err := _BurnMintERC677.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintERC677Transfer0Iterator struct { + Event *BurnMintERC677Transfer0 + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintERC677Transfer0Iterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintERC677Transfer0) + 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(BurnMintERC677Transfer0) + 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 *BurnMintERC677Transfer0Iterator) Error() error { + return it.fail +} + +func (it *BurnMintERC677Transfer0Iterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintERC677Transfer0 struct { + From common.Address + To common.Address + Value *big.Int + Data []byte + Raw types.Log +} + +func (_BurnMintERC677 *BurnMintERC677Filterer) FilterTransfer0(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintERC677Transfer0Iterator, 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 := _BurnMintERC677.contract.FilterLogs(opts, "Transfer0", fromRule, toRule) + if err != nil { + return nil, err + } + return &BurnMintERC677Transfer0Iterator{contract: _BurnMintERC677.contract, event: "Transfer0", logs: logs, sub: sub}, nil +} + +func (_BurnMintERC677 *BurnMintERC677Filterer) WatchTransfer0(opts *bind.WatchOpts, sink chan<- *BurnMintERC677Transfer0, 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 := _BurnMintERC677.contract.WatchLogs(opts, "Transfer0", 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(BurnMintERC677Transfer0) + if err := _BurnMintERC677.contract.UnpackLog(event, "Transfer0", 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 (_BurnMintERC677 *BurnMintERC677Filterer) ParseTransfer0(log types.Log) (*BurnMintERC677Transfer0, error) { + event := new(BurnMintERC677Transfer0) + if err := _BurnMintERC677.contract.UnpackLog(event, "Transfer0", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_BurnMintERC677 *BurnMintERC677) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _BurnMintERC677.abi.Events["Approval"].ID: + return _BurnMintERC677.ParseApproval(log) + case _BurnMintERC677.abi.Events["BurnAccessGranted"].ID: + return _BurnMintERC677.ParseBurnAccessGranted(log) + case _BurnMintERC677.abi.Events["BurnAccessRevoked"].ID: + return _BurnMintERC677.ParseBurnAccessRevoked(log) + case _BurnMintERC677.abi.Events["MintAccessGranted"].ID: + return _BurnMintERC677.ParseMintAccessGranted(log) + case _BurnMintERC677.abi.Events["MintAccessRevoked"].ID: + return _BurnMintERC677.ParseMintAccessRevoked(log) + case _BurnMintERC677.abi.Events["OwnershipTransferRequested"].ID: + return _BurnMintERC677.ParseOwnershipTransferRequested(log) + case _BurnMintERC677.abi.Events["OwnershipTransferred"].ID: + return _BurnMintERC677.ParseOwnershipTransferred(log) + case _BurnMintERC677.abi.Events["Transfer"].ID: + return _BurnMintERC677.ParseTransfer(log) + case _BurnMintERC677.abi.Events["Transfer0"].ID: + return _BurnMintERC677.ParseTransfer0(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (BurnMintERC677Approval) Topic() common.Hash { + return common.HexToHash("0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925") +} + +func (BurnMintERC677BurnAccessGranted) Topic() common.Hash { + return common.HexToHash("0x92308bb7573b2a3d17ddb868b39d8ebec433f3194421abc22d084f89658c9bad") +} + +func (BurnMintERC677BurnAccessRevoked) Topic() common.Hash { + return common.HexToHash("0x0a675452746933cefe3d74182e78db7afe57ba60eaa4234b5d85e9aa41b0610c") +} + +func (BurnMintERC677MintAccessGranted) Topic() common.Hash { + return common.HexToHash("0xe46fef8bbff1389d9010703cf8ebb363fb3daf5bf56edc27080b67bc8d9251ea") +} + +func (BurnMintERC677MintAccessRevoked) Topic() common.Hash { + return common.HexToHash("0xed998b960f6340d045f620c119730f7aa7995e7425c2401d3a5b64ff998a59e9") +} + +func (BurnMintERC677OwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (BurnMintERC677OwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (BurnMintERC677Transfer) Topic() common.Hash { + return common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef") +} + +func (BurnMintERC677Transfer0) Topic() common.Hash { + return common.HexToHash("0xe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16") +} + +func (_BurnMintERC677 *BurnMintERC677) Address() common.Address { + return _BurnMintERC677.address +} + +type BurnMintERC677Interface interface { + Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) + + BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) + + Decimals(opts *bind.CallOpts) (uint8, error) + + GetBurners(opts *bind.CallOpts) ([]common.Address, error) + + GetMinters(opts *bind.CallOpts) ([]common.Address, error) + + IsBurner(opts *bind.CallOpts, burner common.Address) (bool, error) + + IsMinter(opts *bind.CallOpts, minter common.Address) (bool, error) + + MaxSupply(opts *bind.CallOpts) (*big.Int, error) + + Name(opts *bind.CallOpts) (string, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + Symbol(opts *bind.CallOpts) (string, error) + + TotalSupply(opts *bind.CallOpts) (*big.Int, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + Approve(opts *bind.TransactOpts, spender common.Address, amount *big.Int) (*types.Transaction, error) + + Burn(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) + + Burn0(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) + + BurnFrom(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) + + DecreaseAllowance(opts *bind.TransactOpts, spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) + + DecreaseApproval(opts *bind.TransactOpts, spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) + + GrantBurnRole(opts *bind.TransactOpts, burner common.Address) (*types.Transaction, error) + + GrantMintAndBurnRoles(opts *bind.TransactOpts, burnAndMinter common.Address) (*types.Transaction, error) + + GrantMintRole(opts *bind.TransactOpts, minter common.Address) (*types.Transaction, error) + + IncreaseAllowance(opts *bind.TransactOpts, spender common.Address, addedValue *big.Int) (*types.Transaction, error) + + IncreaseApproval(opts *bind.TransactOpts, spender common.Address, addedValue *big.Int) (*types.Transaction, error) + + Mint(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) + + RevokeBurnRole(opts *bind.TransactOpts, burner common.Address) (*types.Transaction, error) + + RevokeMintRole(opts *bind.TransactOpts, minter common.Address) (*types.Transaction, error) + + Transfer(opts *bind.TransactOpts, to common.Address, amount *big.Int) (*types.Transaction, error) + + TransferAndCall(opts *bind.TransactOpts, to common.Address, amount *big.Int, data []byte) (*types.Transaction, error) + + TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*BurnMintERC677ApprovalIterator, error) + + WatchApproval(opts *bind.WatchOpts, sink chan<- *BurnMintERC677Approval, owner []common.Address, spender []common.Address) (event.Subscription, error) + + ParseApproval(log types.Log) (*BurnMintERC677Approval, error) + + FilterBurnAccessGranted(opts *bind.FilterOpts, burner []common.Address) (*BurnMintERC677BurnAccessGrantedIterator, error) + + WatchBurnAccessGranted(opts *bind.WatchOpts, sink chan<- *BurnMintERC677BurnAccessGranted, burner []common.Address) (event.Subscription, error) + + ParseBurnAccessGranted(log types.Log) (*BurnMintERC677BurnAccessGranted, error) + + FilterBurnAccessRevoked(opts *bind.FilterOpts, burner []common.Address) (*BurnMintERC677BurnAccessRevokedIterator, error) + + WatchBurnAccessRevoked(opts *bind.WatchOpts, sink chan<- *BurnMintERC677BurnAccessRevoked, burner []common.Address) (event.Subscription, error) + + ParseBurnAccessRevoked(log types.Log) (*BurnMintERC677BurnAccessRevoked, error) + + FilterMintAccessGranted(opts *bind.FilterOpts, minter []common.Address) (*BurnMintERC677MintAccessGrantedIterator, error) + + WatchMintAccessGranted(opts *bind.WatchOpts, sink chan<- *BurnMintERC677MintAccessGranted, minter []common.Address) (event.Subscription, error) + + ParseMintAccessGranted(log types.Log) (*BurnMintERC677MintAccessGranted, error) + + FilterMintAccessRevoked(opts *bind.FilterOpts, minter []common.Address) (*BurnMintERC677MintAccessRevokedIterator, error) + + WatchMintAccessRevoked(opts *bind.WatchOpts, sink chan<- *BurnMintERC677MintAccessRevoked, minter []common.Address) (event.Subscription, error) + + ParseMintAccessRevoked(log types.Log) (*BurnMintERC677MintAccessRevoked, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintERC677OwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *BurnMintERC677OwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*BurnMintERC677OwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintERC677OwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *BurnMintERC677OwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*BurnMintERC677OwnershipTransferred, error) + + FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintERC677TransferIterator, error) + + WatchTransfer(opts *bind.WatchOpts, sink chan<- *BurnMintERC677Transfer, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseTransfer(log types.Log) (*BurnMintERC677Transfer, error) + + FilterTransfer0(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BurnMintERC677Transfer0Iterator, error) + + WatchTransfer0(opts *bind.WatchOpts, sink chan<- *BurnMintERC677Transfer0, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseTransfer0(log types.Log) (*BurnMintERC677Transfer0, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/shared/generated/erc20/erc20.go b/core/gethwrappers/shared/generated/erc20/erc20.go new file mode 100644 index 00000000000..f5b1d9b7bf2 --- /dev/null +++ b/core/gethwrappers/shared/generated/erc20/erc20.go @@ -0,0 +1,702 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package erc20 + +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 ERC20MetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b5060405162000de638038062000de683398101604081905262000034916200011f565b600362000042838262000218565b50600462000051828262000218565b505050620002e4565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200008257600080fd5b81516001600160401b03808211156200009f576200009f6200005a565b604051601f8301601f19908116603f01168101908282118183101715620000ca57620000ca6200005a565b81604052838152602092508683858801011115620000e757600080fd5b600091505b838210156200010b5785820183015181830184015290820190620000ec565b600093810190920192909252949350505050565b600080604083850312156200013357600080fd5b82516001600160401b03808211156200014b57600080fd5b620001598683870162000070565b935060208501519150808211156200017057600080fd5b506200017f8582860162000070565b9150509250929050565b600181811c908216806200019e57607f821691505b602082108103620001bf57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200021357600081815260208120601f850160051c81016020861015620001ee5750805b601f850160051c820191505b818110156200020f57828155600101620001fa565b5050505b505050565b81516001600160401b038111156200023457620002346200005a565b6200024c8162000245845462000189565b84620001c5565b602080601f8311600181146200028457600084156200026b5750858301515b600019600386901b1c1916600185901b1785556200020f565b600085815260208120601f198616915b82811015620002b55788860151825594840194600190910190840162000294565b5085821015620002d45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b610af280620002f46000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80633950935111610081578063a457c2d71161005b578063a457c2d714610194578063a9059cbb146101a7578063dd62ed3e146101ba57600080fd5b8063395093511461014357806370a082311461015657806395d89b411461018c57600080fd5b806318160ddd116100b257806318160ddd1461010f57806323b872dd14610121578063313ce5671461013457600080fd5b806306fdde03146100ce578063095ea7b3146100ec575b600080fd5b6100d6610200565b6040516100e39190610908565b60405180910390f35b6100ff6100fa36600461099d565b610292565b60405190151581526020016100e3565b6002545b6040519081526020016100e3565b6100ff61012f3660046109c7565b6102ac565b604051601281526020016100e3565b6100ff61015136600461099d565b6102d0565b610113610164366004610a03565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6100d661031c565b6100ff6101a236600461099d565b61032b565b6100ff6101b536600461099d565b610401565b6101136101c8366004610a25565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b60606003805461020f90610a58565b80601f016020809104026020016040519081016040528092919081815260200182805461023b90610a58565b80156102885780601f1061025d57610100808354040283529160200191610288565b820191906000526020600020905b81548152906001019060200180831161026b57829003601f168201915b5050505050905090565b6000336102a081858561040f565b60019150505b92915050565b6000336102ba8582856105c2565b6102c5858585610699565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906102a09082908690610317908790610aab565b61040f565b60606004805461020f90610a58565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909190838110156103f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102c5828686840361040f565b6000336102a0818585610699565b73ffffffffffffffffffffffffffffffffffffffff83166104b1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016103eb565b73ffffffffffffffffffffffffffffffffffffffff8216610554576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016103eb565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146106935781811015610686576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016103eb565b610693848484840361040f565b50505050565b73ffffffffffffffffffffffffffffffffffffffff831661073c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016103eb565b73ffffffffffffffffffffffffffffffffffffffff82166107df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016103eb565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610895576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016103eb565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610693565b600060208083528351808285015260005b8181101561093557858101830151858201604001528201610919565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461099857600080fd5b919050565b600080604083850312156109b057600080fd5b6109b983610974565b946020939093013593505050565b6000806000606084860312156109dc57600080fd5b6109e584610974565b92506109f360208501610974565b9150604084013590509250925092565b600060208284031215610a1557600080fd5b610a1e82610974565b9392505050565b60008060408385031215610a3857600080fd5b610a4183610974565b9150610a4f60208401610974565b90509250929050565b600181811c90821680610a6c57607f821691505b602082108103610aa5577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b808201808211156102a6577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea164736f6c6343000813000a", +} + +var ERC20ABI = ERC20MetaData.ABI + +var ERC20Bin = ERC20MetaData.Bin + +func DeployERC20(auth *bind.TransactOpts, backend bind.ContractBackend, name_ string, symbol_ string) (common.Address, *types.Transaction, *ERC20, error) { + parsed, err := ERC20MetaData.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(ERC20Bin), backend, name_, symbol_) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ERC20{ERC20Caller: ERC20Caller{contract: contract}, ERC20Transactor: ERC20Transactor{contract: contract}, ERC20Filterer: ERC20Filterer{contract: contract}}, nil +} + +type ERC20 struct { + address common.Address + abi abi.ABI + ERC20Caller + ERC20Transactor + ERC20Filterer +} + +type ERC20Caller struct { + contract *bind.BoundContract +} + +type ERC20Transactor struct { + contract *bind.BoundContract +} + +type ERC20Filterer struct { + contract *bind.BoundContract +} + +type ERC20Session struct { + Contract *ERC20 + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type ERC20CallerSession struct { + Contract *ERC20Caller + CallOpts bind.CallOpts +} + +type ERC20TransactorSession struct { + Contract *ERC20Transactor + TransactOpts bind.TransactOpts +} + +type ERC20Raw struct { + Contract *ERC20 +} + +type ERC20CallerRaw struct { + Contract *ERC20Caller +} + +type ERC20TransactorRaw struct { + Contract *ERC20Transactor +} + +func NewERC20(address common.Address, backend bind.ContractBackend) (*ERC20, error) { + abi, err := abi.JSON(strings.NewReader(ERC20ABI)) + if err != nil { + return nil, err + } + contract, err := bindERC20(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ERC20{address: address, abi: abi, ERC20Caller: ERC20Caller{contract: contract}, ERC20Transactor: ERC20Transactor{contract: contract}, ERC20Filterer: ERC20Filterer{contract: contract}}, nil +} + +func NewERC20Caller(address common.Address, caller bind.ContractCaller) (*ERC20Caller, error) { + contract, err := bindERC20(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ERC20Caller{contract: contract}, nil +} + +func NewERC20Transactor(address common.Address, transactor bind.ContractTransactor) (*ERC20Transactor, error) { + contract, err := bindERC20(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ERC20Transactor{contract: contract}, nil +} + +func NewERC20Filterer(address common.Address, filterer bind.ContractFilterer) (*ERC20Filterer, error) { + contract, err := bindERC20(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ERC20Filterer{contract: contract}, nil +} + +func bindERC20(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ERC20MetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_ERC20 *ERC20Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ERC20.Contract.ERC20Caller.contract.Call(opts, result, method, params...) +} + +func (_ERC20 *ERC20Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20.Contract.ERC20Transactor.contract.Transfer(opts) +} + +func (_ERC20 *ERC20Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ERC20.Contract.ERC20Transactor.contract.Transact(opts, method, params...) +} + +func (_ERC20 *ERC20CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ERC20.Contract.contract.Call(opts, result, method, params...) +} + +func (_ERC20 *ERC20TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20.Contract.contract.Transfer(opts) +} + +func (_ERC20 *ERC20TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ERC20.Contract.contract.Transact(opts, method, params...) +} + +func (_ERC20 *ERC20Caller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) { + var out []interface{} + err := _ERC20.contract.Call(opts, &out, "allowance", owner, spender) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ERC20 *ERC20Session) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _ERC20.Contract.Allowance(&_ERC20.CallOpts, owner, spender) +} + +func (_ERC20 *ERC20CallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _ERC20.Contract.Allowance(&_ERC20.CallOpts, owner, spender) +} + +func (_ERC20 *ERC20Caller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) { + var out []interface{} + err := _ERC20.contract.Call(opts, &out, "balanceOf", account) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ERC20 *ERC20Session) BalanceOf(account common.Address) (*big.Int, error) { + return _ERC20.Contract.BalanceOf(&_ERC20.CallOpts, account) +} + +func (_ERC20 *ERC20CallerSession) BalanceOf(account common.Address) (*big.Int, error) { + return _ERC20.Contract.BalanceOf(&_ERC20.CallOpts, account) +} + +func (_ERC20 *ERC20Caller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _ERC20.contract.Call(opts, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_ERC20 *ERC20Session) Decimals() (uint8, error) { + return _ERC20.Contract.Decimals(&_ERC20.CallOpts) +} + +func (_ERC20 *ERC20CallerSession) Decimals() (uint8, error) { + return _ERC20.Contract.Decimals(&_ERC20.CallOpts) +} + +func (_ERC20 *ERC20Caller) Name(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _ERC20.contract.Call(opts, &out, "name") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_ERC20 *ERC20Session) Name() (string, error) { + return _ERC20.Contract.Name(&_ERC20.CallOpts) +} + +func (_ERC20 *ERC20CallerSession) Name() (string, error) { + return _ERC20.Contract.Name(&_ERC20.CallOpts) +} + +func (_ERC20 *ERC20Caller) Symbol(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _ERC20.contract.Call(opts, &out, "symbol") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_ERC20 *ERC20Session) Symbol() (string, error) { + return _ERC20.Contract.Symbol(&_ERC20.CallOpts) +} + +func (_ERC20 *ERC20CallerSession) Symbol() (string, error) { + return _ERC20.Contract.Symbol(&_ERC20.CallOpts) +} + +func (_ERC20 *ERC20Caller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20.contract.Call(opts, &out, "totalSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_ERC20 *ERC20Session) TotalSupply() (*big.Int, error) { + return _ERC20.Contract.TotalSupply(&_ERC20.CallOpts) +} + +func (_ERC20 *ERC20CallerSession) TotalSupply() (*big.Int, error) { + return _ERC20.Contract.TotalSupply(&_ERC20.CallOpts) +} + +func (_ERC20 *ERC20Transactor) Approve(opts *bind.TransactOpts, spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _ERC20.contract.Transact(opts, "approve", spender, amount) +} + +func (_ERC20 *ERC20Session) Approve(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _ERC20.Contract.Approve(&_ERC20.TransactOpts, spender, amount) +} + +func (_ERC20 *ERC20TransactorSession) Approve(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _ERC20.Contract.Approve(&_ERC20.TransactOpts, spender, amount) +} + +func (_ERC20 *ERC20Transactor) DecreaseAllowance(opts *bind.TransactOpts, spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { + return _ERC20.contract.Transact(opts, "decreaseAllowance", spender, subtractedValue) +} + +func (_ERC20 *ERC20Session) DecreaseAllowance(spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { + return _ERC20.Contract.DecreaseAllowance(&_ERC20.TransactOpts, spender, subtractedValue) +} + +func (_ERC20 *ERC20TransactorSession) DecreaseAllowance(spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { + return _ERC20.Contract.DecreaseAllowance(&_ERC20.TransactOpts, spender, subtractedValue) +} + +func (_ERC20 *ERC20Transactor) IncreaseAllowance(opts *bind.TransactOpts, spender common.Address, addedValue *big.Int) (*types.Transaction, error) { + return _ERC20.contract.Transact(opts, "increaseAllowance", spender, addedValue) +} + +func (_ERC20 *ERC20Session) IncreaseAllowance(spender common.Address, addedValue *big.Int) (*types.Transaction, error) { + return _ERC20.Contract.IncreaseAllowance(&_ERC20.TransactOpts, spender, addedValue) +} + +func (_ERC20 *ERC20TransactorSession) IncreaseAllowance(spender common.Address, addedValue *big.Int) (*types.Transaction, error) { + return _ERC20.Contract.IncreaseAllowance(&_ERC20.TransactOpts, spender, addedValue) +} + +func (_ERC20 *ERC20Transactor) Transfer(opts *bind.TransactOpts, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _ERC20.contract.Transact(opts, "transfer", to, amount) +} + +func (_ERC20 *ERC20Session) Transfer(to common.Address, amount *big.Int) (*types.Transaction, error) { + return _ERC20.Contract.Transfer(&_ERC20.TransactOpts, to, amount) +} + +func (_ERC20 *ERC20TransactorSession) Transfer(to common.Address, amount *big.Int) (*types.Transaction, error) { + return _ERC20.Contract.Transfer(&_ERC20.TransactOpts, to, amount) +} + +func (_ERC20 *ERC20Transactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _ERC20.contract.Transact(opts, "transferFrom", from, to, amount) +} + +func (_ERC20 *ERC20Session) TransferFrom(from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _ERC20.Contract.TransferFrom(&_ERC20.TransactOpts, from, to, amount) +} + +func (_ERC20 *ERC20TransactorSession) TransferFrom(from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _ERC20.Contract.TransferFrom(&_ERC20.TransactOpts, from, to, amount) +} + +type ERC20ApprovalIterator struct { + Event *ERC20Approval + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ERC20ApprovalIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20Approval) + 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(ERC20Approval) + 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 *ERC20ApprovalIterator) Error() error { + return it.fail +} + +func (it *ERC20ApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ERC20Approval struct { + Owner common.Address + Spender common.Address + Value *big.Int + Raw types.Log +} + +func (_ERC20 *ERC20Filterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*ERC20ApprovalIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _ERC20.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return &ERC20ApprovalIterator{contract: _ERC20.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +func (_ERC20 *ERC20Filterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *ERC20Approval, owner []common.Address, spender []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _ERC20.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(ERC20Approval) + if err := _ERC20.contract.UnpackLog(event, "Approval", 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 (_ERC20 *ERC20Filterer) ParseApproval(log types.Log) (*ERC20Approval, error) { + event := new(ERC20Approval) + if err := _ERC20.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type ERC20TransferIterator struct { + Event *ERC20Transfer + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *ERC20TransferIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20Transfer) + 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(ERC20Transfer) + 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 *ERC20TransferIterator) Error() error { + return it.fail +} + +func (it *ERC20TransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type ERC20Transfer struct { + From common.Address + To common.Address + Value *big.Int + Raw types.Log +} + +func (_ERC20 *ERC20Filterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ERC20TransferIterator, 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 := _ERC20.contract.FilterLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return &ERC20TransferIterator{contract: _ERC20.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +func (_ERC20 *ERC20Filterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *ERC20Transfer, 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 := _ERC20.contract.WatchLogs(opts, "Transfer", 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(ERC20Transfer) + if err := _ERC20.contract.UnpackLog(event, "Transfer", 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 (_ERC20 *ERC20Filterer) ParseTransfer(log types.Log) (*ERC20Transfer, error) { + event := new(ERC20Transfer) + if err := _ERC20.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_ERC20 *ERC20) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _ERC20.abi.Events["Approval"].ID: + return _ERC20.ParseApproval(log) + case _ERC20.abi.Events["Transfer"].ID: + return _ERC20.ParseTransfer(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (ERC20Approval) Topic() common.Hash { + return common.HexToHash("0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925") +} + +func (ERC20Transfer) Topic() common.Hash { + return common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef") +} + +func (_ERC20 *ERC20) Address() common.Address { + return _ERC20.address +} + +type ERC20Interface interface { + Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) + + BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) + + Decimals(opts *bind.CallOpts) (uint8, error) + + Name(opts *bind.CallOpts) (string, error) + + Symbol(opts *bind.CallOpts) (string, error) + + TotalSupply(opts *bind.CallOpts) (*big.Int, error) + + Approve(opts *bind.TransactOpts, spender common.Address, amount *big.Int) (*types.Transaction, error) + + DecreaseAllowance(opts *bind.TransactOpts, spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) + + IncreaseAllowance(opts *bind.TransactOpts, spender common.Address, addedValue *big.Int) (*types.Transaction, error) + + Transfer(opts *bind.TransactOpts, to common.Address, amount *big.Int) (*types.Transaction, error) + + TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) + + FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*ERC20ApprovalIterator, error) + + WatchApproval(opts *bind.WatchOpts, sink chan<- *ERC20Approval, owner []common.Address, spender []common.Address) (event.Subscription, error) + + ParseApproval(log types.Log) (*ERC20Approval, error) + + FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ERC20TransferIterator, error) + + WatchTransfer(opts *bind.WatchOpts, sink chan<- *ERC20Transfer, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseTransfer(log types.Log) (*ERC20Transfer, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/shared/generated/link_token/link_token.go b/core/gethwrappers/shared/generated/link_token/link_token.go new file mode 100644 index 00000000000..98de7de66a0 --- /dev/null +++ b/core/gethwrappers/shared/generated/link_token/link_token.go @@ -0,0 +1,2068 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package link_token + +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 LinkTokenMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"supplyAfterMint\",\"type\":\"uint256\"}],\"name\":\"MaxSupplyExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotBurner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotMinter\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"BurnAccessGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"BurnAccessRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MintAccessGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MintAccessRevoked\",\"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\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseApproval\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBurners\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMinters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"grantBurnRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burnAndMinter\",\"type\":\"address\"}],\"name\":\"grantMintAndBurnRoles\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"grantMintRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"isBurner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"revokeBurnRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"revokeMintRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"transferAndCall\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60c06040523480156200001157600080fd5b506040518060400160405280600f81526020016e21b430b4b72634b735902a37b5b2b760891b815250604051806040016040528060048152602001634c494e4b60e01b81525060126b033b2e3c9fd0803ce8000000338060008686818181600390816200007f91906200028c565b5060046200008e82826200028c565b5050506001600160a01b0384169150620000f190505760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600580546001600160a01b0319166001600160a01b0384811691909117909155811615620001245762000124816200013b565b50505060ff90911660805260a05250620003589050565b336001600160a01b03821603620001955760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000e8565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200021257607f821691505b6020821081036200023357634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200028757600081815260208120601f850160051c81016020861015620002625750805b601f850160051c820191505b8181101562000283578281556001016200026e565b5050505b505050565b81516001600160401b03811115620002a857620002a8620001e7565b620002c081620002b98454620001fd565b8462000239565b602080601f831160018114620002f85760008415620002df5750858301515b600019600386901b1c1916600185901b17855562000283565b600085815260208120601f198616915b82811015620003295788860151825594840194600190910190840162000308565b5085821015620003485787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a051611e4c6200038c60003960008181610447015281816108c301526108ed015260006102710152611e4c6000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c806379cc67901161010f578063c2e3273d116100a2578063d73dd62311610071578063d73dd6231461046b578063dd62ed3e1461047e578063f2fde38b146104c4578063f81094f3146104d757600080fd5b8063c2e3273d1461040c578063c630948d1461041f578063c64d0ebc14610432578063d5abeb011461044557600080fd5b80639dc29fac116100de5780639dc29fac146103c0578063a457c2d7146103d3578063a9059cbb146103e6578063aa271e1a146103f957600080fd5b806379cc67901461037557806386fe8b43146103885780638da5cb5b1461039057806395d89b41146103b857600080fd5b806340c10f19116101875780636618846311610156578063661884631461030f5780636b32810b1461032257806370a082311461033757806379ba50971461036d57600080fd5b806340c10f19146102c157806342966c68146102d65780634334614a146102e95780634f5632f8146102fc57600080fd5b806323b872dd116101c357806323b872dd14610257578063313ce5671461026a578063395093511461029b5780634000aea0146102ae57600080fd5b806301ffc9a7146101f557806306fdde031461021d578063095ea7b31461023257806318160ddd14610245575b600080fd5b6102086102033660046119b9565b6104ea565b60405190151581526020015b60405180910390f35b61022561061b565b6040516102149190611a5f565b610208610240366004611a9b565b6106ad565b6002545b604051908152602001610214565b610208610265366004611ac5565b6106c5565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610214565b6102086102a9366004611a9b565b6106e9565b6102086102bc366004611b30565b610735565b6102d46102cf366004611a9b565b610858565b005b6102d46102e4366004611c19565b61097f565b6102086102f7366004611c32565b6109cc565b6102d461030a366004611c32565b6109d9565b61020861031d366004611a9b565b610a35565b61032a610a48565b6040516102149190611c4d565b610249610345366004611c32565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6102d4610a59565b6102d4610383366004611a9b565b610b5a565b61032a610ba9565b60055460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b610225610bb5565b6102d46103ce366004611a9b565b610bc4565b6102086103e1366004611a9b565b610bce565b6102086103f4366004611a9b565b610c9f565b610208610407366004611c32565b610cad565b6102d461041a366004611c32565b610cba565b6102d461042d366004611c32565b610d16565b6102d4610440366004611c32565b610d24565b7f0000000000000000000000000000000000000000000000000000000000000000610249565b6102d4610479366004611a9b565b610d80565b61024961048c366004611ca7565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6102d46104d2366004611c32565b610d8a565b6102d46104e5366004611c32565b610d9b565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f36372b0700000000000000000000000000000000000000000000000000000000148061057d57507fffffffff0000000000000000000000000000000000000000000000000000000082167f4000aea000000000000000000000000000000000000000000000000000000000145b806105c957507fffffffff0000000000000000000000000000000000000000000000000000000082167fe6599b4d00000000000000000000000000000000000000000000000000000000145b8061061557507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b60606003805461062a90611cda565b80601f016020809104026020016040519081016040528092919081815260200182805461065690611cda565b80156106a35780601f10610678576101008083540402835291602001916106a3565b820191906000526020600020905b81548152906001019060200180831161068657829003601f168201915b5050505050905090565b6000336106bb818585610df7565b5060019392505050565b6000336106d3858285610e2b565b6106de858585610efc565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906106bb9082908690610730908790611d5c565b610df7565b60006107418484610c9f565b508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c1685856040516107a1929190611d6f565b60405180910390a373ffffffffffffffffffffffffffffffffffffffff84163b156106bb576040517fa4c0ed3600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063a4c0ed369061081c90339087908790600401611d90565b600060405180830381600087803b15801561083657600080fd5b505af115801561084a573d6000803e3d6000fd5b505050505060019392505050565b61086133610cad565b61089e576040517fe2c8c9d50000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b813073ffffffffffffffffffffffffffffffffffffffff8216036108c157600080fd5b7f00000000000000000000000000000000000000000000000000000000000000001580159061092257507f00000000000000000000000000000000000000000000000000000000000000008261091660025490565b6109209190611d5c565b115b15610970578161093160025490565b61093b9190611d5c565b6040517fcbbf111300000000000000000000000000000000000000000000000000000000815260040161089591815260200190565b61097a8383610f2a565b505050565b610988336109cc565b6109c0576040517fc820b10b000000000000000000000000000000000000000000000000000000008152336004820152602401610895565b6109c98161101d565b50565b6000610615600983611027565b6109e1611056565b6109ec6009826110d9565b156109c95760405173ffffffffffffffffffffffffffffffffffffffff8216907f0a675452746933cefe3d74182e78db7afe57ba60eaa4234b5d85e9aa41b0610c90600090a250565b6000610a418383610bce565b9392505050565b6060610a5460076110fb565b905090565b60065473ffffffffffffffffffffffffffffffffffffffff163314610ada576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610895565b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560068054909116905560405173ffffffffffffffffffffffffffffffffffffffff909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b610b63336109cc565b610b9b576040517fc820b10b000000000000000000000000000000000000000000000000000000008152336004820152602401610895565b610ba58282611108565b5050565b6060610a5460096110fb565b60606004805461062a90611cda565b610ba58282610b5a565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610c92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610895565b6106de8286868403610df7565b6000336106bb818585610efc565b6000610615600783611027565b610cc2611056565b610ccd60078261111d565b156109c95760405173ffffffffffffffffffffffffffffffffffffffff8216907fe46fef8bbff1389d9010703cf8ebb363fb3daf5bf56edc27080b67bc8d9251ea90600090a250565b610d1f81610cba565b6109c9815b610d2c611056565b610d3760098261111d565b156109c95760405173ffffffffffffffffffffffffffffffffffffffff8216907f92308bb7573b2a3d17ddb868b39d8ebec433f3194421abc22d084f89658c9bad90600090a250565b61097a82826106e9565b610d92611056565b6109c98161113f565b610da3611056565b610dae6007826110d9565b156109c95760405173ffffffffffffffffffffffffffffffffffffffff8216907fed998b960f6340d045f620c119730f7aa7995e7425c2401d3a5b64ff998a59e990600090a250565b813073ffffffffffffffffffffffffffffffffffffffff821603610e1a57600080fd5b610e25848484611235565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610e255781811015610eef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610895565b610e258484848403610df7565b813073ffffffffffffffffffffffffffffffffffffffff821603610f1f57600080fd5b610e258484846113e8565b73ffffffffffffffffffffffffffffffffffffffff8216610fa7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610895565b8060026000828254610fb99190611d5c565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6109c93382611657565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610a41565b60055473ffffffffffffffffffffffffffffffffffffffff1633146110d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610895565b565b6000610a418373ffffffffffffffffffffffffffffffffffffffff841661181b565b60606000610a418361190e565b611113823383610e2b565b610ba58282611657565b6000610a418373ffffffffffffffffffffffffffffffffffffffff841661196a565b3373ffffffffffffffffffffffffffffffffffffffff8216036111be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610895565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b73ffffffffffffffffffffffffffffffffffffffff83166112d7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff821661137a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff831661148b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff821661152e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040902054818110156115e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610e25565b73ffffffffffffffffffffffffffffffffffffffff82166116fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156117b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6000818152600183016020526040812054801561190457600061183f600183611dce565b855490915060009061185390600190611dce565b90508181146118b857600086600001828154811061187357611873611de1565b906000526020600020015490508087600001848154811061189657611896611de1565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806118c9576118c9611e10565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610615565b6000915050610615565b60608160000180548060200260200160405190810160405280929190818152602001828054801561195e57602002820191906000526020600020905b81548152602001906001019080831161194a575b50505050509050919050565b60008181526001830160205260408120546119b157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610615565b506000610615565b6000602082840312156119cb57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610a4157600080fd5b6000815180845260005b81811015611a2157602081850181015186830182015201611a05565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610a4160208301846119fb565b803573ffffffffffffffffffffffffffffffffffffffff81168114611a9657600080fd5b919050565b60008060408385031215611aae57600080fd5b611ab783611a72565b946020939093013593505050565b600080600060608486031215611ada57600080fd5b611ae384611a72565b9250611af160208501611a72565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080600060608486031215611b4557600080fd5b611b4e84611a72565b925060208401359150604084013567ffffffffffffffff80821115611b7257600080fd5b818601915086601f830112611b8657600080fd5b813581811115611b9857611b98611b01565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611bde57611bde611b01565b81604052828152896020848701011115611bf757600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b600060208284031215611c2b57600080fd5b5035919050565b600060208284031215611c4457600080fd5b610a4182611a72565b6020808252825182820181905260009190848201906040850190845b81811015611c9b57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611c69565b50909695505050505050565b60008060408385031215611cba57600080fd5b611cc383611a72565b9150611cd160208401611a72565b90509250929050565b600181811c90821680611cee57607f821691505b602082108103611d27577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561061557610615611d2d565b828152604060208201526000611d8860408301846119fb565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000611dc560608301846119fb565b95945050505050565b8181038181111561061557610615611d2d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", +} + +var LinkTokenABI = LinkTokenMetaData.ABI + +var LinkTokenBin = LinkTokenMetaData.Bin + +func DeployLinkToken(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *LinkToken, error) { + parsed, err := LinkTokenMetaData.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(LinkTokenBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &LinkToken{LinkTokenCaller: LinkTokenCaller{contract: contract}, LinkTokenTransactor: LinkTokenTransactor{contract: contract}, LinkTokenFilterer: LinkTokenFilterer{contract: contract}}, nil +} + +type LinkToken struct { + address common.Address + abi abi.ABI + LinkTokenCaller + LinkTokenTransactor + LinkTokenFilterer +} + +type LinkTokenCaller struct { + contract *bind.BoundContract +} + +type LinkTokenTransactor struct { + contract *bind.BoundContract +} + +type LinkTokenFilterer struct { + contract *bind.BoundContract +} + +type LinkTokenSession struct { + Contract *LinkToken + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type LinkTokenCallerSession struct { + Contract *LinkTokenCaller + CallOpts bind.CallOpts +} + +type LinkTokenTransactorSession struct { + Contract *LinkTokenTransactor + TransactOpts bind.TransactOpts +} + +type LinkTokenRaw struct { + Contract *LinkToken +} + +type LinkTokenCallerRaw struct { + Contract *LinkTokenCaller +} + +type LinkTokenTransactorRaw struct { + Contract *LinkTokenTransactor +} + +func NewLinkToken(address common.Address, backend bind.ContractBackend) (*LinkToken, error) { + abi, err := abi.JSON(strings.NewReader(LinkTokenABI)) + if err != nil { + return nil, err + } + contract, err := bindLinkToken(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &LinkToken{address: address, abi: abi, LinkTokenCaller: LinkTokenCaller{contract: contract}, LinkTokenTransactor: LinkTokenTransactor{contract: contract}, LinkTokenFilterer: LinkTokenFilterer{contract: contract}}, nil +} + +func NewLinkTokenCaller(address common.Address, caller bind.ContractCaller) (*LinkTokenCaller, error) { + contract, err := bindLinkToken(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &LinkTokenCaller{contract: contract}, nil +} + +func NewLinkTokenTransactor(address common.Address, transactor bind.ContractTransactor) (*LinkTokenTransactor, error) { + contract, err := bindLinkToken(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &LinkTokenTransactor{contract: contract}, nil +} + +func NewLinkTokenFilterer(address common.Address, filterer bind.ContractFilterer) (*LinkTokenFilterer, error) { + contract, err := bindLinkToken(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &LinkTokenFilterer{contract: contract}, nil +} + +func bindLinkToken(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := LinkTokenMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_LinkToken *LinkTokenRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LinkToken.Contract.LinkTokenCaller.contract.Call(opts, result, method, params...) +} + +func (_LinkToken *LinkTokenRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LinkToken.Contract.LinkTokenTransactor.contract.Transfer(opts) +} + +func (_LinkToken *LinkTokenRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LinkToken.Contract.LinkTokenTransactor.contract.Transact(opts, method, params...) +} + +func (_LinkToken *LinkTokenCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LinkToken.Contract.contract.Call(opts, result, method, params...) +} + +func (_LinkToken *LinkTokenTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LinkToken.Contract.contract.Transfer(opts) +} + +func (_LinkToken *LinkTokenTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LinkToken.Contract.contract.Transact(opts, method, params...) +} + +func (_LinkToken *LinkTokenCaller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) { + var out []interface{} + err := _LinkToken.contract.Call(opts, &out, "allowance", owner, spender) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LinkToken *LinkTokenSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _LinkToken.Contract.Allowance(&_LinkToken.CallOpts, owner, spender) +} + +func (_LinkToken *LinkTokenCallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _LinkToken.Contract.Allowance(&_LinkToken.CallOpts, owner, spender) +} + +func (_LinkToken *LinkTokenCaller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) { + var out []interface{} + err := _LinkToken.contract.Call(opts, &out, "balanceOf", account) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LinkToken *LinkTokenSession) BalanceOf(account common.Address) (*big.Int, error) { + return _LinkToken.Contract.BalanceOf(&_LinkToken.CallOpts, account) +} + +func (_LinkToken *LinkTokenCallerSession) BalanceOf(account common.Address) (*big.Int, error) { + return _LinkToken.Contract.BalanceOf(&_LinkToken.CallOpts, account) +} + +func (_LinkToken *LinkTokenCaller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _LinkToken.contract.Call(opts, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_LinkToken *LinkTokenSession) Decimals() (uint8, error) { + return _LinkToken.Contract.Decimals(&_LinkToken.CallOpts) +} + +func (_LinkToken *LinkTokenCallerSession) Decimals() (uint8, error) { + return _LinkToken.Contract.Decimals(&_LinkToken.CallOpts) +} + +func (_LinkToken *LinkTokenCaller) GetBurners(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _LinkToken.contract.Call(opts, &out, "getBurners") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_LinkToken *LinkTokenSession) GetBurners() ([]common.Address, error) { + return _LinkToken.Contract.GetBurners(&_LinkToken.CallOpts) +} + +func (_LinkToken *LinkTokenCallerSession) GetBurners() ([]common.Address, error) { + return _LinkToken.Contract.GetBurners(&_LinkToken.CallOpts) +} + +func (_LinkToken *LinkTokenCaller) GetMinters(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _LinkToken.contract.Call(opts, &out, "getMinters") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_LinkToken *LinkTokenSession) GetMinters() ([]common.Address, error) { + return _LinkToken.Contract.GetMinters(&_LinkToken.CallOpts) +} + +func (_LinkToken *LinkTokenCallerSession) GetMinters() ([]common.Address, error) { + return _LinkToken.Contract.GetMinters(&_LinkToken.CallOpts) +} + +func (_LinkToken *LinkTokenCaller) IsBurner(opts *bind.CallOpts, burner common.Address) (bool, error) { + var out []interface{} + err := _LinkToken.contract.Call(opts, &out, "isBurner", burner) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LinkToken *LinkTokenSession) IsBurner(burner common.Address) (bool, error) { + return _LinkToken.Contract.IsBurner(&_LinkToken.CallOpts, burner) +} + +func (_LinkToken *LinkTokenCallerSession) IsBurner(burner common.Address) (bool, error) { + return _LinkToken.Contract.IsBurner(&_LinkToken.CallOpts, burner) +} + +func (_LinkToken *LinkTokenCaller) IsMinter(opts *bind.CallOpts, minter common.Address) (bool, error) { + var out []interface{} + err := _LinkToken.contract.Call(opts, &out, "isMinter", minter) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LinkToken *LinkTokenSession) IsMinter(minter common.Address) (bool, error) { + return _LinkToken.Contract.IsMinter(&_LinkToken.CallOpts, minter) +} + +func (_LinkToken *LinkTokenCallerSession) IsMinter(minter common.Address) (bool, error) { + return _LinkToken.Contract.IsMinter(&_LinkToken.CallOpts, minter) +} + +func (_LinkToken *LinkTokenCaller) MaxSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _LinkToken.contract.Call(opts, &out, "maxSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LinkToken *LinkTokenSession) MaxSupply() (*big.Int, error) { + return _LinkToken.Contract.MaxSupply(&_LinkToken.CallOpts) +} + +func (_LinkToken *LinkTokenCallerSession) MaxSupply() (*big.Int, error) { + return _LinkToken.Contract.MaxSupply(&_LinkToken.CallOpts) +} + +func (_LinkToken *LinkTokenCaller) Name(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _LinkToken.contract.Call(opts, &out, "name") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_LinkToken *LinkTokenSession) Name() (string, error) { + return _LinkToken.Contract.Name(&_LinkToken.CallOpts) +} + +func (_LinkToken *LinkTokenCallerSession) Name() (string, error) { + return _LinkToken.Contract.Name(&_LinkToken.CallOpts) +} + +func (_LinkToken *LinkTokenCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LinkToken.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 (_LinkToken *LinkTokenSession) Owner() (common.Address, error) { + return _LinkToken.Contract.Owner(&_LinkToken.CallOpts) +} + +func (_LinkToken *LinkTokenCallerSession) Owner() (common.Address, error) { + return _LinkToken.Contract.Owner(&_LinkToken.CallOpts) +} + +func (_LinkToken *LinkTokenCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _LinkToken.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LinkToken *LinkTokenSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _LinkToken.Contract.SupportsInterface(&_LinkToken.CallOpts, interfaceId) +} + +func (_LinkToken *LinkTokenCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _LinkToken.Contract.SupportsInterface(&_LinkToken.CallOpts, interfaceId) +} + +func (_LinkToken *LinkTokenCaller) Symbol(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _LinkToken.contract.Call(opts, &out, "symbol") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_LinkToken *LinkTokenSession) Symbol() (string, error) { + return _LinkToken.Contract.Symbol(&_LinkToken.CallOpts) +} + +func (_LinkToken *LinkTokenCallerSession) Symbol() (string, error) { + return _LinkToken.Contract.Symbol(&_LinkToken.CallOpts) +} + +func (_LinkToken *LinkTokenCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _LinkToken.contract.Call(opts, &out, "totalSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LinkToken *LinkTokenSession) TotalSupply() (*big.Int, error) { + return _LinkToken.Contract.TotalSupply(&_LinkToken.CallOpts) +} + +func (_LinkToken *LinkTokenCallerSession) TotalSupply() (*big.Int, error) { + return _LinkToken.Contract.TotalSupply(&_LinkToken.CallOpts) +} + +func (_LinkToken *LinkTokenTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LinkToken.contract.Transact(opts, "acceptOwnership") +} + +func (_LinkToken *LinkTokenSession) AcceptOwnership() (*types.Transaction, error) { + return _LinkToken.Contract.AcceptOwnership(&_LinkToken.TransactOpts) +} + +func (_LinkToken *LinkTokenTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _LinkToken.Contract.AcceptOwnership(&_LinkToken.TransactOpts) +} + +func (_LinkToken *LinkTokenTransactor) Approve(opts *bind.TransactOpts, spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _LinkToken.contract.Transact(opts, "approve", spender, amount) +} + +func (_LinkToken *LinkTokenSession) Approve(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.Approve(&_LinkToken.TransactOpts, spender, amount) +} + +func (_LinkToken *LinkTokenTransactorSession) Approve(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.Approve(&_LinkToken.TransactOpts, spender, amount) +} + +func (_LinkToken *LinkTokenTransactor) Burn(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _LinkToken.contract.Transact(opts, "burn", amount) +} + +func (_LinkToken *LinkTokenSession) Burn(amount *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.Burn(&_LinkToken.TransactOpts, amount) +} + +func (_LinkToken *LinkTokenTransactorSession) Burn(amount *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.Burn(&_LinkToken.TransactOpts, amount) +} + +func (_LinkToken *LinkTokenTransactor) Burn0(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) { + return _LinkToken.contract.Transact(opts, "burn0", account, amount) +} + +func (_LinkToken *LinkTokenSession) Burn0(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.Burn0(&_LinkToken.TransactOpts, account, amount) +} + +func (_LinkToken *LinkTokenTransactorSession) Burn0(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.Burn0(&_LinkToken.TransactOpts, account, amount) +} + +func (_LinkToken *LinkTokenTransactor) BurnFrom(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) { + return _LinkToken.contract.Transact(opts, "burnFrom", account, amount) +} + +func (_LinkToken *LinkTokenSession) BurnFrom(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.BurnFrom(&_LinkToken.TransactOpts, account, amount) +} + +func (_LinkToken *LinkTokenTransactorSession) BurnFrom(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.BurnFrom(&_LinkToken.TransactOpts, account, amount) +} + +func (_LinkToken *LinkTokenTransactor) DecreaseAllowance(opts *bind.TransactOpts, spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { + return _LinkToken.contract.Transact(opts, "decreaseAllowance", spender, subtractedValue) +} + +func (_LinkToken *LinkTokenSession) DecreaseAllowance(spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.DecreaseAllowance(&_LinkToken.TransactOpts, spender, subtractedValue) +} + +func (_LinkToken *LinkTokenTransactorSession) DecreaseAllowance(spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.DecreaseAllowance(&_LinkToken.TransactOpts, spender, subtractedValue) +} + +func (_LinkToken *LinkTokenTransactor) DecreaseApproval(opts *bind.TransactOpts, spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { + return _LinkToken.contract.Transact(opts, "decreaseApproval", spender, subtractedValue) +} + +func (_LinkToken *LinkTokenSession) DecreaseApproval(spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.DecreaseApproval(&_LinkToken.TransactOpts, spender, subtractedValue) +} + +func (_LinkToken *LinkTokenTransactorSession) DecreaseApproval(spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.DecreaseApproval(&_LinkToken.TransactOpts, spender, subtractedValue) +} + +func (_LinkToken *LinkTokenTransactor) GrantBurnRole(opts *bind.TransactOpts, burner common.Address) (*types.Transaction, error) { + return _LinkToken.contract.Transact(opts, "grantBurnRole", burner) +} + +func (_LinkToken *LinkTokenSession) GrantBurnRole(burner common.Address) (*types.Transaction, error) { + return _LinkToken.Contract.GrantBurnRole(&_LinkToken.TransactOpts, burner) +} + +func (_LinkToken *LinkTokenTransactorSession) GrantBurnRole(burner common.Address) (*types.Transaction, error) { + return _LinkToken.Contract.GrantBurnRole(&_LinkToken.TransactOpts, burner) +} + +func (_LinkToken *LinkTokenTransactor) GrantMintAndBurnRoles(opts *bind.TransactOpts, burnAndMinter common.Address) (*types.Transaction, error) { + return _LinkToken.contract.Transact(opts, "grantMintAndBurnRoles", burnAndMinter) +} + +func (_LinkToken *LinkTokenSession) GrantMintAndBurnRoles(burnAndMinter common.Address) (*types.Transaction, error) { + return _LinkToken.Contract.GrantMintAndBurnRoles(&_LinkToken.TransactOpts, burnAndMinter) +} + +func (_LinkToken *LinkTokenTransactorSession) GrantMintAndBurnRoles(burnAndMinter common.Address) (*types.Transaction, error) { + return _LinkToken.Contract.GrantMintAndBurnRoles(&_LinkToken.TransactOpts, burnAndMinter) +} + +func (_LinkToken *LinkTokenTransactor) GrantMintRole(opts *bind.TransactOpts, minter common.Address) (*types.Transaction, error) { + return _LinkToken.contract.Transact(opts, "grantMintRole", minter) +} + +func (_LinkToken *LinkTokenSession) GrantMintRole(minter common.Address) (*types.Transaction, error) { + return _LinkToken.Contract.GrantMintRole(&_LinkToken.TransactOpts, minter) +} + +func (_LinkToken *LinkTokenTransactorSession) GrantMintRole(minter common.Address) (*types.Transaction, error) { + return _LinkToken.Contract.GrantMintRole(&_LinkToken.TransactOpts, minter) +} + +func (_LinkToken *LinkTokenTransactor) IncreaseAllowance(opts *bind.TransactOpts, spender common.Address, addedValue *big.Int) (*types.Transaction, error) { + return _LinkToken.contract.Transact(opts, "increaseAllowance", spender, addedValue) +} + +func (_LinkToken *LinkTokenSession) IncreaseAllowance(spender common.Address, addedValue *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.IncreaseAllowance(&_LinkToken.TransactOpts, spender, addedValue) +} + +func (_LinkToken *LinkTokenTransactorSession) IncreaseAllowance(spender common.Address, addedValue *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.IncreaseAllowance(&_LinkToken.TransactOpts, spender, addedValue) +} + +func (_LinkToken *LinkTokenTransactor) IncreaseApproval(opts *bind.TransactOpts, spender common.Address, addedValue *big.Int) (*types.Transaction, error) { + return _LinkToken.contract.Transact(opts, "increaseApproval", spender, addedValue) +} + +func (_LinkToken *LinkTokenSession) IncreaseApproval(spender common.Address, addedValue *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.IncreaseApproval(&_LinkToken.TransactOpts, spender, addedValue) +} + +func (_LinkToken *LinkTokenTransactorSession) IncreaseApproval(spender common.Address, addedValue *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.IncreaseApproval(&_LinkToken.TransactOpts, spender, addedValue) +} + +func (_LinkToken *LinkTokenTransactor) Mint(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) { + return _LinkToken.contract.Transact(opts, "mint", account, amount) +} + +func (_LinkToken *LinkTokenSession) Mint(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.Mint(&_LinkToken.TransactOpts, account, amount) +} + +func (_LinkToken *LinkTokenTransactorSession) Mint(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.Mint(&_LinkToken.TransactOpts, account, amount) +} + +func (_LinkToken *LinkTokenTransactor) RevokeBurnRole(opts *bind.TransactOpts, burner common.Address) (*types.Transaction, error) { + return _LinkToken.contract.Transact(opts, "revokeBurnRole", burner) +} + +func (_LinkToken *LinkTokenSession) RevokeBurnRole(burner common.Address) (*types.Transaction, error) { + return _LinkToken.Contract.RevokeBurnRole(&_LinkToken.TransactOpts, burner) +} + +func (_LinkToken *LinkTokenTransactorSession) RevokeBurnRole(burner common.Address) (*types.Transaction, error) { + return _LinkToken.Contract.RevokeBurnRole(&_LinkToken.TransactOpts, burner) +} + +func (_LinkToken *LinkTokenTransactor) RevokeMintRole(opts *bind.TransactOpts, minter common.Address) (*types.Transaction, error) { + return _LinkToken.contract.Transact(opts, "revokeMintRole", minter) +} + +func (_LinkToken *LinkTokenSession) RevokeMintRole(minter common.Address) (*types.Transaction, error) { + return _LinkToken.Contract.RevokeMintRole(&_LinkToken.TransactOpts, minter) +} + +func (_LinkToken *LinkTokenTransactorSession) RevokeMintRole(minter common.Address) (*types.Transaction, error) { + return _LinkToken.Contract.RevokeMintRole(&_LinkToken.TransactOpts, minter) +} + +func (_LinkToken *LinkTokenTransactor) Transfer(opts *bind.TransactOpts, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _LinkToken.contract.Transact(opts, "transfer", to, amount) +} + +func (_LinkToken *LinkTokenSession) Transfer(to common.Address, amount *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.Transfer(&_LinkToken.TransactOpts, to, amount) +} + +func (_LinkToken *LinkTokenTransactorSession) Transfer(to common.Address, amount *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.Transfer(&_LinkToken.TransactOpts, to, amount) +} + +func (_LinkToken *LinkTokenTransactor) TransferAndCall(opts *bind.TransactOpts, to common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _LinkToken.contract.Transact(opts, "transferAndCall", to, amount, data) +} + +func (_LinkToken *LinkTokenSession) TransferAndCall(to common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _LinkToken.Contract.TransferAndCall(&_LinkToken.TransactOpts, to, amount, data) +} + +func (_LinkToken *LinkTokenTransactorSession) TransferAndCall(to common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _LinkToken.Contract.TransferAndCall(&_LinkToken.TransactOpts, to, amount, data) +} + +func (_LinkToken *LinkTokenTransactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _LinkToken.contract.Transact(opts, "transferFrom", from, to, amount) +} + +func (_LinkToken *LinkTokenSession) TransferFrom(from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.TransferFrom(&_LinkToken.TransactOpts, from, to, amount) +} + +func (_LinkToken *LinkTokenTransactorSession) TransferFrom(from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _LinkToken.Contract.TransferFrom(&_LinkToken.TransactOpts, from, to, amount) +} + +func (_LinkToken *LinkTokenTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _LinkToken.contract.Transact(opts, "transferOwnership", to) +} + +func (_LinkToken *LinkTokenSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _LinkToken.Contract.TransferOwnership(&_LinkToken.TransactOpts, to) +} + +func (_LinkToken *LinkTokenTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _LinkToken.Contract.TransferOwnership(&_LinkToken.TransactOpts, to) +} + +type LinkTokenApprovalIterator struct { + Event *LinkTokenApproval + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LinkTokenApprovalIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LinkTokenApproval) + 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(LinkTokenApproval) + 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 *LinkTokenApprovalIterator) Error() error { + return it.fail +} + +func (it *LinkTokenApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LinkTokenApproval struct { + Owner common.Address + Spender common.Address + Value *big.Int + Raw types.Log +} + +func (_LinkToken *LinkTokenFilterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*LinkTokenApprovalIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _LinkToken.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return &LinkTokenApprovalIterator{contract: _LinkToken.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +func (_LinkToken *LinkTokenFilterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *LinkTokenApproval, owner []common.Address, spender []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _LinkToken.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LinkTokenApproval) + if err := _LinkToken.contract.UnpackLog(event, "Approval", 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 (_LinkToken *LinkTokenFilterer) ParseApproval(log types.Log) (*LinkTokenApproval, error) { + event := new(LinkTokenApproval) + if err := _LinkToken.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LinkTokenBurnAccessGrantedIterator struct { + Event *LinkTokenBurnAccessGranted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LinkTokenBurnAccessGrantedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LinkTokenBurnAccessGranted) + 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(LinkTokenBurnAccessGranted) + 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 *LinkTokenBurnAccessGrantedIterator) Error() error { + return it.fail +} + +func (it *LinkTokenBurnAccessGrantedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LinkTokenBurnAccessGranted struct { + Burner common.Address + Raw types.Log +} + +func (_LinkToken *LinkTokenFilterer) FilterBurnAccessGranted(opts *bind.FilterOpts, burner []common.Address) (*LinkTokenBurnAccessGrantedIterator, error) { + + var burnerRule []interface{} + for _, burnerItem := range burner { + burnerRule = append(burnerRule, burnerItem) + } + + logs, sub, err := _LinkToken.contract.FilterLogs(opts, "BurnAccessGranted", burnerRule) + if err != nil { + return nil, err + } + return &LinkTokenBurnAccessGrantedIterator{contract: _LinkToken.contract, event: "BurnAccessGranted", logs: logs, sub: sub}, nil +} + +func (_LinkToken *LinkTokenFilterer) WatchBurnAccessGranted(opts *bind.WatchOpts, sink chan<- *LinkTokenBurnAccessGranted, burner []common.Address) (event.Subscription, error) { + + var burnerRule []interface{} + for _, burnerItem := range burner { + burnerRule = append(burnerRule, burnerItem) + } + + logs, sub, err := _LinkToken.contract.WatchLogs(opts, "BurnAccessGranted", burnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LinkTokenBurnAccessGranted) + if err := _LinkToken.contract.UnpackLog(event, "BurnAccessGranted", 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 (_LinkToken *LinkTokenFilterer) ParseBurnAccessGranted(log types.Log) (*LinkTokenBurnAccessGranted, error) { + event := new(LinkTokenBurnAccessGranted) + if err := _LinkToken.contract.UnpackLog(event, "BurnAccessGranted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LinkTokenBurnAccessRevokedIterator struct { + Event *LinkTokenBurnAccessRevoked + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LinkTokenBurnAccessRevokedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LinkTokenBurnAccessRevoked) + 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(LinkTokenBurnAccessRevoked) + 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 *LinkTokenBurnAccessRevokedIterator) Error() error { + return it.fail +} + +func (it *LinkTokenBurnAccessRevokedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LinkTokenBurnAccessRevoked struct { + Burner common.Address + Raw types.Log +} + +func (_LinkToken *LinkTokenFilterer) FilterBurnAccessRevoked(opts *bind.FilterOpts, burner []common.Address) (*LinkTokenBurnAccessRevokedIterator, error) { + + var burnerRule []interface{} + for _, burnerItem := range burner { + burnerRule = append(burnerRule, burnerItem) + } + + logs, sub, err := _LinkToken.contract.FilterLogs(opts, "BurnAccessRevoked", burnerRule) + if err != nil { + return nil, err + } + return &LinkTokenBurnAccessRevokedIterator{contract: _LinkToken.contract, event: "BurnAccessRevoked", logs: logs, sub: sub}, nil +} + +func (_LinkToken *LinkTokenFilterer) WatchBurnAccessRevoked(opts *bind.WatchOpts, sink chan<- *LinkTokenBurnAccessRevoked, burner []common.Address) (event.Subscription, error) { + + var burnerRule []interface{} + for _, burnerItem := range burner { + burnerRule = append(burnerRule, burnerItem) + } + + logs, sub, err := _LinkToken.contract.WatchLogs(opts, "BurnAccessRevoked", burnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LinkTokenBurnAccessRevoked) + if err := _LinkToken.contract.UnpackLog(event, "BurnAccessRevoked", 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 (_LinkToken *LinkTokenFilterer) ParseBurnAccessRevoked(log types.Log) (*LinkTokenBurnAccessRevoked, error) { + event := new(LinkTokenBurnAccessRevoked) + if err := _LinkToken.contract.UnpackLog(event, "BurnAccessRevoked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LinkTokenMintAccessGrantedIterator struct { + Event *LinkTokenMintAccessGranted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LinkTokenMintAccessGrantedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LinkTokenMintAccessGranted) + 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(LinkTokenMintAccessGranted) + 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 *LinkTokenMintAccessGrantedIterator) Error() error { + return it.fail +} + +func (it *LinkTokenMintAccessGrantedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LinkTokenMintAccessGranted struct { + Minter common.Address + Raw types.Log +} + +func (_LinkToken *LinkTokenFilterer) FilterMintAccessGranted(opts *bind.FilterOpts, minter []common.Address) (*LinkTokenMintAccessGrantedIterator, error) { + + var minterRule []interface{} + for _, minterItem := range minter { + minterRule = append(minterRule, minterItem) + } + + logs, sub, err := _LinkToken.contract.FilterLogs(opts, "MintAccessGranted", minterRule) + if err != nil { + return nil, err + } + return &LinkTokenMintAccessGrantedIterator{contract: _LinkToken.contract, event: "MintAccessGranted", logs: logs, sub: sub}, nil +} + +func (_LinkToken *LinkTokenFilterer) WatchMintAccessGranted(opts *bind.WatchOpts, sink chan<- *LinkTokenMintAccessGranted, minter []common.Address) (event.Subscription, error) { + + var minterRule []interface{} + for _, minterItem := range minter { + minterRule = append(minterRule, minterItem) + } + + logs, sub, err := _LinkToken.contract.WatchLogs(opts, "MintAccessGranted", minterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LinkTokenMintAccessGranted) + if err := _LinkToken.contract.UnpackLog(event, "MintAccessGranted", 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 (_LinkToken *LinkTokenFilterer) ParseMintAccessGranted(log types.Log) (*LinkTokenMintAccessGranted, error) { + event := new(LinkTokenMintAccessGranted) + if err := _LinkToken.contract.UnpackLog(event, "MintAccessGranted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LinkTokenMintAccessRevokedIterator struct { + Event *LinkTokenMintAccessRevoked + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LinkTokenMintAccessRevokedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LinkTokenMintAccessRevoked) + 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(LinkTokenMintAccessRevoked) + 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 *LinkTokenMintAccessRevokedIterator) Error() error { + return it.fail +} + +func (it *LinkTokenMintAccessRevokedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LinkTokenMintAccessRevoked struct { + Minter common.Address + Raw types.Log +} + +func (_LinkToken *LinkTokenFilterer) FilterMintAccessRevoked(opts *bind.FilterOpts, minter []common.Address) (*LinkTokenMintAccessRevokedIterator, error) { + + var minterRule []interface{} + for _, minterItem := range minter { + minterRule = append(minterRule, minterItem) + } + + logs, sub, err := _LinkToken.contract.FilterLogs(opts, "MintAccessRevoked", minterRule) + if err != nil { + return nil, err + } + return &LinkTokenMintAccessRevokedIterator{contract: _LinkToken.contract, event: "MintAccessRevoked", logs: logs, sub: sub}, nil +} + +func (_LinkToken *LinkTokenFilterer) WatchMintAccessRevoked(opts *bind.WatchOpts, sink chan<- *LinkTokenMintAccessRevoked, minter []common.Address) (event.Subscription, error) { + + var minterRule []interface{} + for _, minterItem := range minter { + minterRule = append(minterRule, minterItem) + } + + logs, sub, err := _LinkToken.contract.WatchLogs(opts, "MintAccessRevoked", minterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LinkTokenMintAccessRevoked) + if err := _LinkToken.contract.UnpackLog(event, "MintAccessRevoked", 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 (_LinkToken *LinkTokenFilterer) ParseMintAccessRevoked(log types.Log) (*LinkTokenMintAccessRevoked, error) { + event := new(LinkTokenMintAccessRevoked) + if err := _LinkToken.contract.UnpackLog(event, "MintAccessRevoked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LinkTokenOwnershipTransferRequestedIterator struct { + Event *LinkTokenOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LinkTokenOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LinkTokenOwnershipTransferRequested) + 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(LinkTokenOwnershipTransferRequested) + 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 *LinkTokenOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *LinkTokenOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LinkTokenOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_LinkToken *LinkTokenFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LinkTokenOwnershipTransferRequestedIterator, 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 := _LinkToken.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &LinkTokenOwnershipTransferRequestedIterator{contract: _LinkToken.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_LinkToken *LinkTokenFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *LinkTokenOwnershipTransferRequested, 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 := _LinkToken.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(LinkTokenOwnershipTransferRequested) + if err := _LinkToken.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 (_LinkToken *LinkTokenFilterer) ParseOwnershipTransferRequested(log types.Log) (*LinkTokenOwnershipTransferRequested, error) { + event := new(LinkTokenOwnershipTransferRequested) + if err := _LinkToken.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LinkTokenOwnershipTransferredIterator struct { + Event *LinkTokenOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LinkTokenOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LinkTokenOwnershipTransferred) + 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(LinkTokenOwnershipTransferred) + 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 *LinkTokenOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *LinkTokenOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LinkTokenOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_LinkToken *LinkTokenFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LinkTokenOwnershipTransferredIterator, 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 := _LinkToken.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &LinkTokenOwnershipTransferredIterator{contract: _LinkToken.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_LinkToken *LinkTokenFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *LinkTokenOwnershipTransferred, 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 := _LinkToken.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(LinkTokenOwnershipTransferred) + if err := _LinkToken.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 (_LinkToken *LinkTokenFilterer) ParseOwnershipTransferred(log types.Log) (*LinkTokenOwnershipTransferred, error) { + event := new(LinkTokenOwnershipTransferred) + if err := _LinkToken.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LinkTokenTransferIterator struct { + Event *LinkTokenTransfer + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LinkTokenTransferIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LinkTokenTransfer) + 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(LinkTokenTransfer) + 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 *LinkTokenTransferIterator) Error() error { + return it.fail +} + +func (it *LinkTokenTransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LinkTokenTransfer struct { + From common.Address + To common.Address + Value *big.Int + Raw types.Log +} + +func (_LinkToken *LinkTokenFilterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LinkTokenTransferIterator, 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 := _LinkToken.contract.FilterLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return &LinkTokenTransferIterator{contract: _LinkToken.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +func (_LinkToken *LinkTokenFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *LinkTokenTransfer, 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 := _LinkToken.contract.WatchLogs(opts, "Transfer", 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(LinkTokenTransfer) + if err := _LinkToken.contract.UnpackLog(event, "Transfer", 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 (_LinkToken *LinkTokenFilterer) ParseTransfer(log types.Log) (*LinkTokenTransfer, error) { + event := new(LinkTokenTransfer) + if err := _LinkToken.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LinkTokenTransfer0Iterator struct { + Event *LinkTokenTransfer0 + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LinkTokenTransfer0Iterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LinkTokenTransfer0) + 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(LinkTokenTransfer0) + 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 *LinkTokenTransfer0Iterator) Error() error { + return it.fail +} + +func (it *LinkTokenTransfer0Iterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LinkTokenTransfer0 struct { + From common.Address + To common.Address + Value *big.Int + Data []byte + Raw types.Log +} + +func (_LinkToken *LinkTokenFilterer) FilterTransfer0(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LinkTokenTransfer0Iterator, 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 := _LinkToken.contract.FilterLogs(opts, "Transfer0", fromRule, toRule) + if err != nil { + return nil, err + } + return &LinkTokenTransfer0Iterator{contract: _LinkToken.contract, event: "Transfer0", logs: logs, sub: sub}, nil +} + +func (_LinkToken *LinkTokenFilterer) WatchTransfer0(opts *bind.WatchOpts, sink chan<- *LinkTokenTransfer0, 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 := _LinkToken.contract.WatchLogs(opts, "Transfer0", 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(LinkTokenTransfer0) + if err := _LinkToken.contract.UnpackLog(event, "Transfer0", 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 (_LinkToken *LinkTokenFilterer) ParseTransfer0(log types.Log) (*LinkTokenTransfer0, error) { + event := new(LinkTokenTransfer0) + if err := _LinkToken.contract.UnpackLog(event, "Transfer0", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_LinkToken *LinkToken) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _LinkToken.abi.Events["Approval"].ID: + return _LinkToken.ParseApproval(log) + case _LinkToken.abi.Events["BurnAccessGranted"].ID: + return _LinkToken.ParseBurnAccessGranted(log) + case _LinkToken.abi.Events["BurnAccessRevoked"].ID: + return _LinkToken.ParseBurnAccessRevoked(log) + case _LinkToken.abi.Events["MintAccessGranted"].ID: + return _LinkToken.ParseMintAccessGranted(log) + case _LinkToken.abi.Events["MintAccessRevoked"].ID: + return _LinkToken.ParseMintAccessRevoked(log) + case _LinkToken.abi.Events["OwnershipTransferRequested"].ID: + return _LinkToken.ParseOwnershipTransferRequested(log) + case _LinkToken.abi.Events["OwnershipTransferred"].ID: + return _LinkToken.ParseOwnershipTransferred(log) + case _LinkToken.abi.Events["Transfer"].ID: + return _LinkToken.ParseTransfer(log) + case _LinkToken.abi.Events["Transfer0"].ID: + return _LinkToken.ParseTransfer0(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (LinkTokenApproval) Topic() common.Hash { + return common.HexToHash("0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925") +} + +func (LinkTokenBurnAccessGranted) Topic() common.Hash { + return common.HexToHash("0x92308bb7573b2a3d17ddb868b39d8ebec433f3194421abc22d084f89658c9bad") +} + +func (LinkTokenBurnAccessRevoked) Topic() common.Hash { + return common.HexToHash("0x0a675452746933cefe3d74182e78db7afe57ba60eaa4234b5d85e9aa41b0610c") +} + +func (LinkTokenMintAccessGranted) Topic() common.Hash { + return common.HexToHash("0xe46fef8bbff1389d9010703cf8ebb363fb3daf5bf56edc27080b67bc8d9251ea") +} + +func (LinkTokenMintAccessRevoked) Topic() common.Hash { + return common.HexToHash("0xed998b960f6340d045f620c119730f7aa7995e7425c2401d3a5b64ff998a59e9") +} + +func (LinkTokenOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (LinkTokenOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (LinkTokenTransfer) Topic() common.Hash { + return common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef") +} + +func (LinkTokenTransfer0) Topic() common.Hash { + return common.HexToHash("0xe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16") +} + +func (_LinkToken *LinkToken) Address() common.Address { + return _LinkToken.address +} + +type LinkTokenInterface interface { + Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) + + BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) + + Decimals(opts *bind.CallOpts) (uint8, error) + + GetBurners(opts *bind.CallOpts) ([]common.Address, error) + + GetMinters(opts *bind.CallOpts) ([]common.Address, error) + + IsBurner(opts *bind.CallOpts, burner common.Address) (bool, error) + + IsMinter(opts *bind.CallOpts, minter common.Address) (bool, error) + + MaxSupply(opts *bind.CallOpts) (*big.Int, error) + + Name(opts *bind.CallOpts) (string, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + Symbol(opts *bind.CallOpts) (string, error) + + TotalSupply(opts *bind.CallOpts) (*big.Int, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + Approve(opts *bind.TransactOpts, spender common.Address, amount *big.Int) (*types.Transaction, error) + + Burn(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) + + Burn0(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) + + BurnFrom(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) + + DecreaseAllowance(opts *bind.TransactOpts, spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) + + DecreaseApproval(opts *bind.TransactOpts, spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) + + GrantBurnRole(opts *bind.TransactOpts, burner common.Address) (*types.Transaction, error) + + GrantMintAndBurnRoles(opts *bind.TransactOpts, burnAndMinter common.Address) (*types.Transaction, error) + + GrantMintRole(opts *bind.TransactOpts, minter common.Address) (*types.Transaction, error) + + IncreaseAllowance(opts *bind.TransactOpts, spender common.Address, addedValue *big.Int) (*types.Transaction, error) + + IncreaseApproval(opts *bind.TransactOpts, spender common.Address, addedValue *big.Int) (*types.Transaction, error) + + Mint(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) + + RevokeBurnRole(opts *bind.TransactOpts, burner common.Address) (*types.Transaction, error) + + RevokeMintRole(opts *bind.TransactOpts, minter common.Address) (*types.Transaction, error) + + Transfer(opts *bind.TransactOpts, to common.Address, amount *big.Int) (*types.Transaction, error) + + TransferAndCall(opts *bind.TransactOpts, to common.Address, amount *big.Int, data []byte) (*types.Transaction, error) + + TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*LinkTokenApprovalIterator, error) + + WatchApproval(opts *bind.WatchOpts, sink chan<- *LinkTokenApproval, owner []common.Address, spender []common.Address) (event.Subscription, error) + + ParseApproval(log types.Log) (*LinkTokenApproval, error) + + FilterBurnAccessGranted(opts *bind.FilterOpts, burner []common.Address) (*LinkTokenBurnAccessGrantedIterator, error) + + WatchBurnAccessGranted(opts *bind.WatchOpts, sink chan<- *LinkTokenBurnAccessGranted, burner []common.Address) (event.Subscription, error) + + ParseBurnAccessGranted(log types.Log) (*LinkTokenBurnAccessGranted, error) + + FilterBurnAccessRevoked(opts *bind.FilterOpts, burner []common.Address) (*LinkTokenBurnAccessRevokedIterator, error) + + WatchBurnAccessRevoked(opts *bind.WatchOpts, sink chan<- *LinkTokenBurnAccessRevoked, burner []common.Address) (event.Subscription, error) + + ParseBurnAccessRevoked(log types.Log) (*LinkTokenBurnAccessRevoked, error) + + FilterMintAccessGranted(opts *bind.FilterOpts, minter []common.Address) (*LinkTokenMintAccessGrantedIterator, error) + + WatchMintAccessGranted(opts *bind.WatchOpts, sink chan<- *LinkTokenMintAccessGranted, minter []common.Address) (event.Subscription, error) + + ParseMintAccessGranted(log types.Log) (*LinkTokenMintAccessGranted, error) + + FilterMintAccessRevoked(opts *bind.FilterOpts, minter []common.Address) (*LinkTokenMintAccessRevokedIterator, error) + + WatchMintAccessRevoked(opts *bind.WatchOpts, sink chan<- *LinkTokenMintAccessRevoked, minter []common.Address) (event.Subscription, error) + + ParseMintAccessRevoked(log types.Log) (*LinkTokenMintAccessRevoked, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LinkTokenOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *LinkTokenOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*LinkTokenOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LinkTokenOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *LinkTokenOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*LinkTokenOwnershipTransferred, error) + + FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LinkTokenTransferIterator, error) + + WatchTransfer(opts *bind.WatchOpts, sink chan<- *LinkTokenTransfer, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseTransfer(log types.Log) (*LinkTokenTransfer, error) + + FilterTransfer0(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LinkTokenTransfer0Iterator, error) + + WatchTransfer0(opts *bind.WatchOpts, sink chan<- *LinkTokenTransfer0, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseTransfer0(log types.Log) (*LinkTokenTransfer0, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/shared/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/shared/generation/generated-wrapper-dependency-versions-do-not-edit.txt new file mode 100644 index 00000000000..3094b1a94f0 --- /dev/null +++ b/core/gethwrappers/shared/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -0,0 +1,4 @@ +GETH_VERSION: 1.12.0 +burn_mint_erc677: ../../../contracts/solc/v0.8.19/BurnMintERC677.abi ../../../contracts/solc/v0.8.19/BurnMintERC677.bin 405c9016171e614b17e10588653ef8d33dcea21dd569c3fddc596a46fcff68a3 +erc20: ../../../contracts/solc/v0.8.19/ERC20.abi ../../../contracts/solc/v0.8.19/ERC20.bin 5b1a93d9b24f250e49a730c96335a8113c3f7010365cba578f313b483001d4fc +link_token: ../../../contracts/solc/v0.8.19/LinkToken.abi ../../../contracts/solc/v0.8.19/LinkToken.bin c0ef9b507103aae541ebc31d87d051c2764ba9d843076b30ec505d37cdfffaba diff --git a/core/gethwrappers/shared/go_generate.go b/core/gethwrappers/shared/go_generate.go new file mode 100644 index 00000000000..169a87b9b2d --- /dev/null +++ b/core/gethwrappers/shared/go_generate.go @@ -0,0 +1,7 @@ +// Package gethwrappers provides tools for wrapping solidity contracts with +// golang packages, using abigen. +package gethwrappers + +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/BurnMintERC677.abi ../../../contracts/solc/v0.8.19/BurnMintERC677.bin BurnMintERC677 burn_mint_erc677 +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/LinkToken.abi ../../../contracts/solc/v0.8.19/LinkToken.bin LinkToken link_token +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/ERC20.abi ../../../contracts/solc/v0.8.19/ERC20.bin ERC20 erc20 diff --git a/core/internal/cltest/cltest.go b/core/internal/cltest/cltest.go index f67b80c224f..c57e35d46f6 100644 --- a/core/internal/cltest/cltest.go +++ b/core/internal/cltest/cltest.go @@ -41,8 +41,7 @@ import ( "github.com/tidwall/gjson" "github.com/urfave/cli" - pkgsolana "github.com/smartcontractkit/chainlink-solana/pkg/solana" - pkgstarknet "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink" + "github.com/smartcontractkit/chainlink-relay/pkg/loop" clienttypes "github.com/smartcontractkit/chainlink/v2/common/chains/client" txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" @@ -50,7 +49,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/assets" "github.com/smartcontractkit/chainlink/v2/core/auth" "github.com/smartcontractkit/chainlink/v2/core/bridges" - "github.com/smartcontractkit/chainlink/v2/core/chains/cosmos" "github.com/smartcontractkit/chainlink/v2/core/chains/evm" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" evmclimocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" @@ -59,8 +57,6 @@ import ( httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - "github.com/smartcontractkit/chainlink/v2/core/chains/solana" - "github.com/smartcontractkit/chainlink/v2/core/chains/starknet" "github.com/smartcontractkit/chainlink/v2/core/cmd" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" @@ -86,7 +82,6 @@ import ( "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" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/services/webhook" clsessions "github.com/smartcontractkit/chainlink/v2/core/sessions" "github.com/smartcontractkit/chainlink/v2/core/static" @@ -196,12 +191,12 @@ type JobPipelineConfig interface { MaxSuccessfulRuns() uint64 } -func NewJobPipelineV2(t testing.TB, cfg pipeline.BridgeConfig, jpcfg JobPipelineConfig, dbCfg pg.QConfig, cc evm.ChainSet, db *sqlx.DB, keyStore keystore.Master, restrictedHTTPClient, unrestrictedHTTPClient *http.Client) JobPipelineV2TestHelper { +func NewJobPipelineV2(t testing.TB, cfg pipeline.BridgeConfig, jpcfg JobPipelineConfig, dbCfg pg.QConfig, legacyChains evm.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) - jrm := job.NewORM(db, cc, prm, btORM, keyStore, lggr, dbCfg) - pr := pipeline.NewRunner(prm, btORM, jpcfg, cfg, cc, keyStore.Eth(), keyStore.VRF(), lggr, restrictedHTTPClient, unrestrictedHTTPClient) + jrm := job.NewORM(db, legacyChains, prm, btORM, keyStore, lggr, dbCfg) + pr := pipeline.NewRunner(prm, btORM, jpcfg, cfg, legacyChains, keyStore.Eth(), keyStore.VRF(), lggr, restrictedHTTPClient, unrestrictedHTTPClient) return JobPipelineV2TestHelper{ prm, jrm, @@ -366,7 +361,7 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn var externalInitiatorManager webhook.ExternalInitiatorManager externalInitiatorManager = &webhook.NullExternalInitiatorManager{} var useRealExternalInitiatorManager bool - var chainCfgs evmtypes.Configs + for _, flag := range flagsAndDeps { switch dep := flag.(type) { case evmclient.Client: @@ -388,110 +383,81 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn } keyStore := keystore.New(db, utils.FastScryptParams, lggr, cfg.Database()) - var ids []utils.Big - for _, c := range cfg.EVMConfigs() { - ids = append(ids, *c.ChainID) - } mailMon := utils.NewMailboxMonitor(cfg.AppID().String()) - var chains chainlink.Chains + loopRegistry := plugins.NewLoopRegistry(lggr.Named("LoopRegistry")) + + relayerFactory := chainlink.RelayerFactory{ + Logger: lggr, + DB: db, + QConfig: cfg.Database(), + LoopRegistry: loopRegistry, + GRPCOpts: loop.GRPCOpts{}, + } + chainId := ethClient.ConfiguredChainID() - chains.EVM, err = evm.NewTOMLChainSet(testutils.Context(t), evm.ChainSetOpts{ - Configs: chainCfgs, - Config: cfg, - Logger: lggr, - DB: db, - KeyStore: keyStore.Eth(), - EventBroadcaster: eventBroadcaster, - GenEthClient: func(_ *big.Int) evmclient.Client { - if chainId.Cmp(cfg.DefaultChainID()) != 0 { - t.Fatalf("expected eth client ChainID %d to match configured DefaultChainID %d", chainId, cfg.DefaultChainID()) - } - return ethClient + evmOpts := chainlink.EVMFactoryConfig{ + RelayerConfig: evm.RelayerConfig{ + AppConfig: cfg, + EventBroadcaster: eventBroadcaster, + MailMon: mailMon, + GenEthClient: func(_ *big.Int) evmclient.Client { + if chainId.Cmp(cfg.DefaultChainID()) != 0 { + t.Fatalf("expected eth client ChainID %d to match configured DefaultChainID %d", chainId, cfg.DefaultChainID()) + } + return ethClient + }, }, - MailMon: mailMon, - }) - if err != nil { - lggr.Fatal(err) + CSAETHKeystore: keyStore, } + + testCtx := testutils.Context(t) + // evm alway enabled for backward compatibility + initOps := []chainlink.CoreRelayerChainInitFunc{chainlink.InitEVM(testCtx, relayerFactory, evmOpts)} + if cfg.CosmosEnabled() { - cosmosLggr := lggr.Named("Cosmos") - opts := cosmos.ChainSetOpts{ - Config: cfg, - Logger: cosmosLggr, - DB: db, - KeyStore: keyStore.Cosmos(), + cosmosCfg := chainlink.CosmosFactoryConfig{ + Keystore: keyStore.Cosmos(), + CosmosConfigs: cfg.CosmosConfigs(), EventBroadcaster: eventBroadcaster, } - cfgs := cfg.CosmosConfigs() - opts.Configs = cosmos.NewConfigs(cfgs) - chains.Cosmos, err = cosmos.NewChainSet(opts, cfgs) - if err != nil { - lggr.Fatal(err) - } + initOps = append(initOps, chainlink.InitCosmos(testCtx, relayerFactory, cosmosCfg)) } if cfg.SolanaEnabled() { - solLggr := lggr.Named("Solana") - cfgs := cfg.SolanaConfigs() - var ids []string - for _, c := range cfgs { - ids = append(ids, *c.ChainID) + solanaCfg := chainlink.SolanaFactoryConfig{ + Keystore: keyStore.Solana(), + SolanaConfigs: cfg.SolanaConfigs(), } - - opts := solana.ChainSetOpts{ - Logger: solLggr, - KeyStore: &keystore.SolanaSigner{keyStore.Solana()}, - Configs: solana.NewConfigs(cfgs), - } - chainSet, err := solana.NewChainSet(opts, cfgs) - if err != nil { - lggr.Fatal(err) - } - - chains.Solana = relay.NewRelayerAdapter(pkgsolana.NewRelayer(solLggr, chainSet), chainSet) + initOps = append(initOps, chainlink.InitSolana(testCtx, relayerFactory, solanaCfg)) } if cfg.StarkNetEnabled() { - starkLggr := lggr.Named("StarkNet") - cfgs := cfg.StarknetConfigs() - - var ids []string - for _, c := range cfgs { - ids = append(ids, *c.ChainID) - } - - if err != nil { - lggr.Fatal(err) - } - - opts := starknet.ChainSetOpts{ - Logger: starkLggr, - KeyStore: &keystore.StarknetLooppSigner{StarkNet: keyStore.StarkNet()}, - Configs: starknet.NewConfigs(cfgs), + starkCfg := chainlink.StarkNetFactoryConfig{ + Keystore: keyStore.StarkNet(), + StarknetConfigs: cfg.StarknetConfigs(), } + initOps = append(initOps, chainlink.InitStarknet(testCtx, relayerFactory, starkCfg)) - chainSet, err := starknet.NewChainSet(opts, cfgs) - if err != nil { - lggr.Fatal(err) - } - - chains.StarkNet = relay.NewRelayerAdapter(pkgstarknet.NewRelayer(starkLggr, chainSet), chainSet) + } + relayChainInterops, err := chainlink.NewCoreRelayerChainInteroperators(initOps...) + if err != nil { + t.Fatal(err) } c := clhttptest.NewTestLocalOnlyHTTPClient() appInstance, err := chainlink.NewApplication(chainlink.ApplicationOpts{ - Config: cfg, - EventBroadcaster: eventBroadcaster, - MailMon: mailMon, - SqlxDB: db, - KeyStore: keyStore, - Chains: chains, - Logger: lggr, - AuditLogger: auditLogger, - CloseLogger: lggr.Sync, - ExternalInitiatorManager: externalInitiatorManager, - RestrictedHTTPClient: c, - UnrestrictedHTTPClient: c, - SecretGenerator: MockSecretGenerator{}, - LoopRegistry: plugins.NewLoopRegistry(lggr), + Config: cfg, + EventBroadcaster: eventBroadcaster, + MailMon: mailMon, + SqlxDB: db, + KeyStore: keyStore, + RelayerChainInteroperators: relayChainInterops, + Logger: lggr, + AuditLogger: auditLogger, + CloseLogger: lggr.Sync, + ExternalInitiatorManager: externalInitiatorManager, + RestrictedHTTPClient: c, + UnrestrictedHTTPClient: c, + SecretGenerator: MockSecretGenerator{}, + LoopRegistry: plugins.NewLoopRegistry(lggr), }) require.NoError(t, err) app := appInstance.(*chainlink.ChainlinkApplication) @@ -555,9 +521,13 @@ func NewEthMocksWithTransactionsOnBlocksAssertions(t testing.TB) *evmclimocks.Cl c.On("SubscribeNewHead", mock.Anything, mock.Anything).Maybe().Return(EmptyMockSubscription(t), nil) c.On("SendTransaction", mock.Anything, mock.Anything).Maybe().Return(nil) c.On("SendTransactionReturnCode", mock.Anything, mock.Anything, mock.Anything).Maybe().Return(clienttypes.Successful, nil) - c.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Maybe().Return(Head(2), nil) - c.On("HeadByNumber", mock.Anything, big.NewInt(1)).Maybe().Return(Head(1), nil) - c.On("HeadByNumber", mock.Anything, big.NewInt(0)).Maybe().Return(Head(0), nil) + // Construct chain + h2 := Head(2) + h1 := HeadWithHash(1, h2.ParentHash) + h0 := HeadWithHash(0, h1.ParentHash) + c.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Maybe().Return(h2, nil) + c.On("HeadByHash", mock.Anything, h1.Hash).Maybe().Return(h1, nil) + c.On("HeadByHash", mock.Anything, h0.Hash).Maybe().Return(h0, nil) c.On("BatchCallContext", mock.Anything, mock.Anything).Maybe().Return(nil).Run(func(args mock.Arguments) { elems := args.Get(1).([]rpc.BatchElem) elems[0].Result = &evmtypes.Block{ @@ -577,7 +547,7 @@ func NewEthMocksWithTransactionsOnBlocksAssertions(t testing.TB) *evmclimocks.Cl block := &types.Header{ Number: big.NewInt(100), } - c.On("HeaderByNumber", mock.Anything, mock.Anything).Maybe().Return(block, nil) + c.On("HeaderByHash", mock.Anything, mock.Anything).Maybe().Return(block, nil) return c } @@ -1039,6 +1009,14 @@ func Head(val interface{}) *evmtypes.Head { return &h } +func HeadWithHash(n int64, hash common.Hash) *evmtypes.Head { + var h evmtypes.Head + time := uint64(0) + h = evmtypes.NewHead(big.NewInt(n), hash, utils.NewHash(), time, utils.NewBig(&FixtureChainID)) + return &h + +} + // LegacyTransactionsFromGasPrices returns transactions matching the given gas prices func LegacyTransactionsFromGasPrices(gasPrices ...int64) []evmtypes.Transaction { return LegacyTransactionsFromGasPricesTxType(0x0, gasPrices...) diff --git a/core/internal/cltest/job_factories.go b/core/internal/cltest/job_factories.go index 649b2f9d015..fd496c5f972 100644 --- a/core/internal/cltest/job_factories.go +++ b/core/internal/cltest/job_factories.go @@ -6,6 +6,7 @@ import ( "github.com/google/uuid" "github.com/smartcontractkit/sqlx" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/bridges" @@ -16,6 +17,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" ) const ( @@ -63,8 +65,10 @@ func getORMs(t *testing.T, db *sqlx.DB) (jobORM job.ORM, pipelineORM pipeline.OR lggr := logger.TestLogger(t) pipelineORM = pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgeORM := bridges.NewORM(db, lggr, config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - jobORM = job.NewORM(db, cc, pipelineORM, bridgeORM, keyStore, lggr, config.Database()) + cc := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(cc) + assert.NoError(t, err) + jobORM = job.NewORM(db, legacyChains, 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 f3a8cdc74cf..4984b8157f1 100644 --- a/core/internal/cltest/mocks.go +++ b/core/internal/cltest/mocks.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "io" - "math/big" "net/http" "net/http/httptest" "sync" @@ -16,10 +15,10 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" - evmconfig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config" evmmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/mocks" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/cmd" + "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/sessions" @@ -28,6 +27,7 @@ import ( gethTypes "github.com/ethereum/go-ethereum/core/types" "github.com/robfig/cron/v3" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) // MockSubscription a mock subscription @@ -135,7 +135,9 @@ type MockCountingPrompter struct { } // Prompt returns an entered string -func (p *MockCountingPrompter) Prompt(string) string { +func (p *MockCountingPrompter) Prompt(string) string { return p.prompt() } + +func (p *MockCountingPrompter) prompt() string { i := p.Count p.Count++ if len(p.EnteredStrings)-1 < i { @@ -146,15 +148,7 @@ func (p *MockCountingPrompter) Prompt(string) string { } // PasswordPrompt returns an entered string -func (p *MockCountingPrompter) PasswordPrompt(string) string { - i := p.Count - p.Count++ - if len(p.EnteredStrings)-1 < i { - p.T.Errorf("Not enough passwords supplied to MockCountingPrompter, wanted %d", i) - p.T.FailNow() - } - return p.EnteredStrings[i] -} +func (p *MockCountingPrompter) PasswordPrompt(string) string { return p.prompt() } // IsTerminal always returns true in tests func (p *MockCountingPrompter) IsTerminal() bool { @@ -422,15 +416,22 @@ func (m MockPasswordPrompter) Prompt() string { return m.Password } -func NewChainSetMockWithOneChain(t testing.TB, ethClient evmclient.Client, cfg evmconfig.ChainScopedConfig) evm.ChainSet { - cc := new(evmmocks.ChainSet) +func NewLegacyChainsWithMockChain(t testing.TB, ethClient evmclient.Client, cfg evm.AppConfig) evm.LegacyChainContainer { ch := new(evmmocks.Chain) ch.On("Client").Return(ethClient) - ch.On("Config").Return(cfg) ch.On("Logger").Return(logger.TestLogger(t)) - ch.On("ID").Return(cfg.EVM().ChainID()) - cc.On("Default").Return(ch, nil) - cc.On("Get", (*big.Int)(nil)).Return(ch, nil) - cc.On("Chains").Return([]evm.Chain{ch}) - return cc + scopedCfg := evmtest.NewChainScopedConfig(t, cfg) + ch.On("ID").Return(scopedCfg.EVM().ChainID()) + ch.On("Config").Return(scopedCfg) + + return NewLegacyChainsWithChain(t, ch, cfg) + +} + +func NewLegacyChainsWithChain(t testing.TB, ch evm.Chain, cfg evm.AppConfig) evm.LegacyChainContainer { + m := map[string]evm.Chain{ch.ID().String(): ch} + legacyChains, err := evm.NewLegacyChains(cfg, m) + require.NoError(t, err) + legacyChains.SetDefault(ch) + return legacyChains } diff --git a/core/internal/cltest/simulated_backend.go b/core/internal/cltest/simulated_backend.go index 177bfc25ce7..9a3dcfd5184 100644 --- a/core/internal/cltest/simulated_backend.go +++ b/core/internal/cltest/simulated_backend.go @@ -73,7 +73,7 @@ func NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain( return NewApplicationWithConfigAndKey(t, cfg, flagsAndDeps...) } -// Mine forces the simulated backend to produce a new block every 2 seconds +// Mine forces the simulated backend to produce a new block every X seconds func Mine(backend *backends.SimulatedBackend, blockTime time.Duration) (stopMining func()) { timer := time.NewTicker(blockTime) chStop := make(chan struct{}) diff --git a/core/internal/features/features_test.go b/core/internal/features/features_test.go index 58cb744ace0..e730ec5f3a0 100644 --- a/core/internal/features/features_test.go +++ b/core/internal/features/features_test.go @@ -65,6 +65,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" "github.com/smartcontractkit/chainlink/v2/core/services/ocr" "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/webhook" "github.com/smartcontractkit/chainlink/v2/core/static" "github.com/smartcontractkit/chainlink/v2/core/store/models" @@ -234,7 +235,8 @@ observationSource = """ pipelineORM := pipeline.NewORM(app.GetSqlxDB(), logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns()) bridgeORM := bridges.NewORM(app.GetSqlxDB(), logger.TestLogger(t), cfg.Database()) - jobORM := job.NewORM(app.GetSqlxDB(), app.GetChains().EVM, pipelineORM, bridgeORM, app.KeyStore, logger.TestLogger(t), cfg.Database()) + legacyChains := app.GetRelayers().LegacyEVMChains() + jobORM := job.NewORM(app.GetSqlxDB(), legacyChains, pipelineORM, bridgeORM, app.KeyStore, logger.TestLogger(t), cfg.Database()) runs := cltest.WaitForPipelineComplete(t, 0, jobID, 1, 2, jobORM, 5*time.Second, 300*time.Millisecond) require.Len(t, runs, 1) @@ -922,7 +924,7 @@ func TestIntegration_OCR(t *testing.T) { err = appBootstrap.Start(testutils.Context(t)) require.NoError(t, err) - jb, err := ocr.ValidatedOracleSpecToml(appBootstrap.GetChains().EVM, fmt.Sprintf(` + jb, err := ocr.ValidatedOracleSpecToml(appBootstrap.GetRelayers().LegacyEVMChains(), fmt.Sprintf(` type = "offchainreporting" schemaVersion = 1 name = "boot" @@ -990,7 +992,7 @@ isBootstrapPeer = true // Note we need: observationTimeout + observationGracePeriod + DeltaGrace (500ms) < DeltaRound (1s) // So 200ms + 200ms + 500ms < 1s - jb, err := ocr.ValidatedOracleSpecToml(apps[i].GetChains().EVM, fmt.Sprintf(` + jb, err := ocr.ValidatedOracleSpecToml(apps[i].GetRelayers().LegacyEVMChains(), fmt.Sprintf(` type = "offchainreporting" schemaVersion = 1 name = "web oracle spec" @@ -1150,7 +1152,7 @@ func TestIntegration_OCR_ForwarderFlow(t *testing.T) { require.NoError(t, err) // set forwardingAllowed = true - jb, err := ocr.ValidatedOracleSpecToml(appBootstrap.GetChains().EVM, fmt.Sprintf(` + jb, err := ocr.ValidatedOracleSpecToml(appBootstrap.GetRelayers().LegacyEVMChains(), fmt.Sprintf(` type = "offchainreporting" schemaVersion = 1 name = "boot" @@ -1220,7 +1222,7 @@ isBootstrapPeer = true // Note we need: observationTimeout + observationGracePeriod + DeltaGrace (500ms) < DeltaRound (1s) // So 200ms + 200ms + 500ms < 1s // forwardingAllowed = true - jb, err := ocr.ValidatedOracleSpecToml(apps[i].GetChains().EVM, fmt.Sprintf(` + jb, err := ocr.ValidatedOracleSpecToml(apps[i].GetRelayers().LegacyEVMChains(), fmt.Sprintf(` type = "offchainreporting" schemaVersion = 1 name = "web oracle spec" @@ -1322,7 +1324,7 @@ func TestIntegration_BlockHistoryEstimator(t *testing.T) { kst := cltest.NewKeyStore(t, db, cfg.Database()) require.NoError(t, kst.Unlock(cltest.Password)) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, KeyStore: kst.Eth(), Client: ethClient, GeneralConfig: cfg}) + cc := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, KeyStore: kst.Eth(), Client: ethClient, GeneralConfig: cfg}) b41 := evmtypes.Block{ Number: 41, @@ -1373,8 +1375,16 @@ func TestIntegration_BlockHistoryEstimator(t *testing.T) { ethClient.On("Dial", mock.Anything).Return(nil) ethClient.On("ConfiguredChainID", mock.Anything).Return(cfg.DefaultChainID(), nil) ethClient.On("BalanceAt", mock.Anything, mock.Anything, mock.Anything).Maybe().Return(oneETH.ToInt(), nil) + // HeadTracker backfill + ethClient.On("HeadByHash", mock.Anything, h40.Hash).Return(&h40, nil).Maybe() + ethClient.On("HeadByHash", mock.Anything, h41.Hash).Return(&h41, nil).Maybe() + ethClient.On("HeadByHash", mock.Anything, h42.Hash).Return(&h42, nil).Maybe() - require.NoError(t, cc.Start(testutils.Context(t))) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(cc) + require.NoError(t, err) + for _, re := range cc.Slice() { + require.NoError(t, re.Start(testutils.Context(t))) + } var newHeads evmtest.RawSub[*evmtypes.Head] select { case newHeads = <-chchNewHeads: @@ -1382,7 +1392,7 @@ func TestIntegration_BlockHistoryEstimator(t *testing.T) { t.Fatal("timed out waiting for app to subscribe") } - chain := evmtest.MustGetDefaultChain(t, cc) + chain := evmtest.MustGetDefaultChain(t, legacyChains) estimator := chain.GasEstimator() gasPrice, gasLimit, err := estimator.GetFee(testutils.Context(t), nil, 500_000, maxGasPrice) require.NoError(t, err) @@ -1398,12 +1408,10 @@ func TestIntegration_BlockHistoryEstimator(t *testing.T) { elems[0].Result = &b43 }) - // HeadTracker backfill - ethClient.On("HeadByNumber", mock.Anything, big.NewInt(42)).Return(&h42, nil) - ethClient.On("HeadByNumber", mock.Anything, big.NewInt(41)).Return(&h41, nil) - // Simulate one new head and check the gas price got updated - newHeads.TrySend(cltest.Head(43)) + h43 := cltest.Head(43) + h43.ParentHash = h42.Hash + newHeads.TrySend(h43) gomega.NewWithT(t).Eventually(func() string { gasPrice, _, err := estimator.GetFee(testutils.Context(t), nil, 500000, maxGasPrice) @@ -1413,7 +1421,7 @@ func TestIntegration_BlockHistoryEstimator(t *testing.T) { } func triggerAllKeys(t *testing.T, app *cltest.TestApplication) { - for _, chain := range app.GetChains().EVM.Chains() { + for _, chain := range app.GetRelayers().LegacyEVMChains().Slice() { keys, err := app.KeyStore.Eth().EnabledKeysForChain(chain.ID()) require.NoError(t, err) for _, k := range keys { diff --git a/core/internal/features/ocr2/features_ocr2_test.go b/core/internal/features/ocr2/features_ocr2_test.go index 7c1335dbf80..10317597ebc 100644 --- a/core/internal/features/ocr2/features_ocr2_test.go +++ b/core/internal/features/ocr2/features_ocr2_test.go @@ -266,7 +266,7 @@ func TestIntegration_OCR2(t *testing.T) { err = bootstrapNode.app.Start(testutils.Context(t)) require.NoError(t, err) - chainSet := bootstrapNode.app.GetChains().EVM + chainSet := bootstrapNode.app.GetRelayers().LegacyEVMChains() require.NotNil(t, chainSet) ocrJob, err := ocrbootstrap.ValidatedBootstrapSpecToml(fmt.Sprintf(` type = "bootstrap" @@ -434,7 +434,8 @@ juelsPerFeeCoinSource = """ // Assert we can read the latest config digest and epoch after a report has been submitted. contractABI, err := abi.JSON(strings.NewReader(ocr2aggregator.OCR2AggregatorABI)) require.NoError(t, err) - ct, err := evm.NewOCRContractTransmitter(ocrContractAddress, apps[0].Chains.EVM.Chains()[0].Client(), contractABI, nil, apps[0].Chains.EVM.Chains()[0].LogPoller(), lggr, nil) + apps[0].GetRelayers().LegacyEVMChains().Slice() + ct, err := evm.NewOCRContractTransmitter(ocrContractAddress, apps[0].GetRelayers().LegacyEVMChains().Slice()[0].Client(), contractABI, nil, apps[0].GetRelayers().LegacyEVMChains().Slice()[0].LogPoller(), lggr, nil) require.NoError(t, err) configDigest, epoch, err := ct.LatestConfigDigestAndEpoch(testutils.Context(t)) require.NoError(t, err) @@ -535,7 +536,7 @@ func TestIntegration_OCR2_ForwarderFlow(t *testing.T) { err = bootstrapNode.app.Start(testutils.Context(t)) require.NoError(t, err) - chainSet := bootstrapNode.app.GetChains().EVM + chainSet := bootstrapNode.app.GetRelayers().LegacyEVMChains() require.NotNil(t, chainSet) ocrJob, err := ocrbootstrap.ValidatedBootstrapSpecToml(fmt.Sprintf(` type = "bootstrap" @@ -657,9 +658,9 @@ juelsPerFeeCoinSource = """ // Once all the jobs are added, replay to ensure we have the configSet logs. for _, app := range apps { - require.NoError(t, app.Chains.EVM.Chains()[0].LogPoller().Replay(testutils.Context(t), blockBeforeConfig.Number().Int64())) + require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Replay(testutils.Context(t), blockBeforeConfig.Number().Int64())) } - require.NoError(t, bootstrapNode.app.Chains.EVM.Chains()[0].LogPoller().Replay(testutils.Context(t), blockBeforeConfig.Number().Int64())) + require.NoError(t, bootstrapNode.app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Replay(testutils.Context(t), blockBeforeConfig.Number().Int64())) // Assert that all the OCR jobs get a run with valid values eventually. var wg sync.WaitGroup @@ -709,7 +710,7 @@ juelsPerFeeCoinSource = """ // Assert we can read the latest config digest and epoch after a report has been submitted. contractABI, err := abi.JSON(strings.NewReader(ocr2aggregator.OCR2AggregatorABI)) require.NoError(t, err) - ct, err := evm.NewOCRContractTransmitter(ocrContractAddress, apps[0].Chains.EVM.Chains()[0].Client(), contractABI, nil, apps[0].Chains.EVM.Chains()[0].LogPoller(), lggr, nil) + ct, err := evm.NewOCRContractTransmitter(ocrContractAddress, apps[0].GetRelayers().LegacyEVMChains().Slice()[0].Client(), contractABI, nil, apps[0].GetRelayers().LegacyEVMChains().Slice()[0].LogPoller(), lggr, nil) require.NoError(t, err) configDigest, epoch, err := ct.LatestConfigDigestAndEpoch(testutils.Context(t)) require.NoError(t, err) diff --git a/core/internal/mocks/application.go b/core/internal/mocks/application.go index 62264f1ff59..fd065dc5dec 100644 --- a/core/internal/mocks/application.go +++ b/core/internal/mocks/application.go @@ -127,20 +127,6 @@ func (_m *Application) GetAuditLogger() audit.AuditLogger { return r0 } -// GetChains provides a mock function with given fields: -func (_m *Application) GetChains() chainlink.Chains { - ret := _m.Called() - - var r0 chainlink.Chains - if rf, ok := ret.Get(0).(func() chainlink.Chains); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(chainlink.Chains) - } - - return r0 -} - // GetConfig provides a mock function with given fields: func (_m *Application) GetConfig() chainlink.GeneralConfig { ret := _m.Called() @@ -269,6 +255,22 @@ func (_m *Application) GetLoopRegistry() *plugins.LoopRegistry { return r0 } +// GetRelayers provides a mock function with given fields: +func (_m *Application) GetRelayers() chainlink.RelayerChainInteroperators { + ret := _m.Called() + + var r0 chainlink.RelayerChainInteroperators + if rf, ok := ret.Get(0).(func() chainlink.RelayerChainInteroperators); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(chainlink.RelayerChainInteroperators) + } + } + + return r0 +} + // GetSqlxDB provides a mock function with given fields: func (_m *Application) GetSqlxDB() *sqlx.DB { ret := _m.Called() diff --git a/core/internal/testutils/configtest/v2/general_config.go b/core/internal/testutils/configtest/v2/general_config.go index 168906c263e..34843c740d6 100644 --- a/core/internal/testutils/configtest/v2/general_config.go +++ b/core/internal/testutils/configtest/v2/general_config.go @@ -66,7 +66,15 @@ func overrides(c *chainlink.Config, s *chainlink.Secrets) { c.EVM = append(c.EVM, &evmcfg.EVMConfig{ ChainID: chainID, Chain: evmcfg.Defaults(chainID), - Nodes: evmcfg.EVMNodes{{Name: ptr("test")}}, + Nodes: evmcfg.EVMNodes{ + &evmcfg.Node{ + Name: ptr("test"), + WSURL: &models.URL{}, + HTTPURL: &models.URL{}, + SendOnly: new(bool), + Order: ptr[int32](100), + }, + }, }) } @@ -91,7 +99,7 @@ func simulated(c *chainlink.Config, s *chainlink.Secrets) { ChainID: chainID, Chain: evmcfg.Defaults(chainID), Enabled: &enabled, - Nodes: evmcfg.EVMNodes{{}}, + Nodes: evmcfg.EVMNodes{&validTestNode}, } if len(c.EVM) == 1 && c.EVM[0].ChainID.Cmp(utils.NewBigI(client.NullClientChainID)) == 0 { c.EVM[0] = &cfg // replace null, if only entry @@ -100,4 +108,12 @@ func simulated(c *chainlink.Config, s *chainlink.Secrets) { } } +var validTestNode = evmcfg.Node{ + Name: ptr("simulated-node"), + WSURL: models.MustParseURL("WSS://simulated-wss.com/ws"), + HTTPURL: models.MustParseURL("http://simulated.com"), + SendOnly: nil, + Order: ptr(int32(1)), +} + func ptr[T any](v T) *T { return &v } diff --git a/core/internal/testutils/evmtest/evmtest.go b/core/internal/testutils/evmtest/evmtest.go index 88f0b0137f5..0fd391c3a23 100644 --- a/core/internal/testutils/evmtest/evmtest.go +++ b/core/internal/testutils/evmtest/evmtest.go @@ -1,6 +1,7 @@ package evmtest import ( + "fmt" "math/big" "sync" "sync/atomic" @@ -27,18 +28,18 @@ import ( httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - evmmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/services/pg" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/services/srvctest" "github.com/smartcontractkit/chainlink/v2/core/utils" ) -func NewChainScopedConfig(t testing.TB, cfg evm.GeneralConfig) evmconfig.ChainScopedConfig { +func NewChainScopedConfig(t testing.TB, cfg evm.AppConfig) evmconfig.ChainScopedConfig { var evmCfg *evmtoml.EVMConfig if len(cfg.EVMConfigs()) > 0 { evmCfg = cfg.EVMConfigs()[0] @@ -58,7 +59,7 @@ type TestChainOpts struct { Client evmclient.Client LogBroadcaster log.Broadcaster LogPoller logpoller.LogPoller - GeneralConfig evm.GeneralConfig + GeneralConfig evm.AppConfig HeadTracker httypes.HeadTracker DB *sqlx.DB TxManager txmgr.TxManager @@ -67,32 +68,27 @@ type TestChainOpts struct { GasEstimator gas.EvmFeeEstimator } -// NewChainSet returns a simple chain collection with one chain and +// NewChainRelayExtenders returns a simple chain collection with one chain and // allows to mock client/config on that chain -func NewChainSet(t testing.TB, testopts TestChainOpts) evm.ChainSet { - opts := NewChainSetOpts(t, testopts) - cc, err := evm.NewTOMLChainSet(testutils.Context(t), opts) +func NewChainRelayExtenders(t testing.TB, testopts TestChainOpts) *evmrelay.ChainRelayerExtenders { + opts := NewChainRelayExtOpts(t, testopts) + cc, err := evmrelay.NewChainRelayerExtenders(testutils.Context(t), opts) require.NoError(t, err) return cc } -// NewMockChainSetWithChain returns a mock chainset with one chain -func NewMockChainSetWithChain(t testing.TB, ch evm.Chain) *evmmocks.ChainSet { - cc := evmmocks.NewChainSet(t) - cc.On("Default").Return(ch, nil) - return cc -} - -func NewChainSetOpts(t testing.TB, testopts TestChainOpts) evm.ChainSetOpts { +func NewChainRelayExtOpts(t testing.TB, testopts TestChainOpts) evm.ChainRelayExtenderConfig { require.NotNil(t, testopts.KeyStore) - opts := evm.ChainSetOpts{ - Config: testopts.GeneralConfig, - Logger: logger.TestLogger(t), - DB: testopts.DB, - KeyStore: testopts.KeyStore, - EventBroadcaster: pg.NewNullEventBroadcaster(), - MailMon: testopts.MailMon, - GasEstimator: testopts.GasEstimator, + opts := evm.ChainRelayExtenderConfig{ + Logger: logger.TestLogger(t), + DB: testopts.DB, + KeyStore: testopts.KeyStore, + RelayerConfig: evm.RelayerConfig{ + AppConfig: testopts.GeneralConfig, + EventBroadcaster: pg.NewNullEventBroadcaster(), + MailMon: testopts.MailMon, + GasEstimator: testopts.GasEstimator, + }, } opts.GenEthClient = func(*big.Int) evmclient.Client { if testopts.Client != nil { @@ -132,7 +128,7 @@ func NewChainSetOpts(t testing.TB, testopts TestChainOpts) evm.ChainSetOpts { return opts } -func MustGetDefaultChain(t testing.TB, cc evm.ChainSet) evm.Chain { +func MustGetDefaultChain(t testing.TB, cc evm.LegacyChainContainer) evm.Chain { chain, err := cc.Default() require.NoError(t, err) return chain @@ -216,7 +212,7 @@ func (mo *TestConfigs) Nodes(chainID utils.Big) (nodes []evmtypes.Node, err erro } } } - err = chains.ErrNotFound + err = fmt.Errorf("no nodes: chain %s: %w", chainID.String(), chains.ErrNotFound) return } @@ -232,7 +228,7 @@ func (mo *TestConfigs) Node(name string) (evmtypes.Node, error) { } } } - return evmtypes.Node{}, chains.ErrNotFound + return evmtypes.Node{}, fmt.Errorf("node %s: %w", name, chains.ErrNotFound) } func (mo *TestConfigs) NodeStatusesPaged(offset int, limit int, chainIDs ...string) (nodes []types.NodeStatus, cnt int, err error) { diff --git a/core/internal/testutils/testutils.go b/core/internal/testutils/testutils.go index 58d6afd4ea0..447475251c4 100644 --- a/core/internal/testutils/testutils.go +++ b/core/internal/testutils/testutils.go @@ -4,6 +4,7 @@ import ( "context" "crypto/ecdsa" "crypto/rand" + "encoding/base64" "flag" "fmt" "math" @@ -440,3 +441,12 @@ func NewTestFlagSet() *flag.FlagSet { func Ptr[T any](v T) *T { return &v } + +func MustDecodeBase64(s string) (b []byte) { + var err error + b, err = base64.StdEncoding.DecodeString(s) + if err != nil { + panic(err) + } + return +} diff --git a/core/logger/logger.go b/core/logger/logger.go index 20788ed4174..1d8feb139f7 100644 --- a/core/logger/logger.go +++ b/core/logger/logger.go @@ -21,8 +21,22 @@ import ( // logsFile describes the logs file name const logsFile = "chainlink_debug.log" +// Create a standard error writer to avoid test issues around os.Stderr being +// reassigned when verbose logging is enabled +type stderrWriter struct{} + +func (sw stderrWriter) Write(p []byte) (n int, err error) { + return os.Stderr.Write(p) +} +func (sw stderrWriter) Close() error { + return nil // never close stderr +} +func (sw stderrWriter) Sync() error { + return os.Stderr.Sync() +} + func init() { - err := zap.RegisterSink("pretty", prettyConsoleSink(os.Stderr)) + err := zap.RegisterSink("pretty", prettyConsoleSink(stderrWriter{})) if err != nil { log.Fatalf("failed to register pretty printer %+v", err) } diff --git a/core/logger/logger_test.go b/core/logger/logger_test.go index 186058de90c..dc7558a5156 100644 --- a/core/logger/logger_test.go +++ b/core/logger/logger_test.go @@ -15,3 +15,16 @@ func TestConfig(t *testing.T) { assert.False(t, newZapConfigBase().Development) assert.False(t, newZapConfigProd(false, false).Development) } + +func TestStderrWriter(t *testing.T) { + sw := stderrWriter{} + + // Test Write + n, err := sw.Write([]byte("Hello, World!")) + assert.NoError(t, err) + assert.Equal(t, 13, n, "Expected 13 bytes written") + + // Test Close + err = sw.Close() + assert.NoError(t, err) +} diff --git a/core/scripts/chaincli/.env.example b/core/scripts/chaincli/.env.example index d6356ae18dc..0003df7d280 100644 --- a/core/scripts/chaincli/.env.example +++ b/core/scripts/chaincli/.env.example @@ -46,3 +46,10 @@ UPKEEP_GAS_LIMIT=5000000 UPKEEP_MERCURY=true UPKEEP_ADD_FUNDS_AMOUNT=10000000000000000000 # 10 LINK +# UPKEEP_TYPE is used to select if we should deploy a conditional, log trigger, mercury, etc upkeep. +# See chainlink/core/scripts/chaincli/config/config.go. Example usage: +# UPKEEP_TYPE=0 # for conditional +# UPKEEP_TYPE=1 # for mercury +# UPKEEP_TYPE=2 # for log trigger +# UPKEEP_TYPE=3 # for log triggered feed lookup + diff --git a/core/scripts/chaincli/handler/keeper.go b/core/scripts/chaincli/handler/keeper.go index 9a5457f8cc0..0cbc1525577 100644 --- a/core/scripts/chaincli/handler/keeper.go +++ b/core/scripts/chaincli/handler/keeper.go @@ -17,6 +17,7 @@ import ( "github.com/smartcontractkit/chainlink/core/scripts/chaincli/config" helpers "github.com/smartcontractkit/chainlink/core/scripts/common" "github.com/smartcontractkit/chainlink/v2/core/cmd" + automationForwarderLogic "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_forwarder_logic" iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" registrylogic20 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_logic2_0" registrylogica21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_logic_a_wrapper_2_1" @@ -250,6 +251,13 @@ func (k *Keeper) VerifyContract(params ...string) { // deployRegistry21 deploys a version 2.1 keeper registry func (k *Keeper) deployRegistry21(ctx context.Context, verify bool) (common.Address, *iregistry21.IKeeperRegistryMaster) { + automationForwarderLogicAddr, tx, _, err := automationForwarderLogic.DeployAutomationForwarderLogic(k.buildTxOpts(ctx), k.client) + if err != nil { + log.Fatal("Deploy AutomationForwarderLogic failed: ", err) + } + k.waitDeployment(ctx, tx) + log.Println("AutomationForwarderLogic deployed:", automationForwarderLogicAddr.Hex(), "-", helpers.ExplorerLink(k.cfg.ChainID, tx.Hash())) + registryLogicBAddr, tx, _, err := registrylogicb21.DeployKeeperRegistryLogicB( k.buildTxOpts(ctx), k.client, @@ -257,12 +265,13 @@ func (k *Keeper) deployRegistry21(ctx context.Context, verify bool) (common.Addr common.HexToAddress(k.cfg.LinkTokenAddr), common.HexToAddress(k.cfg.LinkETHFeedAddr), common.HexToAddress(k.cfg.FastGasFeedAddr), + automationForwarderLogicAddr, ) if err != nil { log.Fatal("DeployAbi failed: ", err) } k.waitDeployment(ctx, tx) - log.Println("KeeperRegistryLogicB 2.1 Logic deployed:", registryLogicBAddr.Hex(), "-", helpers.ExplorerLink(k.cfg.ChainID, tx.Hash())) + log.Println("KeeperRegistry LogicB 2.1 deployed:", registryLogicBAddr.Hex(), "-", helpers.ExplorerLink(k.cfg.ChainID, tx.Hash())) // verify KeeperRegistryLogicB if verify { @@ -279,7 +288,7 @@ func (k *Keeper) deployRegistry21(ctx context.Context, verify bool) (common.Addr log.Fatal("DeployAbi failed: ", err) } k.waitDeployment(ctx, tx) - log.Println("KeeperRegistryLogicA 2.1 Logic deployed:", registryLogicAAddr.Hex(), "-", helpers.ExplorerLink(k.cfg.ChainID, tx.Hash())) + log.Println("KeeperRegistry LogicA 2.1 deployed:", registryLogicAAddr.Hex(), "-", helpers.ExplorerLink(k.cfg.ChainID, tx.Hash())) // verify KeeperRegistryLogicA if verify { @@ -520,6 +529,7 @@ func (k *Keeper) deployUpkeeps(ctx context.Context, registryAddr common.Address, var upkeepAddr common.Address var deployUpkeepTx *types.Transaction var registerUpkeepTx *types.Transaction + var logUpkeepCounter *log_upkeep_counter_wrapper.LogUpkeepCounter var checkData []byte var err error switch k.cfg.UpkeepType { @@ -594,7 +604,7 @@ func (k *Keeper) deployUpkeeps(ctx context.Context, registryAddr common.Address, log.Fatal(i, upkeepAddr.Hex(), ": RegisterUpkeep failed - ", err) } case config.LogTrigger: - upkeepAddr, deployUpkeepTx, _, err = log_upkeep_counter_wrapper.DeployLogUpkeepCounter( + upkeepAddr, deployUpkeepTx, logUpkeepCounter, err = log_upkeep_counter_wrapper.DeployLogUpkeepCounter( k.buildTxOpts(ctx), k.client, big.NewInt(k.cfg.UpkeepTestRange), @@ -622,6 +632,16 @@ func (k *Keeper) deployUpkeeps(ctx context.Context, registryAddr common.Address, if err != nil { log.Fatal(i, upkeepAddr.Hex(), ": RegisterUpkeep failed - ", err) } + + // Start up log trigger cycle + logUpkeepStartTx, err := logUpkeepCounter.Start(k.buildTxOpts(ctx)) + if err != nil { + log.Fatal("failed to start log upkeep counter", err) + } + if err := k.waitTx(ctx, logUpkeepStartTx); err != nil { + log.Fatalf("Log upkeep Start() failed for upkeepId: %s, error is %s", upkeepAddr.Hex(), err.Error()) + } + log.Println(i, upkeepAddr.Hex(), ": Log upkeep successfully started - ", helpers.ExplorerLink(k.cfg.ChainID, logUpkeepStartTx.Hash())) default: log.Fatal("unexpected upkeep type") } diff --git a/core/scripts/chaincli/handler/keeper_deployer.go b/core/scripts/chaincli/handler/keeper_deployer.go index f353a602911..089b176695c 100644 --- a/core/scripts/chaincli/handler/keeper_deployer.go +++ b/core/scripts/chaincli/handler/keeper_deployer.go @@ -19,7 +19,7 @@ import ( "github.com/smartcontractkit/chainlink/core/scripts/chaincli/config" - offchain "github.com/smartcontractkit/ocr2keepers/pkg/config" + offchain20config "github.com/smartcontractkit/ocr2keepers/pkg/v2/config" "github.com/smartcontractkit/chainlink/v2/core/cmd" iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" @@ -148,7 +148,7 @@ func (d *v20KeeperDeployer) SetKeepers(opts *bind.TransactOpts, cls []cmd.HTTPCl } wg.Wait() - offC, err := json.Marshal(offchain.OffchainConfig{ + offC, err := json.Marshal(offchain20config.OffchainConfig{ PerformLockoutWindow: 100 * 3 * 1000, // ~100 block lockout (on mumbai) MinConfirmations: 1, }) @@ -288,7 +288,7 @@ func (d *v21KeeperDeployer) SetKeepers(opts *bind.TransactOpts, cls []cmd.HTTPCl } wg.Wait() - offC, err := json.Marshal(offchain.OffchainConfig{ + offC, err := json.Marshal(offchain20config.OffchainConfig{ PerformLockoutWindow: 100 * 3 * 1000, // ~100 block lockout (on mumbai) MinConfirmations: 1, MercuryLookup: d.cfg.UpkeepType == config.Mercury || d.cfg.UpkeepType == config.LogTriggeredFeedLookup, @@ -353,7 +353,7 @@ func (d *v21KeeperDeployer) SetKeepers(opts *bind.TransactOpts, cls []cmd.HTTPCl UpkeepPrivilegeManager: common.HexToAddress(d.cfg.UpkeepPrivilegeManager), } - return d.IKeeperRegistryMasterInterface.SetConfig(opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + return d.IKeeperRegistryMasterInterface.SetConfigTypeSafe(opts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) } // legacy support function diff --git a/core/scripts/chaincli/handler/keeper_verifiable_load.go b/core/scripts/chaincli/handler/keeper_verifiable_load.go index d954ad4d180..ad704393877 100644 --- a/core/scripts/chaincli/handler/keeper_verifiable_load.go +++ b/core/scripts/chaincli/handler/keeper_verifiable_load.go @@ -26,41 +26,42 @@ const ( maxUpkeepNum = 100 ) -type UpkeepInfo struct { - mu sync.Mutex - ID *big.Int - Bucket uint16 - TimestampBucket uint16 - DelayBuckets map[uint16][]float64 - DelayTimestampBuckets map[uint16][]float64 - SortedAllDelays []float64 - TotalDelayBlock float64 - TotalPerforms uint64 +type upkeepInfo struct { + mu sync.Mutex + ID *big.Int + Bucket uint16 + DelayBuckets map[uint16][]float64 + SortedAllDelays []float64 + TotalDelayBlock float64 + TotalPerforms uint64 } -func (ui *UpkeepInfo) AddBucket(bucketNum uint16, bucketDelays []float64) { - ui.mu.Lock() - defer ui.mu.Unlock() - ui.DelayBuckets[bucketNum] = bucketDelays +type verifiableLoad interface { + GetActiveUpkeepIDs(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) + Counters(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error) + GetBucketedDelays(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) ([]*big.Int, error) + Buckets(opts *bind.CallOpts, arg0 *big.Int) (uint16, error) } -func (ui *UpkeepInfo) AddTimestampBucket(bucketNum uint16, bucketDelays []float64) { +func (ui *upkeepInfo) AddBucket(bucketNum uint16, bucketDelays []float64) { ui.mu.Lock() defer ui.mu.Unlock() - ui.DelayTimestampBuckets[bucketNum] = bucketDelays + ui.DelayBuckets[bucketNum] = bucketDelays } -type UpkeepStats struct { +type upkeepStats struct { BlockNumber uint64 - AllInfos []*UpkeepInfo + AllInfos []*upkeepInfo TotalDelayBlock float64 TotalPerforms uint64 SortedAllDelays []float64 } func (k *Keeper) GetVerifiableLoadStats(ctx context.Context) { + var v verifiableLoad + var err error addr := common.HexToAddress(k.cfg.VerifiableLoadContractAddress) - v, err := verifiable_load_upkeep_wrapper.NewVerifiableLoadUpkeep(addr, k.client) + v, err = verifiable_load_upkeep_wrapper.NewVerifiableLoadUpkeep(addr, k.client) if err != nil { log.Fatalf("failed to create a new verifiable load upkeep from address %s: %v", k.cfg.VerifiableLoadContractAddress, err) } @@ -83,9 +84,9 @@ func (k *Keeper) GetVerifiableLoadStats(ctx context.Context) { log.Fatalf("failed to get active upkeep IDs from %s: %v", k.cfg.VerifiableLoadContractAddress, err) } - upkeepStats := &UpkeepStats{BlockNumber: blockNum} + us := &upkeepStats{BlockNumber: blockNum} - resultsChan := make(chan *UpkeepInfo, maxUpkeepNum) + resultsChan := make(chan *upkeepInfo, maxUpkeepNum) idChan := make(chan *big.Int, maxUpkeepNum) var wg sync.WaitGroup @@ -106,25 +107,25 @@ func (k *Keeper) GetVerifiableLoadStats(ctx context.Context) { close(resultsChan) for info := range resultsChan { - upkeepStats.AllInfos = append(upkeepStats.AllInfos, info) - upkeepStats.TotalPerforms += info.TotalPerforms - upkeepStats.TotalDelayBlock += info.TotalDelayBlock - upkeepStats.SortedAllDelays = append(upkeepStats.SortedAllDelays, info.SortedAllDelays...) + us.AllInfos = append(us.AllInfos, info) + us.TotalPerforms += info.TotalPerforms + us.TotalDelayBlock += info.TotalDelayBlock + us.SortedAllDelays = append(us.SortedAllDelays, info.SortedAllDelays...) } - sort.Float64s(upkeepStats.SortedAllDelays) + sort.Float64s(us.SortedAllDelays) log.Println("\n\n================================== ALL UPKEEPS SUMMARY =======================================================") - p50, _ := stats.Percentile(upkeepStats.SortedAllDelays, 50) - p90, _ := stats.Percentile(upkeepStats.SortedAllDelays, 90) - p95, _ := stats.Percentile(upkeepStats.SortedAllDelays, 95) - p99, _ := stats.Percentile(upkeepStats.SortedAllDelays, 99) - maxDelay := upkeepStats.SortedAllDelays[len(upkeepStats.SortedAllDelays)-1] - log.Printf("For total %d upkeeps: total performs: %d, p50: %f, p90: %f, p95: %f, p99: %f, max delay: %f, total delay blocks: %f, average perform delay: %f\n", len(upkeepIds), upkeepStats.TotalPerforms, p50, p90, p95, p99, maxDelay, upkeepStats.TotalDelayBlock, upkeepStats.TotalDelayBlock/float64(upkeepStats.TotalPerforms)) + p50, _ := stats.Percentile(us.SortedAllDelays, 50) + p90, _ := stats.Percentile(us.SortedAllDelays, 90) + p95, _ := stats.Percentile(us.SortedAllDelays, 95) + p99, _ := stats.Percentile(us.SortedAllDelays, 99) + maxDelay := us.SortedAllDelays[len(us.SortedAllDelays)-1] + log.Printf("For total %d upkeeps: total performs: %d, p50: %f, p90: %f, p95: %f, p99: %f, max delay: %f, total delay blocks: %f, average perform delay: %f\n", len(upkeepIds), us.TotalPerforms, p50, p90, p95, p99, maxDelay, us.TotalDelayBlock, us.TotalDelayBlock/float64(us.TotalPerforms)) log.Printf("All STATS ABOVE ARE CALCULATED AT BLOCK %d", blockNum) } -func (k *Keeper) getUpkeepInfo(idChan chan *big.Int, resultsChan chan *UpkeepInfo, v *verifiable_load_upkeep_wrapper.VerifiableLoadUpkeep, opts *bind.CallOpts, wg *sync.WaitGroup) { +func (k *Keeper) getUpkeepInfo(idChan chan *big.Int, resultsChan chan *upkeepInfo, v verifiableLoad, opts *bind.CallOpts, wg *sync.WaitGroup) { defer wg.Done() for id := range idChan { @@ -140,31 +141,18 @@ func (k *Keeper) getUpkeepInfo(idChan chan *big.Int, resultsChan chan *UpkeepInf log.Fatalf("failed to get current bucket count for %s: %v", id.String(), err) } - info := &UpkeepInfo{ - ID: id, - Bucket: b, - TotalPerforms: c.Uint64(), - DelayBuckets: map[uint16][]float64{}, - DelayTimestampBuckets: map[uint16][]float64{}, + info := &upkeepInfo{ + ID: id, + Bucket: b, + TotalPerforms: c.Uint64(), + DelayBuckets: map[uint16][]float64{}, } var delays []float64 var wg1 sync.WaitGroup for i := uint16(0); i <= b; i++ { wg1.Add(1) - go k.getBucketData(v, opts, false, id, i, &wg1, info) - } - wg1.Wait() - - // get all the timestamp buckets of an upkeep. performs which happen every 1 hour after the first perform fall into the same bucket. - t, err := v.TimestampBuckets(opts, id) - if err != nil { - log.Fatalf("failed to get timestamp bucket for %s: %v", id.String(), err) - } - info.TimestampBucket = t - for i := uint16(0); i <= t; i++ { - wg1.Add(1) - go k.getBucketData(v, opts, true, id, i, &wg1, info) + go k.getBucketData(v, opts, id, i, &wg1, info) } wg1.Wait() @@ -183,7 +171,6 @@ func (k *Keeper) getUpkeepInfo(idChan chan *big.Int, resultsChan chan *UpkeepInf p90, _ := stats.Percentile(info.SortedAllDelays, 90) p95, _ := stats.Percentile(info.SortedAllDelays, 95) p99, _ := stats.Percentile(info.SortedAllDelays, 99) - // TODO sometimes SortedAllDelays is empty maxDelay := info.SortedAllDelays[len(info.SortedAllDelays)-1] log.Printf("upkeep ID %s has %d performs in total. p50: %f, p90: %f, p95: %f, p99: %f, max delay: %f, total delay blocks: %d, average perform delay: %f\n", id, info.TotalPerforms, p50, p90, p95, p99, maxDelay, uint64(info.TotalDelayBlock), info.TotalDelayBlock/float64(info.TotalPerforms)) @@ -191,30 +178,18 @@ func (k *Keeper) getUpkeepInfo(idChan chan *big.Int, resultsChan chan *UpkeepInf } } -func (k *Keeper) getBucketData(v *verifiable_load_upkeep_wrapper.VerifiableLoadUpkeep, opts *bind.CallOpts, getTimestampBucket bool, id *big.Int, bucketNum uint16, wg *sync.WaitGroup, info *UpkeepInfo) { +func (k *Keeper) getBucketData(v verifiableLoad, opts *bind.CallOpts, id *big.Int, bucketNum uint16, wg *sync.WaitGroup, info *upkeepInfo) { defer wg.Done() var bucketDelays []*big.Int var err error - if getTimestampBucket { - for i := 0; i < retryNum; i++ { - bucketDelays, err = v.GetTimestampDelays(opts, id, bucketNum) - if err != nil { - log.Printf("failed to get timestamp bucketed delays for upkeep id %s timestamp bucket %d: %v, retrying...", id.String(), bucketNum, err) - time.Sleep(retryDelay) - } else { - break - } - } - } else { - for i := 0; i < retryNum; i++ { - bucketDelays, err = v.GetBucketedDelays(opts, id, bucketNum) - if err != nil { - log.Printf("failed to get bucketed delays for upkeep id %s bucket %d: %v, retrying...", id.String(), bucketNum, err) - time.Sleep(retryDelay) - } else { - break - } + for i := 0; i < retryNum; i++ { + bucketDelays, err = v.GetBucketedDelays(opts, id, bucketNum) + if err != nil { + log.Printf("failed to get bucketed delays for upkeep id %s bucket %d: %v, retrying...", id.String(), bucketNum, err) + time.Sleep(retryDelay) + } else { + break } } @@ -223,10 +198,5 @@ func (k *Keeper) getBucketData(v *verifiable_load_upkeep_wrapper.VerifiableLoadU floatBucketDelays = append(floatBucketDelays, float64(d.Uint64())) } sort.Float64s(floatBucketDelays) - - if getTimestampBucket { - info.AddTimestampBucket(bucketNum, floatBucketDelays) - } else { - info.AddBucket(bucketNum, floatBucketDelays) - } + info.AddBucket(bucketNum, floatBucketDelays) } diff --git a/core/scripts/chaincli/handler/ocr2_config.go b/core/scripts/chaincli/handler/ocr2_config.go index 4586fdbc419..7cf25364058 100644 --- a/core/scripts/chaincli/handler/ocr2_config.go +++ b/core/scripts/chaincli/handler/ocr2_config.go @@ -12,7 +12,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/olekukonko/tablewriter" "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" - ocr2config "github.com/smartcontractkit/ocr2keepers/pkg/config" + ocr2keepers20config "github.com/smartcontractkit/ocr2keepers/pkg/v2/config" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper2_0" ) @@ -112,7 +112,7 @@ func printConfigValues(config *confighelper.PublicConfig) { data = append(data, []string{"MaxDurationShouldTransmitAcceptedReport", config.MaxDurationShouldTransmitAcceptedReport.String()}) data = append(data, []string{"F", fmt.Sprintf("%v", config.F)}) - if offConf, err := ocr2config.DecodeOffchainConfig(config.ReportingPluginConfig); err == nil { + if offConf, err := ocr2keepers20config.DecodeOffchainConfig(config.ReportingPluginConfig); err == nil { data = append(data, []string{"", ""}) data = append(data, []string{"TargetProbability", offConf.TargetProbability}) data = append(data, []string{"GasLimitPerReport", fmt.Sprintf("%d", offConf.GasLimitPerReport)}) diff --git a/core/scripts/chaincli/handler/report.go b/core/scripts/chaincli/handler/report.go index d1523632dbf..90f2be96548 100644 --- a/core/scripts/chaincli/handler/report.go +++ b/core/scripts/chaincli/handler/report.go @@ -17,7 +17,7 @@ import ( "github.com/ethereum/go-ethereum/rpc" "github.com/olekukonko/tablewriter" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" + ocr2keepers20 "github.com/smartcontractkit/ocr2keepers/pkg/v2" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper2_0" evm "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm20" @@ -294,7 +294,7 @@ type OCR2TransmitTx struct { OCR2Transaction } -func (t *OCR2TransmitTx) UpkeepsInTransmit() ([]ocr2keepers.UpkeepResult, error) { +func (t *OCR2TransmitTx) UpkeepsInTransmit() ([]ocr2keepers20.UpkeepResult, error) { txData := t.tx.Data() diff --git a/core/scripts/chaincli/handler/scrape_node_config.go b/core/scripts/chaincli/handler/scrape_node_config.go index 932a03ea77a..f00beb4b4fe 100644 --- a/core/scripts/chaincli/handler/scrape_node_config.go +++ b/core/scripts/chaincli/handler/scrape_node_config.go @@ -27,18 +27,18 @@ type CSAKeyInfo struct { } func (ci *CSAKeyInfo) Equals(ci2 *CSAKeyInfo) bool { - return ci.PublicKey == ci2.PublicKey && ci.NodeAddress == ci.NodeAddress + return ci.PublicKey == ci2.PublicKey && ci.NodeAddress == ci2.NodeAddress } type NodeInfo struct { AdminAddress common.Address `json:"adminAddress"` CSAKeys []*CSAKeyInfo `json:"csaKeys"` DisplayName string `json:"displayName"` - NodeAddress []string `json:"nodeAddress"` Ocr2ConfigPublicKey []string `json:"ocr2ConfigPublicKey"` Ocr2Id []string `json:"ocr2Id"` Ocr2OffchainPublicKey []string `json:"ocr2OffchainPublicKey"` Ocr2OnchainPublicKey []string `json:"ocr2OnchainPublicKey"` + NodeAddress []string `json:"ocrNodeAddress"` OcrSigningAddress []string `json:"ocrSigningAddress"` PayeeAddress common.Address `json:"payeeAddress"` PeerId []string `json:"peerId"` @@ -243,7 +243,7 @@ func (h *baseHandler) scrapeNodeInfo(wg *sync.WaitGroup, i int, cl cmd.HTTPClien // CSA key for each chain. but this is still pending so assume only 1 CSA key on a node for now. csaKey := &CSAKeyInfo{ NodeAddress: nodeAddresses[0], - PublicKey: (*csaKeys)[0].PubKey, + PublicKey: strings.TrimPrefix((*csaKeys)[0].PubKey, "csa_"), } ni := &NodeInfo{ CSAKeys: []*CSAKeyInfo{csaKey}, diff --git a/core/scripts/common/helpers.go b/core/scripts/common/helpers.go index 4a4864485c1..c5d6499b2fd 100644 --- a/core/scripts/common/helpers.go +++ b/core/scripts/common/helpers.go @@ -109,6 +109,7 @@ func SetupEnv(overrideNonce bool) Environment { // Explicitly set gas price to ensure non-eip 1559 gp, err := ec.SuggestGasPrice(context.Background()) PanicErr(err) + fmt.Println("Suggested Gas Price:", gp, "wei") owner.GasPrice = gp gasLimit, set := os.LookupEnv("GAS_LIMIT") if set { @@ -127,9 +128,9 @@ func SetupEnv(overrideNonce bool) Environment { PanicErr(err) owner.Nonce = big.NewInt(int64(nonce)) - owner.GasPrice = gp.Mul(gp, big.NewInt(2)) } - + owner.GasPrice = gp.Mul(gp, big.NewInt(2)) + fmt.Println("Modified Gas Price that will be set:", owner.GasPrice, "wei") // the execution environment for the scripts return Environment{ Owner: owner, @@ -334,43 +335,52 @@ func ParseHexSlice(arg string) (ret [][]byte) { } func FundNodes(e Environment, transmitters []string, fundingAmount *big.Int) { + for _, transmitter := range transmitters { + FundNode(e, transmitter, fundingAmount) + } +} + +func FundNode(e Environment, address string, fundingAmount *big.Int) { block, err := e.Ec.BlockNumber(context.Background()) PanicErr(err) nonce, err := e.Ec.NonceAt(context.Background(), e.Owner.From, big.NewInt(int64(block))) PanicErr(err) - - for i := 0; i < len(transmitters); i++ { - // Special case for Arbitrum since gas estimation there is different. - var gasLimit uint64 - if IsArbitrumChainID(e.ChainID) { - to := common.HexToAddress(transmitters[i]) - estimated, err := e.Ec.EstimateGas(context.Background(), ethereum.CallMsg{ - From: e.Owner.From, - To: &to, - Value: fundingAmount, - }) - PanicErr(err) - gasLimit = estimated - } else { - gasLimit = uint64(21_000) - } - - tx := types.NewTransaction( - nonce+uint64(i), - common.HexToAddress(transmitters[i]), - fundingAmount, - gasLimit, - e.Owner.GasPrice, - nil, - ) - signedTx, err := e.Owner.Signer(e.Owner.From, tx) + // Special case for Arbitrum since gas estimation there is different. + + var gasLimit uint64 + if IsArbitrumChainID(e.ChainID) { + to := common.HexToAddress(address) + estimated, err := e.Ec.EstimateGas(context.Background(), ethereum.CallMsg{ + From: e.Owner.From, + To: &to, + Value: fundingAmount, + }) PanicErr(err) - err = e.Ec.SendTransaction(context.Background(), signedTx) - PanicErr(err) - - fmt.Printf("Sending to %s: %s\n", transmitters[i], ExplorerLink(e.ChainID, signedTx.Hash())) + gasLimit = estimated + } else { + gasLimit = uint64(21_000) } + toAddress := common.HexToAddress(address) + + tx := types.NewTx( + &types.LegacyTx{ + Nonce: nonce, + GasPrice: e.Owner.GasPrice, + Gas: gasLimit, + To: &toAddress, + Value: fundingAmount, + Data: nil, + }) + + signedTx, err := e.Owner.Signer(e.Owner.From, tx) + PanicErr(err) + err = e.Ec.SendTransaction(context.Background(), signedTx) + PanicErr(err) + fmt.Printf("Sending to %s: %s\n", address, ExplorerLink(e.ChainID, signedTx.Hash())) + PanicErr(err) + _, err = bind.WaitMined(context.Background(), e.Ec, signedTx) + PanicErr(err) } // binarySearch finds the highest value within the range bottom-top at which the test function is @@ -403,10 +413,15 @@ func BinarySearch(top, bottom *big.Int, test func(amount *big.Int) bool) *big.In // Get RLP encoded headers of a list of block numbers // Makes RPC network call eth_getBlockByNumber to blockchain RPC node // to fetch header info -func GetRlpHeaders(env Environment, blockNumbers []*big.Int) (headers [][]byte, hashes []string, err error) { +func GetRlpHeaders(env Environment, blockNumbers []*big.Int, getParentBlocks bool) (headers [][]byte, hashes []string, err error) { hashes = make([]string, 0) + var offset *big.Int = big.NewInt(0) + if getParentBlocks { + offset = big.NewInt(1) + } + headers = [][]byte{} var rlpHeader []byte for _, blockNum := range blockNumbers { @@ -416,7 +431,7 @@ func GetRlpHeaders(env Environment, blockNumbers []*big.Int) (headers [][]byte, // Get child block since it's the one that has the parent hash in its header. h, err := env.AvaxEc.HeaderByNumber( context.Background(), - new(big.Int).Set(blockNum).Add(blockNum, big.NewInt(1)), + new(big.Int).Set(blockNum).Add(blockNum, offset), ) if err != nil { return nil, hashes, fmt.Errorf("failed to get header: %+v", err) @@ -435,12 +450,12 @@ func GetRlpHeaders(env Environment, blockNumbers []*big.Int) (headers [][]byte, //bh := crypto.Keccak256Hash(rlpHeader) //fmt.Println("Calculated BH:", bh.String(), // "fetched BH:", h.Hash(), - // "block number:", new(big.Int).Set(blockNum).Add(blockNum, big.NewInt(1)).String()) + // "block number:", new(big.Int).Set(blockNum).Add(blockNum, offset).String()) } else if IsPolygonEdgeNetwork(env.ChainID) { // Get child block since it's the one that has the parent hash in its header. - nextBlockNum := new(big.Int).Set(blockNum).Add(blockNum, big.NewInt(1)) + nextBlockNum := new(big.Int).Set(blockNum).Add(blockNum, offset) var hash string rlpHeader, hash, err = GetPolygonEdgeRLPHeader(env.Jc, nextBlockNum) if err != nil { @@ -453,7 +468,7 @@ func GetRlpHeaders(env Environment, blockNumbers []*big.Int) (headers [][]byte, // Get child block since it's the one that has the parent hash in its header. h, err := env.Ec.HeaderByNumber( context.Background(), - new(big.Int).Set(blockNum).Add(blockNum, big.NewInt(1)), + new(big.Int).Set(blockNum).Add(blockNum, offset), ) if err != nil { return nil, hashes, fmt.Errorf("failed to get header: %+v", err) @@ -491,7 +506,7 @@ func CalculateLatestBlockHeader(env Environment, blockNumberInput int) (err erro blockNumber = blockNumber - 1 blockNumberBigInts := []*big.Int{big.NewInt(int64(blockNumber))} - headers, hashes, err := GetRlpHeaders(env, blockNumberBigInts) + headers, hashes, err := GetRlpHeaders(env, blockNumberBigInts, true) if err != nil { fmt.Println(err) return err diff --git a/core/scripts/functions/USAGE.md b/core/scripts/functions/USAGE.md index b3102b4bb36..59883946f2b 100644 --- a/core/scripts/functions/USAGE.md +++ b/core/scripts/functions/USAGE.md @@ -28,6 +28,7 @@ Initial set of commands: - `generate-ocr2config` generates `FunctionsOracleConfig.json` that is consumed by contracts tooling. - If manual configuration is preferred instead of automatically fetching the required parameters from the nodes, create a file that follows the same format as `src/sample_keys.json` and enter the required parameters which can be found on each node's Key Management page in the UI. Note that the bootstrap node is not included in this file. The path to this file should be entered for the `-keys` parameter instead of using the `-nodes` parameter. + - When using the `-nodes` parameter, a `DONPublicKeys.json` file will be generated. This can be used to simplify the creation of the `keyGenConfig.json` file when generating threshold keys with the [Functions admin tooling](https://github.com/smartcontractkit/functions-admin-tooling/blob/main/threshold_key_manager/README.md). - Use `src/sample_config.json` as a template for the `-config` file. - `generate-jobspecs` generates Job Specs (toml) for each node based on its role. - Jobspecs can also be created manually by swapping the relevant values in the `toml` files. @@ -41,13 +42,13 @@ Each command has its own parameters. Simply run a command without parameters to - The current implementation expects a single bootstrap node and a few oracle nodes. Bootstrap node must come first in the nodes list file. -- You may or may not specify `https://` prefix for hosts, the tool will handle this. +- You must provide the `http://` or `https://` prefix for hosts - Any command would terminate immediately with the first issue detected. - `deploy-jobspecs` command does NOT check for the existing jobs, be careful. - `deploy-jobspecs` command does not deploy bridges, they should exist prior to execution. - The tooling does not interact with chains/contracts. -5. Future enhancements +1. Future enhancements - Add `deploy-bridges` command. - For NOPs: make commands to run against a single node with terminal authorization. diff --git a/core/scripts/functions/src/files.go b/core/scripts/functions/src/files.go index c9de82a31a7..a388413ef5f 100644 --- a/core/scripts/functions/src/files.go +++ b/core/scripts/functions/src/files.go @@ -13,6 +13,7 @@ const ( templatesDir = "templates" artefactsDir = "artefacts" ocr2ConfigJson = "FunctionsOracleConfig.json" + ocr2PublicKeysJSON = "OCR2PublicKeys.json" bootstrapSpecTemplate = "bootstrap.toml" oracleSpecTemplate = "oracle.toml" ) diff --git a/core/scripts/functions/src/generate_jobspecs_cmd.go b/core/scripts/functions/src/generate_jobspecs_cmd.go index 8d4837b8e8f..332e2bdc0cb 100644 --- a/core/scripts/functions/src/generate_jobspecs_cmd.go +++ b/core/scripts/functions/src/generate_jobspecs_cmd.go @@ -28,10 +28,11 @@ func (g *generateJobSpecs) Run(args []string) { nodesFile := fs.String("nodes", "", "a file containing nodes urls, logins and passwords") chainID := fs.Int64("chainid", 80001, "chain id") p2pPort := fs.Int64("p2pport", 6690, "p2p port") - contractAddress := fs.String("contract", "", "oracle contract address") + donID := fs.String("donid", "", "don id string") + routerAddress := fs.String("contract", "", "router contract address") truncateHostname := fs.Bool("truncateboothostname", false, "truncate host name to first segment (needed for staging DONs)") err := fs.Parse(args) - if err != nil || nodesFile == nil || *nodesFile == "" || contractAddress == nil || *contractAddress == "" { + if err != nil || nodesFile == nil || *nodesFile == "" || routerAddress == nil || *routerAddress == "" { fs.Usage() os.Exit(1) } @@ -44,7 +45,7 @@ func (g *generateJobSpecs) Run(args []string) { helpers.PanicErr(err) bootHost := nodes[0].url.Host - lines = replacePlaceholders(lines, *chainID, *p2pPort, *contractAddress, bootHost, &bootstrapNode, &bootstrapNode, *truncateHostname) + lines = replacePlaceholders(lines, *donID, *chainID, *p2pPort, *routerAddress, bootHost, &bootstrapNode, &bootstrapNode, *truncateHostname) outputPath := filepath.Join(artefactsDir, bootHost+".toml") err = writeLines(lines, outputPath) helpers.PanicErr(err) @@ -53,7 +54,7 @@ func (g *generateJobSpecs) Run(args []string) { lines, err = readLines(filepath.Join(templatesDir, oracleSpecTemplate)) helpers.PanicErr(err) for i := 1; i < len(nodes); i++ { - oracleLines := replacePlaceholders(lines, *chainID, *p2pPort, *contractAddress, bootHost, &bootstrapNode, &nca[i], *truncateHostname) + oracleLines := replacePlaceholders(lines, *donID, *chainID, *p2pPort, *routerAddress, bootHost, &bootstrapNode, &nca[i], *truncateHostname) outputPath := filepath.Join(artefactsDir, nodes[i].url.Host+".toml") err = writeLines(oracleLines, outputPath) helpers.PanicErr(err) @@ -61,7 +62,7 @@ func (g *generateJobSpecs) Run(args []string) { } } -func replacePlaceholders(lines []string, chainID, p2pPort int64, contractAddress, bootHost string, boot *NodeKeys, node *NodeKeys, truncateHostname bool) (output []string) { +func replacePlaceholders(lines []string, donID string, chainID, p2pPort int64, routerAddress, bootHost string, boot *NodeKeys, node *NodeKeys, truncateHostname bool) (output []string) { chainIDStr := strconv.FormatInt(chainID, 10) if truncateHostname { bootHost = bootHost[:strings.IndexByte(bootHost, '.')] @@ -70,11 +71,12 @@ func replacePlaceholders(lines []string, chainID, p2pPort int64, contractAddress ts := time.Now().UTC().Format("2006-01-02T15:04") for _, l := range lines { l = strings.Replace(l, "{{chain_id}}", chainIDStr, 1) - l = strings.Replace(l, "{{oracle_contract_address}}", contractAddress, 1) + l = strings.Replace(l, "{{router_contract_address}}", routerAddress, 1) l = strings.Replace(l, "{{node_eth_address}}", node.EthAddress, 1) l = strings.Replace(l, "{{ocr2_key_bundle_id}}", node.OCR2BundleID, 1) l = strings.Replace(l, "{{p2p_bootstrapper}}", bootstrapper, 1) l = strings.Replace(l, "{{timestamp}}", ts, 1) + l = strings.Replace(l, "{{don_id}}", donID, 1) output = append(output, l) } return diff --git a/core/scripts/functions/src/generate_ocr2_config_cmd.go b/core/scripts/functions/src/generate_ocr2_config_cmd.go index 1fca78368dc..cbb6a7f3bbc 100644 --- a/core/scripts/functions/src/generate_ocr2_config_cmd.go +++ b/core/scripts/functions/src/generate_ocr2_config_cmd.go @@ -32,6 +32,7 @@ type ThresholdOffchainConfig struct { RequestCountLimit uint32 RequestTotalBytesLimit uint32 RequireLocalRequestCheck bool + K uint32 } type S4ReportingPluginConfig struct { @@ -102,23 +103,14 @@ func (g *generateOCR2Config) Name() string { } func mustParseJSONConfigFile(fileName string) (output TopLevelConfigSource) { - jsonFile, err := os.Open(fileName) - if err != nil { - panic(err) - } - defer jsonFile.Close() - bytes, err := io.ReadAll(jsonFile) - if err != nil { - panic(err) - } - err = json.Unmarshal(bytes, &output) - if err != nil { - panic(err) - } - return + return mustParseJSON[TopLevelConfigSource](fileName) } func mustParseKeysFile(fileName string) (output []NodeKeys) { + return mustParseJSON[[]NodeKeys](fileName) +} + +func mustParseJSON[T any](fileName string) (output T) { jsonFile, err := os.Open(fileName) if err != nil { panic(err) @@ -155,6 +147,17 @@ func (g *generateOCR2Config) Run(args []string) { } else { nodes := mustReadNodesList(*nodesFile) nca = mustFetchNodesKeys(*chainID, nodes)[1:] // ignore boot node + + nodePublicKeys, err := json.MarshalIndent(nca, "", " ") + if err != nil { + panic(err) + } + filepath := filepath.Join(artefactsDir, ocr2PublicKeysJSON) + err = os.WriteFile(filepath, nodePublicKeys, 0600) + if err != nil { + panic(err) + } + fmt.Println("Functions OCR2 public keys have been saved to:", filepath) } onchainPubKeys := []common.Address{} @@ -220,6 +223,7 @@ func (g *generateOCR2Config) Run(args []string) { RequestCountLimit: cfg.ThresholdOffchainConfig.RequestCountLimit, RequestTotalBytesLimit: cfg.ThresholdOffchainConfig.RequestTotalBytesLimit, RequireLocalRequestCheck: cfg.ThresholdOffchainConfig.RequireLocalRequestCheck, + K: cfg.ThresholdOffchainConfig.K, }, S4PluginConfig: &config.S4ReportingPluginConfig{ MaxQueryLengthBytes: cfg.S4ReportingPluginConfig.MaxQueryLengthBytes, diff --git a/core/scripts/functions/src/nodes.go b/core/scripts/functions/src/nodes.go index dd69c94a3a2..20f392f8086 100644 --- a/core/scripts/functions/src/nodes.go +++ b/core/scripts/functions/src/nodes.go @@ -45,9 +45,6 @@ func mustReadNodesList(path string) []*node { if len(s) != 3 { helpers.PanicErr(errors.New("wrong nodes list format")) } - if !strings.HasPrefix(s[0], "https://") { - s[0] = "https://" + s[0] - } if strings.Contains(s[0], "boot") && hasBoot { helpers.PanicErr(errors.New("the single boot node must come first")) } diff --git a/core/scripts/functions/src/sample_config.json b/core/scripts/functions/src/sample_config.json index 5c5dcacc4c4..a6f4f5b0aa2 100644 --- a/core/scripts/functions/src/sample_config.json +++ b/core/scripts/functions/src/sample_config.json @@ -6,6 +6,7 @@ "MaxRequestBatchSize": 10, "DefaultAggregationMethod": 0, "UniqueReports": true, + "MaxReportTotalCallbackGas": 2000000, "ThresholdOffchainConfig": { "MaxQueryLengthBytes": 10000, @@ -13,7 +14,8 @@ "MaxReportLengthBytes": 10000, "RequestCountLimit": 100, "RequestTotalBytesLimit": 100000, - "RequireLocalRequestCheck": true + "RequireLocalRequestCheck": true, + "K": 3 }, "S4ReportingPluginConfig": { diff --git a/core/scripts/functions/templates/bootstrap.toml b/core/scripts/functions/templates/bootstrap.toml index 48d011e30d0..a738a53eea6 100644 --- a/core/scripts/functions/templates/bootstrap.toml +++ b/core/scripts/functions/templates/bootstrap.toml @@ -1,9 +1,12 @@ type = "bootstrap" schemaVersion = 1 -name = "Functions bootstrap {{timestamp}}" +name = "Functions V1 bootstrap {{timestamp}}" forwardingAllowed = false -contractID = "{{oracle_contract_address}}" +contractID = "{{router_contract_address}}" relay = "evm" [relayConfig] chainID = {{chain_id}} +contractUpdateCheckFrequencySec = 60 +contractVersion = 1 +donID = "{{don_id}}" diff --git a/core/scripts/functions/templates/oracle.toml b/core/scripts/functions/templates/oracle.toml index 9e4b3704ad8..10e2164a047 100644 --- a/core/scripts/functions/templates/oracle.toml +++ b/core/scripts/functions/templates/oracle.toml @@ -1,8 +1,8 @@ type = "offchainreporting2" schemaVersion = 1 -name = "Functions {{timestamp}}" +name = "Functions V1 {{timestamp}}" forwardingAllowed = false -contractID = "{{oracle_contract_address}}" +contractID = "{{router_contract_address}}" ocrKeyBundleID = "{{ocr2_key_bundle_id}}" p2pv2Bootstrappers = [ "{{p2p_bootstrapper}}" @@ -11,17 +11,25 @@ relay = "evm" pluginType = "functions" transmitterID = "{{node_eth_address}}" observationSource = """ - run_computation [type="bridge" name="ea_bridge" requestData="{\\"note\\": \\"observationSource is unused but the bridge is required\\"}"] - run_computation + run_computation [type="bridge" name="ea_bridge" requestData="{\\"note\\": \\"observationSource is unused but the bridge is required\\"}"] + run_computation """ [relayConfig] chainID = {{chain_id}} [pluginConfig] +contractUpdateCheckFrequencySec = 300 +contractVersion = 1 +donID = "{{don_id}}" +enableRequestSignatureCheck = false +listenerEventHandlerTimeoutSec = 180 +listenerEventsCheckFrequencyMillis = 500 +maxRequestSizeBytes = 30_720 minIncomingConfirmations = 3 -requestTimeoutSec = 300 -requestTimeoutCheckFrequencySec = 10 +pruneBatchSize = 5 +pruneCheckFrequencySec = 30 +pruneMaxStoredRequests = 20 requestTimeoutBatchLookupSize = 20 -listenerEventHandlerTimeoutSec = 120 -maxRequestSizeBytes = 30720 +requestTimeoutCheckFrequencySec = 10 +requestTimeoutSec = 300 diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 06e52154e53..50da3a9cc76 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -15,19 +15,19 @@ require ( github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f github.com/montanaflynn/stats v0.7.1 github.com/olekukonko/tablewriter v0.0.5 - github.com/pelletier/go-toml/v2 v2.0.8 + github.com/pelletier/go-toml/v2 v2.0.9 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 - github.com/smartcontractkit/libocr v0.0.0-20230724105022-c5e49b4195ac - github.com/smartcontractkit/ocr2keepers v1.0.0-alpha.0 - github.com/smartcontractkit/ocr2vrf v0.0.0-20230616201444-d8b4222aff3c + github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 + github.com/smartcontractkit/ocr2keepers v0.7.17 + github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb github.com/spf13/cobra v1.6.1 github.com/spf13/viper v1.15.0 github.com/stretchr/testify v1.8.4 github.com/umbracle/ethgo v0.1.3 github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 - github.com/urfave/cli v1.22.13 + github.com/urfave/cli v1.22.14 go.dedis.ch/kyber/v3 v3.1.0 ) @@ -192,7 +192,7 @@ require ( github.com/jmoiron/sqlx v1.3.5 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.16.3 // indirect + github.com/klauspost/compress v1.16.7 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/koron/go-ssdp v0.0.2 // indirect github.com/kr/pretty v0.3.1 // indirect @@ -266,9 +266,10 @@ require ( github.com/multiformats/go-multihash v0.0.14 // indirect github.com/multiformats/go-multistream v0.2.0 // indirect github.com/multiformats/go-varint v0.0.6 // indirect + github.com/mwitkow/grpc-proxy v0.0.0-20230212185441-f345521cb9c9 // indirect github.com/oklog/run v1.1.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc3 // indirect + github.com/opencontainers/image-spec v1.1.0-rc4 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible // indirect github.com/pelletier/go-toml v1.9.5 // indirect @@ -276,7 +277,7 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect - github.com/pressly/goose/v3 v3.5.3 // indirect + github.com/pressly/goose/v3 v3.15.0 // indirect github.com/prometheus/client_golang v1.16.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.44.0 // indirect @@ -296,12 +297,12 @@ require ( github.com/shirou/gopsutil/v3 v3.22.12 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 // indirect - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230725012331-9007d9fb0d7b // indirect - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230620171700-bbcb3a99b7d3 // indirect - github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230612131011-369bfb503592 // indirect - github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230622060316-7ce48476dd7d // indirect - github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230616141813-ca0ecf03ca5c // indirect - github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230625174811-4934857d1c4a // indirect + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230824124058-9b063c470048 // indirect + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230824125819-215fd09979a2 // indirect + github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230802143301-165000751a85 // indirect + github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230802150127-d2c95679d61a // indirect + github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230823081604-f2a0e6b108bb // indirect + github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230823081604-f2a0e6b108bb // indirect github.com/smartcontractkit/wsrpc v0.7.2 // indirect github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect @@ -383,5 +384,9 @@ replace ( github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 // until merged upstream: https://github.com/hashicorp/go-plugin/pull/257 - github.com/hashicorp/go-plugin => github.com/jmank88/go-plugin v0.0.0-20230604120638-7bb12ec27e75 + github.com/hashicorp/go-plugin => github.com/smartcontractkit/go-plugin v0.0.0-20230605132010-0f4d515d1472 + + // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 + github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f + ) diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 98f0b7f5025..7da9f19e2be 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1,4 +1,3 @@ -bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -71,19 +70,13 @@ github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI= github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE= github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0= -github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= -github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= -github.com/ClickHouse/clickhouse-go v1.5.4/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= github.com/CosmWasm/wasmd v0.40.1 h1:LxbO78t/6S8TkeQlUrJ0m5O87HtAwLx4RGHq3rdrOEU= @@ -102,11 +95,9 @@ github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETF github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.5 h1:zl/OfRA6nftbBK9qTohYBJ5xvw6C/oNKizR7cZGl3cI= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= @@ -156,8 +147,6 @@ github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1U github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= @@ -182,7 +171,6 @@ github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= @@ -192,7 +180,6 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= @@ -200,11 +187,9 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -232,10 +217,7 @@ github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0 github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= -github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= -github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.2.2/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk= -github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= +github.com/containerd/continuity v0.4.1 h1:wQnVrjIyQ8vhU2sgOiL5T07jo+ouqc2bnKsv5/EqGhU= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -245,7 +227,6 @@ github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmf github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= @@ -269,17 +250,14 @@ github.com/cosmos/ledger-cosmos-go v0.12.1 h1:sMBxza5p/rNK/06nBSNmsI/WDqI0pVJFVN github.com/cosmos/ledger-cosmos-go v0.12.1/go.mod h1:dhO6kj+Y+AHIOgAe4L9HL/6NDdyyth4q238I9yFpD2g= github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzUGSKFTcM= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creachadair/taskgroup v0.4.2 h1:jsBLdAJE42asreGss2xZGZ8fJra7WtwnHWeJFxv2Li8= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= -github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= @@ -299,7 +277,6 @@ github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5il github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= -github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/dfuse-io/logging v0.0.0-20201110202154-26697de88c79/go.mod h1:V+ED4kT/t/lKtH99JQmKIb0v9WL3VaYkJ36CfHlVECI= github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 h1:CuJS05R9jmNlUK8GOxrEELPbfXm0EuGh/30LjkjN5vo= @@ -320,16 +297,12 @@ github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUn github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/cli v20.10.11+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v24.0.2+incompatible h1:eATx+oLz9WdNVkQrr0qjQ8HvRJ4bOOxfzEo8R+dA3cg= github.com/docker/docker v24.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -364,7 +337,6 @@ github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlK github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 h1:u/UEqS66A5ckRmS4yNpjmVH56sVtS/RfclBAYocb4as= github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -445,9 +417,8 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91 github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= @@ -464,7 +435,6 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= @@ -476,8 +446,6 @@ github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= -github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+wXQnTPR4KqTKDgJukSZ6amVRtWMPEjE6sQoK8= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= @@ -512,6 +480,7 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= @@ -575,7 +544,6 @@ github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9S github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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= @@ -690,7 +658,6 @@ github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3 github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -809,13 +776,10 @@ github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0 github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= -github.com/jmank88/go-plugin v0.0.0-20230604120638-7bb12ec27e75 h1:KYTOmcwuezD27O7vNF15lj8H7imCBMXCq1RzCdj4e3A= -github.com/jmank88/go-plugin v0.0.0-20230604120638-7bb12ec27e75/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= -github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= @@ -839,7 +803,6 @@ github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2 github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= @@ -848,8 +811,8 @@ github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0 github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= -github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= @@ -881,12 +844,10 @@ github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a/go.mod h1:U2L/ github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= @@ -1105,8 +1066,6 @@ github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f h1:tVvGiZQFjOXP+9YyGqSA6jE55x1XVxmoPYudncxrZ8U= github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f/go.mod h1:Z60vy0EZVSu0bOugCHdcN5ZxFMKSpjRgsnh0XKPFqqk= -github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= -github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -1133,9 +1092,7 @@ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.10/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -1171,13 +1128,10 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4 github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= -github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= -github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= -github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -1185,7 +1139,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= @@ -1198,7 +1151,6 @@ github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjW github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= @@ -1288,22 +1240,16 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= -github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8= -github.com/opencontainers/image-spec v1.1.0-rc3/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= -github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= +github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= +github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= github.com/opencontainers/runc v1.1.7 h1:y2EZDS8sNng4Ksf0GUYNhKbTShZJPJg1FiXJNH/uoCk= -github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= -github.com/ory/dockertest/v3 v3.8.1/go.mod h1:wSRQ3wmkz+uSARYMk7kVJFDBGm8x5gSxIhI7NDc+BAQ= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -1313,15 +1259,13 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= -github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= -github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0= +github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 h1:hDSdbBuw3Lefr6R18ax0tZ2BJeNB3NehB3trOwYBsdU= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -1334,8 +1278,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/pressly/goose/v3 v3.5.3 h1:lIQIIXVbdO2RuQtJBS1e7MZjKEk0demVWt6i0YPiOrg= -github.com/pressly/goose/v3 v3.5.3/go.mod h1:IL4NNMdXx9O6hHpGbNB5l1hkVe/Avoz4gBDE5g7rQNg= +github.com/pressly/goose/v3 v3.15.0 h1:6tY5aDqFknY6VZkorFGgZtWygodZQxfmmEF4rqyJW9k= +github.com/pressly/goose/v3 v3.15.0/go.mod h1:LlIo3zGccjb/YUgG+Svdb9Er14vefRdlDI7URCDrwYo= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= @@ -1373,8 +1317,7 @@ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqn github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= -github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= -github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -1409,7 +1352,6 @@ github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtm github.com/scylladb/go-reflectx v1.0.1 h1:b917wZM7189pZdlND9PbIJ6NQxfDPfBvUaQ7cjj1iZQ= github.com/scylladb/go-reflectx v1.0.1/go.mod h1:rWnOfDIRWBGN0miMLIcoPt/Dhi2doCMZqwMCJ3KupFc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= @@ -1423,32 +1365,34 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumvbfM1u/etVq42Afwq/jtNSBSOA8n5jntnNPo= github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230725012331-9007d9fb0d7b h1:vh4N/K+TMG8oV7L2i4U8q5aMjlVgf5M8TAZJCsXUh4U= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230725012331-9007d9fb0d7b/go.mod h1:TtLMvOtGV9hwNg59iJj+Sa0vL0Kq3o3eF+6uSIRixDc= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230620171700-bbcb3a99b7d3 h1:rlNWHk15A2im/e9U95q4AkHZk5Wbc77lpx6ys4kUyCE= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230620171700-bbcb3a99b7d3/go.mod h1:MfZBUifutkv3aK7abyw5YmTJbqt8iFwcQDFikrxC/uI= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230612131011-369bfb503592 h1:3Ul/LkULxrolCVguHUFnWJamgUDsSGISlm/DzclstmE= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230612131011-369bfb503592/go.mod h1:km46XAo6xebV4Q+WyRFfo3E2t80YqTkegJM4FEfo5/Y= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230622060316-7ce48476dd7d h1:4jSCp6i/p/EIaAkYQDxPK8nXDuv0fBXzKIcVYzetCoI= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230622060316-7ce48476dd7d/go.mod h1:AW1rNDx4YN0VJzM1OrZtsOV9ORdcqcSFtsOQO3GeOQo= -github.com/smartcontractkit/libocr v0.0.0-20230724105022-c5e49b4195ac h1:ugouvLyN5D2AeztWrByENx08cx0phkxxvfP+AkBv3NI= -github.com/smartcontractkit/libocr v0.0.0-20230724105022-c5e49b4195ac/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= -github.com/smartcontractkit/ocr2keepers v1.0.0-alpha.0 h1:zkXsh4MAARNXqUlsMPBzVtFVV7SN93SxQ3KfCicnans= -github.com/smartcontractkit/ocr2keepers v1.0.0-alpha.0/go.mod h1:13Q6zuYWLByKXzzcSoi7L01bT8OzxM//XgMZQeCZVP0= -github.com/smartcontractkit/ocr2vrf v0.0.0-20230616201444-d8b4222aff3c h1:BX1ibMdGE2QdD8rJEI5nxE4jA6v2bf7LULrSbDrNM+A= -github.com/smartcontractkit/ocr2vrf v0.0.0-20230616201444-d8b4222aff3c/go.mod h1:AT1OrDDOCd8vzmMsCnA70N+tZdq9AbdZAiAw+gQq260= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230824124058-9b063c470048 h1:OHj8qzXajBAIT9TBnHN5LVGoCxvso/4JgCeg/l76Tgk= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230824124058-9b063c470048/go.mod h1:xMwqRdj5vqYhCJXgKVqvyAwdcqM6ZAEhnwEQ4Khsop8= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230824125819-215fd09979a2 h1:z9PIgm0klhunwPy+KZYR4E9vCpjgJaMOyQRLCYgfoLk= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230824125819-215fd09979a2/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230802143301-165000751a85 h1:/fm02hYSUdhbSh7xPn7os9yHj7dnl8aLs2+nFXPiB4g= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230802143301-165000751a85/go.mod h1:H3/j2l84FsxYevCLNERdVasI7FVr+t2mkpv+BCJLSVw= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230802150127-d2c95679d61a h1:b3rjvZLpTV45TmCV+ALX+EDDslf91pnDUugP54Lu9FA= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230802150127-d2c95679d61a/go.mod h1:LL+FLf10gOUHrF3aUsRGEZlT/w8DaW5T/eEo/54W68c= +github.com/smartcontractkit/go-plugin v0.0.0-20230605132010-0f4d515d1472 h1:x3kNwgFlDmbE/n0gTSRMt9GBDfsfGrs4X9b9arPZtFI= +github.com/smartcontractkit/go-plugin v0.0.0-20230605132010-0f4d515d1472/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0= +github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= +github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= +github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 h1:rzbqGoScs9VHGnyCKF7AoQEuUfwJnzcKmGIfaczeanA= +github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= +github.com/smartcontractkit/ocr2keepers v0.7.17 h1:847GG2SHyHIPc3yu+dhB+1HfeLRhSjyiKnhw3umpoJw= +github.com/smartcontractkit/ocr2keepers v0.7.17/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= +github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 h1:NwC3SOc25noBTe1KUQjt45fyTIuInhoE2UfgcHAdihM= +github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687/go.mod h1:YYZq52t4wcHoMQeITksYsorD+tZcOyuVU5+lvot3VFM= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb h1:OMaBUb4X9IFPLbGbCHsMU+kw/BPCrewaVwWGIBc0I4A= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb/go.mod h1:HNUu4cJekUdsJbwRBCiOybtkPJEfGRELQPe2tkoDEyk= -github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230616141813-ca0ecf03ca5c h1:B7jWegIHCHXY32qWGwlNalrJYSz4uZh5zAgd2rQ3Iyc= -github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230616141813-ca0ecf03ca5c/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= -github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230625174811-4934857d1c4a h1:/ZJnNxcdJ75yDJHnKMjd3G9oZ6lcQRvFUdmiR2DPAgQ= -github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230625174811-4934857d1c4a/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw= +github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230823081604-f2a0e6b108bb h1:xNLGJcARfz9HCUKla6wH0gmwsG1/FTAWWeOplW2J72A= +github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230823081604-f2a0e6b108bb/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= +github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230823081604-f2a0e6b108bb h1:jyhgdafuZsex+kEHDIgq8o8wuVoPTr9wsGmuBtcFbEk= +github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230823081604-f2a0e6b108bb/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/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -1504,13 +1448,11 @@ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1F github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= @@ -1541,7 +1483,6 @@ github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+F github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= @@ -1563,9 +1504,8 @@ github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 h1:10Nbw6cACsnQm7 github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722/go.mod h1:c8J0h9aULj2i3umrfyestM6jCq0LK0U6ly6bWy96nd4= github.com/unrolled/secure v1.13.0 h1:sdr3Phw2+f8Px8HE5sd1EHdj1aV3yUwed/uZXChLFsk= github.com/unrolled/secure v1.13.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.13 h1:wsLILXG8qCJNse/qAgLNf23737Cx05GflHg/PJGe1Ok= -github.com/urfave/cli v1.22.13/go.mod h1:VufqObjsMTF2BBwKawpx9R8eAneNEWhoO0yx8Vd+FkE= +github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= +github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bCzK15ozrqo2sZxkh0FHynJZOTVoV6Q= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= @@ -1575,8 +1515,6 @@ github.com/valyala/fastjson v1.4.1/go.mod h1:nV6MsjxL2IMJQUoHDIrjEI7oLyeqK6aBD7E github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= -github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= -github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= @@ -1603,13 +1541,11 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= @@ -1703,7 +1639,6 @@ golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= @@ -1713,7 +1648,6 @@ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220210151621-f4118a5b28e2/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= @@ -1754,7 +1688,6 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -1806,15 +1739,13 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -1869,7 +1800,6 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1881,10 +1811,8 @@ golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1901,36 +1829,31 @@ golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210629170331-7dc0b73dc9fb/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1991,7 +1914,6 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -2033,7 +1955,6 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -2044,7 +1965,6 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 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.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= @@ -2131,6 +2051,7 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 h1:Au6te5hbKUV8pIYWHqOUZ1pva5qK/rwbIhoXEUB9Lu8= google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y= @@ -2160,6 +2081,7 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI= @@ -2227,8 +2149,6 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -2237,134 +2157,17 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= -lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI= -lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= -modernc.org/cc/v3 v3.33.6/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.33.9/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.33.11/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.34.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.4/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.5/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.7/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.8/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.10/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.15/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.16/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.17/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.18/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.20/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.22 h1:BzShpwCAP7TWzFppM4k2t03RhXhgYqaibROWkrWq7lE= -modernc.org/cc/v3 v3.35.22/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/ccgo/v3 v3.9.5/go.mod h1:umuo2EP2oDSBnD3ckjaVUXMrmeAw8C8OSICVa0iFf60= -modernc.org/ccgo/v3 v3.10.0/go.mod h1:c0yBmkRFi7uW4J7fwx/JiijwOjeAeR2NoSaRVFPmjMw= -modernc.org/ccgo/v3 v3.11.0/go.mod h1:dGNposbDp9TOZ/1KBxghxtUp/bzErD0/0QW4hhSaBMI= -modernc.org/ccgo/v3 v3.11.1/go.mod h1:lWHxfsn13L3f7hgGsGlU28D9eUOf6y3ZYHKoPaKU0ag= -modernc.org/ccgo/v3 v3.11.3/go.mod h1:0oHunRBMBiXOKdaglfMlRPBALQqsfrCKXgw9okQ3GEw= -modernc.org/ccgo/v3 v3.12.4/go.mod h1:Bk+m6m2tsooJchP/Yk5ji56cClmN6R1cqc9o/YtbgBQ= -modernc.org/ccgo/v3 v3.12.6/go.mod h1:0Ji3ruvpFPpz+yu+1m0wk68pdr/LENABhTrDkMDWH6c= -modernc.org/ccgo/v3 v3.12.8/go.mod h1:Hq9keM4ZfjCDuDXxaHptpv9N24JhgBZmUG5q60iLgUo= -modernc.org/ccgo/v3 v3.12.11/go.mod h1:0jVcmyDwDKDGWbcrzQ+xwJjbhZruHtouiBEvDfoIsdg= -modernc.org/ccgo/v3 v3.12.14/go.mod h1:GhTu1k0YCpJSuWwtRAEHAol5W7g1/RRfS4/9hc9vF5I= -modernc.org/ccgo/v3 v3.12.18/go.mod h1:jvg/xVdWWmZACSgOiAhpWpwHWylbJaSzayCqNOJKIhs= -modernc.org/ccgo/v3 v3.12.20/go.mod h1:aKEdssiu7gVgSy/jjMastnv/q6wWGRbszbheXgWRHc8= -modernc.org/ccgo/v3 v3.12.21/go.mod h1:ydgg2tEprnyMn159ZO/N4pLBqpL7NOkJ88GT5zNU2dE= -modernc.org/ccgo/v3 v3.12.22/go.mod h1:nyDVFMmMWhMsgQw+5JH6B6o4MnZ+UQNw1pp52XYFPRk= -modernc.org/ccgo/v3 v3.12.25/go.mod h1:UaLyWI26TwyIT4+ZFNjkyTbsPsY3plAEB6E7L/vZV3w= -modernc.org/ccgo/v3 v3.12.29/go.mod h1:FXVjG7YLf9FetsS2OOYcwNhcdOLGt8S9bQ48+OP75cE= -modernc.org/ccgo/v3 v3.12.36/go.mod h1:uP3/Fiezp/Ga8onfvMLpREq+KUjUmYMxXPO8tETHtA8= -modernc.org/ccgo/v3 v3.12.38/go.mod h1:93O0G7baRST1vNj4wnZ49b1kLxt0xCW5Hsa2qRaZPqc= -modernc.org/ccgo/v3 v3.12.43/go.mod h1:k+DqGXd3o7W+inNujK15S5ZYuPoWYLpF5PYougCmthU= -modernc.org/ccgo/v3 v3.12.46/go.mod h1:UZe6EvMSqOxaJ4sznY7b23/k13R8XNlyWsO5bAmSgOE= -modernc.org/ccgo/v3 v3.12.47/go.mod h1:m8d6p0zNps187fhBwzY/ii6gxfjob1VxWb919Nk1HUk= -modernc.org/ccgo/v3 v3.12.50/go.mod h1:bu9YIwtg+HXQxBhsRDE+cJjQRuINuT9PUK4orOco/JI= -modernc.org/ccgo/v3 v3.12.51/go.mod h1:gaIIlx4YpmGO2bLye04/yeblmvWEmE4BBBls4aJXFiE= -modernc.org/ccgo/v3 v3.12.53/go.mod h1:8xWGGTFkdFEWBEsUmi+DBjwu/WLy3SSOrqEmKUjMeEg= -modernc.org/ccgo/v3 v3.12.54/go.mod h1:yANKFTm9llTFVX1FqNKHE0aMcQb1fuPJx6p8AcUx+74= -modernc.org/ccgo/v3 v3.12.55/go.mod h1:rsXiIyJi9psOwiBkplOaHye5L4MOOaCjHg1Fxkj7IeU= -modernc.org/ccgo/v3 v3.12.56/go.mod h1:ljeFks3faDseCkr60JMpeDb2GSO3TKAmrzm7q9YOcMU= -modernc.org/ccgo/v3 v3.12.57/go.mod h1:hNSF4DNVgBl8wYHpMvPqQWDQx8luqxDnNGCMM4NFNMc= -modernc.org/ccgo/v3 v3.12.60/go.mod h1:k/Nn0zdO1xHVWjPYVshDeWKqbRWIfif5dtsIOCUVMqM= -modernc.org/ccgo/v3 v3.12.66/go.mod h1:jUuxlCFZTUZLMV08s7B1ekHX5+LIAurKTTaugUr/EhQ= -modernc.org/ccgo/v3 v3.12.67/go.mod h1:Bll3KwKvGROizP2Xj17GEGOTrlvB1XcVaBrC90ORO84= -modernc.org/ccgo/v3 v3.12.73/go.mod h1:hngkB+nUUqzOf3iqsM48Gf1FZhY599qzVg1iX+BT3cQ= -modernc.org/ccgo/v3 v3.12.81/go.mod h1:p2A1duHoBBg1mFtYvnhAnQyI6vL0uw5PGYLSIgF6rYY= -modernc.org/ccgo/v3 v3.12.84/go.mod h1:ApbflUfa5BKadjHynCficldU1ghjen84tuM5jRynB7w= -modernc.org/ccgo/v3 v3.12.86/go.mod h1:dN7S26DLTgVSni1PVA3KxxHTcykyDurf3OgUzNqTSrU= -modernc.org/ccgo/v3 v3.12.90/go.mod h1:obhSc3CdivCRpYZmrvO88TXlW0NvoSVvdh/ccRjJYko= -modernc.org/ccgo/v3 v3.12.92/go.mod h1:5yDdN7ti9KWPi5bRVWPl8UNhpEAtCjuEE7ayQnzzqHA= -modernc.org/ccgo/v3 v3.13.1/go.mod h1:aBYVOUfIlcSnrsRVU8VRS35y2DIfpgkmVkYZ0tpIXi4= -modernc.org/ccgo/v3 v3.15.1/go.mod h1:md59wBwDT2LznX/OTCPoVS6KIsdRgY8xqQwBV+hkTH0= -modernc.org/ccgo/v3 v3.15.9/go.mod h1:md59wBwDT2LznX/OTCPoVS6KIsdRgY8xqQwBV+hkTH0= -modernc.org/ccgo/v3 v3.15.10/go.mod h1:wQKxoFn0ynxMuCLfFD09c8XPUCc8obfchoVR9Cn0fI8= -modernc.org/ccgo/v3 v3.15.12/go.mod h1:VFePOWoCd8uDGRJpq/zfJ29D0EVzMSyID8LCMWYbX6I= -modernc.org/ccgo/v3 v3.15.13 h1:hqlCzNJTXLrhS70y1PqWckrF9x1btSQRC7JFuQcBg5c= -modernc.org/ccgo/v3 v3.15.13/go.mod h1:QHtvdpeODlXjdK3tsbpyK+7U9JV4PQsrPGIbtmc0KfY= -modernc.org/ccorpus v1.11.1/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= -modernc.org/ccorpus v1.11.4/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= -modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= -modernc.org/libc v1.9.8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w= -modernc.org/libc v1.9.11/go.mod h1:NyF3tsA5ArIjJ83XB0JlqhjTabTCHm9aX4XMPHyQn0Q= -modernc.org/libc v1.11.0/go.mod h1:2lOfPmj7cz+g1MrPNmX65QCzVxgNq2C5o0jdLY2gAYg= -modernc.org/libc v1.11.2/go.mod h1:ioIyrl3ETkugDO3SGZ+6EOKvlP3zSOycUETe4XM4n8M= -modernc.org/libc v1.11.5/go.mod h1:k3HDCP95A6U111Q5TmG3nAyUcp3kR5YFZTeDS9v8vSU= -modernc.org/libc v1.11.6/go.mod h1:ddqmzR6p5i4jIGK1d/EiSw97LBcE3dK24QEwCFvgNgE= -modernc.org/libc v1.11.11/go.mod h1:lXEp9QOOk4qAYOtL3BmMve99S5Owz7Qyowzvg6LiZso= -modernc.org/libc v1.11.13/go.mod h1:ZYawJWlXIzXy2Pzghaf7YfM8OKacP3eZQI81PDLFdY8= -modernc.org/libc v1.11.16/go.mod h1:+DJquzYi+DMRUtWI1YNxrlQO6TcA5+dRRiq8HWBWRC8= -modernc.org/libc v1.11.19/go.mod h1:e0dgEame6mkydy19KKaVPBeEnyJB4LGNb0bBH1EtQ3I= -modernc.org/libc v1.11.24/go.mod h1:FOSzE0UwookyT1TtCJrRkvsOrX2k38HoInhw+cSCUGk= -modernc.org/libc v1.11.26/go.mod h1:SFjnYi9OSd2W7f4ct622o/PAYqk7KHv6GS8NZULIjKY= -modernc.org/libc v1.11.27/go.mod h1:zmWm6kcFXt/jpzeCgfvUNswM0qke8qVwxqZrnddlDiE= -modernc.org/libc v1.11.28/go.mod h1:Ii4V0fTFcbq3qrv3CNn+OGHAvzqMBvC7dBNyC4vHZlg= -modernc.org/libc v1.11.31/go.mod h1:FpBncUkEAtopRNJj8aRo29qUiyx5AvAlAxzlx9GNaVM= -modernc.org/libc v1.11.34/go.mod h1:+Tzc4hnb1iaX/SKAutJmfzES6awxfU1BPvrrJO0pYLg= -modernc.org/libc v1.11.37/go.mod h1:dCQebOwoO1046yTrfUE5nX1f3YpGZQKNcITUYWlrAWo= -modernc.org/libc v1.11.39/go.mod h1:mV8lJMo2S5A31uD0k1cMu7vrJbSA3J3waQJxpV4iqx8= -modernc.org/libc v1.11.42/go.mod h1:yzrLDU+sSjLE+D4bIhS7q1L5UwXDOw99PLSX0BlZvSQ= -modernc.org/libc v1.11.44/go.mod h1:KFq33jsma7F5WXiYelU8quMJasCCTnHK0mkri4yPHgA= -modernc.org/libc v1.11.45/go.mod h1:Y192orvfVQQYFzCNsn+Xt0Hxt4DiO4USpLNXBlXg/tM= -modernc.org/libc v1.11.47/go.mod h1:tPkE4PzCTW27E6AIKIR5IwHAQKCAtudEIeAV1/SiyBg= -modernc.org/libc v1.11.49/go.mod h1:9JrJuK5WTtoTWIFQ7QjX2Mb/bagYdZdscI3xrvHbXjE= -modernc.org/libc v1.11.51/go.mod h1:R9I8u9TS+meaWLdbfQhq2kFknTW0O3aw3kEMqDDxMaM= -modernc.org/libc v1.11.53/go.mod h1:5ip5vWYPAoMulkQ5XlSJTy12Sz5U6blOQiYasilVPsU= -modernc.org/libc v1.11.54/go.mod h1:S/FVnskbzVUrjfBqlGFIPA5m7UwB3n9fojHhCNfSsnw= -modernc.org/libc v1.11.55/go.mod h1:j2A5YBRm6HjNkoSs/fzZrSxCuwWqcMYTDPLNx0URn3M= -modernc.org/libc v1.11.56/go.mod h1:pakHkg5JdMLt2OgRadpPOTnyRXm/uzu+Yyg/LSLdi18= -modernc.org/libc v1.11.58/go.mod h1:ns94Rxv0OWyoQrDqMFfWwka2BcaF6/61CqJRK9LP7S8= -modernc.org/libc v1.11.71/go.mod h1:DUOmMYe+IvKi9n6Mycyx3DbjfzSKrdr/0Vgt3j7P5gw= -modernc.org/libc v1.11.75/go.mod h1:dGRVugT6edz361wmD9gk6ax1AbDSe0x5vji0dGJiPT0= -modernc.org/libc v1.11.82/go.mod h1:NF+Ek1BOl2jeC7lw3a7Jj5PWyHPwWD4aq3wVKxqV1fI= -modernc.org/libc v1.11.86/go.mod h1:ePuYgoQLmvxdNT06RpGnaDKJmDNEkV7ZPKI2jnsvZoE= -modernc.org/libc v1.11.87/go.mod h1:Qvd5iXTeLhI5PS0XSyqMY99282y+3euapQFxM7jYnpY= -modernc.org/libc v1.11.88/go.mod h1:h3oIVe8dxmTcchcFuCcJ4nAWaoiwzKCdv82MM0oiIdQ= -modernc.org/libc v1.11.98/go.mod h1:ynK5sbjsU77AP+nn61+k+wxUGRx9rOFcIqWYYMaDZ4c= -modernc.org/libc v1.11.101/go.mod h1:wLLYgEiY2D17NbBOEp+mIJJJBGSiy7fLL4ZrGGZ+8jI= -modernc.org/libc v1.12.0/go.mod h1:2MH3DaF/gCU8i/UBiVE1VFRos4o523M7zipmwH8SIgQ= -modernc.org/libc v1.14.1/go.mod h1:npFeGWjmZTjFeWALQLrvklVmAxv4m80jnG3+xI8FdJk= -modernc.org/libc v1.14.2/go.mod h1:MX1GBLnRLNdvmK9azU9LCxZ5lMyhrbEMK8rG3X/Fe34= -modernc.org/libc v1.14.3/go.mod h1:GPIvQVOVPizzlqyRX3l756/3ppsAgg1QgPxjr5Q4agQ= -modernc.org/libc v1.14.5 h1:DAHvwGoVRDZs5iJXnX9RJrgXSsorupCWmJ2ac964Owk= -modernc.org/libc v1.14.5/go.mod h1:2PJHINagVxO4QW/5OQdRrvMYo+bm5ClpUFfyXCYl9ak= -modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/mathutil v1.4.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8= -modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc= -modernc.org/memory v1.0.5 h1:XRch8trV7GgvTec2i7jc33YlUI0RKVDBvZ5eZ5m8y14= -modernc.org/memory v1.0.5/go.mod h1:B7OYswTRnfGg+4tDH1t1OeUNnsy2viGTdME4tzd+IjM= -modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A= -modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sqlite v1.14.6 h1:Jt5P3k80EtDBWaq1beAxnWW+5MdHXbZITujnRS7+zWg= -modernc.org/sqlite v1.14.6/go.mod h1:yiCvMv3HblGmzENNIaNtFhfaNIwcla4u2JQEwJPzfEc= -modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs= -modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= -modernc.org/tcl v1.11.0/go.mod h1:zsTUpbQ+NxQEjOjCUlImDLPv1sG8Ww0qp66ZvyOxCgw= -modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk= -modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -modernc.org/z v1.3.0/go.mod h1:+mvgLH814oDjtATDdT3rs84JnUIpkvAF5B8AVkNlE2g= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo= +modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q= +modernc.org/ccgo/v3 v3.16.14 h1:af6KNtFgsVmnDYrWk3PQCS9XT6BXe7o3ZFJKkIKvXNQ= +modernc.org/libc v1.24.1 h1:uvJSeCKL/AgzBo2yYIPPTy82v21KgGnizcGYfBHaNuM= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/memory v1.6.0 h1:i6mzavxrE9a30whzMfwf7XWVODx2r5OYXvU46cirX7o= +modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= +modernc.org/sqlite v1.25.0 h1:AFweiwPNd/b3BoKnBOfFm+Y260guGMF+0UFk0savqeA= +modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= diff --git a/core/scripts/ocr2vrf/setup_ocr2vrf.go b/core/scripts/ocr2vrf/setup_ocr2vrf.go index b3643746577..ab43dc0180f 100644 --- a/core/scripts/ocr2vrf/setup_ocr2vrf.go +++ b/core/scripts/ocr2vrf/setup_ocr2vrf.go @@ -434,7 +434,7 @@ func setupOCR2VRFNodesForInfraWithForwarder(e helpers.Environment) { true, // forwardingAllowed "", // P2P Bootstrapper e.ChainID, - sendingKeys[i], + sendingKeys[adjustedIndex], dkgEncrypters[adjustedIndex], dkgSigners[adjustedIndex], *keyID, diff --git a/core/scripts/vrfv2/testnet/README.md b/core/scripts/vrfv2/testnet/README.md index da772594f52..1b2d986f554 100644 --- a/core/scripts/vrfv2/testnet/README.md +++ b/core/scripts/vrfv2/testnet/README.md @@ -56,7 +56,12 @@ cd /core/scripts/vrfv2/testnet To deploy a full VRF environment on-chain, run: ```shell -go run . deploy-universe --link-address=$LINK --link-eth-feed=$LINK_ETH_FEED --subscription-balance= --uncompressed-pub-key=$PUB_KEY --oracle-address=$ORACLE_ADDRESS +go run . deploy-universe \ +--sending-key-funding-amount 100000000000000000 \ +--subscription-balance=10000000000000000000 \ +--uncompressed-pub-key= \ +--vrf-primary-node-sending-keys="" \ +--batch-fulfillment-enabled false ``` ## Deploying the Consumer Contract diff --git a/core/scripts/vrfv2/testnet/constants/constants.go b/core/scripts/vrfv2/testnet/constants/constants.go new file mode 100644 index 00000000000..73356d48ffc --- /dev/null +++ b/core/scripts/vrfv2/testnet/constants/constants.go @@ -0,0 +1,28 @@ +package constants + +import ( + "github.com/smartcontractkit/chainlink/v2/core/assets" + "math/big" +) + +var ( + SubscriptionBalanceJuels = assets.Ether(10).ToInt() + + // optional flags + FallbackWeiPerUnitLink = big.NewInt(6e16) + BatchFulfillmentEnabled = true + MinConfs = 3 + NodeSendingKeyFundingAmountGwei = assets.GWei(0).Int64() //100000000 = 0.1 ETH + MaxGasLimit = int64(2.5e6) + StalenessSeconds = int64(86400) + GasAfterPayment = int64(33285) + FlatFeeTier1 = int64(500) + FlatFeeTier2 = int64(500) + FlatFeeTier3 = int64(500) + FlatFeeTier4 = int64(500) + FlatFeeTier5 = int64(500) + ReqsForTier2 = int64(0) + ReqsForTier3 = int64(0) + ReqsForTier4 = int64(0) + ReqsForTier5 = int64(0) +) diff --git a/core/scripts/vrfv2/testnet/docker/db/create-multiple-databases.sh b/core/scripts/vrfv2/testnet/docker/db/create-multiple-databases.sh new file mode 100755 index 00000000000..9b0c7b0d68b --- /dev/null +++ b/core/scripts/vrfv2/testnet/docker/db/create-multiple-databases.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -e +set -u + +function create_user_and_database() { + local database=$1 + echo " Creating user and database '$database'" + psql -v ON_ERROR_STOP=1 --username postgres <<-EOSQL + CREATE DATABASE $database; +EOSQL +} + +if [ -n "$POSTGRES_MULTIPLE_DATABASES" ]; then + echo "Multiple database creation requested: $POSTGRES_MULTIPLE_DATABASES" + for db in $(echo $POSTGRES_MULTIPLE_DATABASES | tr ',' ' '); do + create_user_and_database $db + done + echo "Multiple databases created" +fi diff --git a/core/scripts/vrfv2/testnet/docker/docker-compose.yml b/core/scripts/vrfv2/testnet/docker/docker-compose.yml new file mode 100644 index 00000000000..d31c50f3463 --- /dev/null +++ b/core/scripts/vrfv2/testnet/docker/docker-compose.yml @@ -0,0 +1,140 @@ +version: '3.5' +services: + chainlink-node-0: + container_name: vrf-primary-node + image: ${NODE_IMAGE_VERSION} + entrypoint: + - /opt/docker-wait-for-others.sh + - database:5432 + - -- + command: chainlink -config /opt/config/base.toml -config /opt/config/rpc-nodes.toml -config /opt/config/vrf-primary.toml node start -p /run/secrets/node_password -a /run/secrets/apicredentials + environment: + - CL_DATABASE_URL=postgresql://postgres:$CHAINLINK_PGPASSWORD@database:5432/chainlink_0_test?sslmode=disable + platform: "linux/x86_64" + volumes: + - ./wait-for-others/docker-wait-for-it.sh:/opt/docker-wait-for-it.sh:ro + - ./wait-for-others/docker-wait-for-others.sh:/opt/docker-wait-for-others.sh:ro + - ./toml-config:/opt/config:ro + ports: + - "6610:6688" + - "6059:6060" + secrets: + - apicredentials + - node_password + depends_on: + - database + + chainlink-node-1: + container_name: vrf-backup-node + image: ${NODE_IMAGE_VERSION} + entrypoint: + - /opt/docker-wait-for-others.sh + - database:5432 + - -- + command: chainlink node -config /opt/config/base.toml -config /opt/config/rpc-nodes.toml -config /opt/config/vrf-primary.toml -config /opt/config/vrf-backup.toml start -p /run/secrets/node_password -a /run/secrets/apicredentials + environment: + - CL_DATABASE_URL=postgresql://postgres:$CHAINLINK_PGPASSWORD@database:5432/chainlink_1_test?sslmode=disable + platform: "linux/x86_64" + volumes: + - ./wait-for-others/docker-wait-for-it.sh:/opt/docker-wait-for-it.sh:ro + - ./wait-for-others/docker-wait-for-others.sh:/opt/docker-wait-for-others.sh:ro + - ./toml-config:/opt/config:ro + ports: + - "6611:6688" + - "6060:6060" + secrets: + - apicredentials + - node_password + depends_on: + - database + + chainlink-node-2: + container_name: bhs-node + image: ${NODE_IMAGE_VERSION} + entrypoint: + - /opt/docker-wait-for-others.sh + - database:5432 + - -- + command: chainlink node -config /opt/config/base.toml -config /opt/config/rpc-nodes.toml -config /opt/config/bhs.toml start -p /run/secrets/node_password -a /run/secrets/apicredentials + volumes: + - ./wait-for-others/docker-wait-for-it.sh:/opt/docker-wait-for-it.sh:ro + - ./wait-for-others/docker-wait-for-others.sh:/opt/docker-wait-for-others.sh:ro + - ./toml-config:/opt/config:ro + environment: + - CL_DATABASE_URL=postgresql://postgres:$CHAINLINK_PGPASSWORD@database:5432/chainlink_2_test?sslmode=disable + platform: "linux/x86_64" + ports: + - "6612:6688" + - "6062:6060" + secrets: + - apicredentials + - node_password + depends_on: + - database + + chainlink-node-3: + container_name: bhs-backup-node + image: ${NODE_IMAGE_VERSION} + entrypoint: + - /opt/docker-wait-for-others.sh + - database:5432 + - -- + command: chainlink node -config /opt/config/base.toml -config /opt/config/rpc-nodes.toml -config /opt/config/bhs.toml start -p /run/secrets/node_password -a /run/secrets/apicredentials + volumes: + - ./wait-for-others/docker-wait-for-it.sh:/opt/docker-wait-for-it.sh:ro + - ./wait-for-others/docker-wait-for-others.sh:/opt/docker-wait-for-others.sh:ro + - ./toml-config:/opt/config:ro + environment: + - CL_DATABASE_URL=postgresql://postgres:$CHAINLINK_PGPASSWORD@database:5432/chainlink_3_test?sslmode=disable + platform: "linux/x86_64" + ports: + - "6613:6688" + - "6063:6060" + secrets: + - apicredentials + - node_password + depends_on: + - database + + chainlink-node-4: + container_name: bhf-node + image: ${NODE_IMAGE_VERSION} + entrypoint: + - /opt/docker-wait-for-others.sh + - database:5432 + - -- + command: chainlink node -config /opt/config/base.toml -config /opt/config/rpc-nodes.toml -config /opt/config/bhf.toml start -p /run/secrets/node_password -a /run/secrets/apicredentials + volumes: + - ./wait-for-others/docker-wait-for-it.sh:/opt/docker-wait-for-it.sh:ro + - ./wait-for-others/docker-wait-for-others.sh:/opt/docker-wait-for-others.sh:ro + - ./toml-config:/opt/config:ro + environment: + - CL_DATABASE_URL=postgresql://postgres:$CHAINLINK_PGPASSWORD@database:5432/chainlink_4_test?sslmode=disable + platform: "linux/x86_64" + ports: + - "6614:6688" + - "6064:6060" + secrets: + - apicredentials + - node_password + depends_on: + - database + + database: + image: postgres:11.6 + volumes: + - ./db/create-multiple-databases.sh:/docker-entrypoint-initdb.d/create-multiple-databases.sh + environment: + POSTGRES_PASSWORD: chainlink + POSTGRES_MULTIPLE_DATABASES: chainlink_0_test,chainlink_1_test,chainlink_2_test,chainlink_3_test,chainlink_4_test + ports: + - "5432:5432" + +secrets: + node_password: + file: ./secrets/password.txt + apicredentials: + file: ./secrets/apicredentials + +volumes: + docker-compose-db: diff --git a/core/scripts/vrfv2/testnet/docker/sample.env b/core/scripts/vrfv2/testnet/docker/sample.env new file mode 100644 index 00000000000..4fb63b40b6c --- /dev/null +++ b/core/scripts/vrfv2/testnet/docker/sample.env @@ -0,0 +1,5 @@ +#used for docker compose variable only +NODE_IMAGE_VERSION=public.ecr.aws/chainlink/chainlink:2.3.0 + +CHAINLINK_DB_NAME=chainlink +CHAINLINK_PGPASSWORD=chainlink diff --git a/core/scripts/vrfv2/testnet/docker/secrets/apicredentials b/core/scripts/vrfv2/testnet/docker/secrets/apicredentials new file mode 100644 index 00000000000..fa32a892a2c --- /dev/null +++ b/core/scripts/vrfv2/testnet/docker/secrets/apicredentials @@ -0,0 +1,2 @@ +test@test.com +1234567890password diff --git a/core/scripts/vrfv2/testnet/docker/secrets/password.txt b/core/scripts/vrfv2/testnet/docker/secrets/password.txt new file mode 100644 index 00000000000..54714ef7730 --- /dev/null +++ b/core/scripts/vrfv2/testnet/docker/secrets/password.txt @@ -0,0 +1 @@ +1234567890password diff --git a/core/scripts/vrfv2/testnet/docker/toml-config/base.toml b/core/scripts/vrfv2/testnet/docker/toml-config/base.toml new file mode 100644 index 00000000000..0bb83beb94a --- /dev/null +++ b/core/scripts/vrfv2/testnet/docker/toml-config/base.toml @@ -0,0 +1,31 @@ +RootDir = '/home/chainlink' + +[Database] +MaxIdleConns = 20 +MaxOpenConns = 40 +MigrateOnStartup = true + +[Log] +Level = 'debug' +JSONConsole = true + +[Log.File] +MaxSize = '0b' + +[WebServer] +AllowOrigins = '*' +HTTPPort = 6688 +SecureCookies = false + +[WebServer.RateLimit] +Authenticated = 2000 +Unauthenticated = 100 + +[WebServer.TLS] +HTTPSPort = 0 + +[P2P] +[P2P.V2] +Enabled = true +AnnounceAddresses = ['0.0.0.0:6690'] +ListenAddresses = ['0.0.0.0:6690'] diff --git a/core/scripts/vrfv2/testnet/docker/toml-config/bhf.toml b/core/scripts/vrfv2/testnet/docker/toml-config/bhf.toml new file mode 100644 index 00000000000..9de5eb4328e --- /dev/null +++ b/core/scripts/vrfv2/testnet/docker/toml-config/bhf.toml @@ -0,0 +1,7 @@ + +[Feature] +LogPoller = true + +[[EVM]] +ChainID = '11155111' +FinalityDepth = 10 diff --git a/core/scripts/vrfv2/testnet/docker/toml-config/bhs.toml b/core/scripts/vrfv2/testnet/docker/toml-config/bhs.toml new file mode 100644 index 00000000000..9de5eb4328e --- /dev/null +++ b/core/scripts/vrfv2/testnet/docker/toml-config/bhs.toml @@ -0,0 +1,7 @@ + +[Feature] +LogPoller = true + +[[EVM]] +ChainID = '11155111' +FinalityDepth = 10 diff --git a/core/scripts/vrfv2/testnet/docker/toml-config/rpc-nodes.toml b/core/scripts/vrfv2/testnet/docker/toml-config/rpc-nodes.toml new file mode 100644 index 00000000000..c977ee4a9ca --- /dev/null +++ b/core/scripts/vrfv2/testnet/docker/toml-config/rpc-nodes.toml @@ -0,0 +1,8 @@ +[[EVM]] +ChainID = "11155111" + +[[EVM.Nodes]] +HTTPURL = "" +Name = "RPC Node" +SendOnly = false +WSURL = "" diff --git a/core/scripts/vrfv2/testnet/docker/toml-config/secrets.toml b/core/scripts/vrfv2/testnet/docker/toml-config/secrets.toml new file mode 100644 index 00000000000..00d12b0660a --- /dev/null +++ b/core/scripts/vrfv2/testnet/docker/toml-config/secrets.toml @@ -0,0 +1,4 @@ +[Password] +Keystore = 'mysecretkeystorepassword' +[Database] +URL = 'postgresql://postgres:mysecretpassword@host.docker.internal:5432/postgres?sslmode=disable' diff --git a/core/scripts/vrfv2/testnet/docker/toml-config/vrf-backup-other-chains.toml b/core/scripts/vrfv2/testnet/docker/toml-config/vrf-backup-other-chains.toml new file mode 100644 index 00000000000..a39c6b15c57 --- /dev/null +++ b/core/scripts/vrfv2/testnet/docker/toml-config/vrf-backup-other-chains.toml @@ -0,0 +1,20 @@ +[Feature] +LogPoller = false #VRF V2 uses Log Broadcast3er instead of Log poller + +[[EVM]] +ChainID = '11155111' +BlockBackfillDepth = 500 +LogBackfillBatchSize = 1000 +MinIncomingConfirmations = 100 +RPCDefaultBatchSize = 25 + +[EVM.Transactions] +MaxInFlight = 128 +MaxQueued = 0 + +[EVM.GasEstimator] +LimitDefault = 3500000 +PriceMax = '30 gwei' + +[EVM.GasEstimator.BlockHistory] +BatchSize = 100 diff --git a/core/scripts/vrfv2/testnet/docker/toml-config/vrf-backup.toml b/core/scripts/vrfv2/testnet/docker/toml-config/vrf-backup.toml new file mode 100644 index 00000000000..92b9e717b2f --- /dev/null +++ b/core/scripts/vrfv2/testnet/docker/toml-config/vrf-backup.toml @@ -0,0 +1,3 @@ +[[EVM]] +ChainID = '11155111' +MinIncomingConfirmations = 100 diff --git a/core/scripts/vrfv2/testnet/docker/toml-config/vrf-primary.toml b/core/scripts/vrfv2/testnet/docker/toml-config/vrf-primary.toml new file mode 100644 index 00000000000..67cd33659fb --- /dev/null +++ b/core/scripts/vrfv2/testnet/docker/toml-config/vrf-primary.toml @@ -0,0 +1,15 @@ +[Feature] +LogPoller = false #VRF V2 uses Log Broadcast3er instead of Log poller + +[[EVM]] +ChainID = '11155111' +BlockBackfillDepth = 500 +MinIncomingConfirmations = 3 + +[EVM.Transactions] +MaxQueued = 10000 + +[EVM.GasEstimator] +LimitDefault = 3500000 +PriceMax = '30 gwei' +FeeCapDefault = '20 gwei' diff --git a/core/scripts/vrfv2/testnet/docker/wait-for-others/docker-wait-for-it.sh b/core/scripts/vrfv2/testnet/docker/wait-for-others/docker-wait-for-it.sh new file mode 100755 index 00000000000..7f9943c9890 --- /dev/null +++ b/core/scripts/vrfv2/testnet/docker/wait-for-others/docker-wait-for-it.sh @@ -0,0 +1,178 @@ +#!/usr/bin/env bash +# From https://github.com/vishnubob/wait-for-it +# Use this script to test if a given TCP host/port are available + +cmdname=$(basename $0) + +echoerr() { if [[ $QUIET -ne 1 ]]; then echo "$@" 1>&2; fi } + +usage() +{ + cat << USAGE >&2 +Usage: + $cmdname host:port [-s] [-t timeout] [-- command args] + -h HOST | --host=HOST Host or IP under test + -p PORT | --port=PORT TCP port under test + Alternatively, you specify the host and port as host:port + -s | --strict Only execute subcommand if the test succeeds + -q | --quiet Don't output any status messages + -t TIMEOUT | --timeout=TIMEOUT + Timeout in seconds, zero for no timeout + -- COMMAND ARGS Execute command with args after the test finishes +USAGE + exit 1 +} + +wait_for() +{ + if [[ $TIMEOUT -gt 0 ]]; then + echoerr "$cmdname: waiting $TIMEOUT seconds for $HOST:$PORT" + else + echoerr "$cmdname: waiting for $HOST:$PORT without a timeout" + fi + start_ts=$(date +%s) + while : + do + if [[ $ISBUSY -eq 1 ]]; then + nc -z $HOST $PORT + result=$? + else + (echo > /dev/tcp/$HOST/$PORT) >/dev/null 2>&1 + result=$? + fi + if [[ $result -eq 0 ]]; then + end_ts=$(date +%s) + echoerr "$cmdname: $HOST:$PORT is available after $((end_ts - start_ts)) seconds" + break + fi + sleep 1 + done + return $result +} + +wait_for_wrapper() +{ + # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692 + if [[ $QUIET -eq 1 ]]; then + timeout $BUSYTIMEFLAG $TIMEOUT $0 --quiet --child --host=$HOST --port=$PORT --timeout=$TIMEOUT & + else + timeout $BUSYTIMEFLAG $TIMEOUT $0 --child --host=$HOST --port=$PORT --timeout=$TIMEOUT & + fi + PID=$! + trap "kill -INT -$PID" INT + wait $PID + RESULT=$? + if [[ $RESULT -ne 0 ]]; then + echoerr "$cmdname: timeout occurred after waiting $TIMEOUT seconds for $HOST:$PORT" + fi + return $RESULT +} + +# process arguments +while [[ $# -gt 0 ]] +do + case "$1" in + *:* ) + hostport=(${1//:/ }) + HOST=${hostport[0]} + PORT=${hostport[1]} + shift 1 + ;; + --child) + CHILD=1 + shift 1 + ;; + -q | --quiet) + QUIET=1 + shift 1 + ;; + -s | --strict) + STRICT=1 + shift 1 + ;; + -h) + HOST="$2" + if [[ $HOST == "" ]]; then break; fi + shift 2 + ;; + --host=*) + HOST="${1#*=}" + shift 1 + ;; + -p) + PORT="$2" + if [[ $PORT == "" ]]; then break; fi + shift 2 + ;; + --port=*) + PORT="${1#*=}" + shift 1 + ;; + -t) + TIMEOUT="$2" + if [[ $TIMEOUT == "" ]]; then break; fi + shift 2 + ;; + --timeout=*) + TIMEOUT="${1#*=}" + shift 1 + ;; + --) + shift + CLI=("$@") + break + ;; + --help) + usage + ;; + *) + echoerr "Unknown argument: $1" + usage + ;; + esac +done + +if [[ "$HOST" == "" || "$PORT" == "" ]]; then + echoerr "Error: you need to provide a host and port to test." + usage +fi + +TIMEOUT=${TIMEOUT:-15} +STRICT=${STRICT:-0} +CHILD=${CHILD:-0} +QUIET=${QUIET:-0} + +# check to see if timeout is from busybox? +# check to see if timeout is from busybox? +TIMEOUT_PATH=$(realpath $(which timeout)) +if [[ $TIMEOUT_PATH =~ "busybox" ]]; then + ISBUSY=1 + BUSYTIMEFLAG="-t" +else + ISBUSY=0 + BUSYTIMEFLAG="" +fi + +if [[ $CHILD -gt 0 ]]; then + wait_for + RESULT=$? + exit $RESULT +else + if [[ $TIMEOUT -gt 0 ]]; then + wait_for_wrapper + RESULT=$? + else + wait_for + RESULT=$? + fi +fi + +if [[ $CLI != "" ]]; then + if [[ $RESULT -ne 0 && $STRICT -eq 1 ]]; then + echoerr "$cmdname: strict mode, refusing to execute subprocess" + exit $RESULT + fi + exec "${CLI[@]}" +else + exit $RESULT +fi diff --git a/core/scripts/vrfv2/testnet/docker/wait-for-others/docker-wait-for-others.sh b/core/scripts/vrfv2/testnet/docker/wait-for-others/docker-wait-for-others.sh new file mode 100755 index 00000000000..88684e5d18f --- /dev/null +++ b/core/scripts/vrfv2/testnet/docker/wait-for-others/docker-wait-for-others.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +while [ "$#" -gt 1 ] && [ "$1" != "--" ]; do + /opt/docker-wait-for-it.sh $1 + shift +done + +# Hand off to the CMD +exec "$@" diff --git a/core/scripts/vrfv2/testnet/jobs/jobs.go b/core/scripts/vrfv2/testnet/jobs/jobs.go new file mode 100644 index 00000000000..8ff0195bfa8 --- /dev/null +++ b/core/scripts/vrfv2/testnet/jobs/jobs.go @@ -0,0 +1,70 @@ +package jobs + +var ( + VRFJobFormatted = `type = "vrf" +name = "vrf_v2" +schemaVersion = 1 +coordinatorAddress = "%s" +batchCoordinatorAddress = "%s" +batchFulfillmentEnabled = %t +batchFulfillmentGasMultiplier = 1.1 +publicKey = "%s" +minIncomingConfirmations = %d +evmChainID = "%d" +fromAddresses = ["%s"] +pollPeriod = "300ms" +requestTimeout = "30m0s" +observationSource = """decode_log [type=ethabidecodelog + abi="RandomWordsRequested(bytes32 indexed keyHash,uint256 requestId,uint256 preSeed,uint64 indexed subId,uint16 minimumRequestConfirmations,uint32 callbackGasLimit,uint32 numWords,address indexed sender)" + data="$(jobRun.logData)" + topics="$(jobRun.logTopics)"] +vrf [type=vrfv2 + publicKey="$(jobSpec.publicKey)" + requestBlockHash="$(jobRun.logBlockHash)" + requestBlockNumber="$(jobRun.logBlockNumber)" + topics="$(jobRun.logTopics)"] +estimate_gas [type=estimategaslimit + to="%s" + multiplier="1.1" + data="$(vrf.output)"] +simulate [type=ethcall + from="%s" + to="%s" + gas="$(estimate_gas)" + gasPrice="$(jobSpec.maxGasPrice)" + extractRevertReason=true + contract="%s" + data="$(vrf.output)"] +decode_log->vrf->estimate_gas->simulate +"""` + + BHSJobFormatted = `type = "blockhashstore" +schemaVersion = 1 +name = "blockhashstore" +forwardingAllowed = false +coordinatorV2Address = "%s" +waitBlocks = %d +lookbackBlocks = %d +blockhashStoreAddress = "%s" +pollPeriod = "30s" +runTimeout = "1m0s" +evmChainID = "%d" +fromAddresses = ["%s"] +` + BHFJobFormatted = `type = "blockheaderfeeder" +schemaVersion = 1 +name = "blockheaderfeeder" +forwardingAllowed = false +coordinatorV2Address = "%s" +waitBlocks = 256 +lookbackBlocks = 1_000 +blockhashStoreAddress = "%s" +batchBlockhashStoreAddress = "%s" +pollPeriod = "10s" +runTimeout = "30s" +evmChainID = "%d" +fromAddresses = ["%s"] +getBlockhashesBatchSize = 50 +storeBlockhashesBatchSize = 10 +` +) diff --git a/core/scripts/vrfv2/testnet/main.go b/core/scripts/vrfv2/testnet/main.go index ffaa1929fb3..d30c0e7fca3 100644 --- a/core/scripts/vrfv2/testnet/main.go +++ b/core/scripts/vrfv2/testnet/main.go @@ -11,6 +11,9 @@ import ( "os" "strings" + "github.com/smartcontractkit/chainlink/core/scripts/vrfv2/testnet/scripts" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_owner_test_consumer" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" @@ -347,7 +350,7 @@ func main() { cmd := flag.NewFlagSet("batch-bhs-deploy", flag.ExitOnError) bhsAddr := cmd.String("bhs-address", "", "address of the blockhash store contract") helpers.ParseArgs(cmd, os.Args[2:], "bhs-address") - deployBatchBHS(e, common.HexToAddress(*bhsAddr)) + scripts.DeployBatchBHS(e, common.HexToAddress(*bhsAddr)) case "batch-bhs-store": cmd := flag.NewFlagSet("batch-bhs-store", flag.ExitOnError) batchAddr := cmd.String("batch-bhs-address", "", "address of the batch bhs contract") @@ -384,7 +387,7 @@ func main() { helpers.PanicErr(err) blockRange, err := blockhashstore.DecreasingBlockRange(big.NewInt(*startBlock-1), big.NewInt(*startBlock-*numBlocks-1)) helpers.PanicErr(err) - rlpHeaders, _, err := helpers.GetRlpHeaders(e, blockRange) + rlpHeaders, _, err := helpers.GetRlpHeaders(e, blockRange, true) helpers.PanicErr(err) tx, err := batchBHS.StoreVerifyHeader(e.Owner, blockRange, rlpHeaders) helpers.PanicErr(err) @@ -459,7 +462,7 @@ func main() { fmt.Println("using gas price", e.Owner.GasPrice, "wei") blockNumbers := blockRange[i:j] - blockHeaders, _, err := helpers.GetRlpHeaders(e, blockNumbers) + blockHeaders, _, err := helpers.GetRlpHeaders(e, blockNumbers, true) fmt.Println("storing blockNumbers:", blockNumbers) helpers.PanicErr(err) @@ -480,14 +483,14 @@ func main() { helpers.PanicErr(err) fmt.Println("latest head number:", h.Number.String()) case "bhs-deploy": - deployBHS(e) + scripts.DeployBHS(e) case "coordinator-deploy": coordinatorDeployCmd := flag.NewFlagSet("coordinator-deploy", flag.ExitOnError) coordinatorDeployLinkAddress := coordinatorDeployCmd.String("link-address", "", "address of link token") coordinatorDeployBHSAddress := coordinatorDeployCmd.String("bhs-address", "", "address of bhs") coordinatorDeployLinkEthFeedAddress := coordinatorDeployCmd.String("link-eth-feed", "", "address of link-eth-feed") helpers.ParseArgs(coordinatorDeployCmd, os.Args[2:], "link-address", "bhs-address", "link-eth-feed") - deployCoordinator(e, *coordinatorDeployLinkAddress, *coordinatorDeployBHSAddress, *coordinatorDeployLinkEthFeedAddress) + scripts.DeployCoordinator(e, *coordinatorDeployLinkAddress, *coordinatorDeployBHSAddress, *coordinatorDeployLinkEthFeedAddress) case "coordinator-get-config": cmd := flag.NewFlagSet("coordinator-get-config", flag.ExitOnError) coordinatorAddress := cmd.String("coordinator-address", "", "coordinator address") @@ -496,7 +499,7 @@ func main() { coordinator, err := vrf_coordinator_v2.NewVRFCoordinatorV2(common.HexToAddress(*coordinatorAddress), e.Ec) helpers.PanicErr(err) - printCoordinatorConfig(coordinator) + scripts.PrintCoordinatorConfig(coordinator) case "coordinator-set-config": cmd := flag.NewFlagSet("coordinator-set-config", flag.ExitOnError) setConfigAddress := cmd.String("coordinator-address", "", "coordinator address") @@ -519,7 +522,7 @@ func main() { coordinator, err := vrf_coordinator_v2.NewVRFCoordinatorV2(common.HexToAddress(*setConfigAddress), e.Ec) helpers.PanicErr(err) - setCoordinatorConfig( + scripts.SetCoordinatorConfig( e, *coordinator, uint16(*minConfs), @@ -553,7 +556,7 @@ func main() { *registerKeyUncompressedPubKey = strings.Replace(*registerKeyUncompressedPubKey, "0x", "04", 1) } - registerCoordinatorProvingKey(e, *coordinator, *registerKeyUncompressedPubKey, *registerKeyOracleAddress) + scripts.RegisterCoordinatorProvingKey(e, *coordinator, *registerKeyUncompressedPubKey, *registerKeyOracleAddress) case "coordinator-deregister-key": coordinatorDeregisterKey := flag.NewFlagSet("coordinator-deregister-key", flag.ExitOnError) deregisterKeyAddress := coordinatorDeregisterKey.String("address", "", "coordinator address") @@ -681,14 +684,14 @@ func main() { helpers.PanicErr(err) fmt.Printf("Request config %+v Rw %+v Rid %+v\n", rc, rw, rid) case "deploy-universe": - deployUniverse(e) + scripts.DeployUniverseViaCLI(e) case "eoa-consumer-deploy": consumerDeployCmd := flag.NewFlagSet("eoa-consumer-deploy", flag.ExitOnError) consumerCoordinator := consumerDeployCmd.String("coordinator-address", "", "coordinator address") consumerLinkAddress := consumerDeployCmd.String("link-address", "", "link-address") helpers.ParseArgs(consumerDeployCmd, os.Args[2:], "coordinator-address", "link-address") - eoaDeployConsumer(e, *consumerCoordinator, *consumerLinkAddress) + scripts.EoaDeployConsumer(e, *consumerCoordinator, *consumerLinkAddress) case "eoa-load-test-consumer-deploy": loadTestConsumerDeployCmd := flag.NewFlagSet("eoa-load-test-consumer-deploy", flag.ExitOnError) consumerCoordinator := loadTestConsumerDeployCmd.String("coordinator-address", "", "coordinator address") @@ -705,7 +708,12 @@ func main() { loadTestConsumerDeployCmd := flag.NewFlagSet("eoa-load-test-consumer-with-metrics-deploy", flag.ExitOnError) consumerCoordinator := loadTestConsumerDeployCmd.String("coordinator-address", "", "coordinator address") helpers.ParseArgs(loadTestConsumerDeployCmd, os.Args[2:], "coordinator-address") - _, tx, _, err := vrf_load_test_with_metrics.DeployVRFV2LoadTestWithMetrics( + scripts.EoaLoadTestConsumerWithMetricsDeploy(e, *consumerCoordinator) + case "eoa-vrf-owner-test-consumer-deploy": + loadTestConsumerDeployCmd := flag.NewFlagSet("eoa-vrf-owner-test-consumer-deploy", flag.ExitOnError) + consumerCoordinator := loadTestConsumerDeployCmd.String("coordinator-address", "", "coordinator address") + helpers.ParseArgs(loadTestConsumerDeployCmd, os.Args[2:], "coordinator-address") + _, tx, _, err := vrf_owner_test_consumer.DeployVRFV2OwnerTestConsumer( e.Owner, e.Ec, common.HexToAddress(*consumerCoordinator), @@ -718,7 +726,7 @@ func main() { helpers.ParseArgs(createSubCmd, os.Args[2:], "coordinator-address") coordinator, err := vrf_coordinator_v2.NewVRFCoordinatorV2(common.HexToAddress(*coordinatorAddress), e.Ec) helpers.PanicErr(err) - eoaCreateSub(e, *coordinator) + scripts.EoaCreateSub(e, *coordinator) case "eoa-add-sub-consumer": addSubConsCmd := flag.NewFlagSet("eoa-add-sub-consumer", flag.ExitOnError) coordinatorAddress := addSubConsCmd.String("coordinator-address", "", "coordinator address") @@ -727,7 +735,7 @@ func main() { helpers.ParseArgs(addSubConsCmd, os.Args[2:], "coordinator-address", "sub-id", "consumer-address") coordinator, err := vrf_coordinator_v2.NewVRFCoordinatorV2(common.HexToAddress(*coordinatorAddress), e.Ec) helpers.PanicErr(err) - eoaAddConsumerToSub(e, *coordinator, uint64(*subID), *consumerAddress) + scripts.EoaAddConsumerToSub(e, *coordinator, uint64(*subID), *consumerAddress) case "eoa-create-fund-authorize-sub": // Lets just treat the owner key as the EOA controlling the sub cfaSubCmd := flag.NewFlagSet("eoa-create-fund-authorize-sub", flag.ExitOnError) @@ -829,6 +837,75 @@ func main() { for i, tx := range txes { helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID, fmt.Sprintf("load test %d", i+1)) } + case "eoa-vrf-owner-test-request": + request := flag.NewFlagSet("eoa-eoa-vrf-owner-test-request", flag.ExitOnError) + consumerAddress := request.String("consumer-address", "", "consumer address") + requestConfirmations := request.Uint("request-confirmations", 3, "minimum request confirmations") + keyHash := request.String("key-hash", "", "key hash") + cbGasLimit := request.Uint("cb-gas-limit", 100_000, "request callback gas limit") + numWords := request.Uint("num-words", 1, "num words to request") + requests := request.Uint("requests", 10, "number of randomness requests to make per run") + runs := request.Uint("runs", 1, "number of runs to do. total randomness requests will be (requests * runs).") + helpers.ParseArgs(request, os.Args[2:], "consumer-address", "key-hash") + keyHashBytes := common.HexToHash(*keyHash) + + consumer, err := vrf_owner_test_consumer.NewVRFV2OwnerTestConsumer( + common.HexToAddress(*consumerAddress), + e.Ec) + helpers.PanicErr(err) + var txes []*types.Transaction + for i := 0; i < int(*runs); i++ { + tx, err := consumer.RequestRandomWords( + e.Owner, + uint16(*requestConfirmations), + keyHashBytes, + uint32(*cbGasLimit), + uint32(*numWords), + uint16(*requests), + ) + helpers.PanicErr(err) + fmt.Printf("TX %d: %s\n", i+1, helpers.ExplorerLink(e.ChainID, tx.Hash())) + txes = append(txes, tx) + } + fmt.Println("Total number of requests sent:", (*requests)*(*runs)) + fmt.Println("fetching receipts for all transactions") + for i, tx := range txes { + helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID, fmt.Sprintf("load test %d", i+1)) + } + case "eoa-vrf-owner-test-read-metrics": + request := flag.NewFlagSet("eoa-load-test-read-metrics", flag.ExitOnError) + consumerAddress := request.String("consumer-address", "", "consumer address") + helpers.ParseArgs(request, os.Args[2:], "consumer-address") + consumer, err := vrf_owner_test_consumer.NewVRFV2OwnerTestConsumer( + common.HexToAddress(*consumerAddress), + e.Ec) + helpers.PanicErr(err) + responseCount, err := consumer.SResponseCount(nil) + helpers.PanicErr(err) + fmt.Println("Response Count: ", responseCount) + requestCount, err := consumer.SRequestCount(nil) + helpers.PanicErr(err) + fmt.Println("Request Count: ", requestCount) + averageFulfillmentInMillions, err := consumer.SAverageFulfillmentInMillions(nil) + helpers.PanicErr(err) + fmt.Println("Average Fulfillment In Millions: ", averageFulfillmentInMillions) + slowestFulfillment, err := consumer.SSlowestFulfillment(nil) + helpers.PanicErr(err) + fmt.Println("Slowest Fulfillment: ", slowestFulfillment) + fastestFulfillment, err := consumer.SFastestFulfillment(nil) + helpers.PanicErr(err) + fmt.Println("Fastest Fulfillment: ", fastestFulfillment) + case "eoa-vrf-owner-test-reset-metrics": + request := flag.NewFlagSet("eoa-vrf-owner-test-reset-metrics", flag.ExitOnError) + consumerAddress := request.String("consumer-address", "", "consumer address") + helpers.ParseArgs(request, os.Args[2:], "consumer-address") + consumer, err := vrf_owner_test_consumer.NewVRFV2OwnerTestConsumer( + common.HexToAddress(*consumerAddress), + e.Ec) + helpers.PanicErr(err) + _, err = consumer.Reset(e.Owner) + helpers.PanicErr(err) + fmt.Println("Load Test Consumer With Metrics was reset ") case "eoa-load-test-request-with-metrics": request := flag.NewFlagSet("eoa-load-test-request-with-metrics", flag.ExitOnError) consumerAddress := request.String("consumer-address", "", "consumer address") @@ -944,7 +1021,7 @@ func main() { coordinator, err := vrf_coordinator_v2.NewVRFCoordinatorV2(common.HexToAddress(*coordinatorAddress), e.Ec) helpers.PanicErr(err) - eoaFundSubscription(e, *coordinator, *consumerLinkAddress, amount, uint64(*subID)) + scripts.EoaFundSubscription(e, *coordinator, *consumerLinkAddress, amount, uint64(*subID)) case "eoa-read": cmd := flag.NewFlagSet("eoa-read", flag.ExitOnError) consumerAddress := cmd.String("consumer", "", "consumer address") @@ -1112,7 +1189,7 @@ func main() { linkETHFeedAddress := cmd.String("link-eth-feed", "", "address of link-eth-feed") coordinatorAddress := cmd.String("coordinator-address", "", "address of the vrf coordinator v2 contract") helpers.ParseArgs(cmd, os.Args[2:], "link-address", "link-eth-feed", "coordinator-address") - wrapperDeploy(e, + scripts.WrapperDeploy(e, common.HexToAddress(*linkAddress), common.HexToAddress(*linkETHFeedAddress), common.HexToAddress(*coordinatorAddress)) @@ -1150,7 +1227,7 @@ func main() { maxNumWords := cmd.Uint("max-num-words", 10, "the keyhash that wrapper requests should use") helpers.ParseArgs(cmd, os.Args[2:], "wrapper-address", "key-hash") - wrapperConfigure(e, + scripts.WrapperConfigure(e, common.HexToAddress(*wrapperAddress), *wrapperGasOverhead, *coordinatorGasOverhead, @@ -1182,7 +1259,7 @@ func main() { wrapperAddress := cmd.String("wrapper-address", "", "address of the VRFV2Wrapper contract") helpers.ParseArgs(cmd, os.Args[2:], "link-address", "wrapper-address") - wrapperConsumerDeploy(e, + scripts.WrapperConsumerDeploy(e, common.HexToAddress(*linkAddress), common.HexToAddress(*wrapperAddress)) case "wrapper-consumer-request": @@ -1254,7 +1331,7 @@ func main() { helpers.ParseArgs(cmd, os.Args[2:]) _ = helpers.CalculateLatestBlockHeader(e, *blockNumber) case "wrapper-universe-deploy": - deployWrapperUniverse(e) + scripts.DeployWrapperUniverse(e) default: panic("unrecognized subcommand: " + os.Args[1]) } diff --git a/core/scripts/vrfv2/testnet/scripts/super_scripts.go b/core/scripts/vrfv2/testnet/scripts/super_scripts.go new file mode 100644 index 00000000000..3594636a604 --- /dev/null +++ b/core/scripts/vrfv2/testnet/scripts/super_scripts.go @@ -0,0 +1,454 @@ +package scripts + +import ( + "context" + "encoding/hex" + "flag" + "fmt" + "github.com/smartcontractkit/chainlink/core/scripts/vrfv2/testnet/constants" + "github.com/smartcontractkit/chainlink/core/scripts/vrfv2/testnet/jobs" + "math/big" + "os" + "strings" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" + "github.com/shopspring/decimal" + + helpers "github.com/smartcontractkit/chainlink/core/scripts/common" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2" + "github.com/smartcontractkit/chainlink/v2/core/services/signatures/secp256k1" +) + +var ( + VRFPrimaryNodeName = "vrf-primary-node" + VRFBackupNodeName = "vrf-backup-node" + BHSNodeName = "bhs-node" + BHSBackupNodeName = "bhs-backup-node" + BHFNodeName = "bhf-node" +) + +type Node struct { + URL string + CredsFile string + SendingKeys []SendingKey + NumberOfSendingKeysToCreate int + SendingKeyFundingAmount big.Int + VrfKeys []string + jobSpec string +} + +type SendingKey struct { + Address string + BalanceEth big.Int +} + +type JobSpecs struct { + VRFPrimaryNode string + VRFBackupyNode string + BHSNode string + BHSBackupNode string + BHFNode string +} + +type ContractAddresses struct { + LinkAddress string + LinkEthAddress string + BhsContractAddress common.Address + BatchBHSAddress common.Address + CoordinatorAddress common.Address + BatchCoordinatorAddress common.Address +} + +type CoordinatorConfig struct { + MinConfs *int + MaxGasLimit *int64 + StalenessSeconds *int64 + GasAfterPayment *int64 + FallbackWeiPerUnitLink *big.Int + FeeConfig vrf_coordinator_v2.VRFCoordinatorV2FeeConfig +} + +func DeployUniverseViaCLI(e helpers.Environment) { + deployCmd := flag.NewFlagSet("deploy-universe", flag.ExitOnError) + + // required flags + linkAddress := *deployCmd.String("link-address", "", "address of link token") + linkEthAddress := *deployCmd.String("link-eth-feed", "", "address of link eth feed") + bhsContractAddressString := *deployCmd.String("bhs-address", "", "address of BHS contract") + batchBHSAddressString := *deployCmd.String("batch-bhs-address", "", "address of Batch BHS contract") + coordinatorAddressString := *deployCmd.String("coordinator-address", "", "address of VRF Coordinator contract") + batchCoordinatorAddressString := *deployCmd.String("batch-coordinator-address", "", "address Batch VRF Coordinator contract") + + subscriptionBalanceJuelsString := deployCmd.String("subscription-balance", constants.SubscriptionBalanceJuels.String(), "amount to fund subscription") + nodeSendingKeyFundingAmount := deployCmd.Int64("sending-key-funding-amount", constants.NodeSendingKeyFundingAmountGwei, "CL node sending key funding amount") + + batchFulfillmentEnabled := deployCmd.Bool("batch-fulfillment-enabled", constants.BatchFulfillmentEnabled, "whether send randomness fulfillments in batches inside one tx from CL node") + + // optional flags + fallbackWeiPerUnitLinkString := deployCmd.String("fallback-wei-per-unit-link", constants.FallbackWeiPerUnitLink.String(), "fallback wei/link ratio") + registerKeyUncompressedPubKey := deployCmd.String("uncompressed-pub-key", "", "uncompressed public key") + vrfPrimaryNodeSendingKeysString := deployCmd.String("vrf-primary-node-sending-keys", "", "VRF Primary Node sending keys") + + minConfs := deployCmd.Int("min-confs", constants.MinConfs, "min confs") + maxGasLimit := deployCmd.Int64("max-gas-limit", constants.MaxGasLimit, "max gas limit") + stalenessSeconds := deployCmd.Int64("staleness-seconds", constants.StalenessSeconds, "staleness in seconds") + gasAfterPayment := deployCmd.Int64("gas-after-payment", constants.GasAfterPayment, "gas after payment calculation") + flatFeeTier1 := deployCmd.Int64("flat-fee-tier-1", constants.FlatFeeTier1, "flat fee tier 1") + flatFeeTier2 := deployCmd.Int64("flat-fee-tier-2", constants.FlatFeeTier2, "flat fee tier 2") + flatFeeTier3 := deployCmd.Int64("flat-fee-tier-3", constants.FlatFeeTier3, "flat fee tier 3") + flatFeeTier4 := deployCmd.Int64("flat-fee-tier-4", constants.FlatFeeTier4, "flat fee tier 4") + flatFeeTier5 := deployCmd.Int64("flat-fee-tier-5", constants.FlatFeeTier5, "flat fee tier 5") + reqsForTier2 := deployCmd.Int64("reqs-for-tier-2", constants.ReqsForTier2, "requests for tier 2") + reqsForTier3 := deployCmd.Int64("reqs-for-tier-3", constants.ReqsForTier3, "requests for tier 3") + reqsForTier4 := deployCmd.Int64("reqs-for-tier-4", constants.ReqsForTier4, "requests for tier 4") + reqsForTier5 := deployCmd.Int64("reqs-for-tier-5", constants.ReqsForTier5, "requests for tier 5") + + helpers.ParseArgs( + deployCmd, os.Args[2:], + ) + + fallbackWeiPerUnitLink := decimal.RequireFromString(*fallbackWeiPerUnitLinkString).BigInt() + subscriptionBalanceJuels := decimal.RequireFromString(*subscriptionBalanceJuelsString).BigInt() + + feeConfig := vrf_coordinator_v2.VRFCoordinatorV2FeeConfig{ + FulfillmentFlatFeeLinkPPMTier1: uint32(*flatFeeTier1), + FulfillmentFlatFeeLinkPPMTier2: uint32(*flatFeeTier2), + FulfillmentFlatFeeLinkPPMTier3: uint32(*flatFeeTier3), + FulfillmentFlatFeeLinkPPMTier4: uint32(*flatFeeTier4), + FulfillmentFlatFeeLinkPPMTier5: uint32(*flatFeeTier5), + ReqsForTier2: big.NewInt(*reqsForTier2), + ReqsForTier3: big.NewInt(*reqsForTier3), + ReqsForTier4: big.NewInt(*reqsForTier4), + ReqsForTier5: big.NewInt(*reqsForTier5), + } + + vrfPrimaryNodeSendingKeys := strings.Split(*vrfPrimaryNodeSendingKeysString, ",") + + nodesMap := make(map[string]Node) + + nodesMap[VRFPrimaryNodeName] = Node{ + SendingKeys: mapToSendingKeyArr(vrfPrimaryNodeSendingKeys), + SendingKeyFundingAmount: *big.NewInt(*nodeSendingKeyFundingAmount), + } + + bhsContractAddress := common.HexToAddress(bhsContractAddressString) + batchBHSAddress := common.HexToAddress(batchBHSAddressString) + coordinatorAddress := common.HexToAddress(coordinatorAddressString) + batchCoordinatorAddress := common.HexToAddress(batchCoordinatorAddressString) + + contractAddresses := ContractAddresses{ + LinkAddress: linkAddress, + LinkEthAddress: linkEthAddress, + BhsContractAddress: bhsContractAddress, + BatchBHSAddress: batchBHSAddress, + CoordinatorAddress: coordinatorAddress, + BatchCoordinatorAddress: batchCoordinatorAddress, + } + + coordinatorConfig := CoordinatorConfig{ + MinConfs: minConfs, + MaxGasLimit: maxGasLimit, + StalenessSeconds: stalenessSeconds, + GasAfterPayment: gasAfterPayment, + FallbackWeiPerUnitLink: fallbackWeiPerUnitLink, + FeeConfig: feeConfig, + } + + VRFV2DeployUniverse( + e, + subscriptionBalanceJuels, + registerKeyUncompressedPubKey, + contractAddresses, + coordinatorConfig, + *batchFulfillmentEnabled, + nodesMap, + ) + + vrfPrimaryNode := nodesMap[VRFPrimaryNodeName] + fmt.Println("Funding node's sending keys...") + for _, sendingKey := range vrfPrimaryNode.SendingKeys { + helpers.FundNode(e, sendingKey.Address, &vrfPrimaryNode.SendingKeyFundingAmount) + } +} + +func mapToSendingKeyArr(nodeSendingKeys []string) []SendingKey { + var sendingKeys []SendingKey + + for _, key := range nodeSendingKeys { + sendingKeys = append(sendingKeys, SendingKey{Address: key}) + } + return sendingKeys +} + +func VRFV2DeployUniverse( + e helpers.Environment, + subscriptionBalanceJuels *big.Int, + registerKeyUncompressedPubKey *string, + contractAddresses ContractAddresses, + coordinatorConfig CoordinatorConfig, + batchFulfillmentEnabled bool, + nodesMap map[string]Node, +) JobSpecs { + + // Put key in ECDSA format + if strings.HasPrefix(*registerKeyUncompressedPubKey, "0x") { + *registerKeyUncompressedPubKey = strings.Replace(*registerKeyUncompressedPubKey, "0x", "04", 1) + } + + // Generate compressed public key and key hash + pubBytes, err := hex.DecodeString(*registerKeyUncompressedPubKey) + helpers.PanicErr(err) + pk, err := crypto.UnmarshalPubkey(pubBytes) + helpers.PanicErr(err) + var pkBytes []byte + if big.NewInt(0).Mod(pk.Y, big.NewInt(2)).Uint64() != 0 { + pkBytes = append(pk.X.Bytes(), 1) + } else { + pkBytes = append(pk.X.Bytes(), 0) + } + var newPK secp256k1.PublicKey + copy(newPK[:], pkBytes) + + compressedPkHex := hexutil.Encode(pkBytes) + keyHash, err := newPK.Hash() + helpers.PanicErr(err) + + if len(contractAddresses.LinkAddress) == 0 { + fmt.Println("\nDeploying LINK Token...") + contractAddresses.LinkAddress = helpers.DeployLinkToken(e).String() + } + + if len(contractAddresses.LinkEthAddress) == 0 { + fmt.Println("\nDeploying LINK/ETH Feed...") + contractAddresses.LinkEthAddress = helpers.DeployLinkEthFeed(e, contractAddresses.LinkAddress, coordinatorConfig.FallbackWeiPerUnitLink).String() + } + + if contractAddresses.BhsContractAddress.String() == "0x0000000000000000000000000000000000000000" { + fmt.Println("\nDeploying BHS...") + contractAddresses.BhsContractAddress = DeployBHS(e) + } + + if contractAddresses.BatchBHSAddress.String() == "0x0000000000000000000000000000000000000000" { + fmt.Println("\nDeploying Batch BHS...") + contractAddresses.BatchBHSAddress = DeployBatchBHS(e, contractAddresses.BhsContractAddress) + } + + if contractAddresses.CoordinatorAddress.String() == "0x0000000000000000000000000000000000000000" { + fmt.Println("\nDeploying Coordinator...") + contractAddresses.CoordinatorAddress = DeployCoordinator(e, contractAddresses.LinkAddress, contractAddresses.BhsContractAddress.String(), contractAddresses.LinkEthAddress) + } + + coordinator, err := vrf_coordinator_v2.NewVRFCoordinatorV2(contractAddresses.CoordinatorAddress, e.Ec) + helpers.PanicErr(err) + + if contractAddresses.BatchCoordinatorAddress.String() == "0x0000000000000000000000000000000000000000" { + fmt.Println("\nDeploying Batch Coordinator...") + contractAddresses.BatchCoordinatorAddress = deployBatchCoordinatorV2(e, contractAddresses.CoordinatorAddress) + } + + fmt.Println("\nSetting Coordinator Config...") + SetCoordinatorConfig( + e, + *coordinator, + uint16(*coordinatorConfig.MinConfs), + uint32(*coordinatorConfig.MaxGasLimit), + uint32(*coordinatorConfig.StalenessSeconds), + uint32(*coordinatorConfig.GasAfterPayment), + coordinatorConfig.FallbackWeiPerUnitLink, + coordinatorConfig.FeeConfig, + ) + + fmt.Println("\nConfig set, getting current config from deployed contract...") + PrintCoordinatorConfig(coordinator) + + if len(*registerKeyUncompressedPubKey) > 0 { + fmt.Println("\nRegistering proving key...") + + //NOTE - register proving key against EOA account, and not against Oracle's sending address in other to be able + // easily withdraw funds from Coordinator contract back to EOA account + RegisterCoordinatorProvingKey(e, *coordinator, *registerKeyUncompressedPubKey, e.Owner.From.String()) + + fmt.Println("\nProving key registered, getting proving key hashes from deployed contract...") + _, _, provingKeyHashes, configErr := coordinator.GetRequestConfig(nil) + helpers.PanicErr(configErr) + fmt.Println("Key hash registered:", hex.EncodeToString(provingKeyHashes[0][:])) + } else { + fmt.Println("NOT registering proving key - you must do this eventually in order to fully deploy VRF!") + } + + fmt.Println("\nDeploying consumer...") + consumerAddress := EoaLoadTestConsumerWithMetricsDeploy(e, contractAddresses.CoordinatorAddress.String()) + + fmt.Println("\nAdding subscription...") + EoaCreateSub(e, *coordinator) + subID := uint64(1) + + fmt.Println("\nAdding consumer to subscription...") + EoaAddConsumerToSub(e, *coordinator, subID, consumerAddress.String()) + + if subscriptionBalanceJuels.Cmp(big.NewInt(0)) > 0 { + fmt.Println("\nFunding subscription with", subscriptionBalanceJuels, "juels...") + EoaFundSubscription(e, *coordinator, contractAddresses.LinkAddress, subscriptionBalanceJuels, subID) + } else { + fmt.Println("Subscription", subID, "NOT getting funded. You must fund the subscription in order to use it!") + } + + fmt.Println("\nSubscribed and (possibly) funded, retrieving subscription from deployed contract...") + s, err := coordinator.GetSubscription(nil, subID) + helpers.PanicErr(err) + fmt.Printf("Subscription %+v\n", s) + + formattedVrfPrimaryJobSpec := fmt.Sprintf( + jobs.VRFJobFormatted, + contractAddresses.CoordinatorAddress, //coordinatorAddress + contractAddresses.BatchCoordinatorAddress, //batchCoordinatorAddress + batchFulfillmentEnabled, //batchFulfillmentEnabled + compressedPkHex, //publicKey + *coordinatorConfig.MinConfs, //minIncomingConfirmations + e.ChainID, //evmChainID + strings.Join(mapToAddressArr(nodesMap[VRFPrimaryNodeName].SendingKeys), "\",\""), //fromAddresses + contractAddresses.CoordinatorAddress, + nodesMap[VRFPrimaryNodeName].SendingKeys[0].Address, + contractAddresses.CoordinatorAddress, + contractAddresses.CoordinatorAddress, + ) + + formattedVrfBackupJobSpec := fmt.Sprintf( + jobs.VRFJobFormatted, + contractAddresses.CoordinatorAddress, //coordinatorAddress + contractAddresses.BatchCoordinatorAddress, //batchCoordinatorAddress + batchFulfillmentEnabled, //batchFulfillmentEnabled + compressedPkHex, //publicKey + 100, //minIncomingConfirmations + e.ChainID, //evmChainID + strings.Join(mapToAddressArr(nodesMap[VRFBackupNodeName].SendingKeys), "\",\""), //fromAddresses + contractAddresses.CoordinatorAddress, + nodesMap[VRFPrimaryNodeName].SendingKeys[0], + contractAddresses.CoordinatorAddress, + contractAddresses.CoordinatorAddress, + ) + + formattedBHSJobSpec := fmt.Sprintf( + jobs.BHSJobFormatted, + contractAddresses.CoordinatorAddress, //coordinatorAddress + 30, //waitBlocks + 200, //lookbackBlocks + contractAddresses.BhsContractAddress, //bhs address + e.ChainID, //chain id + strings.Join(mapToAddressArr(nodesMap[BHSNodeName].SendingKeys), "\",\""), //sending addresses + ) + + formattedBHSBackupJobSpec := fmt.Sprintf( + jobs.BHSJobFormatted, + contractAddresses.CoordinatorAddress, //coordinatorAddress + 100, //waitBlocks + 200, //lookbackBlocks + contractAddresses.BhsContractAddress, //bhs adreess + e.ChainID, //chain id + strings.Join(mapToAddressArr(nodesMap[BHSBackupNodeName].SendingKeys), "\",\""), //sending addresses + ) + + formattedBHFJobSpec := fmt.Sprintf( + jobs.BHFJobFormatted, + contractAddresses.CoordinatorAddress, //coordinatorAddress + contractAddresses.BhsContractAddress, //bhs adreess + contractAddresses.BatchBHSAddress, //batchBHS + e.ChainID, //chain id + strings.Join(mapToAddressArr(nodesMap[BHFNodeName].SendingKeys), "\",\""), //sending addresses + ) + + fmt.Println( + "\nDeployment complete.", + "\nLINK Token contract address:", contractAddresses.LinkAddress, + "\nLINK/ETH Feed contract address:", contractAddresses.LinkEthAddress, + "\nBlockhash Store contract address:", contractAddresses.BhsContractAddress, + "\nBatch Blockhash Store contract address:", contractAddresses.BatchBHSAddress, + "\nVRF Coordinator Address:", contractAddresses.CoordinatorAddress, + "\nBatch VRF Coordinator Address:", contractAddresses.BatchCoordinatorAddress, + "\nVRF Consumer Address:", consumerAddress, + "\nVRF Subscription Id:", subID, + "\nVRF Subscription Balance:", *subscriptionBalanceJuels, + "\nPossible VRF Request command: ", + fmt.Sprintf("go run . eoa-load-test-request-with-metrics --consumer-address=%s --sub-id=%d --key-hash=%s --request-confirmations %d --requests 1 --runs 1 --cb-gas-limit 1_000_000", consumerAddress, subID, keyHash, *coordinatorConfig.MinConfs), + "\nRetrieve Request Status: ", + fmt.Sprintf("go run . eoa-load-test-read-metrics --consumer-address=%s", consumerAddress), + "\nA node can now be configured to run a VRF job with the below job spec :\n", + formattedVrfPrimaryJobSpec, + ) + + return JobSpecs{ + VRFPrimaryNode: formattedVrfPrimaryJobSpec, + VRFBackupyNode: formattedVrfBackupJobSpec, + BHSNode: formattedBHSJobSpec, + BHSBackupNode: formattedBHSBackupJobSpec, + BHFNode: formattedBHFJobSpec, + } +} + +func mapToAddressArr(sendingKeys []SendingKey) []string { + var sendingKeysString []string + for _, sendingKey := range sendingKeys { + sendingKeysString = append(sendingKeysString, sendingKey.Address) + } + return sendingKeysString +} + +func DeployWrapperUniverse(e helpers.Environment) { + cmd := flag.NewFlagSet("wrapper-universe-deploy", flag.ExitOnError) + linkAddress := cmd.String("link-address", "", "address of link token") + linkETHFeedAddress := cmd.String("link-eth-feed", "", "address of link-eth-feed") + coordinatorAddress := cmd.String("coordinator-address", "", "address of the vrf coordinator v2 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") + wrapperPremiumPercentage := cmd.Uint("wrapper-premium-percentage", 25, "gas premium charged by wrapper") + keyHash := cmd.String("key-hash", "", "the keyhash that wrapper requests should use") + maxNumWords := cmd.Uint("max-num-words", 10, "the keyhash that wrapper requests should use") + subFunding := cmd.String("sub-funding", "10000000000000000000", "amount to fund the subscription with") + consumerFunding := cmd.String("consumer-funding", "10000000000000000000", "amount to fund the consumer with") + helpers.ParseArgs(cmd, os.Args[2:], "link-address", "link-eth-feed", "coordinator-address", "key-hash") + + amount, s := big.NewInt(0).SetString(*subFunding, 10) + if !s { + panic(fmt.Sprintf("failed to parse top up amount '%s'", *subFunding)) + } + + wrapper, subID := WrapperDeploy(e, + common.HexToAddress(*linkAddress), + common.HexToAddress(*linkETHFeedAddress), + common.HexToAddress(*coordinatorAddress)) + + WrapperConfigure(e, + wrapper, + *wrapperGasOverhead, + *coordinatorGasOverhead, + *wrapperPremiumPercentage, + *keyHash, + *maxNumWords) + + consumer := WrapperConsumerDeploy(e, + common.HexToAddress(*linkAddress), + wrapper) + + coordinator, err := vrf_coordinator_v2.NewVRFCoordinatorV2(common.HexToAddress(*coordinatorAddress), e.Ec) + helpers.PanicErr(err) + + EoaFundSubscription(e, *coordinator, *linkAddress, amount, subID) + + link, err := link_token_interface.NewLinkToken(common.HexToAddress(*linkAddress), e.Ec) + helpers.PanicErr(err) + consumerAmount, s := big.NewInt(0).SetString(*consumerFunding, 10) + if !s { + panic(fmt.Sprintf("failed to parse top up amount '%s'", *consumerFunding)) + } + + tx, err := link.Transfer(e.Owner, consumer, consumerAmount) + helpers.PanicErr(err) + helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID, "link transfer to consumer") + + fmt.Println("wrapper universe deployment complete") + fmt.Println("wrapper address:", wrapper.String()) + fmt.Println("wrapper consumer address:", consumer.String()) +} diff --git a/core/scripts/vrfv2/testnet/util.go b/core/scripts/vrfv2/testnet/scripts/util.go similarity index 85% rename from core/scripts/vrfv2/testnet/util.go rename to core/scripts/vrfv2/testnet/scripts/util.go index a72eaf8d5a2..3b429837c93 100644 --- a/core/scripts/vrfv2/testnet/util.go +++ b/core/scripts/vrfv2/testnet/scripts/util.go @@ -1,9 +1,10 @@ -package main +package scripts import ( "context" "encoding/hex" "fmt" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_load_test_with_metrics" "math/big" "github.com/ethereum/go-ethereum/common" @@ -21,19 +22,19 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/utils" ) -func deployBHS(e helpers.Environment) (blockhashStoreAddress common.Address) { +func DeployBHS(e helpers.Environment) (blockhashStoreAddress common.Address) { _, tx, _, err := blockhash_store.DeployBlockhashStore(e.Owner, e.Ec) helpers.PanicErr(err) return helpers.ConfirmContractDeployed(context.Background(), e.Ec, tx, e.ChainID) } -func deployBatchBHS(e helpers.Environment, bhsAddress common.Address) (batchBHSAddress common.Address) { +func DeployBatchBHS(e helpers.Environment, bhsAddress common.Address) (batchBHSAddress common.Address) { _, tx, _, err := batch_blockhash_store.DeployBatchBlockhashStore(e.Owner, e.Ec, bhsAddress) helpers.PanicErr(err) return helpers.ConfirmContractDeployed(context.Background(), e.Ec, tx, e.ChainID) } -func deployCoordinator( +func DeployCoordinator( e helpers.Environment, linkAddress string, bhsAddress string, @@ -55,19 +56,19 @@ func deployBatchCoordinatorV2(e helpers.Environment, coordinatorAddress common.A return helpers.ConfirmContractDeployed(context.Background(), e.Ec, tx, e.ChainID) } -func eoaAddConsumerToSub(e helpers.Environment, coordinator vrf_coordinator_v2.VRFCoordinatorV2, subID uint64, consumerAddress string) { +func EoaAddConsumerToSub(e helpers.Environment, coordinator vrf_coordinator_v2.VRFCoordinatorV2, subID uint64, consumerAddress string) { txadd, err := coordinator.AddConsumer(e.Owner, subID, common.HexToAddress(consumerAddress)) helpers.PanicErr(err) helpers.ConfirmTXMined(context.Background(), e.Ec, txadd, e.ChainID) } -func eoaCreateSub(e helpers.Environment, coordinator vrf_coordinator_v2.VRFCoordinatorV2) { +func EoaCreateSub(e helpers.Environment, coordinator vrf_coordinator_v2.VRFCoordinatorV2) { tx, err := coordinator.CreateSubscription(e.Owner) helpers.PanicErr(err) helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID) } -func eoaDeployConsumer(e helpers.Environment, coordinatorAddress string, linkAddress string) (consumerAddress common.Address) { +func EoaDeployConsumer(e helpers.Environment, coordinatorAddress string, linkAddress string) (consumerAddress common.Address) { _, tx, _, err := vrf_external_sub_owner_example.DeployVRFExternalSubOwnerExample( e.Owner, e.Ec, @@ -77,7 +78,7 @@ func eoaDeployConsumer(e helpers.Environment, coordinatorAddress string, linkAdd return helpers.ConfirmContractDeployed(context.Background(), e.Ec, tx, e.ChainID) } -func eoaFundSubscription(e helpers.Environment, coordinator vrf_coordinator_v2.VRFCoordinatorV2, linkAddress string, amount *big.Int, subID uint64) { +func EoaFundSubscription(e helpers.Environment, coordinator vrf_coordinator_v2.VRFCoordinatorV2, linkAddress string, amount *big.Int, subID uint64) { linkToken, err := link_token_interface.NewLinkToken(common.HexToAddress(linkAddress), e.Ec) helpers.PanicErr(err) bal, err := linkToken.BalanceOf(nil, e.Owner.From) @@ -91,7 +92,7 @@ func eoaFundSubscription(e helpers.Environment, coordinator vrf_coordinator_v2.V helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID, fmt.Sprintf("sub ID: %d", subID)) } -func printCoordinatorConfig(coordinator *vrf_coordinator_v2.VRFCoordinatorV2) { +func PrintCoordinatorConfig(coordinator *vrf_coordinator_v2.VRFCoordinatorV2) { cfg, err := coordinator.GetConfig(nil) helpers.PanicErr(err) @@ -102,7 +103,7 @@ func printCoordinatorConfig(coordinator *vrf_coordinator_v2.VRFCoordinatorV2) { fmt.Printf("Coordinator fee config: %+v\n", feeConfig) } -func setCoordinatorConfig( +func SetCoordinatorConfig( e helpers.Environment, coordinator vrf_coordinator_v2.VRFCoordinatorV2, minConfs uint16, @@ -125,7 +126,7 @@ func setCoordinatorConfig( helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID) } -func registerCoordinatorProvingKey(e helpers.Environment, coordinator vrf_coordinator_v2.VRFCoordinatorV2, uncompressed string, oracleAddress string) { +func RegisterCoordinatorProvingKey(e helpers.Environment, coordinator vrf_coordinator_v2.VRFCoordinatorV2, uncompressed string, oracleAddress string) { pubBytes, err := hex.DecodeString(uncompressed) helpers.PanicErr(err) pk, err := crypto.UnmarshalPubkey(pubBytes) @@ -144,7 +145,7 @@ func registerCoordinatorProvingKey(e helpers.Environment, coordinator vrf_coordi ) } -func wrapperDeploy( +func WrapperDeploy( e helpers.Environment, link, linkEthFeed, coordinator common.Address, ) (common.Address, uint64) { @@ -167,7 +168,7 @@ func wrapperDeploy( return address, subID } -func wrapperConfigure( +func WrapperConfigure( e helpers.Environment, wrapperAddress common.Address, wrapperGasOverhead, coordinatorGasOverhead, premiumPercentage uint, @@ -188,7 +189,7 @@ func wrapperConfigure( helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID) } -func wrapperConsumerDeploy( +func WrapperConsumerDeploy( e helpers.Environment, link, wrapper common.Address, ) common.Address { @@ -201,3 +202,13 @@ func wrapperConsumerDeploy( fmt.Printf("VRFV2WrapperConsumerExample address: %s\n", address) return address } + +func EoaLoadTestConsumerWithMetricsDeploy(e helpers.Environment, consumerCoordinator string) (consumerAddress common.Address) { + _, tx, _, err := vrf_load_test_with_metrics.DeployVRFV2LoadTestWithMetrics( + e.Owner, + e.Ec, + common.HexToAddress(consumerCoordinator), + ) + helpers.PanicErr(err) + return helpers.ConfirmContractDeployed(context.Background(), e.Ec, tx, e.ChainID) +} diff --git a/core/scripts/vrfv2/testnet/setup-envs/README.md b/core/scripts/vrfv2/testnet/setup-envs/README.md new file mode 100644 index 00000000000..ed045003fba --- /dev/null +++ b/core/scripts/vrfv2/testnet/setup-envs/README.md @@ -0,0 +1,46 @@ +## NOTE: +* Script will delete all existing jobs on the node! +* Currently works only with 0 or 1 VRF Keys on the node! Otherwise, will stop execution! +* Currently possible to fund all nodes with one amount of native tokens +## Commands: +1. If using Docker Compose + 1. create `.env` file in `core/scripts/vrfv2/testnet/docker` (can use `sample.env` file as an example) + 2. go to `core/scripts/vrfv2/testnet/docker` folder and start containers - `docker compose up` +2. Update [rpc-nodes.toml](..%2Fdocker%2Ftoml-config%2Frpc-nodes.toml) with relevant RPC nodes +3. Create files with credentials desirably outside `chainlink` repo (just not to push creds accidentally). Populate the files with relevant credentials for the nodes +4. Ensure that following env variables are set +``` +export ETH_URL= +export ETH_CHAIN_ID= +export ACCOUNT_KEY= +``` +5. execute from `core/scripts/vrfv2/testnet/setup-envs` folder +``` +go run . \ +--vrf-primary-node-url=http://localhost:6610 \ +--vrf-primary-creds-file \ +--vrf-backup-node-url=http://localhost:6611 \ +--vrf-bk-creds-file \ +--bhs-node-url=http://localhost:6612 \ +--bhs-creds-file \ +--bhs-backup-node-url=http://localhost:6613 \ +--bhs-bk-creds-file \ +--bhf-node-url=http://localhost:6614 \ +--bhf-creds-file \ +--batch-fulfillment-enabled true \ +--min-confs 1 \ +--num-eth-keys 5 \ +--num-vrf-keys 1 \ +--sending-key-funding-amount 100000000000000000 + +``` + +Optional parameters - will not be deployed if specified (NOT WORKING YET) +``` + --link-address
\ + --link-eth-feed
\ + --bhs-address
\ + --batch-bhs-address
\ + --coordinator-address
\ + --batch-coordinator-address
+``` \ No newline at end of file diff --git a/core/scripts/vrfv2/testnet/setup-envs/main.go b/core/scripts/vrfv2/testnet/setup-envs/main.go new file mode 100644 index 00000000000..1196108b32f --- /dev/null +++ b/core/scripts/vrfv2/testnet/setup-envs/main.go @@ -0,0 +1,470 @@ +package main + +import ( + "bytes" + "encoding/json" + "flag" + "fmt" + "github.com/ethereum/go-ethereum/common" + helpers "github.com/smartcontractkit/chainlink/core/scripts/common" + "github.com/smartcontractkit/chainlink/core/scripts/vrfv2/testnet/constants" + "github.com/smartcontractkit/chainlink/core/scripts/vrfv2/testnet/scripts" + clcmd "github.com/smartcontractkit/chainlink/v2/core/cmd" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2" + "github.com/smartcontractkit/chainlink/v2/core/web/presenters" + "github.com/urfave/cli" + "io" + "math/big" + "os" + "strings" +) + +func newApp(remoteNodeURL string, writer io.Writer) (*clcmd.Shell, *cli.App) { + prompter := clcmd.NewTerminalPrompter() + client := &clcmd.Shell{ + Renderer: clcmd.RendererJSON{Writer: writer}, + AppFactory: clcmd.ChainlinkAppFactory{}, + KeyStoreAuthenticator: clcmd.TerminalKeyStoreAuthenticator{Prompter: prompter}, + FallbackAPIInitializer: clcmd.NewPromptingAPIInitializer(prompter), + Runner: clcmd.ChainlinkRunner{}, + PromptingSessionRequestBuilder: clcmd.NewPromptingSessionRequestBuilder(prompter), + ChangePasswordPrompter: clcmd.NewChangePasswordPrompter(), + PasswordPrompter: clcmd.NewPasswordPrompter(), + } + app := clcmd.NewApp(client) + fs := flag.NewFlagSet("blah", flag.ContinueOnError) + fs.Bool("json", true, "") + fs.String("remote-node-url", remoteNodeURL, "") + helpers.PanicErr(app.Before(cli.NewContext(nil, fs, nil))) + // overwrite renderer since it's set to stdout after Before() is called + client.Renderer = clcmd.RendererJSON{Writer: writer} + return client, app +} + +var ( + checkMarkEmoji = "✅" + xEmoji = "❌" + infoEmoji = "ℹ️" +) + +func main() { + + vrfPrimaryNodeURL := flag.String("vrf-primary-node-url", "", "remote node URL") + vrfBackupNodeURL := flag.String("vrf-backup-node-url", "", "remote node URL") + bhsNodeURL := flag.String("bhs-node-url", "", "remote node URL") + bhsBackupNodeURL := flag.String("bhs-backup-node-url", "", "remote node URL") + bhfNodeURL := flag.String("bhf-node-url", "", "remote node URL") + nodeSendingKeyFundingAmount := flag.Int64("sending-key-funding-amount", constants.NodeSendingKeyFundingAmountGwei, "remote node URL") + + vrfPrimaryCredsFile := flag.String("vrf-primary-creds-file", "", "Creds to authenticate to the node") + vrfBackupCredsFile := flag.String("vrf-bk-creds-file", "", "Creds to authenticate to the node") + bhsCredsFile := flag.String("bhs-creds-file", "", "Creds to authenticate to the node") + bhsBackupCredsFile := flag.String("bhs-bk-creds-file", "", "Creds to authenticate to the node") + bhfCredsFile := flag.String("bhf-creds-file", "", "Creds to authenticate to the node") + + numEthKeys := flag.Int("num-eth-keys", 5, "Number of eth keys to create") + maxGasPriceGwei := flag.Int("max-gas-price-gwei", -1, "Max gas price gwei of the eth keys") + numVRFKeys := flag.Int("num-vrf-keys", 1, "Number of vrf keys to create") + + batchFulfillmentEnabled := flag.Bool("batch-fulfillment-enabled", constants.BatchFulfillmentEnabled, "whether to enable batch fulfillment on Cl node") + minConfs := flag.Int("min-confs", constants.MinConfs, "minimum confirmations") + + linkAddress := flag.String("link-address", "", "address of link token") + linkEthAddress := flag.String("link-eth-feed", "", "address of link eth feed") + bhsContractAddressString := flag.String("bhs-address", "", "address of BHS contract") + batchBHSAddressString := flag.String("batch-bhs-address", "", "address of Batch BHS contract") + coordinatorAddressString := flag.String("coordinator-address", "", "address of VRF Coordinator contract") + batchCoordinatorAddressString := flag.String("batch-coordinator-address", "", "address Batch VRF Coordinator contract") + + e := helpers.SetupEnv(false) + flag.Parse() + nodesMap := make(map[string]scripts.Node) + + if *vrfPrimaryNodeURL != "" { + nodesMap[scripts.VRFPrimaryNodeName] = scripts.Node{ + URL: *vrfPrimaryNodeURL, + SendingKeyFundingAmount: *big.NewInt(*nodeSendingKeyFundingAmount), + CredsFile: *vrfPrimaryCredsFile, + } + } + if *vrfBackupNodeURL != "" { + nodesMap[scripts.VRFBackupNodeName] = scripts.Node{ + URL: *vrfBackupNodeURL, + SendingKeyFundingAmount: *big.NewInt(*nodeSendingKeyFundingAmount), + CredsFile: *vrfBackupCredsFile, + } + } + if *bhsNodeURL != "" { + nodesMap[scripts.BHSNodeName] = scripts.Node{ + URL: *bhsNodeURL, + SendingKeyFundingAmount: *big.NewInt(*nodeSendingKeyFundingAmount), + CredsFile: *bhsCredsFile, + } + } + if *bhsBackupNodeURL != "" { + nodesMap[scripts.BHSBackupNodeName] = scripts.Node{ + URL: *bhsBackupNodeURL, + SendingKeyFundingAmount: *big.NewInt(*nodeSendingKeyFundingAmount), + CredsFile: *bhsBackupCredsFile, + } + } + + if *bhfNodeURL != "" { + nodesMap[scripts.BHFNodeName] = scripts.Node{ + URL: *bhfNodeURL, + SendingKeyFundingAmount: *big.NewInt(*nodeSendingKeyFundingAmount), + CredsFile: *bhfCredsFile, + } + } + + output := &bytes.Buffer{} + for key, node := range nodesMap { + + client, app := connectToNode(&node.URL, output, node.CredsFile) + ethKeys := createETHKeysIfNeeded(client, app, output, numEthKeys, &node.URL, maxGasPriceGwei) + if key == scripts.VRFPrimaryNodeName { + vrfKeys := createVRFKeyIfNeeded(client, app, output, numVRFKeys, &node.URL) + node.VrfKeys = mapVrfKeysToStringArr(vrfKeys) + printVRFKeyData(vrfKeys) + exportVRFKey(client, app, vrfKeys[0], output) + } + + if key == scripts.VRFBackupNodeName { + vrfKeys := getVRFKeys(client, app, output) + node.VrfKeys = mapVrfKeysToStringArr(vrfKeys) + } + + node.SendingKeys = mapEthKeysToSendingKeyArr(ethKeys) + printETHKeyData(ethKeys) + fundNodesIfNeeded(node, key, e) + nodesMap[key] = node + } + importVRFKeyToNodeIfSet(vrfBackupNodeURL, nodesMap, output, nodesMap[scripts.VRFBackupNodeName].CredsFile) + fmt.Println() + feeConfig := vrf_coordinator_v2.VRFCoordinatorV2FeeConfig{ + FulfillmentFlatFeeLinkPPMTier1: uint32(constants.FlatFeeTier1), + FulfillmentFlatFeeLinkPPMTier2: uint32(constants.FlatFeeTier2), + FulfillmentFlatFeeLinkPPMTier3: uint32(constants.FlatFeeTier3), + FulfillmentFlatFeeLinkPPMTier4: uint32(constants.FlatFeeTier4), + FulfillmentFlatFeeLinkPPMTier5: uint32(constants.FlatFeeTier5), + ReqsForTier2: big.NewInt(constants.ReqsForTier2), + ReqsForTier3: big.NewInt(constants.ReqsForTier3), + ReqsForTier4: big.NewInt(constants.ReqsForTier4), + ReqsForTier5: big.NewInt(constants.ReqsForTier5), + } + + contractAddresses := scripts.ContractAddresses{ + LinkAddress: *linkAddress, + LinkEthAddress: *linkEthAddress, + BhsContractAddress: common.HexToAddress(*bhsContractAddressString), + BatchBHSAddress: common.HexToAddress(*batchBHSAddressString), + CoordinatorAddress: common.HexToAddress(*coordinatorAddressString), + BatchCoordinatorAddress: common.HexToAddress(*batchCoordinatorAddressString), + } + + coordinatorConfig := scripts.CoordinatorConfig{ + MinConfs: minConfs, + MaxGasLimit: &constants.MaxGasLimit, + StalenessSeconds: &constants.StalenessSeconds, + GasAfterPayment: &constants.GasAfterPayment, + FallbackWeiPerUnitLink: constants.FallbackWeiPerUnitLink, + FeeConfig: feeConfig, + } + + jobSpecs := scripts.VRFV2DeployUniverse( + e, + constants.SubscriptionBalanceJuels, + &nodesMap[scripts.VRFPrimaryNodeName].VrfKeys[0], + contractAddresses, + coordinatorConfig, + *batchFulfillmentEnabled, + nodesMap, + ) + + for key, node := range nodesMap { + client, app := connectToNode(&node.URL, output, node.CredsFile) + + //GET ALL JOBS + jobIDs := getAllJobIDs(client, app, output) + + //DELETE ALL EXISTING JOBS + for _, jobID := range jobIDs { + deleteJob(jobID, client, app, output) + } + //CREATE JOBS + switch key { + case scripts.VRFPrimaryNodeName: + createJob(jobSpecs.VRFPrimaryNode, client, app, output) + case scripts.VRFBackupNodeName: + createJob(jobSpecs.VRFBackupyNode, client, app, output) + case scripts.BHSNodeName: + createJob(jobSpecs.BHSNode, client, app, output) + case scripts.BHSBackupNodeName: + createJob(jobSpecs.BHSBackupNode, client, app, output) + case scripts.BHFNodeName: + createJob(jobSpecs.BHFNode, client, app, output) + } + } +} + +func fundNodesIfNeeded(node scripts.Node, key string, e helpers.Environment) { + if node.SendingKeyFundingAmount.Int64() > 0 { + fmt.Println("\nFunding", key, "Node's Sending Keys...") + for _, sendingKey := range node.SendingKeys { + fundingToSendWei := node.SendingKeyFundingAmount.Int64() - sendingKey.BalanceEth.Int64() + if fundingToSendWei > 0 { + helpers.FundNode(e, sendingKey.Address, big.NewInt(fundingToSendWei)) + } else { + fmt.Println("\nSkipping Funding", sendingKey.Address, "since it has", sendingKey.BalanceEth.Int64(), "wei") + } + } + } +} + +func importVRFKeyToNodeIfSet(vrfBackupNodeURL *string, nodes map[string]scripts.Node, output *bytes.Buffer, file string) { + if *vrfBackupNodeURL != "" { + vrfBackupNode := nodes[scripts.VRFBackupNodeName] + vrfPrimaryNode := nodes[scripts.VRFBackupNodeName] + + if len(vrfBackupNode.VrfKeys) == 0 || vrfPrimaryNode.VrfKeys[0] != vrfBackupNode.VrfKeys[0] { + client, app := connectToNode(&vrfBackupNode.URL, output, file) + importVRFKey(client, app, output) + + vrfKeys := getVRFKeys(client, app, output) + + vrfBackupNode.VrfKeys = mapVrfKeysToStringArr(vrfKeys) + if len(vrfBackupNode.VrfKeys) == 0 { + panic("VRF Key was not imported to VRF Backup Node") + } + printVRFKeyData(vrfKeys) + } + } +} + +func getVRFKeys(client *clcmd.Shell, app *cli.App, output *bytes.Buffer) []presenters.VRFKeyResource { + var vrfKeys []presenters.VRFKeyResource + + err := client.ListVRFKeys(&cli.Context{ + App: app, + }) + helpers.PanicErr(err) + helpers.PanicErr(json.Unmarshal(output.Bytes(), &vrfKeys)) + output.Reset() + return vrfKeys +} + +func createJob(jobSpec string, client *clcmd.Shell, app *cli.App, output *bytes.Buffer) { + if err := os.WriteFile("job-spec.toml", []byte(jobSpec), 0666); err != nil { + helpers.PanicErr(err) + } + job := presenters.JobResource{} + flagSet := flag.NewFlagSet("blah", flag.ExitOnError) + err := flagSet.Parse([]string{"./job-spec.toml"}) + helpers.PanicErr(err) + err = client.CreateJob(cli.NewContext(app, flagSet, nil)) + helpers.PanicErr(err) + helpers.PanicErr(json.Unmarshal(output.Bytes(), &job)) + output.Reset() +} + +func exportVRFKey(client *clcmd.Shell, app *cli.App, vrfKey presenters.VRFKeyResource, output *bytes.Buffer) { + if err := os.WriteFile("vrf-key-password.txt", []byte("twochains"), 0666); err != nil { + helpers.PanicErr(err) + } + flagSet := flag.NewFlagSet("blah", flag.ExitOnError) + flagSet.String("new-password", "./vrf-key-password.txt", "") + flagSet.String("output", "exportedvrf.json", "") + err := flagSet.Parse([]string{vrfKey.Compressed}) + helpers.PanicErr(err) + err = client.ExportVRFKey(cli.NewContext(app, flagSet, nil)) + helpers.PanicErr(err) + output.Reset() +} + +func importVRFKey(client *clcmd.Shell, app *cli.App, output *bytes.Buffer) { + if err := os.WriteFile("vrf-key-password.txt", []byte("twochains"), 0666); err != nil { + helpers.PanicErr(err) + } + flagSet := flag.NewFlagSet("blah", flag.ExitOnError) + flagSet.String("old-password", "./vrf-key-password.txt", "") + err := flagSet.Parse([]string{"exportedvrf.json"}) + helpers.PanicErr(err) + err = client.ImportVRFKey(cli.NewContext(app, flagSet, nil)) + helpers.PanicErr(err) + output.Reset() +} + +func deleteJob(jobID string, client *clcmd.Shell, app *cli.App, output *bytes.Buffer) { + flagSet := flag.NewFlagSet("blah", flag.ExitOnError) + err := flagSet.Parse([]string{jobID}) + helpers.PanicErr(err) + err = client.DeleteJob(cli.NewContext(app, flagSet, nil)) + helpers.PanicErr(err) + output.Reset() +} + +func getAllJobIDs(client *clcmd.Shell, app *cli.App, output *bytes.Buffer) []string { + flagSet := flag.NewFlagSet("blah", flag.ExitOnError) + err := client.ListJobs(cli.NewContext(app, flagSet, nil)) + helpers.PanicErr(err) + jobs := clcmd.JobPresenters{} + helpers.PanicErr(json.Unmarshal(output.Bytes(), &jobs)) + var jobIDs []string + for _, job := range jobs { + jobIDs = append(jobIDs, job.ID) + } + output.Reset() + return jobIDs +} + +func printETHKeyData(ethKeys []presenters.ETHKeyResource) { + fmt.Println("------------- NODE INFORMATION -------------") + for _, ethKey := range ethKeys { + fmt.Println("-----------ETH Key-----------") + fmt.Println("Address: ", ethKey.Address) + fmt.Println("MaxGasPriceWei: ", ethKey.MaxGasPriceWei) + fmt.Println("EthBalance: ", ethKey.EthBalance) + fmt.Println("NextNonce: ", ethKey.NextNonce) + fmt.Println("-----------------------------") + } +} + +func mapEthKeysToSendingKeyArr(ethKeys []presenters.ETHKeyResource) []scripts.SendingKey { + var sendingKeys []scripts.SendingKey + for _, ethKey := range ethKeys { + sendingKey := scripts.SendingKey{Address: ethKey.Address, BalanceEth: *ethKey.EthBalance.ToInt()} + sendingKeys = append(sendingKeys, sendingKey) + } + return sendingKeys +} + +func mapVrfKeysToStringArr(vrfKeys []presenters.VRFKeyResource) []string { + var vrfKeysString []string + for _, vrfKey := range vrfKeys { + vrfKeysString = append(vrfKeysString, vrfKey.Uncompressed) + } + return vrfKeysString +} + +func printVRFKeyData(vrfKeys []presenters.VRFKeyResource) { + fmt.Println("Number of VRF Keys on the node: ", len(vrfKeys)) + fmt.Println("------------- NODE INFORMATION -------------") + for _, vrfKey := range vrfKeys { + fmt.Println("-----------VRF Key-----------") + fmt.Println("Compressed: ", vrfKey.Compressed) + fmt.Println("Uncompressed: ", vrfKey.Uncompressed) + fmt.Println("Hash: ", vrfKey.Hash) + fmt.Println("-----------------------------") + } +} + +func connectToNode(nodeURL *string, output *bytes.Buffer, credFile string) (*clcmd.Shell, *cli.App) { + client, app := newApp(*nodeURL, output) + // login first to establish the session + fmt.Println("logging in to:", *nodeURL) + loginFs := flag.NewFlagSet("test", flag.ContinueOnError) + loginFs.String("file", credFile, "") + loginFs.Bool("bypass-version-check", true, "") + loginCtx := cli.NewContext(app, loginFs, nil) + err := client.RemoteLogin(loginCtx) + helpers.PanicErr(err) + output.Reset() + fmt.Println() + return client, app +} + +func createVRFKeyIfNeeded(client *clcmd.Shell, app *cli.App, output *bytes.Buffer, numVRFKeys *int, nodeURL *string) []presenters.VRFKeyResource { + var allVRFKeys []presenters.VRFKeyResource + var newKeys []presenters.VRFKeyResource + + vrfKeys := getVRFKeys(client, app, output) + + switch { + case len(vrfKeys) == *numVRFKeys: + fmt.Println(checkMarkEmoji, "found", len(vrfKeys), "vrf keys on", *nodeURL) + case len(vrfKeys) > *numVRFKeys: + fmt.Println(xEmoji, "found", len(vrfKeys), "vrf keys on", nodeURL, " which is more than expected") + os.Exit(1) + default: + fmt.Println(xEmoji, "found only", len(vrfKeys), "vrf keys on", nodeURL, ", creating", + *numVRFKeys-len(vrfKeys), "more") + toCreate := *numVRFKeys - len(vrfKeys) + for i := 0; i < toCreate; i++ { + output.Reset() + newKey := createVRFKey(client, app, output) + newKeys = append(newKeys, newKey) + } + fmt.Println("NEW VRF KEYS:", strings.Join(func() (r []string) { + for _, k := range newKeys { + r = append(r, k.Uncompressed) + } + return + }(), ", ")) + } + fmt.Println() + for _, vrfKey := range vrfKeys { + allVRFKeys = append(allVRFKeys, vrfKey) + } + for _, nk := range newKeys { + allVRFKeys = append(allVRFKeys, nk) + } + return allVRFKeys +} + +func createVRFKey(client *clcmd.Shell, app *cli.App, output *bytes.Buffer) presenters.VRFKeyResource { + var newKey presenters.VRFKeyResource + err := client.CreateVRFKey( + cli.NewContext(app, flag.NewFlagSet("blah", flag.ExitOnError), nil)) + helpers.PanicErr(err) + helpers.PanicErr(json.Unmarshal(output.Bytes(), &newKey)) + output.Reset() + return newKey +} + +func createETHKeysIfNeeded(client *clcmd.Shell, app *cli.App, output *bytes.Buffer, numEthKeys *int, nodeURL *string, maxGasPriceGwei *int) []presenters.ETHKeyResource { + var allETHKeysNode []presenters.ETHKeyResource + var ethKeys []presenters.ETHKeyResource + var newKeys []presenters.ETHKeyResource + // check for ETH keys + err := client.ListETHKeys(&cli.Context{ + App: app, + }) + helpers.PanicErr(err) + helpers.PanicErr(json.Unmarshal(output.Bytes(), ðKeys)) + switch { + case len(ethKeys) >= *numEthKeys: + fmt.Println(checkMarkEmoji, "found", len(ethKeys), "eth keys on", *nodeURL) + case len(ethKeys) < *numEthKeys: + fmt.Println(xEmoji, "found only", len(ethKeys), "eth keys on", *nodeURL, + "; creating", *numEthKeys-len(ethKeys), "more") + toCreate := *numEthKeys - len(ethKeys) + for i := 0; i < toCreate; i++ { + output.Reset() + var newKey presenters.ETHKeyResource + + flagSet := flag.NewFlagSet("blah", flag.ExitOnError) + if *maxGasPriceGwei > 0 { + helpers.PanicErr(flagSet.Set("max-gas-price-gwei", fmt.Sprintf("%d", *maxGasPriceGwei))) + } + err = client.CreateETHKey(cli.NewContext(app, flagSet, nil)) + helpers.PanicErr(err) + helpers.PanicErr(json.Unmarshal(output.Bytes(), &newKey)) + newKeys = append(newKeys, newKey) + } + fmt.Println("NEW ETH KEYS:", strings.Join(func() (r []string) { + for _, k := range newKeys { + r = append(r, k.Address) + } + return + }(), ", ")) + } + output.Reset() + fmt.Println() + for _, ethKey := range ethKeys { + allETHKeysNode = append(allETHKeysNode, ethKey) + } + for _, nk := range newKeys { + allETHKeysNode = append(allETHKeysNode, nk) + } + return allETHKeysNode +} diff --git a/core/scripts/vrfv2/testnet/super_scripts.go b/core/scripts/vrfv2/testnet/super_scripts.go deleted file mode 100644 index 977be9380d3..00000000000 --- a/core/scripts/vrfv2/testnet/super_scripts.go +++ /dev/null @@ -1,297 +0,0 @@ -package main - -import ( - "context" - "encoding/hex" - "flag" - "fmt" - "math/big" - "os" - "strings" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto" - "github.com/shopspring/decimal" - - helpers "github.com/smartcontractkit/chainlink/core/scripts/common" - "github.com/smartcontractkit/chainlink/v2/core/assets" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2" - "github.com/smartcontractkit/chainlink/v2/core/services/signatures/secp256k1" -) - -const formattedVRFJob = ` -type = "vrf" -name = "vrf_v2" -schemaVersion = 1 -coordinatorAddress = "%s" -batchCoordinatorAddress = "%s" -batchFulfillmentEnabled = %t -batchFulfillmentGasMultiplier = 1.1 -publicKey = "%s" -minIncomingConfirmations = 3 -evmChainID = "%d" -fromAddresses = ["%s"] -pollPeriod = "5s" -requestTimeout = "24h" -observationSource = """decode_log [type=ethabidecodelog - abi="RandomWordsRequested(bytes32 indexed keyHash,uint256 requestId,uint256 preSeed,uint64 indexed subId,uint16 minimumRequestConfirmations,uint32 callbackGasLimit,uint32 numWords,address indexed sender)" - data="$(jobRun.logData)" - topics="$(jobRun.logTopics)"] -vrf [type=vrfv2 - publicKey="$(jobSpec.publicKey)" - requestBlockHash="$(jobRun.logBlockHash)" - requestBlockNumber="$(jobRun.logBlockNumber)" - topics="$(jobRun.logTopics)"] -estimate_gas [type=estimategaslimit - to="%s" - multiplier="1.1" - data="$(vrf.output)"] -simulate [type=ethcall - to="%s" - gas="$(estimate_gas)" - gasPrice="$(jobSpec.maxGasPrice)" - extractRevertReason=true - contract="%s" - data="$(vrf.output)"] -decode_log->vrf->estimate_gas->simulate -""" -` - -func deployUniverse(e helpers.Environment) { - deployCmd := flag.NewFlagSet("deploy-universe", flag.ExitOnError) - - // required flags - linkAddress := deployCmd.String("link-address", "", "address of link token") - linkEthAddress := deployCmd.String("link-eth-feed", "", "address of link eth feed") - subscriptionBalanceString := deployCmd.String("subscription-balance", "1e19", "amount to fund subscription") - - // optional flags - fallbackWeiPerUnitLinkString := deployCmd.String("fallback-wei-per-unit-link", "6e16", "fallback wei/link ratio") - registerKeyUncompressedPubKey := deployCmd.String("uncompressed-pub-key", "", "uncompressed public key") - registerKeyOracleAddress := deployCmd.String("oracle-address", "", "oracle sender address") - minConfs := deployCmd.Int("min-confs", 3, "min confs") - oracleFundingAmount := deployCmd.Int64("oracle-funding-amount", assets.GWei(100_000_000).Int64(), "amount to fund sending oracle") - maxGasLimit := deployCmd.Int64("max-gas-limit", 2.5e6, "max gas limit") - stalenessSeconds := deployCmd.Int64("staleness-seconds", 86400, "staleness in seconds") - gasAfterPayment := deployCmd.Int64("gas-after-payment", 33285, "gas after payment calculation") - flatFeeTier1 := deployCmd.Int64("flat-fee-tier-1", 500, "flat fee tier 1") - flatFeeTier2 := deployCmd.Int64("flat-fee-tier-2", 500, "flat fee tier 2") - flatFeeTier3 := deployCmd.Int64("flat-fee-tier-3", 500, "flat fee tier 3") - flatFeeTier4 := deployCmd.Int64("flat-fee-tier-4", 500, "flat fee tier 4") - flatFeeTier5 := deployCmd.Int64("flat-fee-tier-5", 500, "flat fee tier 5") - reqsForTier2 := deployCmd.Int64("reqs-for-tier-2", 0, "requests for tier 2") - reqsForTier3 := deployCmd.Int64("reqs-for-tier-3", 0, "requests for tier 3") - reqsForTier4 := deployCmd.Int64("reqs-for-tier-4", 0, "requests for tier 4") - reqsForTier5 := deployCmd.Int64("reqs-for-tier-5", 0, "requests for tier 5") - - helpers.ParseArgs( - deployCmd, os.Args[2:], - ) - - fallbackWeiPerUnitLink := decimal.RequireFromString(*fallbackWeiPerUnitLinkString).BigInt() - subscriptionBalance := decimal.RequireFromString(*subscriptionBalanceString).BigInt() - - // Put key in ECDSA format - if strings.HasPrefix(*registerKeyUncompressedPubKey, "0x") { - *registerKeyUncompressedPubKey = strings.Replace(*registerKeyUncompressedPubKey, "0x", "04", 1) - } - - // Generate compressed public key and key hash - pubBytes, err := hex.DecodeString(*registerKeyUncompressedPubKey) - helpers.PanicErr(err) - pk, err := crypto.UnmarshalPubkey(pubBytes) - helpers.PanicErr(err) - var pkBytes []byte - if big.NewInt(0).Mod(pk.Y, big.NewInt(2)).Uint64() != 0 { - pkBytes = append(pk.X.Bytes(), 1) - } else { - pkBytes = append(pk.X.Bytes(), 0) - } - var newPK secp256k1.PublicKey - copy(newPK[:], pkBytes) - - compressedPkHex := hexutil.Encode(pkBytes) - keyHash, err := newPK.Hash() - helpers.PanicErr(err) - - if len(*linkAddress) == 0 { - fmt.Println("\nDeploying LINK Token...") - address := helpers.DeployLinkToken(e).String() - linkAddress = &address - } - - if len(*linkEthAddress) == 0 { - fmt.Println("\nDeploying LINK/ETH Feed...") - address := helpers.DeployLinkEthFeed(e, *linkAddress, fallbackWeiPerUnitLink).String() - linkEthAddress = &address - } - - fmt.Println("\nDeploying BHS...") - bhsContractAddress := deployBHS(e) - - fmt.Println("\nDeploying Batch BHS...") - batchBHSAddress := deployBatchBHS(e, bhsContractAddress) - - var coordinatorAddress common.Address - fmt.Println("\nDeploying Coordinator...") - coordinatorAddress = deployCoordinator(e, *linkAddress, bhsContractAddress.String(), *linkEthAddress) - - coordinator, err := vrf_coordinator_v2.NewVRFCoordinatorV2(coordinatorAddress, e.Ec) - helpers.PanicErr(err) - - fmt.Println("\nDeploying Batch Coordinator...") - batchCoordinatorAddress := deployBatchCoordinatorV2(e, coordinatorAddress) - - fmt.Println("\nSetting Coordinator Config...") - setCoordinatorConfig( - e, - *coordinator, - uint16(*minConfs), - uint32(*maxGasLimit), - uint32(*stalenessSeconds), - uint32(*gasAfterPayment), - fallbackWeiPerUnitLink, - vrf_coordinator_v2.VRFCoordinatorV2FeeConfig{ - FulfillmentFlatFeeLinkPPMTier1: uint32(*flatFeeTier1), - FulfillmentFlatFeeLinkPPMTier2: uint32(*flatFeeTier2), - FulfillmentFlatFeeLinkPPMTier3: uint32(*flatFeeTier3), - FulfillmentFlatFeeLinkPPMTier4: uint32(*flatFeeTier4), - FulfillmentFlatFeeLinkPPMTier5: uint32(*flatFeeTier5), - ReqsForTier2: big.NewInt(*reqsForTier2), - ReqsForTier3: big.NewInt(*reqsForTier3), - ReqsForTier4: big.NewInt(*reqsForTier4), - ReqsForTier5: big.NewInt(*reqsForTier5), - }, - ) - - fmt.Println("\nConfig set, getting current config from deployed contract...") - printCoordinatorConfig(coordinator) - - if len(*registerKeyUncompressedPubKey) > 0 && len(*registerKeyOracleAddress) > 0 { - fmt.Println("\nRegistering proving key...") - registerCoordinatorProvingKey(e, *coordinator, *registerKeyUncompressedPubKey, *registerKeyOracleAddress) - - fmt.Println("\nProving key registered, getting proving key hashes from deployed contract...") - _, _, provingKeyHashes, configErr := coordinator.GetRequestConfig(nil) - helpers.PanicErr(configErr) - fmt.Println("Key hash registered:", hex.EncodeToString(provingKeyHashes[0][:])) - } else { - fmt.Println("NOT registering proving key - you must do this eventually in order to fully deploy VRF!") - } - - fmt.Println("\nDeploying consumer...") - consumerAddress := eoaDeployConsumer(e, coordinatorAddress.String(), *linkAddress) - - fmt.Println("\nAdding subscription...") - eoaCreateSub(e, *coordinator) - subID := uint64(1) - - fmt.Println("\nAdding consumer to subscription...") - eoaAddConsumerToSub(e, *coordinator, subID, consumerAddress.String()) - - if subscriptionBalance.Cmp(big.NewInt(0)) > 0 { - fmt.Println("\nFunding subscription with", subscriptionBalance, "juels...") - eoaFundSubscription(e, *coordinator, *linkAddress, subscriptionBalance, subID) - } else { - fmt.Println("Subscription", subID, "NOT getting funded. You must fund the subscription in order to use it!") - } - - fmt.Println("\nSubscribed and (possibly) funded, retrieving subscription from deployed contract...") - s, err := coordinator.GetSubscription(nil, subID) - helpers.PanicErr(err) - fmt.Printf("Subscription %+v\n", s) - - if len(*registerKeyOracleAddress) > 0 && *oracleFundingAmount > 0 { - fmt.Println("\nFunding oracle...") - helpers.FundNodes(e, []string{*registerKeyOracleAddress}, big.NewInt(*oracleFundingAmount)) - } - - formattedJobSpec := fmt.Sprintf( - formattedVRFJob, - coordinatorAddress, - batchCoordinatorAddress, - false, - compressedPkHex, - e.ChainID, - *registerKeyOracleAddress, - coordinatorAddress, - coordinatorAddress, - coordinatorAddress, - ) - - fmt.Println( - "\nDeployment complete.", - "\nLINK Token contract address:", *linkAddress, - "\nLINK/ETH Feed contract address:", *linkEthAddress, - "\nBlockhash Store contract address:", bhsContractAddress, - "\nBatch Blockhash Store contract address:", batchBHSAddress, - "\nVRF Coordinator Address:", coordinatorAddress, - "\nBatch VRF Coordinator Address:", batchCoordinatorAddress, - "\nVRF Consumer Address:", consumerAddress, - "\nVRF Subscription Id:", subID, - "\nVRF Subscription Balance:", *subscriptionBalanceString, - "\nPossible VRF Request command: ", - fmt.Sprintf("go run . eoa-request --consumer-address %s --sub-id %d --key-hash %s", consumerAddress, subID, keyHash), - "\nA node can now be configured to run a VRF job with the below job spec :\n", - formattedJobSpec, - ) -} - -func deployWrapperUniverse(e helpers.Environment) { - cmd := flag.NewFlagSet("wrapper-universe-deploy", flag.ExitOnError) - linkAddress := cmd.String("link-address", "", "address of link token") - linkETHFeedAddress := cmd.String("link-eth-feed", "", "address of link-eth-feed") - coordinatorAddress := cmd.String("coordinator-address", "", "address of the vrf coordinator v2 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") - wrapperPremiumPercentage := cmd.Uint("wrapper-premium-percentage", 25, "gas premium charged by wrapper") - keyHash := cmd.String("key-hash", "", "the keyhash that wrapper requests should use") - maxNumWords := cmd.Uint("max-num-words", 10, "the keyhash that wrapper requests should use") - subFunding := cmd.String("sub-funding", "10000000000000000000", "amount to fund the subscription with") - consumerFunding := cmd.String("consumer-funding", "10000000000000000000", "amount to fund the consumer with") - helpers.ParseArgs(cmd, os.Args[2:], "link-address", "link-eth-feed", "coordinator-address", "key-hash") - - amount, s := big.NewInt(0).SetString(*subFunding, 10) - if !s { - panic(fmt.Sprintf("failed to parse top up amount '%s'", *subFunding)) - } - - wrapper, subID := wrapperDeploy(e, - common.HexToAddress(*linkAddress), - common.HexToAddress(*linkETHFeedAddress), - common.HexToAddress(*coordinatorAddress)) - - wrapperConfigure(e, - wrapper, - *wrapperGasOverhead, - *coordinatorGasOverhead, - *wrapperPremiumPercentage, - *keyHash, - *maxNumWords) - - consumer := wrapperConsumerDeploy(e, - common.HexToAddress(*linkAddress), - wrapper) - - coordinator, err := vrf_coordinator_v2.NewVRFCoordinatorV2(common.HexToAddress(*coordinatorAddress), e.Ec) - helpers.PanicErr(err) - - eoaFundSubscription(e, *coordinator, *linkAddress, amount, subID) - - link, err := link_token_interface.NewLinkToken(common.HexToAddress(*linkAddress), e.Ec) - helpers.PanicErr(err) - consumerAmount, s := big.NewInt(0).SetString(*consumerFunding, 10) - if !s { - panic(fmt.Sprintf("failed to parse top up amount '%s'", *consumerFunding)) - } - - tx, err := link.Transfer(e.Owner, consumer, consumerAmount) - helpers.PanicErr(err) - helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID, "link transfer to consumer") - - fmt.Println("wrapper universe deployment complete") - fmt.Println("wrapper address:", wrapper.String()) - fmt.Println("wrapper consumer address:", consumer.String()) -} diff --git a/core/scripts/vrfv2plus/testnet/main.go b/core/scripts/vrfv2plus/testnet/main.go index 92804aeaa26..20e7ea92714 100644 --- a/core/scripts/vrfv2plus/testnet/main.go +++ b/core/scripts/vrfv2plus/testnet/main.go @@ -27,6 +27,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/batch_vrf_coordinator_v2plus" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/blockhash_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/trusted_blockhash_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_load_test_external_sub_owner" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_load_test_with_metrics" @@ -320,7 +321,7 @@ func main() { helpers.PanicErr(err) blockRange, err := blockhashstore.DecreasingBlockRange(big.NewInt(*startBlock-1), big.NewInt(*startBlock-*numBlocks-1)) helpers.PanicErr(err) - rlpHeaders, _, err := helpers.GetRlpHeaders(e, blockRange) + rlpHeaders, _, err := helpers.GetRlpHeaders(e, blockRange, true) helpers.PanicErr(err) tx, err := batchBHS.StoreVerifyHeader(e.Owner, blockRange, rlpHeaders) helpers.PanicErr(err) @@ -395,7 +396,7 @@ func main() { fmt.Println("using gas price", e.Owner.GasPrice, "wei") blockNumbers := blockRange[i:j] - blockHeaders, _, err := helpers.GetRlpHeaders(e, blockNumbers) + blockHeaders, _, err := helpers.GetRlpHeaders(e, blockNumbers, true) fmt.Println("storing blockNumbers:", blockNumbers) helpers.PanicErr(err) @@ -411,6 +412,49 @@ func main() { fmt.Println("received receipt, continuing") } fmt.Println("done") + case "trusted-bhs-store": + cmd := flag.NewFlagSet("trusted-bhs-backwards", flag.ExitOnError) + trustedBHSAddr := cmd.String("trusted-bhs-address", "", "address of the trusted bhs contract") + blockNumbersString := cmd.String("block-numbers", "", "comma-separated list of block numbers e.g 123,456 ") + batchSizePtr := cmd.Int64("batch-size", -1, "batch size") + helpers.ParseArgs(cmd, os.Args[2:], "trusted-bhs-address", "batch-size", "block-numbers") + + // Parse batch size. + batchSize := int(*batchSizePtr) + + // Parse block numbers. + blockNumbers := helpers.ParseBigIntSlice(*blockNumbersString) + + // Instantiate trusted bhs. + trustedBHS, err := trusted_blockhash_store.NewTrustedBlockhashStore(common.HexToAddress(*trustedBHSAddr), e.Ec) + helpers.PanicErr(err) + + for i := 0; i < len(blockNumbers); i += batchSize { + // Get recent blockhash and block number anew each iteration. We do this so they do not get stale. + recentBlockNumber, err := e.Ec.BlockNumber(context.Background()) + helpers.PanicErr(err) + recentBlock, err := e.Ec.HeaderByNumber(context.Background(), big.NewInt(int64(recentBlockNumber))) + helpers.PanicErr(err) + recentBlockhash := recentBlock.Hash() + + // Get blockhashes to store. + blockNumbersSlice := blockNumbers[i : i+batchSize] + _, blockhashesStrings, err := helpers.GetRlpHeaders(e, blockNumbersSlice, false) + helpers.PanicErr(err) + fmt.Println("storing blockNumbers:", blockNumbers) + var blockhashes [][32]byte + for _, h := range blockhashesStrings { + blockhashes = append(blockhashes, common.HexToHash(h)) + } + + // Execute storage tx. + tx, err := trustedBHS.StoreTrusted(e.Owner, blockNumbersSlice, blockhashes, big.NewInt(int64(recentBlockNumber)), recentBlockhash) + helpers.PanicErr(err) + fmt.Println("waiting for it to mine...") + helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID) + fmt.Println("received receipt, continuing") + } + fmt.Println("done") case "latest-head": h, err := e.Ec.HeaderByNumber(context.Background(), nil) helpers.PanicErr(err) diff --git a/core/scripts/vrfv2plus/testnet/super_scripts.go b/core/scripts/vrfv2plus/testnet/super_scripts.go index c91a46ab3e8..a617733cb19 100644 --- a/core/scripts/vrfv2plus/testnet/super_scripts.go +++ b/core/scripts/vrfv2plus/testnet/super_scripts.go @@ -19,7 +19,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus" "github.com/smartcontractkit/chainlink/v2/core/services/signatures/secp256k1" - v2 "github.com/smartcontractkit/chainlink/v2/core/services/vrf/v2" ) const formattedVRFJob = ` @@ -38,7 +37,7 @@ pollPeriod = "5s" requestTimeout = "24h" observationSource = """ decode_log [type=ethabidecodelog - abi="%s" + abi="RandomWordsRequested(bytes32 indexed keyHash,uint256 requestId,uint256 preSeed,uint256 indexed subId,uint16 minimumRequestConfirmations,uint32 callbackGasLimit,uint32 numWords,bytes extraArgs,address indexed sender)" data="$(jobRun.logData)" topics="$(jobRun.logTopics)"] generate_proof [type=vrfv2plus @@ -82,7 +81,7 @@ func deployUniverse(e helpers.Environment) { flatFeeEthPPM := deployCmd.Int64("flat-fee-eth-ppm", 500, "fulfillment flat fee ETH ppm") helpers.ParseArgs( - deployCmd, os.Args[2:], + deployCmd, os.Args[2:], "uncompressed-pub-key", "oracle-address", ) fallbackWeiPerUnitLink := decimal.RequireFromString(*fallbackWeiPerUnitLinkString).BigInt() @@ -206,7 +205,6 @@ func deployUniverse(e helpers.Environment) { compressedPkHex, e.ChainID, *registerKeyOracleAddress, - v2.RandomWordsRequestedV2PlusABI, coordinatorAddress, coordinatorAddress, coordinatorAddress, diff --git a/core/scripts/vrfv2plus/testnet/util.go b/core/scripts/vrfv2plus/testnet/util.go index da8f9d6824c..d002b8c03b4 100644 --- a/core/scripts/vrfv2plus/testnet/util.go +++ b/core/scripts/vrfv2plus/testnet/util.go @@ -51,13 +51,10 @@ func deployCoordinator( coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(coordinatorAddress, e.Ec) helpers.PanicErr(err) - linkTx, err := coordinator.SetLINK(e.Owner, common.HexToAddress(linkAddress)) + linkTx, err := coordinator.SetLINKAndLINKETHFeed(e.Owner, + common.HexToAddress(linkAddress), common.HexToAddress(linkEthAddress)) helpers.PanicErr(err) helpers.ConfirmTXMined(context.Background(), e.Ec, linkTx, e.ChainID) - - linkETHTx, err := coordinator.SetLinkEthFeed(e.Owner, common.HexToAddress(linkEthAddress)) - helpers.PanicErr(err) - helpers.ConfirmTXMined(context.Background(), e.Ec, linkETHTx, e.ChainID) return coordinatorAddress } diff --git a/core/services/blockhashstore/bhs.go b/core/services/blockhashstore/bhs.go index adc1cdb354d..70a9c77669c 100644 --- a/core/services/blockhashstore/bhs.go +++ b/core/services/blockhashstore/bhs.go @@ -17,6 +17,7 @@ import ( txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/blockhash_store" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/trusted_blockhash_store" "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" @@ -41,7 +42,9 @@ type BulletproofBHS struct { fromAddresses []ethkey.EIP55Address txm txmgr.TxManager abi *abi.ABI + trustedAbi *abi.ABI bhs blockhash_store.BlockhashStoreInterface + trustedBHS *trusted_blockhash_store.TrustedBlockhashStore chainID *big.Int gethks keystore.Eth } @@ -53,6 +56,7 @@ func NewBulletproofBHS( fromAddresses []ethkey.EIP55Address, txm txmgr.TxManager, bhs blockhash_store.BlockhashStoreInterface, + trustedBHS *trusted_blockhash_store.TrustedBlockhashStore, chainID *big.Int, gethks keystore.Eth, ) (*BulletproofBHS, error) { @@ -62,13 +66,20 @@ func NewBulletproofBHS( return nil, errors.Wrap(err, "building ABI") } + trustedBHSAbi, err := trusted_blockhash_store.TrustedBlockhashStoreMetaData.GetAbi() + if err != nil { + return nil, errors.Wrap(err, "building trusted BHS ABI") + } + return &BulletproofBHS{ config: config, dbConfig: dbConfig, fromAddresses: fromAddresses, txm: txm, abi: bhsABI, + trustedAbi: trustedBHSAbi, bhs: bhs, + trustedBHS: trustedBHS, chainID: chainID, gethks: gethks, }, nil @@ -103,9 +114,56 @@ func (c *BulletproofBHS) Store(ctx context.Context, blockNum uint64) error { return nil } +func (c *BulletproofBHS) StoreTrusted( + ctx context.Context, + blockNums []uint64, + blockhashes []common.Hash, + recentBlock uint64, + recentBlockhash common.Hash, +) error { + // Convert and pack arguments for a "storeTrusted" function call to the trusted BHS. + var blockNumsBig []*big.Int + for _, b := range blockNums { + blockNumsBig = append(blockNumsBig, new(big.Int).SetUint64(b)) + } + recentBlockBig := new(big.Int).SetUint64(recentBlock) + payload, err := c.trustedAbi.Pack("storeTrusted", blockNumsBig, blockhashes, recentBlockBig, recentBlockhash) + if err != nil { + return errors.Wrap(err, "packing args") + } + + // Create a transaction from the given batch and send it to the TXM. + fromAddress, err := c.gethks.GetRoundRobinAddress(c.chainID, SendingKeys(c.fromAddresses)...) + if err != nil { + return errors.Wrap(err, "getting next from address") + } + _, err = c.txm.CreateTransaction(txmgr.TxRequest{ + FromAddress: fromAddress, + ToAddress: c.trustedBHS.Address(), + EncodedPayload: payload, + FeeLimit: c.config.LimitDefault(), + + Strategy: txmgrcommon.NewSendEveryStrategy(), + }, pg.WithParentCtx(ctx)) + if err != nil { + return errors.Wrap(err, "creating transaction") + } + + return nil +} + +func (c *BulletproofBHS) IsTrusted() bool { + return c.trustedBHS != nil +} + // IsStored satisfies the BHS interface. func (c *BulletproofBHS) IsStored(ctx context.Context, blockNum uint64) (bool, error) { - _, err := c.bhs.GetBlockhash(&bind.CallOpts{Context: ctx}, big.NewInt(int64(blockNum))) + var err error + if c.IsTrusted() { + _, err = c.trustedBHS.GetBlockhash(&bind.CallOpts{Context: ctx}, big.NewInt(int64(blockNum))) + } else { + _, err = c.bhs.GetBlockhash(&bind.CallOpts{Context: ctx}, big.NewInt(int64(blockNum))) + } if err != nil && strings.Contains(err.Error(), "reverted") { // Transaction reverted because the blockhash is not stored return false, nil diff --git a/core/services/blockhashstore/bhs_test.go b/core/services/blockhashstore/bhs_test.go index 61332ecb0ab..d0e5ac71a7b 100644 --- a/core/services/blockhashstore/bhs_test.go +++ b/core/services/blockhashstore/bhs_test.go @@ -19,6 +19,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/blockhashstore" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -28,8 +29,10 @@ func TestStoreRotatesFromAddresses(t *testing.T) { cfg := configtest.NewTestGeneralConfig(t) kst := cltest.NewKeyStore(t, db, cfg.Database()) require.NoError(t, kst.Unlock(cltest.Password)) - chainSet := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, KeyStore: kst.Eth(), GeneralConfig: cfg, Client: ethClient}) - chain, err := chainSet.Get(&cltest.FixtureChainID) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, KeyStore: kst.Eth(), GeneralConfig: cfg, Client: ethClient}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + chain, err := legacyChains.Get(cltest.FixtureChainID.String()) require.NoError(t, err) lggr := logger.TestLogger(t) ks := keystore.New(db, utils.FastScryptParams, lggr, cfg.Database()) @@ -50,6 +53,7 @@ func TestStoreRotatesFromAddresses(t *testing.T) { fromAddresses, txm, store, + nil, &cltest.FixtureChainID, ks.Eth(), ) diff --git a/core/services/blockhashstore/common.go b/core/services/blockhashstore/common.go index f8c5b62b98d..61aaf989298 100644 --- a/core/services/blockhashstore/common.go +++ b/core/services/blockhashstore/common.go @@ -42,6 +42,10 @@ type BHS interface { // StoreEarliest stores the earliest possible blockhash (i.e. block.number - 256) StoreEarliest(ctx context.Context) error + + IsTrusted() bool + + StoreTrusted(ctx context.Context, blockNums []uint64, blockhashes []common.Hash, recentBlock uint64, recentBlockhash common.Hash) error } func GetUnfulfilledBlocksAndRequests( diff --git a/core/services/blockhashstore/delegate.go b/core/services/blockhashstore/delegate.go index d8d51327bcd..3c2c241a0b7 100644 --- a/core/services/blockhashstore/delegate.go +++ b/core/services/blockhashstore/delegate.go @@ -10,6 +10,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/blockhash_store" v1 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/solidity_vrf_coordinator_interface" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/trusted_blockhash_store" v2 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2" v2plus "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -24,21 +25,21 @@ var _ job.ServiceCtx = &service{} // Delegate creates BlockhashStore feeder jobs. type Delegate struct { - logger logger.Logger - chains evm.ChainSet - ks keystore.Eth + logger logger.Logger + legacyChains evm.LegacyChainContainer + ks keystore.Eth } // NewDelegate creates a new Delegate. func NewDelegate( logger logger.Logger, - chains evm.ChainSet, + legacyChains evm.LegacyChainContainer, ks keystore.Eth, ) *Delegate { return &Delegate{ - logger: logger, - chains: chains, - ks: ks, + logger: logger, + legacyChains: legacyChains, + ks: ks, } } @@ -48,13 +49,13 @@ func (d *Delegate) JobType() job.Type { } // ServicesForSpec satisfies the job.Delegate interface. -func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { +func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceCtx, error) { if jb.BlockhashStoreSpec == nil { return nil, errors.Errorf( "blockhashstore.Delegate expects a BlockhashStoreSpec to be present, got %+v", jb) } - chain, err := d.chains.Get(jb.BlockhashStoreSpec.EVMChainID.ToInt()) + chain, err := d.legacyChains.Get(jb.BlockhashStoreSpec.EVMChainID.String()) if err != nil { return nil, fmt.Errorf( "getting chain ID %d: %w", jb.BlockhashStoreSpec.EVMChainID.ToInt(), err) @@ -88,6 +89,17 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { return nil, errors.Wrap(err, "building BHS") } + var trustedBHS *trusted_blockhash_store.TrustedBlockhashStore + if jb.BlockhashStoreSpec.TrustedBlockhashStoreAddress != nil && jb.BlockhashStoreSpec.TrustedBlockhashStoreAddress.Hex() != EmptyAddress { + trustedBHS, err = trusted_blockhash_store.NewTrustedBlockhashStore( + jb.BlockhashStoreSpec.TrustedBlockhashStoreAddress.Address(), + chain.Client(), + ) + if err != nil { + return nil, errors.Wrap(err, "building trusted BHS") + } + } + lp := chain.LogPoller() var coordinators []Coordinator if jb.BlockhashStoreSpec.CoordinatorV1Address != nil { @@ -136,7 +148,16 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { coordinators = append(coordinators, coord) } - bpBHS, err := NewBulletproofBHS(chain.Config().EVM().GasEstimator(), chain.Config().Database(), fromAddresses, chain.TxManager(), bhs, chain.ID(), d.ks) + bpBHS, err := NewBulletproofBHS( + chain.Config().EVM().GasEstimator(), + chain.Config().Database(), + fromAddresses, + chain.TxManager(), + bhs, + trustedBHS, + chain.ID(), + d.ks, + ) if err != nil { return nil, errors.Wrap(err, "building bulletproof bhs") } @@ -146,14 +167,16 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { log, NewMultiCoordinator(coordinators...), bpBHS, + lp, + jb.BlockhashStoreSpec.TrustedBlockhashStoreBatchSize, int(jb.BlockhashStoreSpec.WaitBlocks), int(jb.BlockhashStoreSpec.LookbackBlocks), func(ctx context.Context) (uint64, error) { - head, err := chain.Client().HeadByNumber(ctx, nil) + head, err := lp.LatestBlock(pg.WithParentCtx(ctx)) if err != nil { return 0, errors.Wrap(err, "getting chain head") } - return uint64(head.Number), nil + return uint64(head), nil }) return []job.ServiceCtx{&service{ diff --git a/core/services/blockhashstore/delegate_test.go b/core/services/blockhashstore/delegate_test.go index 7ed3a9119c7..b0456206861 100644 --- a/core/services/blockhashstore/delegate_test.go +++ b/core/services/blockhashstore/delegate_test.go @@ -24,6 +24,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -37,11 +38,11 @@ func TestDelegate_JobType(t *testing.T) { } type testData struct { - ethClient *mocks.Client - ethKeyStore keystore.Eth - chainSet evm.ChainSet - sendingKey ethkey.KeyV2 - logs *observer.ObservedLogs + ethClient *mocks.Client + ethKeyStore keystore.Eth + legacyChains evm.LegacyChainContainer + sendingKey ethkey.KeyV2 + logs *observer.ObservedLogs } func createTestDelegate(t *testing.T) (*blockhashstore.Delegate, *testData) { @@ -57,7 +58,9 @@ func createTestDelegate(t *testing.T) (*blockhashstore.Delegate, *testData) { sendingKey, _ := cltest.MustAddRandomKeyToKeystore(t, kst) lp := &mocklp.LogPoller{} lp.On("RegisterFilter", mock.Anything).Return(nil) - chainSet := evmtest.NewChainSet( + lp.On("LatestBlock", mock.Anything, mock.Anything).Return(int64(0), nil) + + relayExtenders := evmtest.NewChainRelayExtenders( t, evmtest.TestChainOpts{ DB: db, @@ -67,13 +70,14 @@ func createTestDelegate(t *testing.T) (*blockhashstore.Delegate, *testData) { LogPoller: lp, }, ) - - return blockhashstore.NewDelegate(lggr, chainSet, kst), &testData{ - ethClient: ethClient, - ethKeyStore: kst, - chainSet: chainSet, - sendingKey: sendingKey, - logs: logs, + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + return blockhashstore.NewDelegate(lggr, legacyChains, kst), &testData{ + ethClient: ethClient, + ethKeyStore: kst, + legacyChains: legacyChains, + sendingKey: sendingKey, + logs: logs, } } @@ -82,8 +86,8 @@ func TestDelegate_ServicesForSpec(t *testing.T) { delegate, testData := createTestDelegate(t) - require.NotEmpty(t, testData.chainSet.Chains()) - defaultWaitBlocks := (int32)(testData.chainSet.Chains()[0].Config().EVM().FinalityDepth()) + require.NotEmpty(t, testData.legacyChains.Slice()) + defaultWaitBlocks := (int32)(testData.legacyChains.Slice()[0].Config().EVM().FinalityDepth()) t.Run("happy", func(t *testing.T) { spec := job.Job{BlockhashStoreSpec: &job.BlockhashStoreSpec{WaitBlocks: defaultWaitBlocks}} @@ -149,8 +153,8 @@ func TestDelegate_StartStop(t *testing.T) { delegate, testData := createTestDelegate(t) - require.NotEmpty(t, testData.chainSet.Chains()) - defaultWaitBlocks := (int32)(testData.chainSet.Chains()[0].Config().EVM().FinalityDepth()) + require.NotEmpty(t, testData.legacyChains.Slice()) + defaultWaitBlocks := (int32)(testData.legacyChains.Slice()[0].Config().EVM().FinalityDepth()) spec := job.Job{BlockhashStoreSpec: &job.BlockhashStoreSpec{ WaitBlocks: defaultWaitBlocks, PollPeriod: time.Second, @@ -161,8 +165,6 @@ func TestDelegate_StartStop(t *testing.T) { require.NoError(t, err) require.Len(t, services, 1) - blocks := cltest.NewBlocks(t, 1) - testData.ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(blocks.Head(0), nil) err = services[0].Start(testutils.Context(t)) require.NoError(t, err) diff --git a/core/services/blockhashstore/feeder.go b/core/services/blockhashstore/feeder.go index ba1445f0e1a..22bbf7f163d 100644 --- a/core/services/blockhashstore/feeder.go +++ b/core/services/blockhashstore/feeder.go @@ -2,46 +2,64 @@ package blockhashstore import ( "context" + "sync" + "time" + "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" "go.uber.org/multierr" + "golang.org/x/exp/maps" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/logger" ) +const trustedTimeout = 1 * time.Second + // NewFeeder creates a new Feeder instance. func NewFeeder( logger logger.Logger, coordinator Coordinator, bhs BHS, + lp logpoller.LogPoller, + trustedBHSBatchSize int32, waitBlocks int, lookbackBlocks int, latestBlock func(ctx context.Context) (uint64, error), ) *Feeder { return &Feeder{ - lggr: logger, - coordinator: coordinator, - bhs: bhs, - waitBlocks: waitBlocks, - lookbackBlocks: lookbackBlocks, - latestBlock: latestBlock, - stored: make(map[uint64]struct{}), - lastRunBlock: 0, + lggr: logger, + coordinator: coordinator, + bhs: bhs, + lp: lp, + trustedBHSBatchSize: trustedBHSBatchSize, + waitBlocks: waitBlocks, + lookbackBlocks: lookbackBlocks, + latestBlock: latestBlock, + stored: make(map[uint64]struct{}), + lastRunBlock: 0, + wgStored: sync.WaitGroup{}, } } // Feeder checks recent VRF coordinator events and stores any blockhashes for blocks within // waitBlocks and lookbackBlocks that have unfulfilled requests. type Feeder struct { - lggr logger.Logger - coordinator Coordinator - bhs BHS - waitBlocks int - lookbackBlocks int - latestBlock func(ctx context.Context) (uint64, error) + lggr logger.Logger + coordinator Coordinator + bhs BHS + lp logpoller.LogPoller + trustedBHSBatchSize int32 + waitBlocks int + lookbackBlocks int + latestBlock func(ctx context.Context) (uint64, error) stored map[uint64]struct{} lastRunBlock uint64 + wgStored sync.WaitGroup + batchLock sync.Mutex + storedLock sync.RWMutex + errsLock sync.Mutex } // Run the feeder. @@ -64,6 +82,11 @@ func (f *Feeder) Run(ctx context.Context) error { return err } + // For a trusted BHS, run our trusted logic. + if f.bhs.IsTrusted() { + return f.runTrusted(ctx, latestBlock, fromBlock, blockToRequests) + } + var errs error for block, unfulfilledReqs := range blockToRequests { if len(unfulfilledReqs) == 0 { @@ -114,3 +137,123 @@ func (f *Feeder) Run(ctx context.Context) error { f.lastRunBlock = latestBlock return errs } + +func (f *Feeder) runTrusted( + ctx context.Context, + latestBlock uint64, + fromBlock uint64, + blockToRequests map[uint64]map[string]struct{}, +) error { + var errs error + + // Iterate through each request block via waitGroup. + // For blocks with pending requests, add them to the batch to be stored. + // Note: Golang maps sort items in a range randomly, so although the batch size is used + // to limit blocks-per-batch, every block has an equal chance of getting picked up + // on each run. + var batch = make(map[uint64]struct{}) + for blockKey, unfulfilledReqs := range blockToRequests { + f.wgStored.Add(1) + var unfulfilled = unfulfilledReqs + var block = blockKey + go func() { + defer f.wgStored.Done() + if len(unfulfilled) == 0 { + return + } + f.storedLock.RLock() + if _, ok := f.stored[block]; ok { + // Already stored + f.storedLock.RUnlock() + return + } + f.storedLock.RUnlock() + + // Do not store a block if it has been marked as stored; otherwise, store it even + // if the RPC call errors, as to be conservative. + timeoutCtx, cancel := context.WithTimeout(ctx, trustedTimeout) + defer cancel() + stored, err := f.bhs.IsStored(timeoutCtx, block) + if err != nil { + f.lggr.Errorw("Failed to check if block is already stored, attempting to store anyway", + "err", err, + "block", block) + f.errsLock.Lock() + errs = multierr.Append(errs, errors.Wrap(err, "checking if stored")) + f.errsLock.Unlock() + } else if stored { + f.lggr.Infow("Blockhash already stored", + "block", block, "latestBlock", latestBlock, + "unfulfilledReqIDs", LimitReqIDs(unfulfilled, 50)) + f.storedLock.Lock() + f.stored[block] = struct{}{} + f.storedLock.Unlock() + return + } + + // If there's room, store the block in the batch. Threadsafe. + f.batchLock.Lock() + if len(batch) < int(f.trustedBHSBatchSize) { + batch[block] = struct{}{} + } + f.batchLock.Unlock() + }() + } + + // Ensure all blocks are checked before storing the batch. + f.wgStored.Wait() + + // For a non-empty batch, store all blocks. + if len(batch) != 0 { + var blocksToStore []uint64 + var blockhashesToStore []common.Hash + var latestBlockhash common.Hash + + // Get all logpoller blocks for the range including the batch and the latest block, + // as to include the recent blockhash. + lpBlocks, err := f.lp.GetBlocksRange(ctx, append(maps.Keys(batch), latestBlock)) + if err != nil { + f.lggr.Errorw("Failed to get blocks range", + "err", err, + "blocks", batch) + errs = multierr.Append(errs, errors.Wrap(err, "log poller get blocks range")) + return errs + } + + // If the log poller block's blocknumber is included in the desired batch, + // append its blockhash to our blockhashes we want to store. + // If it is the log poller block pertaining to our recent block number, assig it. + for _, b := range lpBlocks { + if _, ok := batch[uint64(b.BlockNumber)]; ok { + blocksToStore = append(blocksToStore, uint64(b.BlockNumber)) + blockhashesToStore = append(blockhashesToStore, b.BlockHash) + } + if b.BlockNumber == int64(latestBlock) { + latestBlockhash = b.BlockHash + } + } + + // Store the batch of blocks and their blockhashes. + err = f.bhs.StoreTrusted(ctx, blocksToStore, blockhashesToStore, latestBlock, latestBlockhash) + if err != nil { + f.lggr.Errorw("Failed to store trusted", + "err", err, + "blocks", blocksToStore, + "blockhashesToStore", blockhashesToStore, + "latestBlock", latestBlock, + "latestBlockhash", latestBlockhash, + ) + errs = multierr.Append(errs, errors.Wrap(err, "checking if stored")) + return errs + } + } + + // Prune stored, anything older than fromBlock can be discarded. + for b := range f.stored { + if b < fromBlock { + delete(f.stored, b) + } + } + + return errs +} diff --git a/core/services/blockhashstore/feeder_test.go b/core/services/blockhashstore/feeder_test.go index c6f8c1f4302..7efb7052985 100644 --- a/core/services/blockhashstore/feeder_test.go +++ b/core/services/blockhashstore/feeder_test.go @@ -19,12 +19,15 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/solidity_vrf_coordinator_interface" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" ) const ( // VRF-only events. + randomWordsRequestedV2Plus string = "RandomWordsRequested" + randomWordsFulfilledV2Plus string = "RandomWordsFulfilled" randomWordsRequestedV2 string = "RandomWordsRequested" randomWordsFulfilledV2 string = "RandomWordsFulfilled" randomWordsRequestedV1 string = "RandomnessRequest" @@ -36,8 +39,9 @@ const ( ) var ( - vrfCoordinatorV2ABI = evmtypes.MustGetABI(vrf_coordinator_v2.VRFCoordinatorV2MetaData.ABI) - vrfCoordinatorV1ABI = evmtypes.MustGetABI(solidity_vrf_coordinator_interface.VRFCoordinatorMetaData.ABI) + vrfCoordinatorV2PlusABI = evmtypes.MustGetABI(vrf_coordinator_v2plus.VRFCoordinatorV2PlusMetaData.ABI) + vrfCoordinatorV2ABI = evmtypes.MustGetABI(vrf_coordinator_v2.VRFCoordinatorV2MetaData.ABI) + vrfCoordinatorV1ABI = evmtypes.MustGetABI(solidity_vrf_coordinator_interface.VRFCoordinatorMetaData.ABI) _ Coordinator = &TestCoordinator{} _ BHS = &TestBHS{} @@ -225,10 +229,13 @@ func TestFeeder(t *testing.T) { FulfillmentEvents: test.fulfillments, } + lp := &mocklp.LogPoller{} feeder := NewFeeder( logger.TestLogger(t), coordinator, &test.bhs, + lp, + 0, test.wait, test.lookback, func(ctx context.Context) (uint64, error) { @@ -318,6 +325,8 @@ func TestFeederWithLogPollerVRFv1(t *testing.T) { logger.TestLogger(t), coordinator, &test.bhs, + lp, + 0, test.wait, test.lookback, func(ctx context.Context) (uint64, error) { @@ -411,6 +420,103 @@ func TestFeederWithLogPollerVRFv2(t *testing.T) { logger.TestLogger(t), coordinator, &test.bhs, + lp, + 0, + test.wait, + test.lookback, + func(ctx context.Context) (uint64, error) { + return test.latest, nil + }) + + // Run feeder and assert correct results. + err = feeder.Run(testutils.Context(t)) + if test.expectedErrMsg == "" { + require.NoError(t, err) + } else { + require.EqualError(t, err, test.expectedErrMsg) + } + require.ElementsMatch(t, test.expectedStored, test.bhs.Stored) + }) + } +} + +func TestFeederWithLogPollerVRFv2Plus(t *testing.T) { + + var coordinatorAddress = common.HexToAddress("0x514910771AF9Ca656af840dff83E8264EcF986CA") + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + // Instantiate log poller & coordinator. + lp := &mocklp.LogPoller{} + lp.On("RegisterFilter", mock.Anything).Return(nil) + c, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(coordinatorAddress, nil) + require.NoError(t, err) + coordinator := &V2PlusCoordinator{ + c: c, + lp: lp, + } + + // Assert search window. + latest := int64(test.latest) + fromBlock := mathutil.Max(latest-int64(test.lookback), 0) + toBlock := mathutil.Max(latest-int64(test.wait), 0) + + // Construct request logs. + var requestLogs []logpoller.Log + for _, r := range test.requests { + if r.Block < uint64(fromBlock) || r.Block > uint64(toBlock) { + continue // do not include blocks outside our search window + } + reqId, ok := big.NewInt(0).SetString(r.ID, 10) + require.True(t, ok) + requestLogs = append( + requestLogs, + newRandomnessRequestedLogV2Plus(t, r.Block, reqId, coordinatorAddress), + ) + } + + // Construct fulfillment logs. + var fulfillmentLogs []logpoller.Log + for _, r := range test.fulfillments { + reqId, ok := big.NewInt(0).SetString(r.ID, 10) + require.True(t, ok) + fulfillmentLogs = append( + fulfillmentLogs, + newRandomnessFulfilledLogV2Plus(t, r.Block, reqId, coordinatorAddress), + ) + } + + // Mock log poller. + lp.On("LatestBlock", mock.Anything). + Return(latest, nil) + lp.On( + "LogsWithSigs", + fromBlock, + toBlock, + []common.Hash{ + vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsRequested{}.Topic(), + }, + coordinatorAddress, + mock.Anything, + ).Return(requestLogs, nil) + lp.On( + "LogsWithSigs", + fromBlock, + latest, + []common.Hash{ + vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsFulfilled{}.Topic(), + }, + coordinatorAddress, + mock.Anything, + ).Return(fulfillmentLogs, nil) + + // Instantiate feeder. + feeder := NewFeeder( + logger.TestLogger(t), + coordinator, + &test.bhs, + lp, + 0, test.wait, test.lookback, func(ctx context.Context) (uint64, error) { @@ -436,10 +542,13 @@ func TestFeeder_CachesStoredBlocks(t *testing.T) { bhs := &TestBHS{} + lp := &mocklp.LogPoller{} feeder := NewFeeder( logger.TestLogger(t), coordinator, bhs, + lp, + 0, 100, 200, func(ctx context.Context) (uint64, error) { @@ -697,3 +806,158 @@ func newRandomnessFulfilledLogV2( } return lg } + +func newRandomnessRequestedLogV2Plus( + t *testing.T, + requestBlock uint64, + requestID *big.Int, + coordinatorAddress common.Address, +) logpoller.Log { + e := vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsRequested{ + RequestId: requestID, + PreSeed: big.NewInt(0), + MinimumRequestConfirmations: 0, + CallbackGasLimit: 0, + NumWords: 0, + Sender: common.HexToAddress("0xeFF41C8725be95e66F6B10489B6bF34b08055853"), + ExtraArgs: []byte{}, + SubId: big.NewInt(0), + Raw: types.Log{ + BlockNumber: requestBlock, + }, + } + var unindexed abi.Arguments + for _, a := range vrfCoordinatorV2PlusABI.Events[randomWordsRequestedV2Plus].Inputs { + if !a.Indexed { + unindexed = append(unindexed, a) + } + } + nonIndexedData, err := unindexed.Pack( + e.RequestId, + e.PreSeed, + e.MinimumRequestConfirmations, + e.CallbackGasLimit, + e.NumWords, + e.ExtraArgs, + ) + require.NoError(t, err) + + keyHashType, err := abi.NewType("bytes32", "", nil) + require.NoError(t, err) + + subIdType, err := abi.NewType("uint256", "", nil) + require.NoError(t, err) + + senderType, err := abi.NewType("address", "", nil) + require.NoError(t, err) + + keyHashArg := abi.Arguments{abi.Argument{ + Name: "keyHash", + Type: keyHashType, + Indexed: true, + }} + subIdArg := abi.Arguments{abi.Argument{ + Name: "subId", + Type: subIdType, + Indexed: true, + }} + + senderArg := abi.Arguments{abi.Argument{ + Name: "sender", + Type: senderType, + Indexed: true, + }} + + topic1, err := keyHashArg.Pack(e.KeyHash) + require.NoError(t, err) + topic2, err := subIdArg.Pack(e.SubId) + require.NoError(t, err) + topic3, err := senderArg.Pack(e.Sender) + require.NoError(t, err) + + topic0 := vrfCoordinatorV2PlusABI.Events[randomWordsRequestedV2Plus].ID + lg := logpoller.Log{ + Address: coordinatorAddress, + Data: nonIndexedData, + Topics: [][]byte{ + // first topic is the event signature + topic0.Bytes(), + // second topic is keyHash since it's indexed + topic1, + // third topic is subId since it's indexed + topic2, + // third topic is sender since it's indexed + topic3, + }, + BlockNumber: int64(requestBlock), + EventSig: topic0, + } + return lg +} + +func newRandomnessFulfilledLogV2Plus( + t *testing.T, + requestBlock uint64, + requestID *big.Int, + coordinatorAddress common.Address, +) logpoller.Log { + e := vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsFulfilled{ + RequestId: requestID, + OutputSeed: big.NewInt(0), + Payment: big.NewInt(0), + Success: true, + Raw: types.Log{ + BlockNumber: requestBlock, + }, + SubID: big.NewInt(0), + } + var unindexed abi.Arguments + for _, a := range vrfCoordinatorV2PlusABI.Events[randomWordsFulfilledV2Plus].Inputs { + if !a.Indexed { + unindexed = append(unindexed, a) + } + } + nonIndexedData, err := unindexed.Pack( + e.OutputSeed, + e.Payment, + e.Success, + ) + require.NoError(t, err) + + requestIdType, err := abi.NewType("uint256", "", nil) + require.NoError(t, err) + subIdType, err := abi.NewType("uint256", "", nil) + require.NoError(t, err) + + requestIdArg := abi.Arguments{abi.Argument{ + Name: "requestId", + Type: requestIdType, + Indexed: true, + }} + subIdArg := abi.Arguments{abi.Argument{ + Name: "subID", + Type: subIdType, + Indexed: true, + }} + + topic1, err := requestIdArg.Pack(e.RequestId) + require.NoError(t, err) + topic2, err := subIdArg.Pack(e.SubID) + require.NoError(t, err) + + topic0 := vrfCoordinatorV2PlusABI.Events[randomWordsFulfilledV2Plus].ID + lg := logpoller.Log{ + Address: coordinatorAddress, + Data: nonIndexedData, + Topics: [][]byte{ + // first topic is the event signature + topic0.Bytes(), + // second topic is requestId since it's indexed + topic1, + topic2, + }, + BlockNumber: int64(requestBlock), + EventSig: topic0, + } + return lg +} diff --git a/core/services/blockhashstore/test_util.go b/core/services/blockhashstore/test_util.go index f82296e7d00..6b7c3836650 100644 --- a/core/services/blockhashstore/test_util.go +++ b/core/services/blockhashstore/test_util.go @@ -61,6 +61,16 @@ func (t *TestBHS) Store(_ context.Context, blockNum uint64) error { return nil } +func (t *TestBHS) IsTrusted() bool { + return false +} + +func (t *TestBHS) StoreTrusted( + ctx context.Context, blockNums []uint64, blockhashes []common.Hash, recentBlock uint64, recentBlockhash common.Hash, +) error { + return errors.New("not implemented") +} + func (t *TestBHS) IsStored(_ context.Context, blockNum uint64) (bool, error) { for _, e := range t.ErrorsIsStored { if e == blockNum { diff --git a/core/services/blockhashstore/validate.go b/core/services/blockhashstore/validate.go index 503e15c9a19..157f6f2ec03 100644 --- a/core/services/blockhashstore/validate.go +++ b/core/services/blockhashstore/validate.go @@ -8,8 +8,11 @@ import ( "github.com/pkg/errors" "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/utils" ) +var EmptyAddress = utils.ZeroAddress.Hex() + // ValidatedSpec validates and converts the given toml string to a job.Job. func ValidatedSpec(tomlString string) (job.Job, error) { jb := job.Job{ @@ -48,6 +51,9 @@ func ValidatedSpec(tomlString string) (job.Job, error) { if spec.EVMChainID == nil { return jb, notSet("evmChainID") } + if spec.TrustedBlockhashStoreAddress != nil && spec.TrustedBlockhashStoreAddress.Hex() != EmptyAddress && spec.TrustedBlockhashStoreBatchSize == 0 { + return jb, notSet("trustedBlockhashStoreBatchSize") + } // Defaults if spec.WaitBlocks == 0 { @@ -67,10 +73,10 @@ func ValidatedSpec(tomlString string) (job.Job, error) { if spec.WaitBlocks >= spec.LookbackBlocks { return jb, errors.New(`"waitBlocks" must be less than "lookbackBlocks"`) } - if spec.WaitBlocks >= 256 { + if (spec.TrustedBlockhashStoreAddress == nil || spec.TrustedBlockhashStoreAddress.Hex() == EmptyAddress) && spec.WaitBlocks >= 256 { return jb, errors.New(`"waitBlocks" must be less than 256`) } - if spec.LookbackBlocks >= 256 { + if (spec.TrustedBlockhashStoreAddress == nil || spec.TrustedBlockhashStoreAddress.Hex() == EmptyAddress) && spec.LookbackBlocks >= 256 { return jb, errors.New(`"lookbackBlocks" must be less than 256`) } diff --git a/core/services/blockhashstore/validate_test.go b/core/services/blockhashstore/validate_test.go index d6d158f4c24..10eaae10d34 100644 --- a/core/services/blockhashstore/validate_test.go +++ b/core/services/blockhashstore/validate_test.go @@ -183,6 +183,22 @@ evmChainID = "4"`, require.EqualError(t, err, `"waitBlocks" must be less than "lookbackBlocks"`) }, }, + { + name: "invalid waitBlocks higher than lookbackBlocks", + toml: ` +type = "blockhashstore" +name = "valid-test" +coordinatorV1Address = "0x1F72B4A5DCf7CC6d2E38423bF2f4BFA7db97d139" +coordinatorV2Address = "0x2be990eE17832b59E0086534c5ea2459Aa75E38F" +waitBlocks = 10 +lookbackBlocks = 100 +blockhashStoreAddress = "0x3e20Cef636EdA7ba135bCbA4fe6177Bd3cE0aB17" +trustedBlockhashStoreAddress = "0x469aA2CD13e037DC5236320783dCfd0e641c0559" +evmChainID = "4"`, + assertion: func(t *testing.T, os job.Job, err error) { + require.EqualError(t, err, `"trustedBlockhashStoreBatchSize" must be set`) + }, + }, { name: "invalid toml", toml: ` diff --git a/core/services/blockheaderfeeder/delegate.go b/core/services/blockheaderfeeder/delegate.go index 3d026289e8f..938df59bb76 100644 --- a/core/services/blockheaderfeeder/delegate.go +++ b/core/services/blockheaderfeeder/delegate.go @@ -25,20 +25,20 @@ import ( var _ job.ServiceCtx = &service{} type Delegate struct { - logger logger.Logger - chains evm.ChainSet - ks keystore.Eth + logger logger.Logger + legacyChains evm.LegacyChainContainer + ks keystore.Eth } func NewDelegate( logger logger.Logger, - chains evm.ChainSet, + legacyChains evm.LegacyChainContainer, ks keystore.Eth, ) *Delegate { return &Delegate{ - logger: logger, - chains: chains, - ks: ks, + logger: logger, + legacyChains: legacyChains, + ks: ks, } } @@ -48,12 +48,12 @@ func (d *Delegate) JobType() job.Type { } // ServicesForSpec satisfies the job.Delegate interface. -func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { +func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceCtx, error) { if jb.BlockHeaderFeederSpec == nil { return nil, errors.Errorf("Delegate expects a BlockHeaderFeederSpec to be present, got %+v", jb) } - chain, err := d.chains.Get(jb.BlockHeaderFeederSpec.EVMChainID.ToInt()) + chain, err := d.legacyChains.Get(jb.BlockHeaderFeederSpec.EVMChainID.String()) if err != nil { return nil, fmt.Errorf( "getting chain ID %d: %w", jb.BlockHeaderFeederSpec.EVMChainID.ToInt(), err) @@ -138,7 +138,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { coordinators = append(coordinators, coord) } - bpBHS, err := blockhashstore.NewBulletproofBHS(chain.Config().EVM().GasEstimator(), chain.Config().Database(), fromAddresses, chain.TxManager(), bhs, chain.ID(), d.ks) + bpBHS, err := blockhashstore.NewBulletproofBHS(chain.Config().EVM().GasEstimator(), chain.Config().Database(), fromAddresses, chain.TxManager(), bhs, nil, chain.ID(), d.ks) if err != nil { return nil, errors.Wrap(err, "building bulletproof bhs") } diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 1541f473c12..e031973e561 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -3,6 +3,7 @@ package chainlink import ( "bytes" "context" + "fmt" "math/big" "net/http" "sync" @@ -17,13 +18,10 @@ import ( "github.com/smartcontractkit/sqlx" - pkgcosmos "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos" "github.com/smartcontractkit/chainlink-relay/pkg/loop" "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/build" - "github.com/smartcontractkit/chainlink/v2/core/chains/cosmos" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/config" @@ -48,8 +46,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/services/promreporter" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" - evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" "github.com/smartcontractkit/chainlink/v2/core/services/vrf" @@ -59,9 +56,9 @@ import ( "github.com/smartcontractkit/chainlink/v2/plugins" ) -//go:generate mockery --quiet --name Application --output ../../internal/mocks/ --case=underscore - // Application implements the common functions used in the core node. +// +//go:generate mockery --quiet --name Application --output ../../internal/mocks/ --case=underscore type Application interface { Start(ctx context.Context) error Stop() error @@ -77,8 +74,7 @@ type Application interface { GetWebAuthnConfiguration() sessions.WebAuthnConfiguration GetExternalInitiatorManager() webhook.ExternalInitiatorManager - GetChains() Chains - + GetRelayers() RelayerChainInteroperators GetLoopRegistry() *plugins.LoopRegistry // V2 Jobs (TOML specified) @@ -113,7 +109,7 @@ type Application interface { // and Store. The JobSubscriber and Scheduler are also available // in the services package, but the Store has its own package. type ChainlinkApplication struct { - Chains Chains + relayers *CoreRelayerChainInteroperators EventBroadcaster pg.EventBroadcaster jobORM job.ORM jobSpawner job.Spawner @@ -146,46 +142,22 @@ type ChainlinkApplication struct { } type ApplicationOpts struct { - Config GeneralConfig - Logger logger.Logger - EventBroadcaster pg.EventBroadcaster - MailMon *utils.MailboxMonitor - SqlxDB *sqlx.DB - KeyStore keystore.Master - Chains Chains - AuditLogger audit.AuditLogger - CloseLogger func() error - ExternalInitiatorManager webhook.ExternalInitiatorManager - Version string - RestrictedHTTPClient *http.Client - UnrestrictedHTTPClient *http.Client - SecretGenerator SecretGenerator - LoopRegistry *plugins.LoopRegistry - GRPCOpts loop.GRPCOpts -} - -// Chains holds a ChainSet for each type of chain. -type Chains struct { - EVM evm.ChainSet - Cosmos cosmos.ChainSet // nil if disabled - Solana loop.Relayer // nil if disabled - StarkNet loop.Relayer // nil if disabled -} - -func (c *Chains) services() (s []services.ServiceCtx) { - if c.Cosmos != nil { - s = append(s, c.Cosmos) - } - if c.EVM != nil { - s = append(s, c.EVM) - } - if c.Solana != nil { - s = append(s, c.Solana) - } - if c.StarkNet != nil { - s = append(s, c.StarkNet) - } - return + Config GeneralConfig + Logger logger.Logger + EventBroadcaster pg.EventBroadcaster + MailMon *utils.MailboxMonitor + SqlxDB *sqlx.DB + KeyStore keystore.Master + RelayerChainInteroperators *CoreRelayerChainInteroperators + AuditLogger audit.AuditLogger + CloseLogger func() error + ExternalInitiatorManager webhook.ExternalInitiatorManager + Version string + RestrictedHTTPClient *http.Client + UnrestrictedHTTPClient *http.Client + SecretGenerator SecretGenerator + LoopRegistry *plugins.LoopRegistry + GRPCOpts loop.GRPCOpts } // NewApplication initializes a new store if one is not already @@ -198,7 +170,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { auditLogger := opts.AuditLogger db := opts.SqlxDB cfg := opts.Config - chains := opts.Chains + relayerChainInterops := opts.RelayerChainInteroperators eventBroadcaster := opts.EventBroadcaster mailMon := opts.MailMon externalInitiatorManager := opts.ExternalInitiatorManager @@ -292,47 +264,56 @@ func NewApplication(opts ApplicationOpts) (Application, error) { } srvcs = append(srvcs, eventBroadcaster, mailMon) - srvcs = append(srvcs, chains.services()...) + srvcs = append(srvcs, relayerChainInterops.Services()...) promReporter := promreporter.NewPromReporter(db.DB, globalLogger) srvcs = append(srvcs, promReporter) + // EVM chains are used all over the place. This will need to change for fully EVM extraction + // TODO: BCF-2510, BCF-2511 + + legacyEVMChains := relayerChainInterops.LegacyEVMChains() + if legacyEVMChains == nil { + return nil, fmt.Errorf("no evm chains found") + } + var ( pipelineORM = pipeline.NewORM(db, globalLogger, cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns()) bridgeORM = bridges.NewORM(db, globalLogger, cfg.Database()) sessionORM = sessions.NewORM(db, cfg.WebServer().SessionTimeout().Duration(), globalLogger, cfg.Database(), auditLogger) - pipelineRunner = pipeline.NewRunner(pipelineORM, bridgeORM, cfg.JobPipeline(), cfg.WebServer(), chains.EVM, keyStore.Eth(), keyStore.VRF(), globalLogger, restrictedHTTPClient, unrestrictedHTTPClient) - jobORM = job.NewORM(db, chains.EVM, pipelineORM, bridgeORM, keyStore, globalLogger, cfg.Database()) + mercuryORM = mercury.NewORM(db, globalLogger, cfg.Database()) + pipelineRunner = pipeline.NewRunner(pipelineORM, bridgeORM, cfg.JobPipeline(), cfg.WebServer(), legacyEVMChains, keyStore.Eth(), keyStore.VRF(), globalLogger, restrictedHTTPClient, unrestrictedHTTPClient) + jobORM = job.NewORM(db, legacyEVMChains, pipelineORM, bridgeORM, keyStore, globalLogger, cfg.Database()) txmORM = txmgr.NewTxStore(db, globalLogger, cfg.Database()) ) - srvcs = append(srvcs, pipelineORM) - - for _, chain := range chains.EVM.Chains() { + for _, chain := range legacyEVMChains.Slice() { chain.HeadBroadcaster().Subscribe(promReporter) chain.TxManager().RegisterResumeCallback(pipelineRunner.ResumeRun) } + srvcs = append(srvcs, pipelineORM) + var ( delegates = map[job.Type]job.Delegate{ job.DirectRequest: directrequest.NewDelegate( globalLogger, pipelineRunner, pipelineORM, - chains.EVM, + legacyEVMChains, mailMon), job.Keeper: keeper.NewDelegate( db, jobORM, pipelineRunner, globalLogger, - chains.EVM, + legacyEVMChains, mailMon), job.VRF: vrf.NewDelegate( db, keyStore, pipelineRunner, pipelineORM, - chains.EVM, + legacyEVMChains, globalLogger, cfg.Database(), mailMon), @@ -345,14 +326,14 @@ func NewApplication(opts ApplicationOpts) (Application, error) { globalLogger), job.BlockhashStore: blockhashstore.NewDelegate( globalLogger, - chains.EVM, + legacyEVMChains, keyStore.Eth()), job.BlockHeaderFeeder: blockheaderfeeder.NewDelegate( globalLogger, - chains.EVM, + legacyEVMChains, keyStore.Eth()), job.Gateway: gateway.NewDelegate( - chains.EVM, + legacyEVMChains, keyStore.Eth(), globalLogger), } @@ -369,7 +350,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { pipelineORM, pipelineRunner, db, - chains.EVM, + legacyEVMChains, globalLogger, ) } @@ -393,7 +374,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { pipelineRunner, peerWrapper, monitoringEndpointGen, - chains.EVM, + legacyEVMChains, globalLogger, cfg.Database(), mailMon, @@ -403,40 +384,24 @@ func NewApplication(opts ApplicationOpts) (Application, error) { } if cfg.OCR2().Enabled() { globalLogger.Debug("Off-chain reporting v2 enabled") - relayers := make(map[relay.Network]loop.Relayer) - if cfg.EVMEnabled() { - lggr := globalLogger.Named("EVM") - evmRelayer := evmrelay.NewRelayer(db, chains.EVM, lggr, cfg.Database(), keyStore, eventBroadcaster) - relayers[relay.EVM] = relay.NewRelayerAdapter(evmRelayer, chains.EVM) - } - if cfg.CosmosEnabled() { - lggr := globalLogger.Named("Cosmos.Relayer") - cosmosRelayer := pkgcosmos.NewRelayer(lggr, chains.Cosmos) - relayers[relay.Cosmos] = relay.NewRelayerAdapter(cosmosRelayer, chains.Cosmos) - } - if cfg.SolanaEnabled() { - relayers[relay.Solana] = chains.Solana - } - if cfg.StarkNetEnabled() { - relayers[relay.StarkNet] = chains.StarkNet - } registrarConfig := plugins.NewRegistrarConfig(opts.GRPCOpts, opts.LoopRegistry.Register) ocr2DelegateConfig := ocr2.NewDelegateConfig(cfg.OCR2(), cfg.Mercury(), cfg.Threshold(), cfg.Insecure(), cfg.JobPipeline(), cfg.Database(), registrarConfig) delegates[job.OffchainReporting2] = ocr2.NewDelegate( db, jobORM, bridgeORM, + mercuryORM, pipelineRunner, peerWrapper, monitoringEndpointGen, - chains.EVM, + legacyEVMChains, globalLogger, ocr2DelegateConfig, keyStore.OCR2(), keyStore.DKGSign(), keyStore.DKGEncrypt(), keyStore.Eth(), - relayers, + opts.RelayerChainInteroperators, mailMon, eventBroadcaster, ) @@ -447,14 +412,14 @@ func NewApplication(opts ApplicationOpts) (Application, error) { globalLogger, cfg.OCR2(), cfg.Insecure(), - relayers, + opts.RelayerChainInteroperators, ) } else { globalLogger.Debug("Off-chain reporting v2 disabled") } var lbs []utils.DependentAwaiter - for _, c := range chains.EVM.Chains() { + for _, c := range legacyEVMChains.Slice() { lbs = append(lbs, c.LogBroadcaster()) } jobSpawner := job.NewSpawner(jobORM, cfg.Database(), delegates, db, globalLogger, lbs) @@ -463,7 +428,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { // We start the log poller after the job spawner // so jobs have a chance to apply their initial log filters. if cfg.Feature().LogPoller() { - for _, c := range chains.EVM.Chains() { + for _, c := range legacyEVMChains.Slice() { srvcs = append(srvcs, c.LogPoller()) } } @@ -482,7 +447,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { cfg.OCR(), cfg.OCR2(), cfg.Database(), - chains.EVM, + legacyEVMChains, globalLogger, opts.Version, ) @@ -491,7 +456,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { } app := &ChainlinkApplication{ - Chains: chains, + relayers: opts.RelayerChainInteroperators, EventBroadcaster: eventBroadcaster, jobORM: jobORM, jobSpawner: jobSpawner, @@ -532,7 +497,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { // To avoid subscribing chain services twice, we only subscribe them if OCR2 is not enabled. // If it's enabled, they are going to be registered with relayers by default. if !cfg.OCR2().Enabled() { - for _, service := range app.Chains.services() { + for _, service := range app.relayers.Services() { checkable := service.(services.Checkable) if err := app.HealthChecker.Register(service.Name(), checkable); err != nil { return nil, err @@ -695,8 +660,9 @@ func (app *ChainlinkApplication) SessionORM() sessions.ORM { return app.sessionORM } +// TODO BCF-2516 remove this all together remove EVM specifics func (app *ChainlinkApplication) EVMORM() evmtypes.Configs { - return app.Chains.EVM.Configs() + return app.GetRelayers().LegacyEVMChains().ChainNodeConfigs() } func (app *ChainlinkApplication) PipelineORM() pipeline.ORM { @@ -820,7 +786,7 @@ func (app *ChainlinkApplication) GetFeedsService() feeds.Service { // ReplayFromBlock implements the Application interface. func (app *ChainlinkApplication) ReplayFromBlock(chainID *big.Int, number uint64, forceBroadcast bool) error { - chain, err := app.Chains.EVM.Get(chainID) + chain, err := app.GetRelayers().LegacyEVMChains().Get(chainID.String()) if err != nil { return err } @@ -831,9 +797,8 @@ func (app *ChainlinkApplication) ReplayFromBlock(chainID *big.Int, number uint64 return nil } -// GetChains returns Chains. -func (app *ChainlinkApplication) GetChains() Chains { - return app.Chains +func (app *ChainlinkApplication) GetRelayers() RelayerChainInteroperators { + return app.relayers } func (app *ChainlinkApplication) GetEventBroadcaster() pg.EventBroadcaster { diff --git a/core/services/chainlink/config_ocr2.go b/core/services/chainlink/config_ocr2.go index 59df8cb14eb..801abb380d6 100644 --- a/core/services/chainlink/config_ocr2.go +++ b/core/services/chainlink/config_ocr2.go @@ -57,6 +57,10 @@ func (o *ocr2Config) CaptureEATelemetry() bool { return *o.c.CaptureEATelemetry } +func (o *ocr2Config) CaptureAutomationCustomTelemetry() bool { + return *o.c.CaptureAutomationCustomTelemetry +} + func (o *ocr2Config) DefaultTransactionQueueDepth() uint32 { return *o.c.DefaultTransactionQueueDepth } diff --git a/core/services/chainlink/config_ocr2_test.go b/core/services/chainlink/config_ocr2_test.go index 5702c9a89d4..66427489241 100644 --- a/core/services/chainlink/config_ocr2_test.go +++ b/core/services/chainlink/config_ocr2_test.go @@ -38,6 +38,7 @@ func TestOCR2Config(t *testing.T) { require.Equal(t, false, ocr2Cfg.TraceLogging()) require.Equal(t, uint32(1), ocr2Cfg.DefaultTransactionQueueDepth()) require.Equal(t, false, ocr2Cfg.CaptureEATelemetry()) + require.Equal(t, false, ocr2Cfg.CaptureAutomationCustomTelemetry()) keyBundleID, err := ocr2Cfg.KeyBundleID() require.NoError(t, err) diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index d8bc7c3bdc1..e2e12545613 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -348,6 +348,7 @@ func TestConfig_Marshal(t *testing.T) { DatabaseTimeout: models.MustNewDuration(8 * time.Second), KeyBundleID: ptr(models.MustSha256HashFromHex("7a5f66bbe6594259325bf2b4f5b1a9c9")), CaptureEATelemetry: ptr(false), + CaptureAutomationCustomTelemetry: ptr(false), DefaultTransactionQueueDepth: ptr[uint32](1), SimulateTransactions: ptr(false), TraceLogging: ptr(false), @@ -608,11 +609,12 @@ func TestConfig_Marshal(t *testing.T) { ChainID: ptr("Malaga-420"), Enabled: ptr(true), Chain: coscfg.Chain{ + Bech32Prefix: ptr("wasm"), BlockRate: relayutils.MustNewDuration(time.Minute), BlocksUntilTxTimeout: ptr[int64](12), ConfirmPollPeriod: relayutils.MustNewDuration(time.Second), FallbackGasPrice: mustDecimal("0.001"), - FCDURL: relayutils.MustParseURL("http://cosmos.com"), + FeeToken: ptr("ucosm"), GasLimitMultiplier: mustDecimal("1.2"), MaxMsgsPerBatch: ptr[int64](17), OCR2CachePollPeriod: relayutils.MustNewDuration(time.Minute), @@ -772,6 +774,7 @@ ContractTransmitterTransmitTimeout = '1m0s' DatabaseTimeout = '8s' KeyBundleID = '7a5f66bbe6594259325bf2b4f5b1a9c900000000000000000000000000000000' CaptureEATelemetry = false +CaptureAutomationCustomTelemetry = false DefaultTransactionQueueDepth = 1 SimulateTransactions = false TraceLogging = false @@ -954,11 +957,12 @@ SendOnly = true {"Cosmos", Config{Cosmos: full.Cosmos}, `[[Cosmos]] ChainID = 'Malaga-420' Enabled = true +Bech32Prefix = 'wasm' BlockRate = '1m0s' BlocksUntilTxTimeout = 12 ConfirmPollPeriod = '1s' FallbackGasPrice = '0.001' -FCDURL = 'http://cosmos.com' +FeeToken = 'ucosm' GasLimitMultiplier = '1.2' MaxMsgsPerBatch = 17 OCR2CachePollPeriod = '1m0s' diff --git a/core/services/chainlink/mocks/relayer_chain_interoperators.go b/core/services/chainlink/mocks/relayer_chain_interoperators.go new file mode 100644 index 00000000000..f25ced6c3ca --- /dev/null +++ b/core/services/chainlink/mocks/relayer_chain_interoperators.go @@ -0,0 +1,248 @@ +// Code generated by mockery v2.28.1. DO NOT EDIT. + +package mocks + +import ( + context "context" + + chainlink "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + + cosmos "github.com/smartcontractkit/chainlink/v2/core/chains/cosmos" + + evm "github.com/smartcontractkit/chainlink/v2/core/chains/evm" + + // Manually edited. mockery generates the wrong dependency. edited to use `loop` rather than `loop/internal` + // seems to caused by incorrect alias resolution of the relayer dep + internal "github.com/smartcontractkit/chainlink-relay/pkg/loop" + + mock "github.com/stretchr/testify/mock" + + relay "github.com/smartcontractkit/chainlink/v2/core/services/relay" + + services "github.com/smartcontractkit/chainlink/v2/core/services" + + types "github.com/smartcontractkit/chainlink-relay/pkg/types" +) + +// RelayerChainInteroperators is an autogenerated mock type for the RelayerChainInteroperators type +type RelayerChainInteroperators struct { + mock.Mock +} + +// ChainStatus provides a mock function with given fields: ctx, id +func (_m *RelayerChainInteroperators) ChainStatus(ctx context.Context, id relay.ID) (types.ChainStatus, error) { + ret := _m.Called(ctx, id) + + var r0 types.ChainStatus + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, relay.ID) (types.ChainStatus, error)); ok { + return rf(ctx, id) + } + if rf, ok := ret.Get(0).(func(context.Context, relay.ID) types.ChainStatus); ok { + r0 = rf(ctx, id) + } else { + r0 = ret.Get(0).(types.ChainStatus) + } + + if rf, ok := ret.Get(1).(func(context.Context, relay.ID) error); ok { + r1 = rf(ctx, id) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ChainStatuses provides a mock function with given fields: ctx, offset, limit +func (_m *RelayerChainInteroperators) ChainStatuses(ctx context.Context, offset int, limit int) ([]types.ChainStatus, int, error) { + ret := _m.Called(ctx, offset, limit) + + var r0 []types.ChainStatus + var r1 int + var r2 error + if rf, ok := ret.Get(0).(func(context.Context, int, int) ([]types.ChainStatus, int, error)); ok { + return rf(ctx, offset, limit) + } + if rf, ok := ret.Get(0).(func(context.Context, int, int) []types.ChainStatus); ok { + r0 = rf(ctx, offset, limit) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]types.ChainStatus) + } + } + + 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(context.Context, int, int) error); ok { + r2 = rf(ctx, offset, limit) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// Get provides a mock function with given fields: id +func (_m *RelayerChainInteroperators) Get(id relay.ID) (internal.Relayer, error) { + ret := _m.Called(id) + + var r0 internal.Relayer + var r1 error + if rf, ok := ret.Get(0).(func(relay.ID) (internal.Relayer, error)); ok { + return rf(id) + } + if rf, ok := ret.Get(0).(func(relay.ID) internal.Relayer); ok { + r0 = rf(id) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(internal.Relayer) + } + } + + if rf, ok := ret.Get(1).(func(relay.ID) error); ok { + r1 = rf(id) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LegacyCosmosChains provides a mock function with given fields: +func (_m *RelayerChainInteroperators) LegacyCosmosChains() cosmos.LegacyChainContainer { + ret := _m.Called() + + var r0 cosmos.LegacyChainContainer + if rf, ok := ret.Get(0).(func() cosmos.LegacyChainContainer); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(cosmos.LegacyChainContainer) + } + } + + return r0 +} + +// LegacyEVMChains provides a mock function with given fields: +func (_m *RelayerChainInteroperators) LegacyEVMChains() evm.LegacyChainContainer { + ret := _m.Called() + + var r0 evm.LegacyChainContainer + if rf, ok := ret.Get(0).(func() evm.LegacyChainContainer); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(evm.LegacyChainContainer) + } + } + + return r0 +} + +// List provides a mock function with given fields: filter +func (_m *RelayerChainInteroperators) List(filter chainlink.FilterFn) chainlink.RelayerChainInteroperators { + ret := _m.Called(filter) + + var r0 chainlink.RelayerChainInteroperators + if rf, ok := ret.Get(0).(func(chainlink.FilterFn) chainlink.RelayerChainInteroperators); ok { + r0 = rf(filter) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(chainlink.RelayerChainInteroperators) + } + } + + return r0 +} + +// NodeStatuses provides a mock function with given fields: ctx, offset, limit, chainIDs +func (_m *RelayerChainInteroperators) NodeStatuses(ctx context.Context, offset int, limit int, chainIDs ...string) ([]types.NodeStatus, int, error) { + _va := make([]interface{}, len(chainIDs)) + for _i := range chainIDs { + _va[_i] = chainIDs[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, offset, limit) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 []types.NodeStatus + var r1 int + var r2 error + if rf, ok := ret.Get(0).(func(context.Context, int, int, ...string) ([]types.NodeStatus, int, error)); ok { + return rf(ctx, offset, limit, chainIDs...) + } + if rf, ok := ret.Get(0).(func(context.Context, int, int, ...string) []types.NodeStatus); ok { + r0 = rf(ctx, offset, limit, chainIDs...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]types.NodeStatus) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, int, int, ...string) int); ok { + r1 = rf(ctx, offset, limit, chainIDs...) + } else { + r1 = ret.Get(1).(int) + } + + if rf, ok := ret.Get(2).(func(context.Context, int, int, ...string) error); ok { + r2 = rf(ctx, offset, limit, chainIDs...) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// Services provides a mock function with given fields: +func (_m *RelayerChainInteroperators) Services() []services.ServiceCtx { + ret := _m.Called() + + var r0 []services.ServiceCtx + if rf, ok := ret.Get(0).(func() []services.ServiceCtx); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]services.ServiceCtx) + } + } + + return r0 +} + +// Slice provides a mock function with given fields: +func (_m *RelayerChainInteroperators) Slice() []internal.Relayer { + ret := _m.Called() + + var r0 []internal.Relayer + if rf, ok := ret.Get(0).(func() []internal.Relayer); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]internal.Relayer) + } + } + + return r0 +} + +type mockConstructorTestingTNewRelayerChainInteroperators interface { + mock.TestingT + Cleanup(func()) +} + +// NewRelayerChainInteroperators creates a new instance of RelayerChainInteroperators. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewRelayerChainInteroperators(t mockConstructorTestingTNewRelayerChainInteroperators) *RelayerChainInteroperators { + mock := &RelayerChainInteroperators{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/chainlink/relayer_chain_interoperators.go b/core/services/chainlink/relayer_chain_interoperators.go new file mode 100644 index 00000000000..e4de1352925 --- /dev/null +++ b/core/services/chainlink/relayer_chain_interoperators.go @@ -0,0 +1,372 @@ +package chainlink + +import ( + "context" + "errors" + "fmt" + "sort" + "sync" + + "github.com/smartcontractkit/chainlink-relay/pkg/loop" + "github.com/smartcontractkit/chainlink-relay/pkg/types" + "github.com/smartcontractkit/chainlink/v2/core/chains" + "github.com/smartcontractkit/chainlink/v2/core/chains/cosmos" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm" + "github.com/smartcontractkit/chainlink/v2/core/services" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" +) + +var ErrNoSuchRelayer = errors.New("relayer does not exist") + +// RelayerChainInteroperators +// encapsulates relayers and chains and is the primary entry point for +// the node to access relayers, get legacy chains associated to a relayer +// and get status about the chains and nodes +// +// note the generated mockery code incorrectly resolves dependencies and needs to be manually edited +// therefore this interface is not auto-generated. for reference use and edit the result: +// `go:generate mockery --quiet --name RelayerChainInteroperators --output ./mocks/ --case=underscore“` +type RelayerChainInteroperators interface { + Services() []services.ServiceCtx + + List(filter FilterFn) RelayerChainInteroperators + + LoopRelayerStorer + LegacyChainer + ChainsNodesStatuser +} + +// LoopRelayerStorer is key-value like interface for storing and +// retrieving [loop.Relayer] +type LoopRelayerStorer interface { + ocr2.RelayGetter + Slice() []loop.Relayer +} + +// LegacyChainer is an interface for getting legacy chains +// This will be deprecated/removed when products depend only +// on the relayer interface. +type LegacyChainer interface { + LegacyEVMChains() evm.LegacyChainContainer + LegacyCosmosChains() cosmos.LegacyChainContainer +} + +// Similar to [chains.ChainStatuser] but keyed by relay identifier instead of string +// TODO BCF-2441 remove this comment when chains.ChainStatus is no longer keyed. +type ChainStatuser interface { + ChainStatus(ctx context.Context, id relay.ID) (types.ChainStatus, error) + ChainStatuses(ctx context.Context, offset, limit int) ([]types.ChainStatus, int, error) +} + +// ChainsNodesStatuser report statuses about chains and nodes +type ChainsNodesStatuser interface { + ChainStatuser + chains.NodesStatuser +} + +var _ RelayerChainInteroperators = &CoreRelayerChainInteroperators{} + +// CoreRelayerChainInteroperators implements [RelayerChainInteroperators] +// as needed for the core [chainlink.Application] +type CoreRelayerChainInteroperators struct { + mu sync.Mutex + loopRelayers map[relay.ID]loop.Relayer + legacyChains legacyChains + + // we keep an explicit list of services because the legacy implementations have more than + // just the relayer service + srvs []services.ServiceCtx +} + +func NewCoreRelayerChainInteroperators(initFuncs ...CoreRelayerChainInitFunc) (*CoreRelayerChainInteroperators, error) { + cr := &CoreRelayerChainInteroperators{ + loopRelayers: make(map[relay.ID]loop.Relayer), + srvs: make([]services.ServiceCtx, 0), + } + for _, initFn := range initFuncs { + err2 := initFn(cr) + if err2 != nil { + return nil, err2 + } + } + return cr, nil +} + +// CoreRelayerChainInitFunc is a hook in the constructor to create relayers from a factory. +type CoreRelayerChainInitFunc func(op *CoreRelayerChainInteroperators) error + +// InitEVM is a option for instantiating evm relayers +func InitEVM(ctx context.Context, factory RelayerFactory, config EVMFactoryConfig) CoreRelayerChainInitFunc { + return func(op *CoreRelayerChainInteroperators) (err error) { + adapters, err2 := factory.NewEVM(ctx, config) + if err2 != nil { + return fmt.Errorf("failed to setup EVM relayer: %w", err2) + } + + legacyMap := make(map[string]evm.Chain) + var defaultChain evm.Chain + for id, a := range adapters { + // adapter is a service + op.srvs = append(op.srvs, a) + op.loopRelayers[id] = a + legacyMap[id.ChainID.String()] = a.Chain() + if a.Default() { + defaultChain = a.Chain() + } + + } + legacy, err := evm.NewLegacyChains(config.AppConfig, legacyMap) + if err != nil { + return err + } + op.legacyChains.EVMChains = legacy + // TODO BCF-2510 this may not be necessary if EVM is not enabled by default + if defaultChain != nil { + op.legacyChains.EVMChains.SetDefault(defaultChain) + } + return nil + } +} + +// InitCosmos is a option for instantiating Cosmos relayers +func InitCosmos(ctx context.Context, factory RelayerFactory, config CosmosFactoryConfig) CoreRelayerChainInitFunc { + return func(op *CoreRelayerChainInteroperators) (err error) { + adapters, err2 := factory.NewCosmos(ctx, config) + if err2 != nil { + return fmt.Errorf("failed to setup Cosmos relayer: %w", err2) + } + legacyMap := make(map[string]cosmos.Chain) + for id, a := range adapters { + op.srvs = append(op.srvs, a) + op.loopRelayers[id] = a + legacyMap[id.ChainID.String()] = a.Chain() + } + op.legacyChains.CosmosChains = cosmos.NewLegacyChains(legacyMap) + + return nil + } +} + +// InitSolana is a option for instantiating Solana relayers +func InitSolana(ctx context.Context, factory RelayerFactory, config SolanaFactoryConfig) CoreRelayerChainInitFunc { + return func(op *CoreRelayerChainInteroperators) error { + solRelayers, err2 := factory.NewSolana(config.Keystore, config.SolanaConfigs) + if err2 != nil { + return fmt.Errorf("failed to setup Solana relayer: %w", err2) + } + for id, relayer := range solRelayers { + op.srvs = append(op.srvs, relayer) + op.loopRelayers[id] = relayer + } + + return nil + } +} + +// InitStarknet is a option for instantiating Starknet relayers +func InitStarknet(ctx context.Context, factory RelayerFactory, config StarkNetFactoryConfig) CoreRelayerChainInitFunc { + return func(op *CoreRelayerChainInteroperators) (err error) { + starkRelayers, err2 := factory.NewStarkNet(config.Keystore, config.StarknetConfigs) + if err2 != nil { + return fmt.Errorf("failed to setup StarkNet relayer: %w", err2) + } + for id, relayer := range starkRelayers { + op.srvs = append(op.srvs, relayer) + op.loopRelayers[id] = relayer + } + return nil + } +} + +// Get a [loop.Relayer] by id +func (rs *CoreRelayerChainInteroperators) Get(id relay.ID) (loop.Relayer, error) { + rs.mu.Lock() + defer rs.mu.Unlock() + lr, exist := rs.loopRelayers[id] + if !exist { + return nil, fmt.Errorf("%w: %s", ErrNoSuchRelayer, id) + } + return lr, nil +} + +// LegacyEVMChains returns a container with all the evm chains +// TODO BCF-2511 +func (rs *CoreRelayerChainInteroperators) LegacyEVMChains() evm.LegacyChainContainer { + rs.mu.Lock() + defer rs.mu.Unlock() + return rs.legacyChains.EVMChains +} + +// LegacyCosmosChains returns a container with all the cosmos chains +// TODO BCF-2511 +func (rs *CoreRelayerChainInteroperators) LegacyCosmosChains() cosmos.LegacyChainContainer { + rs.mu.Lock() + defer rs.mu.Unlock() + return rs.legacyChains.CosmosChains +} + +// ChainStatus gets [types.ChainStatus] +func (rs *CoreRelayerChainInteroperators) ChainStatus(ctx context.Context, id relay.ID) (types.ChainStatus, error) { + + lr, err := rs.Get(id) + if err != nil { + return types.ChainStatus{}, fmt.Errorf("%w: error getting chainstatus: %w", chains.ErrNotFound, err) + } + // this call is weird because the [loop.Relayer] interface still requires id + // but in this context the `relayer` should only have only id + // moreover, the `relayer` here is pinned to one chain we need to pass the chain id + return lr.ChainStatus(ctx, id.ChainID.String()) +} + +func (rs *CoreRelayerChainInteroperators) ChainStatuses(ctx context.Context, offset, limit int) ([]types.ChainStatus, int, error) { + // chain statuses are not dynamic; the call would be better named as ChainConfig or such. + + var ( + stats []types.ChainStatus + totalErr error + ) + rs.mu.Lock() + defer rs.mu.Unlock() + + relayerIds := make([]relay.ID, 0) + for rid := range rs.loopRelayers { + relayerIds = append(relayerIds, rid) + } + sort.Slice(relayerIds, func(i, j int) bool { + return relayerIds[i].String() < relayerIds[j].String() + }) + for _, rid := range relayerIds { + lr := rs.loopRelayers[rid] + // the relayer is chain specific; use the chain id and not the relayer id + stat, err := lr.ChainStatus(ctx, rid.ChainID.String()) + if err != nil { + totalErr = errors.Join(totalErr, err) + continue + } + stats = append(stats, stat) + } + + if totalErr != nil { + return nil, 0, totalErr + } + cnt := len(stats) + if len(stats) > limit+offset && limit > 0 { + return stats[offset : offset+limit], cnt, nil + } + return stats[offset:], cnt, nil +} + +func (rs *CoreRelayerChainInteroperators) Node(ctx context.Context, name string) (types.NodeStatus, error) { + // This implementation is round-about + // TODO BFC-2511, may be better in the loop.Relayer interface itself + stats, _, err := rs.NodeStatuses(ctx, 0, -1) + if err != nil { + return types.NodeStatus{}, err + } + for _, stat := range stats { + if stat.Name == name { + return stat, nil + } + } + return types.NodeStatus{}, fmt.Errorf("node %s: %w", name, chains.ErrNotFound) +} + +// ids must be a string representation of relay.Identifier +// ids are a filter; if none are specificied, all are returned. +// TODO: BCF-2440/1 this signature can be changed to id relay.Identifier which is a much better API +func (rs *CoreRelayerChainInteroperators) NodeStatuses(ctx context.Context, offset, limit int, relayerIDs ...string) (nodes []types.NodeStatus, count int, err error) { + var ( + totalErr error + result []types.NodeStatus + ) + if len(relayerIDs) == 0 { + for rid, lr := range rs.loopRelayers { + stats, _, err := lr.NodeStatuses(ctx, offset, limit, rid.ChainID.String()) + if err != nil { + totalErr = errors.Join(totalErr, err) + continue + } + result = append(result, stats...) + } + } else { + for _, idStr := range relayerIDs { + rid := new(relay.ID) + err := rid.UnmarshalString(idStr) + if err != nil { + totalErr = errors.Join(totalErr, err) + continue + } + lr, exist := rs.loopRelayers[*rid] + if !exist { + totalErr = errors.Join(totalErr, fmt.Errorf("relayer %s does not exist", rid.Name())) + continue + } + nodeStats, _, err := lr.NodeStatuses(ctx, offset, limit, rid.ChainID.String()) + + if err != nil { + totalErr = errors.Join(totalErr, err) + continue + } + result = append(result, nodeStats...) + } + } + if totalErr != nil { + return nil, 0, totalErr + } + if len(result) > limit && limit > 0 { + return result[offset : offset+limit], limit, nil + } + return result[offset:], len(result[offset:]), nil +} + +type FilterFn func(id relay.ID) bool + +var AllRelayers = func(id relay.ID) bool { + return true +} + +// Returns true if the given network matches id.Network +func FilterRelayersByType(network relay.Network) func(id relay.ID) bool { + return func(id relay.ID) bool { + return id.Network == network + } +} + +// List returns all the [RelayerChainInteroperators] that match the [FilterFn]. +// A typical usage pattern to use [List] with [FilterByType] to obtain a set of [RelayerChainInteroperators] +// for a given chain +func (rs *CoreRelayerChainInteroperators) List(filter FilterFn) RelayerChainInteroperators { + + matches := make(map[relay.ID]loop.Relayer) + rs.mu.Lock() + for id, relayer := range rs.loopRelayers { + if filter(id) { + matches[id] = relayer + } + } + rs.mu.Unlock() + return &CoreRelayerChainInteroperators{ + loopRelayers: matches, + } +} + +// Returns a slice of [loop.Relayer]. A typically usage pattern to is +// use [List(criteria)].Slice() for range based operations +func (rs *CoreRelayerChainInteroperators) Slice() []loop.Relayer { + var result []loop.Relayer + for _, r := range rs.loopRelayers { + result = append(result, r) + } + return result +} +func (rs *CoreRelayerChainInteroperators) Services() (s []services.ServiceCtx) { + return rs.srvs +} + +// legacyChains encapsulates the chain-specific dependencies. Will be +// deprecated when chain-specific logic is removed from products. +type legacyChains struct { + EVMChains evm.LegacyChainContainer + CosmosChains cosmos.LegacyChainContainer +} diff --git a/core/services/chainlink/relayer_chain_interoperators_test.go b/core/services/chainlink/relayer_chain_interoperators_test.go new file mode 100644 index 00000000000..e86900ea0ee --- /dev/null +++ b/core/services/chainlink/relayer_chain_interoperators_test.go @@ -0,0 +1,423 @@ +package chainlink_test + +import ( + "errors" + "math/big" + "testing" + + "github.com/shopspring/decimal" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + coscfg "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/config" + "github.com/smartcontractkit/chainlink-relay/pkg/loop" + relayutils "github.com/smartcontractkit/chainlink-relay/pkg/utils" + solcfg "github.com/smartcontractkit/chainlink-solana/pkg/solana/config" + stkcfg "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/config" + + "github.com/smartcontractkit/chainlink/v2/core/chains/cosmos" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm" + "github.com/smartcontractkit/chainlink/v2/core/chains/solana" + "github.com/smartcontractkit/chainlink/v2/core/chains/starknet" + "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/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" + "github.com/smartcontractkit/chainlink/v2/core/store/models" + "github.com/smartcontractkit/chainlink/v2/plugins" + + evmcfg "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" + configtest "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest/v2" + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +func TestCoreRelayerChainInteroperators(t *testing.T) { + + evmChainID1, evmChainID2 := utils.NewBig(big.NewInt(1)), utils.NewBig(big.NewInt(2)) + solanaChainID1, solanaChainID2 := "solana-id-1", "solana-id-2" + starknetChainID1, starknetChainID2 := "starknet-id-1", "starknet-id-2" + cosmosChainID1, cosmosChainID2 := "cosmos-id-1", "cosmos-id-2" + + cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { + + cfg := evmcfg.Defaults(evmChainID1) + node1_1 := evmcfg.Node{ + Name: ptr("Test node chain1:1"), + WSURL: models.MustParseURL("ws://localhost:8546"), + HTTPURL: models.MustParseURL("http://localhost:8546"), + SendOnly: ptr(false), + Order: ptr(int32(15)), + } + node1_2 := evmcfg.Node{ + Name: ptr("Test node chain1:2"), + WSURL: models.MustParseURL("ws://localhost:8547"), + HTTPURL: models.MustParseURL("http://localhost:8547"), + SendOnly: ptr(false), + Order: ptr(int32(36)), + } + node2_1 := evmcfg.Node{ + Name: ptr("Test node chain2:1"), + WSURL: models.MustParseURL("ws://localhost:8547"), + HTTPURL: models.MustParseURL("http://localhost:8547"), + SendOnly: ptr(false), + Order: ptr(int32(11)), + } + c.EVM[0] = &evmcfg.EVMConfig{ + ChainID: evmChainID1, + Enabled: ptr(true), + Chain: cfg, + Nodes: evmcfg.EVMNodes{&node1_1, &node1_2}, + } + id2 := utils.NewBig(big.NewInt(2)) + c.EVM = append(c.EVM, &evmcfg.EVMConfig{ + ChainID: evmChainID2, + Chain: evmcfg.Defaults(id2), + Enabled: ptr(true), + Nodes: evmcfg.EVMNodes{&node2_1}, + }) + + c.Solana = solana.SolanaConfigs{ + &solana.SolanaConfig{ + ChainID: &solanaChainID1, + Enabled: ptr(true), + Chain: solcfg.Chain{}, + Nodes: []*solcfg.Node{{ + Name: ptr("solana chain 1 node 1"), + URL: ((*relayutils.URL)(models.MustParseURL("http://localhost:8547").URL())), + }}, + }, + &solana.SolanaConfig{ + ChainID: &solanaChainID2, + Enabled: ptr(true), + Chain: solcfg.Chain{}, + Nodes: []*solcfg.Node{{ + Name: ptr("solana chain 2 node 1"), + URL: ((*relayutils.URL)(models.MustParseURL("http://localhost:8527").URL())), + }}, + }, + } + + c.Starknet = starknet.StarknetConfigs{ + &starknet.StarknetConfig{ + ChainID: &starknetChainID1, + Enabled: ptr(true), + Chain: stkcfg.Chain{}, + Nodes: []*stkcfg.Node{ + { + Name: ptr("starknet chain 1 node 1"), + URL: ((*relayutils.URL)(models.MustParseURL("http://localhost:8547").URL())), + }, + { + Name: ptr("starknet chain 1 node 2"), + URL: ((*relayutils.URL)(models.MustParseURL("http://localhost:8548").URL())), + }, + { + Name: ptr("starknet chain 1 node 3"), + URL: ((*relayutils.URL)(models.MustParseURL("http://localhost:8549").URL())), + }, + }, + }, + &starknet.StarknetConfig{ + ChainID: &starknetChainID2, + Enabled: ptr(true), + Chain: stkcfg.Chain{}, + Nodes: []*stkcfg.Node{ + { + Name: ptr("starknet chain 2 node 1"), + URL: ((*relayutils.URL)(models.MustParseURL("http://localhost:3547").URL())), + }, + }, + }, + } + + c.Cosmos = cosmos.CosmosConfigs{ + &cosmos.CosmosConfig{ + ChainID: &cosmosChainID1, + Enabled: ptr(true), + Chain: coscfg.Chain{ + GasLimitMultiplier: ptr(decimal.RequireFromString("1.55555")), + Bech32Prefix: ptr("wasm"), + FeeToken: ptr("cosm"), + }, + Nodes: cosmos.CosmosNodes{ + &coscfg.Node{ + Name: ptr("cosmos chain 1 node 1"), + TendermintURL: (*relayutils.URL)(models.MustParseURL("http://localhost:9548").URL()), + }, + }, + }, + &cosmos.CosmosConfig{ + ChainID: &cosmosChainID2, + Enabled: ptr(true), + Chain: coscfg.Chain{ + GasLimitMultiplier: ptr(decimal.RequireFromString("0.777")), + Bech32Prefix: ptr("wasm"), + FeeToken: ptr("cosm"), + }, + Nodes: cosmos.CosmosNodes{ + &coscfg.Node{ + Name: ptr("cosmos chain 2 node 1"), + TendermintURL: (*relayutils.URL)(models.MustParseURL("http://localhost:9598").URL()), + }, + }, + }, + } + }) + + db := pgtest.NewSqlxDB(t) + keyStore := cltest.NewKeyStore(t, db, cfg.Database()) + + lggr := logger.TestLogger(t) + + factory := chainlink.RelayerFactory{ + Logger: lggr, + DB: db, + QConfig: cfg.Database(), + LoopRegistry: plugins.NewLoopRegistry(lggr), + GRPCOpts: loop.GRPCOpts{}, + } + + testctx := testutils.Context(t) + + tests := []struct { + name string + initFuncs []chainlink.CoreRelayerChainInitFunc + + expectedEVMChainCnt int + expectedEVMNodeCnt int + expectedEVMRelayerIds []relay.ID + + expectedSolanaChainCnt int + expectedSolanaNodeCnt int + expectedSolanaRelayerIds []relay.ID + + expectedStarknetChainCnt int + expectedStarknetNodeCnt int + expectedStarknetRelayerIds []relay.ID + + expectedCosmosChainCnt int + expectedCosmosNodeCnt int + expectedCosmosRelayerIds []relay.ID + }{ + + {name: "2 evm chains with 3 nodes", + initFuncs: []chainlink.CoreRelayerChainInitFunc{ + chainlink.InitEVM(testctx, factory, chainlink.EVMFactoryConfig{ + RelayerConfig: evm.RelayerConfig{ + AppConfig: cfg, + EventBroadcaster: pg.NewNullEventBroadcaster(), + MailMon: &utils.MailboxMonitor{}, + }, + CSAETHKeystore: keyStore, + }), + }, + expectedEVMChainCnt: 2, + expectedEVMNodeCnt: 3, + expectedEVMRelayerIds: []relay.ID{ + {Network: relay.EVM, ChainID: relay.ChainID(evmChainID1.String())}, + {Network: relay.EVM, ChainID: relay.ChainID(evmChainID2.String())}, + }, + }, + {name: "2 solana chain with 2 node", + initFuncs: []chainlink.CoreRelayerChainInitFunc{ + chainlink.InitSolana(testctx, factory, chainlink.SolanaFactoryConfig{ + Keystore: keyStore.Solana(), + SolanaConfigs: cfg.SolanaConfigs()}), + }, + expectedSolanaChainCnt: 2, + expectedSolanaNodeCnt: 2, + expectedSolanaRelayerIds: []relay.ID{ + {Network: relay.Solana, ChainID: relay.ChainID(solanaChainID1)}, + {Network: relay.Solana, ChainID: relay.ChainID(solanaChainID2)}, + }, + }, + {name: "2 starknet chain with 4 nodes", + initFuncs: []chainlink.CoreRelayerChainInitFunc{ + chainlink.InitStarknet(testctx, factory, chainlink.StarkNetFactoryConfig{ + Keystore: keyStore.StarkNet(), + StarknetConfigs: cfg.StarknetConfigs()}), + }, + expectedStarknetChainCnt: 2, + expectedStarknetNodeCnt: 4, + expectedStarknetRelayerIds: []relay.ID{ + {Network: relay.StarkNet, ChainID: relay.ChainID(starknetChainID1)}, + {Network: relay.StarkNet, ChainID: relay.ChainID(starknetChainID2)}, + }, + }, + { + name: "2 cosmos chains with 2 nodes", + initFuncs: []chainlink.CoreRelayerChainInitFunc{ + chainlink.InitCosmos(testctx, factory, chainlink.CosmosFactoryConfig{ + Keystore: keyStore.Cosmos(), + CosmosConfigs: cfg.CosmosConfigs(), + EventBroadcaster: pg.NewNullEventBroadcaster()}), + }, + expectedCosmosChainCnt: 2, + expectedCosmosNodeCnt: 2, + expectedCosmosRelayerIds: []relay.ID{ + {Network: relay.Cosmos, ChainID: relay.ChainID(cosmosChainID1)}, + {Network: relay.Cosmos, ChainID: relay.ChainID(cosmosChainID2)}, + }, + }, + + {name: "all chains", + initFuncs: []chainlink.CoreRelayerChainInitFunc{chainlink.InitSolana(testctx, factory, chainlink.SolanaFactoryConfig{ + Keystore: keyStore.Solana(), + SolanaConfigs: cfg.SolanaConfigs()}), + chainlink.InitEVM(testctx, factory, chainlink.EVMFactoryConfig{ + RelayerConfig: evm.RelayerConfig{ + AppConfig: cfg, + EventBroadcaster: pg.NewNullEventBroadcaster(), + MailMon: &utils.MailboxMonitor{}, + }, + CSAETHKeystore: keyStore, + }), + chainlink.InitStarknet(testctx, factory, chainlink.StarkNetFactoryConfig{ + Keystore: keyStore.StarkNet(), + StarknetConfigs: cfg.StarknetConfigs()}), + chainlink.InitCosmos(testctx, factory, chainlink.CosmosFactoryConfig{ + Keystore: keyStore.Cosmos(), + CosmosConfigs: cfg.CosmosConfigs(), + EventBroadcaster: pg.NewNullEventBroadcaster(), + }), + }, + expectedEVMChainCnt: 2, + expectedEVMNodeCnt: 3, + expectedEVMRelayerIds: []relay.ID{ + {Network: relay.EVM, ChainID: relay.ChainID(evmChainID1.String())}, + {Network: relay.EVM, ChainID: relay.ChainID(evmChainID2.String())}, + }, + + expectedSolanaChainCnt: 2, + expectedSolanaNodeCnt: 2, + expectedSolanaRelayerIds: []relay.ID{ + {Network: relay.Solana, ChainID: relay.ChainID(solanaChainID1)}, + {Network: relay.Solana, ChainID: relay.ChainID(solanaChainID2)}, + }, + + expectedStarknetChainCnt: 2, + expectedStarknetNodeCnt: 4, + expectedStarknetRelayerIds: []relay.ID{ + {Network: relay.StarkNet, ChainID: relay.ChainID(starknetChainID1)}, + {Network: relay.StarkNet, ChainID: relay.ChainID(starknetChainID2)}, + }, + + expectedCosmosChainCnt: 2, + expectedCosmosNodeCnt: 2, + expectedCosmosRelayerIds: []relay.ID{ + {Network: relay.Cosmos, ChainID: relay.ChainID(cosmosChainID1)}, + {Network: relay.Cosmos, ChainID: relay.ChainID(cosmosChainID2)}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + cr, err := chainlink.NewCoreRelayerChainInteroperators(tt.initFuncs...) + require.NoError(t, err) + + expectedChainCnt := tt.expectedEVMChainCnt + tt.expectedCosmosChainCnt + tt.expectedSolanaChainCnt + tt.expectedStarknetChainCnt + allChainsStats, cnt, err := cr.ChainStatuses(testctx, 0, 0) + assert.NoError(t, err) + assert.Len(t, allChainsStats, expectedChainCnt) + assert.Equal(t, cnt, len(allChainsStats)) + assert.Len(t, cr.Slice(), expectedChainCnt) + + // should be one relayer per chain and one service per relayer + assert.Len(t, cr.Slice(), expectedChainCnt) + assert.Len(t, cr.Services(), expectedChainCnt) + + expectedNodeCnt := tt.expectedEVMNodeCnt + tt.expectedCosmosNodeCnt + tt.expectedSolanaNodeCnt + tt.expectedStarknetNodeCnt + allNodeStats, cnt, err := cr.NodeStatuses(testctx, 0, 0) + assert.NoError(t, err) + assert.Len(t, allNodeStats, expectedNodeCnt) + assert.Equal(t, cnt, len(allNodeStats)) + + for relayNetwork := range relay.SupportedRelays { + var expectedChainCnt, expectedNodeCnt int + switch relayNetwork { + case relay.EVM: + expectedChainCnt, expectedNodeCnt = tt.expectedEVMChainCnt, tt.expectedEVMNodeCnt + case relay.Cosmos: + expectedChainCnt, expectedNodeCnt = tt.expectedCosmosChainCnt, tt.expectedCosmosNodeCnt + case relay.Solana: + expectedChainCnt, expectedNodeCnt = tt.expectedSolanaChainCnt, tt.expectedSolanaNodeCnt + case relay.StarkNet: + expectedChainCnt, expectedNodeCnt = tt.expectedStarknetChainCnt, tt.expectedStarknetNodeCnt + default: + require.Fail(t, "untested relay network", relayNetwork) + } + + interops := cr.List(chainlink.FilterRelayersByType(relayNetwork)) + assert.Len(t, cr.List(chainlink.FilterRelayersByType(relayNetwork)).Slice(), expectedChainCnt) + if relayNetwork == relay.EVM { + assert.Len(t, cr.LegacyEVMChains().Slice(), expectedChainCnt) + } + if relayNetwork == relay.Cosmos { + assert.Len(t, cr.LegacyCosmosChains().Slice(), expectedChainCnt) + } + + nodesStats, cnt, err := interops.NodeStatuses(testctx, 0, 0) + assert.NoError(t, err) + assert.Len(t, nodesStats, expectedNodeCnt) + assert.Equal(t, cnt, len(nodesStats)) + + } + + allRelayerIds := [][]relay.ID{ + tt.expectedEVMRelayerIds, + tt.expectedCosmosRelayerIds, + tt.expectedSolanaRelayerIds, + tt.expectedStarknetRelayerIds, + } + + for _, chainSpecificRelayerIds := range allRelayerIds { + for _, wantId := range chainSpecificRelayerIds { + lr, err := cr.Get(wantId) + assert.NotNil(t, lr) + assert.NoError(t, err) + stat, err := cr.ChainStatus(testctx, wantId) + assert.NoError(t, err) + assert.Equal(t, wantId.ChainID.String(), stat.ID) + // check legacy chains for evm and cosmos + if wantId.Network == relay.EVM { + c, err := cr.LegacyEVMChains().Get(wantId.ChainID.String()) + assert.NoError(t, err) + assert.NotNil(t, c) + assert.Equal(t, wantId.ChainID.String(), c.ID().String()) + } + if wantId.Network == relay.Cosmos { + c, err := cr.LegacyCosmosChains().Get(wantId.ChainID.String()) + assert.NoError(t, err) + assert.NotNil(t, c) + assert.Equal(t, wantId.ChainID.String(), c.ID()) + } + } + } + + expectedMissing := relay.ID{Network: relay.Cosmos, ChainID: "not a chain id"} + unwanted, err := cr.Get(expectedMissing) + assert.Nil(t, unwanted) + assert.ErrorIs(t, err, chainlink.ErrNoSuchRelayer) + + }) + } + + t.Run("bad init func", func(t *testing.T) { + t.Parallel() + errBadFunc := errors.New("this is a bad func") + badFunc := func() chainlink.CoreRelayerChainInitFunc { + return func(op *chainlink.CoreRelayerChainInteroperators) error { + return errBadFunc + } + } + cr, err := chainlink.NewCoreRelayerChainInteroperators(badFunc()) + assert.Nil(t, cr) + assert.ErrorIs(t, err, errBadFunc) + }) +} + +func ptr[T any](t T) *T { return &t } diff --git a/core/services/chainlink/relayer_factory.go b/core/services/chainlink/relayer_factory.go new file mode 100644 index 00000000000..51f18b7e61b --- /dev/null +++ b/core/services/chainlink/relayer_factory.go @@ -0,0 +1,220 @@ +package chainlink + +import ( + "context" + "fmt" + + "github.com/pelletier/go-toml/v2" + "github.com/smartcontractkit/sqlx" + + pkgcosmos "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos" + "github.com/smartcontractkit/chainlink-relay/pkg/loop" + pkgsolana "github.com/smartcontractkit/chainlink-solana/pkg/solana" + pkgstarknet "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/chains/cosmos" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm" + "github.com/smartcontractkit/chainlink/v2/core/chains/solana" + "github.com/smartcontractkit/chainlink/v2/core/chains/starknet" + "github.com/smartcontractkit/chainlink/v2/core/config/env" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + "github.com/smartcontractkit/chainlink/v2/plugins" +) + +type RelayerFactory struct { + logger.Logger + *sqlx.DB + pg.QConfig + *plugins.LoopRegistry + loop.GRPCOpts +} + +type EVMFactoryConfig struct { + evm.RelayerConfig + evmrelay.CSAETHKeystore +} + +func (r *RelayerFactory) NewEVM(ctx context.Context, config EVMFactoryConfig) (map[relay.ID]evmrelay.LoopRelayAdapter, error) { + // TODO impl EVM loop. For now always 'fallback' to an adapter and embedded chainset + + relayers := make(map[relay.ID]evmrelay.LoopRelayAdapter) + + // override some common opts with the factory values. this seems weird... maybe other signatures should change, or this should take a different type... + ccOpts := evm.ChainRelayExtenderConfig{ + + Logger: r.Logger, + DB: r.DB, + KeyStore: config.CSAETHKeystore.Eth(), + RelayerConfig: config.RelayerConfig, + } + + evmRelayExtenders, err := evmrelay.NewChainRelayerExtenders(ctx, ccOpts) + if err != nil { + return nil, err + } + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(evmRelayExtenders) + if err != nil { + return nil, err + } + for _, ext := range evmRelayExtenders.Slice() { + relayID := relay.ID{Network: relay.EVM, ChainID: relay.ChainID(ext.Chain().ID().String())} + chain, err := legacyChains.Get(relayID.ChainID.String()) + if err != nil { + return nil, err + } + relayer := evmrelay.NewLoopRelayAdapter(evmrelay.NewRelayer(ccOpts.DB, chain, r.QConfig, ccOpts.Logger, config.CSAETHKeystore, ccOpts.EventBroadcaster), ext) + relayers[relayID] = relayer + } + + return relayers, nil +} + +type SolanaFactoryConfig struct { + Keystore keystore.Solana + solana.SolanaConfigs +} + +func (r *RelayerFactory) NewSolana(ks keystore.Solana, chainCfgs solana.SolanaConfigs) (map[relay.ID]loop.Relayer, error) { + solanaRelayers := make(map[relay.ID]loop.Relayer) + var ( + solLggr = r.Logger.Named("Solana") + signer = &keystore.SolanaSigner{Solana: ks} + ) + + // create one relayer per chain id + for _, chainCfg := range chainCfgs { + relayId := relay.ID{Network: relay.Solana, ChainID: relay.ChainID(*chainCfg.ChainID)} + // all the lower level APIs expect chainsets. create a single valued set per id + singleChainCfg := solana.SolanaConfigs{chainCfg} + + if cmdName := env.SolanaPluginCmd.Get(); cmdName != "" { + + // setup the solana relayer to be a LOOP + tomls, err := toml.Marshal(struct { + Solana solana.SolanaConfigs + }{Solana: singleChainCfg}) + if err != nil { + return nil, fmt.Errorf("failed to marshal Solana configs: %w", err) + } + + solCmdFn, err := plugins.NewCmdFactory(r.Register, plugins.CmdConfig{ + ID: solLggr.Name(), + Cmd: cmdName, + }) + if err != nil { + return nil, fmt.Errorf("failed to create Solana LOOP command: %w", err) + } + solanaRelayers[relayId] = loop.NewRelayerService(solLggr, r.GRPCOpts, solCmdFn, string(tomls), signer) + + } else { + // fallback to embedded chainset + opts := solana.ChainSetOpts{ + Logger: solLggr, + KeyStore: signer, + Configs: solana.NewConfigs(singleChainCfg), + } + chainSet, err := solana.NewChainSet(opts, singleChainCfg) + if err != nil { + return nil, fmt.Errorf("failed to load Solana chainset: %w", err) + } + solanaRelayers[relayId] = relay.NewRelayerAdapter(pkgsolana.NewRelayer(solLggr, chainSet), chainSet) + } + } + return solanaRelayers, nil +} + +type StarkNetFactoryConfig struct { + Keystore keystore.StarkNet + starknet.StarknetConfigs +} + +func (r *RelayerFactory) NewStarkNet(ks keystore.StarkNet, chainCfgs starknet.StarknetConfigs) (map[relay.ID]loop.Relayer, error) { + starknetRelayers := make(map[relay.ID]loop.Relayer) + + var ( + starkLggr = r.Logger.Named("StarkNet") + loopKs = &keystore.StarknetLooppSigner{StarkNet: ks} + ) + + // create one relayer per chain id + for _, chainCfg := range chainCfgs { + relayId := relay.ID{Network: relay.StarkNet, ChainID: relay.ChainID(*chainCfg.ChainID)} + // all the lower level APIs expect chainsets. create a single valued set per id + singleChainCfg := starknet.StarknetConfigs{chainCfg} + + if cmdName := env.StarknetPluginCmd.Get(); cmdName != "" { + // setup the starknet relayer to be a LOOP + tomls, err := toml.Marshal(struct { + Starknet starknet.StarknetConfigs + }{Starknet: singleChainCfg}) + if err != nil { + return nil, fmt.Errorf("failed to marshal StarkNet configs: %w", err) + } + + starknetCmdFn, err := plugins.NewCmdFactory(r.Register, plugins.CmdConfig{ + ID: starkLggr.Name(), + Cmd: cmdName, + }) + if err != nil { + return nil, fmt.Errorf("failed to create StarkNet LOOP command: %w", err) + } + // the starknet relayer service has a delicate keystore dependency. the value that is passed to NewRelayerService must + // be compatible with instantiating a starknet transaction manager KeystoreAdapter within the LOOPp executable. + starknetRelayers[relayId] = loop.NewRelayerService(starkLggr, r.GRPCOpts, starknetCmdFn, string(tomls), loopKs) + } else { + // fallback to embedded chainset + opts := starknet.ChainSetOpts{ + Logger: starkLggr, + KeyStore: loopKs, + Configs: starknet.NewConfigs(singleChainCfg), + } + chainSet, err := starknet.NewChainSet(opts, singleChainCfg) + if err != nil { + return nil, fmt.Errorf("failed to load StarkNet chainset: %w", err) + } + starknetRelayers[relayId] = relay.NewRelayerAdapter(pkgstarknet.NewRelayer(starkLggr, chainSet), chainSet) + } + } + return starknetRelayers, nil + +} + +type CosmosFactoryConfig struct { + Keystore keystore.Cosmos + cosmos.CosmosConfigs + EventBroadcaster pg.EventBroadcaster +} + +func (r *RelayerFactory) NewCosmos(ctx context.Context, config CosmosFactoryConfig) (map[relay.ID]cosmos.LoopRelayerChainer, error) { + relayers := make(map[relay.ID]cosmos.LoopRelayerChainer) + + var lggr = r.Logger.Named("Cosmos") + + // create one relayer per chain id + for _, chainCfg := range config.CosmosConfigs { + relayId := relay.ID{Network: relay.Cosmos, ChainID: relay.ChainID(*chainCfg.ChainID)} + // all the lower level APIs expect chainsets. create a single valued set per id + // TODO: Cosmos LOOPp impl. For now, use relayer adapter + + opts := cosmos.ChainSetOpts{ + QueryConfig: r.QConfig, + Logger: lggr.Named(relayId.ChainID.String()), + DB: r.DB, + KeyStore: config.Keystore, + EventBroadcaster: config.EventBroadcaster, + } + opts.Configs = cosmos.NewConfigs(cosmos.CosmosConfigs{chainCfg}) + singleChainChainSet, err := cosmos.NewSingleChainSet(opts, chainCfg) + if err != nil { + return nil, fmt.Errorf("failed to load Cosmos chain %q: %w", relayId, err) + } + + relayers[relayId] = cosmos.NewLoopRelayerSingleChain(pkgcosmos.NewRelayer(lggr, singleChainChainSet), singleChainChainSet) + + } + return relayers, nil + +} diff --git a/core/services/chainlink/testdata/config-empty-effective.toml b/core/services/chainlink/testdata/config-empty-effective.toml index 65c5511c581..8c3eef53f6a 100644 --- a/core/services/chainlink/testdata/config-empty-effective.toml +++ b/core/services/chainlink/testdata/config-empty-effective.toml @@ -118,6 +118,7 @@ ContractTransmitterTransmitTimeout = '10s' DatabaseTimeout = '10s' KeyBundleID = '0000000000000000000000000000000000000000000000000000000000000000' CaptureEATelemetry = false +CaptureAutomationCustomTelemetry = false DefaultTransactionQueueDepth = 1 SimulateTransactions = false TraceLogging = false diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index 865bd6d7e4b..4279cc729f9 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -118,6 +118,7 @@ ContractTransmitterTransmitTimeout = '1m0s' DatabaseTimeout = '8s' KeyBundleID = '7a5f66bbe6594259325bf2b4f5b1a9c900000000000000000000000000000000' CaptureEATelemetry = false +CaptureAutomationCustomTelemetry = false DefaultTransactionQueueDepth = 1 SimulateTransactions = false TraceLogging = false @@ -319,11 +320,12 @@ SendOnly = true [[Cosmos]] ChainID = 'Malaga-420' Enabled = true +Bech32Prefix = 'wasm' BlockRate = '1m0s' BlocksUntilTxTimeout = 12 ConfirmPollPeriod = '1s' FallbackGasPrice = '0.001' -FCDURL = 'http://cosmos.com' +FeeToken = 'ucosm' GasLimitMultiplier = '1.2' MaxMsgsPerBatch = 17 OCR2CachePollPeriod = '1m0s' diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index 73a0d5867a3..d6b38349b83 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -118,6 +118,7 @@ ContractTransmitterTransmitTimeout = '10s' DatabaseTimeout = '20s' KeyBundleID = '0000000000000000000000000000000000000000000000000000000000000000' CaptureEATelemetry = false +CaptureAutomationCustomTelemetry = false DefaultTransactionQueueDepth = 1 SimulateTransactions = false TraceLogging = false @@ -450,11 +451,12 @@ WSURL = 'wss://web.socket/test/bar' [[Cosmos]] ChainID = 'Ibiza-808' +Bech32Prefix = 'wasm' BlockRate = '6s' BlocksUntilTxTimeout = 30 ConfirmPollPeriod = '1s' FallbackGasPrice = '0.015' -FCDURL = '' +FeeToken = 'ucosm' GasLimitMultiplier = '1.5' MaxMsgsPerBatch = 13 OCR2CachePollPeriod = '4s' @@ -467,11 +469,12 @@ TendermintURL = 'http://columbus.cosmos.com' [[Cosmos]] ChainID = 'Malaga-420' +Bech32Prefix = 'wasm' BlockRate = '6s' BlocksUntilTxTimeout = 20 ConfirmPollPeriod = '1s' FallbackGasPrice = '0.015' -FCDURL = '' +FeeToken = 'ucosm' GasLimitMultiplier = '1.5' MaxMsgsPerBatch = 100 OCR2CachePollPeriod = '4s' diff --git a/core/services/cron/cron_test.go b/core/services/cron/cron_test.go index 5ce0414bf1d..1d89248d4a5 100644 --- a/core/services/cron/cron_test.go +++ b/core/services/cron/cron_test.go @@ -19,6 +19,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" pipelinemocks "github.com/smartcontractkit/chainlink/v2/core/services/pipeline/mocks" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" ) func TestCronV2Pipeline(t *testing.T) { @@ -27,11 +28,13 @@ func TestCronV2Pipeline(t *testing.T) { db := pgtest.NewSqlxDB(t) keyStore := cltest.NewKeyStore(t, db, cfg.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, Client: evmtest.NewEthClientMockWithDefaultChain(t), KeyStore: keyStore.Eth()}) + relayerExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, Client: evmtest.NewEthClientMockWithDefaultChain(t), KeyStore: keyStore.Eth()}) lggr := logger.TestLogger(t) orm := pipeline.NewORM(db, lggr, cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns()) btORM := bridges.NewORM(db, lggr, cfg.Database()) - jobORM := job.NewORM(db, cc, orm, btORM, keyStore, lggr, cfg.Database()) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayerExtenders) + require.NoError(t, err) + jobORM := job.NewORM(db, legacyChains, orm, btORM, keyStore, lggr, cfg.Database()) jb := &job.Job{ Type: job.Cron, @@ -42,7 +45,7 @@ func TestCronV2Pipeline(t *testing.T) { } delegate := cron.NewDelegate(runner, lggr) - err := jobORM.CreateJob(jb) + err = jobORM.CreateJob(jb) require.NoError(t, err) serviceArray, err := delegate.ServicesForSpec(*jb) require.NoError(t, err) diff --git a/core/services/cron/delegate.go b/core/services/cron/delegate.go index c227fd60d00..a411a120128 100644 --- a/core/services/cron/delegate.go +++ b/core/services/cron/delegate.go @@ -33,7 +33,7 @@ func (d *Delegate) BeforeJobDeleted(spec job.Job) {} func (d *Delegate) OnDeleteJob(spec job.Job, q pg.Queryer) error { return nil } // ServicesForSpec returns the scheduler to be used for running cron jobs -func (d *Delegate) ServicesForSpec(spec job.Job) (services []job.ServiceCtx, err error) { +func (d *Delegate) ServicesForSpec(spec job.Job, qopts ...pg.QOpt) (services []job.ServiceCtx, err error) { if spec.CronSpec == nil { return nil, errors.Errorf("services.Delegate expects a *jobSpec.CronSpec to be present, got %v", spec) } diff --git a/core/services/directrequest/delegate.go b/core/services/directrequest/delegate.go index 9f32a4e11a2..4e2ca1e1899 100644 --- a/core/services/directrequest/delegate.go +++ b/core/services/directrequest/delegate.go @@ -29,7 +29,7 @@ type ( pipelineRunner pipeline.Runner pipelineORM pipeline.ORM chHeads chan *evmtypes.Head - chainSet evm.ChainSet + legacyChains evm.LegacyChainContainer mailMon *utils.MailboxMonitor } @@ -45,16 +45,16 @@ func NewDelegate( logger logger.Logger, pipelineRunner pipeline.Runner, pipelineORM pipeline.ORM, - chainSet evm.ChainSet, + legacyChains evm.LegacyChainContainer, mailMon *utils.MailboxMonitor, ) *Delegate { return &Delegate{ - logger.Named("DirectRequest"), - pipelineRunner, - pipelineORM, - make(chan *evmtypes.Head, 1), - chainSet, - mailMon, + logger: logger.Named("DirectRequest"), + pipelineRunner: pipelineRunner, + pipelineORM: pipelineORM, + chHeads: make(chan *evmtypes.Head, 1), + legacyChains: legacyChains, + mailMon: mailMon, } } @@ -68,11 +68,11 @@ func (d *Delegate) BeforeJobDeleted(spec job.Job) {} func (d *Delegate) OnDeleteJob(spec job.Job, q pg.Queryer) error { return nil } // ServicesForSpec returns the log listener service for a direct request job -func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { +func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceCtx, error) { if jb.DirectRequestSpec == nil { return nil, errors.Errorf("DirectRequest: directrequest.Delegate expects a *job.DirectRequestSpec to be present, got %v", jb) } - chain, err := d.chainSet.Get(jb.DirectRequestSpec.EVMChainID.ToInt()) + chain, err := d.legacyChains.Get(jb.DirectRequestSpec.EVMChainID.String()) if err != nil { return nil, err } diff --git a/core/services/directrequest/delegate_test.go b/core/services/directrequest/delegate_test.go index c79f5caaafb..8a453dbe9db 100644 --- a/core/services/directrequest/delegate_test.go +++ b/core/services/directrequest/delegate_test.go @@ -30,6 +30,7 @@ import ( "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" "github.com/smartcontractkit/chainlink/v2/core/services/srvctest" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -43,10 +44,12 @@ func TestDelegate_ServicesForSpec(t *testing.T) { }) keyStore := cltest.NewKeyStore(t, db, cfg.Database()) mailMon := srvctest.Start(t, utils.NewMailboxMonitor(t.Name())) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, Client: ethClient, MailMon: mailMon, KeyStore: keyStore.Eth()}) + relayerExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, Client: ethClient, MailMon: mailMon, KeyStore: keyStore.Eth()}) lggr := logger.TestLogger(t) - delegate := directrequest.NewDelegate(lggr, runner, nil, cc, mailMon) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayerExtenders) + require.NoError(t, err) + delegate := directrequest.NewDelegate(lggr, runner, nil, legacyChains, mailMon) t.Run("Spec without DirectRequestSpec", func(t *testing.T) { spec := job.Job{} @@ -82,20 +85,21 @@ func NewDirectRequestUniverseWithConfig(t *testing.T, cfg chainlink.GeneralConfi db := pgtest.NewSqlxDB(t) keyStore := cltest.NewKeyStore(t, db, cfg.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, Client: ethClient, LogBroadcaster: broadcaster, MailMon: mailMon, KeyStore: keyStore.Eth()}) + 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()) - - jobORM := job.NewORM(db, cc, orm, btORM, keyStore, lggr, cfg.Database()) - delegate := directrequest.NewDelegate(lggr, runner, orm, cc, mailMon) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + jobORM := job.NewORM(db, legacyChains, orm, btORM, keyStore, lggr, cfg.Database()) + delegate := directrequest.NewDelegate(lggr, runner, orm, legacyChains, mailMon) jb := cltest.MakeDirectRequestJobSpec(t) jb.ExternalJobID = uuid.New() if specF != nil { specF(jb) } - err := jobORM.CreateJob(jb) + err = jobORM.CreateJob(jb) require.NoError(t, err) serviceArray, err := delegate.ServicesForSpec(*jb) require.NoError(t, err) diff --git a/core/services/feeds/orm_test.go b/core/services/feeds/orm_test.go index 22850c6d703..0ff60188008 100644 --- a/core/services/feeds/orm_test.go +++ b/core/services/feeds/orm_test.go @@ -22,6 +22,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/ocr" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/testdata/testspecs" "github.com/smartcontractkit/chainlink/v2/core/utils" "github.com/smartcontractkit/chainlink/v2/core/utils/crypto" @@ -1467,15 +1468,16 @@ func createJob(t *testing.T, db *sqlx.DB, externalJobID uuid.UUID) *job.Job { t.Helper() var ( - 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()) - cc = evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - orm = job.NewORM(db, cc, pipelineORM, bridgeORM, keyStore, lggr, config.Database()) + 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()) + relayExtenders = evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) ) - + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + orm := job.NewORM(db, legacyChains, pipelineORM, bridgeORM, keyStore, lggr, config.Database()) require.NoError(t, keyStore.OCR().Add(cltest.DefaultOCRKey)) require.NoError(t, keyStore.P2P().Add(cltest.DefaultP2PKey)) @@ -1485,7 +1487,7 @@ func createJob(t *testing.T, db *sqlx.DB, externalJobID uuid.UUID) *job.Job { _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) _, address := cltest.MustInsertRandomKey(t, keyStore.Eth()) - jb, err := ocr.ValidatedOracleSpecToml(cc, + jb, err := ocr.ValidatedOracleSpecToml(legacyChains, testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{ JobID: externalJobID.String(), TransmitterAddress: address.Hex(), diff --git a/core/services/feeds/service.go b/core/services/feeds/service.go index 112750ef1ec..ca0dcbb06cc 100644 --- a/core/services/feeds/service.go +++ b/core/services/feeds/service.go @@ -113,7 +113,7 @@ type service struct { ocrCfg OCRConfig ocr2cfg OCR2Config connMgr ConnectionsManager - chainSet evm.ChainSet + legacyChains evm.LegacyChainContainer lggr logger.Logger version string } @@ -130,7 +130,7 @@ func NewService( ocrCfg OCRConfig, ocr2Cfg OCR2Config, dbCfg pg.QConfig, - chainSet evm.ChainSet, + legacyChains evm.LegacyChainContainer, lggr logger.Logger, version string, ) *service { @@ -149,7 +149,7 @@ func NewService( ocrCfg: ocrCfg, ocr2cfg: ocr2Cfg, connMgr: newConnectionsManager(lggr), - chainSet: chainSet, + legacyChains: legacyChains, lggr: lggr, version: version, } @@ -1094,7 +1094,7 @@ func (s *service) generateJob(spec string) (*job.Job, error) { if !s.ocrCfg.Enabled() { return nil, ErrOCRDisabled } - js, err = ocr.ValidatedOracleSpecToml(s.chainSet, spec) + js, err = ocr.ValidatedOracleSpecToml(s.legacyChains, spec) case job.OffchainReporting2: if !s.ocr2cfg.Enabled() { return nil, ErrOCR2Disabled diff --git a/core/services/feeds/service_test.go b/core/services/feeds/service_test.go index ebe3037eeac..48fefd35daf 100644 --- a/core/services/feeds/service_test.go +++ b/core/services/feeds/service_test.go @@ -31,6 +31,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" ksmocks "github.com/smartcontractkit/chainlink/v2/core/services/keystore/mocks" "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/versioning" "github.com/smartcontractkit/chainlink/v2/core/store/models" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -147,7 +148,7 @@ type TestService struct { p2pKeystore *ksmocks.P2P ocr1Keystore *ksmocks.OCR ocr2Keystore *ksmocks.OCR2 - cc evm.ChainSet + legacyChains evm.LegacyChainContainer } func setupTestService(t *testing.T) *TestService { @@ -178,14 +179,16 @@ func setupTestServiceCfg(t *testing.T, overrideCfg func(c *chainlink.Config, s * keyStore := new(ksmocks.Master) scopedConfig := evmtest.NewChainScopedConfig(t, gcfg) ethKeyStore := cltest.NewKeyStore(t, db, gcfg.Database()).Eth() - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{GeneralConfig: gcfg, + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{GeneralConfig: gcfg, HeadTracker: headtracker.NullTracker, KeyStore: ethKeyStore}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) keyStore.On("Eth").Return(ethKeyStore) keyStore.On("CSA").Return(csaKeystore) keyStore.On("P2P").Return(p2pKeystore) keyStore.On("OCR").Return(ocr1Keystore) keyStore.On("OCR2").Return(ocr2Keystore) - svc := feeds.NewService(orm, jobORM, db, spawner, keyStore, scopedConfig.Insecure(), scopedConfig.JobPipeline(), scopedConfig.OCR(), scopedConfig.OCR2(), scopedConfig.Database(), cc, lggr, "1.0.0") + svc := feeds.NewService(orm, jobORM, db, spawner, keyStore, scopedConfig.Insecure(), scopedConfig.JobPipeline(), scopedConfig.OCR(), scopedConfig.OCR2(), scopedConfig.Database(), legacyChains, lggr, "1.0.0") svc.SetConnectionsManager(connMgr) return &TestService{ @@ -199,7 +202,7 @@ func setupTestServiceCfg(t *testing.T, overrideCfg func(c *chainlink.Config, s * p2pKeystore: p2pKeystore, ocr1Keystore: ocr1Keystore, ocr2Keystore: ocr2Keystore, - cc: cc, + legacyChains: legacyChains, } } diff --git a/core/services/fluxmonitorv2/delegate.go b/core/services/fluxmonitorv2/delegate.go index ba2edf9e0f0..0564eecaee4 100644 --- a/core/services/fluxmonitorv2/delegate.go +++ b/core/services/fluxmonitorv2/delegate.go @@ -21,7 +21,7 @@ type Delegate struct { jobORM job.ORM pipelineORM pipeline.ORM pipelineRunner pipeline.Runner - chainSet evm.ChainSet + legacyChains evm.LegacyChainContainer lggr logger.Logger } @@ -34,17 +34,17 @@ func NewDelegate( pipelineORM pipeline.ORM, pipelineRunner pipeline.Runner, db *sqlx.DB, - chainSet evm.ChainSet, + legacyChains evm.LegacyChainContainer, lggr logger.Logger, ) *Delegate { return &Delegate{ - db, - ethKeyStore, - jobORM, - pipelineORM, - pipelineRunner, - chainSet, - lggr.Named("FluxMonitor"), + db: db, + ethKeyStore: ethKeyStore, + jobORM: jobORM, + pipelineORM: pipelineORM, + pipelineRunner: pipelineRunner, + legacyChains: legacyChains, + lggr: lggr.Named("FluxMonitor"), } } @@ -59,11 +59,11 @@ func (d *Delegate) BeforeJobDeleted(spec job.Job) {} func (d *Delegate) OnDeleteJob(spec job.Job, q pg.Queryer) error { return nil } // ServicesForSpec returns the flux monitor service for the job spec -func (d *Delegate) ServicesForSpec(jb job.Job) (services []job.ServiceCtx, err error) { +func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) (services []job.ServiceCtx, err error) { if jb.FluxMonitorSpec == nil { return nil, errors.Errorf("Delegate expects a *job.FluxMonitorSpec to be present, got %v", jb) } - chain, err := d.chainSet.Get(jb.FluxMonitorSpec.EVMChainID.ToInt()) + chain, err := d.legacyChains.Get(jb.FluxMonitorSpec.EVMChainID.String()) if err != nil { return nil, err } diff --git a/core/services/fluxmonitorv2/integrations_test.go b/core/services/fluxmonitorv2/integrations_test.go index 24d6c86a9c8..e76d859e81b 100644 --- a/core/services/fluxmonitorv2/integrations_test.go +++ b/core/services/fluxmonitorv2/integrations_test.go @@ -529,7 +529,7 @@ func TestFluxMonitor_Deviation(t *testing.T) { // Waiting for flux monitor to finish Register process in log broadcaster // and then to have log broadcaster backfill logs after the debounceResubscribe period of ~ 1 sec g.Eventually(func() uint32 { - lb := evmtest.MustGetDefaultChain(t, app.GetChains().EVM).LogBroadcaster() + lb := evmtest.MustGetDefaultChain(t, app.GetRelayers().LegacyEVMChains()).LogBroadcaster() return lb.(log.BroadcasterInTest).TrackedAddressesCount() }, testutils.WaitTimeout(t), 200*time.Millisecond).Should(gomega.BeNumerically(">=", 1)) @@ -680,7 +680,7 @@ ds1 -> ds1_parse // Waiting for flux monitor to finish Register process in log broadcaster // and then to have log broadcaster backfill logs after the debounceResubscribe period of ~ 1 sec g.Eventually(func() uint32 { - lb := evmtest.MustGetDefaultChain(t, app.GetChains().EVM).LogBroadcaster() + lb := evmtest.MustGetDefaultChain(t, app.GetRelayers().LegacyEVMChains()).LogBroadcaster() return lb.(log.BroadcasterInTest).TrackedAddressesCount() }, testutils.WaitTimeout(t), 200*time.Millisecond).Should(gomega.BeNumerically(">=", 2)) diff --git a/core/services/fluxmonitorv2/orm_test.go b/core/services/fluxmonitorv2/orm_test.go index 90b5c5a4308..e7185efa7bd 100644 --- a/core/services/fluxmonitorv2/orm_test.go +++ b/core/services/fluxmonitorv2/orm_test.go @@ -22,6 +22,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/fluxmonitorv2" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" ) func TestORM_MostRecentFluxMonitorRoundID(t *testing.T) { @@ -93,17 +94,19 @@ func TestORM_UpdateFluxMonitorRoundStats(t *testing.T) { pipelineORM := pipeline.NewORM(db, lggr, cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns()) bridgeORM := bridges.NewORM(db, lggr, cfg.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{GeneralConfig: cfg, DB: db, KeyStore: keyStore.Eth()}) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{GeneralConfig: cfg, DB: db, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) // Instantiate a real job ORM because we need to create a job to satisfy // a check in pipeline.CreateRun - jobORM := job.NewORM(db, cc, pipelineORM, bridgeORM, keyStore, lggr, cfg.Database()) + jobORM := job.NewORM(db, legacyChains, pipelineORM, bridgeORM, keyStore, lggr, cfg.Database()) orm := newORM(t, db, cfg.Database(), nil) address := testutils.NewAddress() var roundID uint32 = 1 jb := makeJob(t) - err := jobORM.CreateJob(jb) + err = jobORM.CreateJob(jb) require.NoError(t, err) for expectedCount := uint64(1); expectedCount < 4; expectedCount++ { diff --git a/core/services/functions/external_adapter_client.go b/core/services/functions/external_adapter_client.go index 3bd8ff74046..fc12406e442 100644 --- a/core/services/functions/external_adapter_client.go +++ b/core/services/functions/external_adapter_client.go @@ -33,6 +33,7 @@ type ExternalAdapterClient interface { jobName string, subscriptionOwner string, subscriptionId uint64, + flags RequestFlags, nodeProvidedSecrets string, requestData *RequestData, ) (userResult, userError []byte, domains []string, err error) @@ -66,6 +67,7 @@ type requestPayload struct { JobName string `json:"jobName"` SubscriptionOwner string `json:"subscriptionOwner"` SubscriptionId uint64 `json:"subscriptionId"` + Flags RequestFlags `json:"flags"` // marshalled as an array of numbers NodeProvidedSecrets string `json:"nodeProvidedSecrets"` Data *RequestData `json:"data"` } @@ -123,6 +125,7 @@ func (ea *externalAdapterClient) RunComputation( jobName string, subscriptionOwner string, subscriptionId uint64, + flags RequestFlags, nodeProvidedSecrets string, requestData *RequestData, ) (userResult, userError []byte, domains []string, err error) { @@ -133,6 +136,7 @@ func (ea *externalAdapterClient) RunComputation( JobName: jobName, SubscriptionOwner: subscriptionOwner, SubscriptionId: subscriptionId, + Flags: flags, NodeProvidedSecrets: nodeProvidedSecrets, Data: requestData, } diff --git a/core/services/functions/external_adapter_client_test.go b/core/services/functions/external_adapter_client_test.go index 9feb3c689c0..a0d6d461099 100644 --- a/core/services/functions/external_adapter_client_test.go +++ b/core/services/functions/external_adapter_client_test.go @@ -51,7 +51,7 @@ func runRequestTest(t *testing.T, adapterJSONResponse, expectedUserResult, expec assert.NoError(t, err, "Unexpected error") ea := functions.NewExternalAdapterClient(*adapterUrl, 100_000) - userResult, userError, domains, err := ea.RunComputation(testutils.Context(t), "requestID1234", "TestJob", "SubOwner", 1, "", &functions.RequestData{}) + userResult, userError, domains, err := ea.RunComputation(testutils.Context(t), "requestID1234", "TestJob", "SubOwner", 1, functions.RequestFlags{}, "", &functions.RequestData{}) if expectedError != nil { assert.Equal(t, expectedError.Error(), err.Error(), "Unexpected error") @@ -167,7 +167,7 @@ func TestRunComputation_CorrectAdapterRequest(t *testing.T) { body, err := io.ReadAll(r.Body) assert.NoError(t, err) expectedData := `{"source":"abcd","language":7,"codeLocation":42,"secrets":"qrvM","secretsLocation":88,"args":["arg1","arg2"]}` - expectedBody := fmt.Sprintf(`{"endpoint":"lambda","requestId":"requestID1234","jobName":"TestJob","subscriptionOwner":"SubOwner","subscriptionId":1,"nodeProvidedSecrets":"secRETS","data":%s}`, expectedData) + expectedBody := fmt.Sprintf(`{"endpoint":"lambda","requestId":"requestID1234","jobName":"TestJob","subscriptionOwner":"SubOwner","subscriptionId":1,"flags":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"nodeProvidedSecrets":"secRETS","data":%s}`, expectedData) assert.Equal(t, expectedBody, string(body)) fmt.Fprintln(w, "}}invalidJSON") @@ -186,7 +186,7 @@ func TestRunComputation_CorrectAdapterRequest(t *testing.T) { SecretsLocation: 88, Args: []string{"arg1", "arg2"}, } - _, _, _, err = ea.RunComputation(testutils.Context(t), "requestID1234", "TestJob", "SubOwner", 1, "secRETS", reqData) + _, _, _, err = ea.RunComputation(testutils.Context(t), "requestID1234", "TestJob", "SubOwner", 1, functions.RequestFlags{}, "secRETS", reqData) assert.Error(t, err) } @@ -200,7 +200,7 @@ func TestRunComputation_HTTP500(t *testing.T) { assert.NoError(t, err) ea := functions.NewExternalAdapterClient(*adapterUrl, 100_000) - _, _, _, err = ea.RunComputation(testutils.Context(t), "requestID1234", "TestJob", "SubOwner", 1, "secRETS", &functions.RequestData{}) + _, _, _, err = ea.RunComputation(testutils.Context(t), "requestID1234", "TestJob", "SubOwner", 1, functions.RequestFlags{}, "secRETS", &functions.RequestData{}) assert.Error(t, err) } @@ -217,7 +217,7 @@ func TestRunComputation_ContextRespected(t *testing.T) { ea := functions.NewExternalAdapterClient(*adapterUrl, 100_000) ctx, cancel := context.WithTimeout(testutils.Context(t), 10*time.Millisecond) defer cancel() - _, _, _, err = ea.RunComputation(ctx, "requestID1234", "TestJob", "SubOwner", 1, "secRETS", &functions.RequestData{}) + _, _, _, err = ea.RunComputation(ctx, "requestID1234", "TestJob", "SubOwner", 1, functions.RequestFlags{}, "secRETS", &functions.RequestData{}) assert.Error(t, err) close(done) } diff --git a/core/services/functions/listener.go b/core/services/functions/listener.go index c5ecb5f2c2a..f7c94437654 100644 --- a/core/services/functions/listener.go +++ b/core/services/functions/listener.go @@ -3,6 +3,7 @@ package functions import ( "context" "fmt" + "math" "reflect" "sync" "time" @@ -14,13 +15,16 @@ import ( "google.golang.org/protobuf/proto" "github.com/smartcontractkit/chainlink/v2/core/cbor" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_coordinator" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/ocr2dr_oracle" "github.com/smartcontractkit/chainlink/v2/core/logger" "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" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -111,27 +115,31 @@ const ( DefaultPruneMaxStoredRequests uint32 = 20_000 DefaultPruneCheckFrequencySec uint32 = 60 * 10 DefaultPruneBatchSize uint32 = 500 + + FlagCBORMaxSize uint32 = 1 + FlagSecretsMaxSize uint32 = 2 ) type FunctionsListener struct { utils.StartStopOnce - oracle *ocr2dr_oracle.OCR2DROracle - oracleHexAddr string - job job.Job - bridgeAccessor BridgeAccessor - logBroadcaster log.Broadcaster - shutdownWaitGroup sync.WaitGroup - mbOracleEvents *utils.Mailbox[log.Broadcast] - serviceContext context.Context - serviceCancel context.CancelFunc - chStop chan struct{} - pluginORM ORM - pluginConfig config.PluginConfig - s4Storage s4.Storage - logger logger.Logger - mailMon *utils.MailboxMonitor - urlsMonEndpoint commontypes.MonitoringEndpoint - decryptor threshold.Decryptor + client client.Client + contractAddressHex string + job job.Job + bridgeAccessor BridgeAccessor + logBroadcaster log.Broadcaster + shutdownWaitGroup sync.WaitGroup + mbOracleEvents *utils.Mailbox[log.Broadcast] + serviceContext context.Context + serviceCancel context.CancelFunc + chStop chan struct{} + pluginORM ORM + pluginConfig config.PluginConfig + s4Storage s4.Storage + logger logger.Logger + mailMon *utils.MailboxMonitor + urlsMonEndpoint commontypes.MonitoringEndpoint + decryptor threshold.Decryptor + logPollerWrapper evmrelayTypes.LogPollerWrapper } func formatRequestId(requestId [32]byte) string { @@ -139,8 +147,9 @@ func formatRequestId(requestId [32]byte) string { } func NewFunctionsListener( - oracle *ocr2dr_oracle.OCR2DROracle, job job.Job, + client client.Client, + contractAddressHex string, bridgeAccessor BridgeAccessor, pluginORM ORM, pluginConfig config.PluginConfig, @@ -150,22 +159,24 @@ func NewFunctionsListener( mailMon *utils.MailboxMonitor, urlsMonEndpoint commontypes.MonitoringEndpoint, decryptor threshold.Decryptor, + logPollerWrapper evmrelayTypes.LogPollerWrapper, ) *FunctionsListener { return &FunctionsListener{ - oracle: oracle, - oracleHexAddr: oracle.Address().Hex(), - job: job, - bridgeAccessor: bridgeAccessor, - logBroadcaster: logBroadcaster, - mbOracleEvents: utils.NewHighCapacityMailbox[log.Broadcast](), - chStop: make(chan struct{}), - pluginORM: pluginORM, - pluginConfig: pluginConfig, - s4Storage: s4Storage, - logger: lggr, - mailMon: mailMon, - urlsMonEndpoint: urlsMonEndpoint, - decryptor: decryptor, + client: client, + contractAddressHex: contractAddressHex, + job: job, + bridgeAccessor: bridgeAccessor, + logBroadcaster: logBroadcaster, + mbOracleEvents: utils.NewHighCapacityMailbox[log.Broadcast](), + chStop: make(chan struct{}), + pluginORM: pluginORM, + pluginConfig: pluginConfig, + s4Storage: s4Storage, + logger: lggr, + mailMon: mailMon, + urlsMonEndpoint: urlsMonEndpoint, + decryptor: decryptor, + logPollerWrapper: logPollerWrapper, } } @@ -173,28 +184,47 @@ func NewFunctionsListener( func (l *FunctionsListener) Start(context.Context) error { return l.StartOnce("FunctionsListener", func() error { l.serviceContext, l.serviceCancel = context.WithCancel(context.Background()) - unsubscribeLogs := l.logBroadcaster.Register(l, log.ListenerOpts{ - Contract: l.oracle.Address(), - ParseLog: l.oracle.ParseLog, - LogsWithTopics: map[common.Hash][][]log.Topic{ - ocr2dr_oracle.OCR2DROracleOracleRequest{}.Topic(): {}, - ocr2dr_oracle.OCR2DROracleOracleResponse{}.Topic(): {}, - ocr2dr_oracle.OCR2DROracleUserCallbackError{}.Topic(): {}, - ocr2dr_oracle.OCR2DROracleUserCallbackRawError{}.Topic(): {}, - ocr2dr_oracle.OCR2DROracleResponseTransmitted{}.Topic(): {}, - }, - MinIncomingConfirmations: l.pluginConfig.MinIncomingConfirmations, - }) + contractAddress := common.HexToAddress(l.contractAddressHex) + var unsubscribeLogs func() + + switch l.pluginConfig.ContractVersion { + case 0: + oracleContract, err := ocr2dr_oracle.NewOCR2DROracle(contractAddress, l.client) + if err != nil { + return err + } + unsubscribeLogs = l.logBroadcaster.Register(l, log.ListenerOpts{ + Contract: oracleContract.Address(), + ParseLog: oracleContract.ParseLog, + LogsWithTopics: map[common.Hash][][]log.Topic{ + ocr2dr_oracle.OCR2DROracleOracleRequest{}.Topic(): {}, + ocr2dr_oracle.OCR2DROracleOracleResponse{}.Topic(): {}, + ocr2dr_oracle.OCR2DROracleUserCallbackError{}.Topic(): {}, + ocr2dr_oracle.OCR2DROracleUserCallbackRawError{}.Topic(): {}, + ocr2dr_oracle.OCR2DROracleResponseTransmitted{}.Topic(): {}, + }, + MinIncomingConfirmations: l.pluginConfig.MinIncomingConfirmations, + }) + l.shutdownWaitGroup.Add(1) + go l.processOracleEventsV0() + case 1: + l.shutdownWaitGroup.Add(1) + go l.processOracleEventsV1() + default: + return errors.New("Functions: unsupported PluginConfig.ContractVersion") + } + if l.pluginConfig.ListenerEventHandlerTimeoutSec == 0 { l.logger.Warn("listenerEventHandlerTimeoutSec set to zero! ORM calls will never time out.") } - l.shutdownWaitGroup.Add(4) - go l.processOracleEvents() + l.shutdownWaitGroup.Add(3) go l.timeoutRequests() go l.pruneRequests() go func() { <-l.chStop - unsubscribeLogs() + if unsubscribeLogs != nil { + unsubscribeLogs() // v0 only + } l.shutdownWaitGroup.Done() }() @@ -224,7 +254,7 @@ func (l *FunctionsListener) HandleLog(lb log.Broadcast) { } switch log := log.(type) { - case *ocr2dr_oracle.OCR2DROracleOracleRequest, *ocr2dr_oracle.OCR2DROracleOracleResponse, *ocr2dr_oracle.OCR2DROracleUserCallbackError, *ocr2dr_oracle.OCR2DROracleUserCallbackRawError, *ocr2dr_oracle.OCR2DROracleResponseTransmitted: + case *ocr2dr_oracle.OCR2DROracleOracleRequest, *ocr2dr_oracle.OCR2DROracleOracleResponse, *ocr2dr_oracle.OCR2DROracleUserCallbackError, *ocr2dr_oracle.OCR2DROracleUserCallbackRawError, *ocr2dr_oracle.OCR2DROracleResponseTransmitted, *functions_coordinator.FunctionsCoordinatorOracleRequest, *functions_coordinator.FunctionsCoordinatorOracleResponse: wasOverCapacity := l.mbOracleEvents.Deliver(lb) if wasOverCapacity { l.logger.Error("OracleRequest log mailbox is over capacity - dropped the oldest log") @@ -239,7 +269,7 @@ func (l *FunctionsListener) JobID() int32 { return l.job.ID } -func (l *FunctionsListener) processOracleEvents() { +func (l *FunctionsListener) processOracleEventsV0() { defer l.shutdownWaitGroup.Done() for { select { @@ -271,22 +301,23 @@ func (l *FunctionsListener) processOracleEvents() { } switch log := log.(type) { + // Version 0 case *ocr2dr_oracle.OCR2DROracleOracleRequest: promOracleEvent.WithLabelValues(log.Raw.Address.Hex(), "OracleRequest").Inc() l.shutdownWaitGroup.Add(1) - go l.handleOracleRequest(log, lb) + go l.handleOracleRequestV0(log, lb) case *ocr2dr_oracle.OCR2DROracleOracleResponse: promOracleEvent.WithLabelValues(log.Raw.Address.Hex(), "OracleResponse").Inc() l.shutdownWaitGroup.Add(1) - go l.handleOracleResponse("OracleResponse", log.RequestId, lb) + go l.handleOracleResponseV0("OracleResponse", log.RequestId, lb) case *ocr2dr_oracle.OCR2DROracleUserCallbackError: promOracleEvent.WithLabelValues(log.Raw.Address.Hex(), "UserCallbackError").Inc() l.shutdownWaitGroup.Add(1) - go l.handleOracleResponse("UserCallbackError", log.RequestId, lb) + go l.handleOracleResponseV0("UserCallbackError", log.RequestId, lb) case *ocr2dr_oracle.OCR2DROracleUserCallbackRawError: promOracleEvent.WithLabelValues(log.Raw.Address.Hex(), "UserCallbackRawError").Inc() l.shutdownWaitGroup.Add(1) - go l.handleOracleResponse("UserCallbackRawError", log.RequestId, lb) + go l.handleOracleResponseV0("UserCallbackRawError", log.RequestId, lb) case *ocr2dr_oracle.OCR2DROracleResponseTransmitted: promOracleEvent.WithLabelValues(log.Raw.Address.Hex(), "ResponseTransmitted").Inc() default: @@ -297,6 +328,40 @@ func (l *FunctionsListener) processOracleEvents() { } } +func (l *FunctionsListener) processOracleEventsV1() { + defer l.shutdownWaitGroup.Done() + freqMillis := l.pluginConfig.ListenerEventsCheckFrequencyMillis + if freqMillis == 0 { + l.logger.Errorw("ListenerEventsCheckFrequencyMillis must set to more than 0 in PluginConfig") + return + } + ticker := time.NewTicker(time.Duration(freqMillis) * time.Millisecond) + defer ticker.Stop() + for { + select { + case <-l.chStop: + return + case <-ticker.C: + requests, responses, err := l.logPollerWrapper.LatestEvents() + if err != nil { + l.logger.Errorw("error when calling LatestEvents()", "err", err) + break + } + l.logger.Debugw("processOracleEventsV1: processing v1 events", "nRequests", len(requests), "nResponses", len(responses)) + for _, request := range requests { + request := request + l.shutdownWaitGroup.Add(1) + go l.handleOracleRequestV1(&request) + } + for _, response := range responses { + response := response + l.shutdownWaitGroup.Add(1) + go l.handleOracleResponseV1(&response) + } + } + } +} + func (l *FunctionsListener) getNewHandlerContext() (context.Context, context.CancelFunc) { timeoutSec := l.pluginConfig.ListenerEventHandlerTimeoutSec if timeoutSec == 0 { @@ -307,9 +372,9 @@ func (l *FunctionsListener) getNewHandlerContext() (context.Context, context.Can func (l *FunctionsListener) setError(ctx context.Context, requestId RequestID, errType ErrType, errBytes []byte) { if errType == INTERNAL_ERROR { - promRequestInternalError.WithLabelValues(l.oracleHexAddr).Inc() + promRequestInternalError.WithLabelValues(l.contractAddressHex).Inc() } else { - promRequestComputationError.WithLabelValues(l.oracleHexAddr).Inc() + 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 { @@ -317,13 +382,63 @@ func (l *FunctionsListener) setError(ctx context.Context, requestId RequestID, e } } -func (l *FunctionsListener) handleOracleRequest(request *ocr2dr_oracle.OCR2DROracleOracleRequest, lb log.Broadcast) { +func (l *FunctionsListener) getMaxCBORsize(flags RequestFlags) uint32 { + idx := flags[FlagCBORMaxSize] + if int(idx) >= len(l.pluginConfig.MaxRequestSizesList) { + return l.pluginConfig.MaxRequestSizeBytes // deprecated + } + return l.pluginConfig.MaxRequestSizesList[idx] +} + +func (l *FunctionsListener) getMaxSecretsSize(flags RequestFlags) uint32 { + idx := flags[FlagSecretsMaxSize] + if int(idx) >= len(l.pluginConfig.MaxSecretsSizesList) { + return math.MaxUint32 // not enforced if not configured + } + return l.pluginConfig.MaxSecretsSizesList[idx] +} + +func (l *FunctionsListener) handleOracleRequestV1(request *evmrelayTypes.OracleRequest) { + defer l.shutdownWaitGroup.Done() + l.logger.Infow("handleOracleRequestV1: oracle request v1 received", "requestID", formatRequestId(request.RequestId)) + ctx, cancel := l.getNewHandlerContext() + defer cancel() + + callbackGasLimit := uint32(request.CallbackGasLimit) + newReq := &Request{ + RequestID: request.RequestId, + RequestTxHash: &request.TxHash, + ReceivedAt: time.Now(), + Flags: request.Flags[:], + CallbackGasLimit: &callbackGasLimit, + CoordinatorContractAddress: &request.CoordinatorContract, + OnchainMetadata: request.OnchainMetadata, + } + if err := l.pluginORM.CreateRequest(newReq, pg.WithParentCtx(ctx)); 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 { + l.logger.Errorw("handleOracleRequestV1: failed to create a DB entry for new request", "requestID", formatRequestId(request.RequestId), "err", err) + } + return + } + + promRequestDataSize.WithLabelValues(l.contractAddressHex).Observe(float64(len(request.Data))) + requestData, err := l.parseCBOR(request.RequestId, request.Data, l.getMaxCBORsize(request.Flags)) + if err != nil { + l.setError(ctx, request.RequestId, USER_ERROR, []byte(err.Error())) + return + } + l.handleRequest(ctx, request.RequestId, request.SubscriptionId, request.SubscriptionOwner, request.Flags, requestData) +} + +// deprecated +func (l *FunctionsListener) handleOracleRequestV0(request *ocr2dr_oracle.OCR2DROracleOracleRequest, lb log.Broadcast) { defer l.shutdownWaitGroup.Done() ctx, cancel := l.getNewHandlerContext() defer cancel() l.logger.Infow("oracle request received", "requestID", formatRequestId(request.RequestId)) - // TODO(FUN-617) extract and set new fields (Flags, AggregationMethod, CallbackGasLimit, CoordinatorContractAddress, OnchainMetadata) newReq := &Request{RequestID: request.RequestId, RequestTxHash: &request.Raw.TxHash, ReceivedAt: time.Now()} if err := l.pluginORM.CreateRequest(newReq, pg.WithParentCtx(ctx)); err != nil { if errors.Is(err, ErrDuplicateRequestID) { @@ -336,33 +451,48 @@ func (l *FunctionsListener) handleOracleRequest(request *ocr2dr_oracle.OCR2DROra } l.markLogConsumed(lb, pg.WithParentCtx(ctx)) - promRequestDataSize.WithLabelValues(l.oracleHexAddr).Observe(float64(len(request.Data))) - - if l.pluginConfig.MaxRequestSizeBytes > 0 && uint32(len(request.Data)) > l.pluginConfig.MaxRequestSizeBytes { - l.logger.Errorw("request too big", "requestID", formatRequestId(request.RequestId), "requestSize", len(request.Data), "maxRequestSize", l.pluginConfig.MaxRequestSizeBytes) - l.setError(ctx, request.RequestId, USER_ERROR, []byte(fmt.Sprintf("request too big (max %d bytes)", l.pluginConfig.MaxRequestSizeBytes))) + promRequestDataSize.WithLabelValues(l.contractAddressHex).Observe(float64(len(request.Data))) + requestData, err := l.parseCBOR(request.RequestId, request.Data, l.pluginConfig.MaxRequestSizeBytes) + if err != nil { + l.setError(ctx, request.RequestId, USER_ERROR, []byte(err.Error())) return } + l.handleRequest(ctx, request.RequestId, request.SubscriptionId, request.SubscriptionOwner, [32]byte{}, requestData) +} + +func (l *FunctionsListener) parseCBOR(requestId RequestID, cborData []byte, maxSizeBytes uint32) (*RequestData, error) { + if maxSizeBytes > 0 && uint32(len(cborData)) > maxSizeBytes { + l.logger.Errorw("request too big", "requestID", formatRequestId(requestId), "requestSize", len(cborData), "maxRequestSize", maxSizeBytes) + return nil, fmt.Errorf("request too big (max %d bytes)", maxSizeBytes) + } var requestData RequestData - if err := cbor.ParseDietCBORToStruct(request.Data, &requestData); err != nil { - l.logger.Errorw("failed to parse CBOR", "requestID", formatRequestId(request.RequestId), "err", err) - l.setError(ctx, request.RequestId, USER_ERROR, []byte("CBOR parsing error")) - return + if err := cbor.ParseDietCBORToStruct(cborData, &requestData); err != nil { + l.logger.Errorw("failed to parse CBOR", "requestID", formatRequestId(requestId), "err", err) + return nil, errors.New("CBOR parsing error") } - l.handleRequest(ctx, request.RequestId, request.SubscriptionId, request.SubscriptionOwner, &requestData) + return &requestData, nil } -func (l *FunctionsListener) handleRequest(ctx context.Context, requestID [32]byte, subscriptionId uint64, subscriptionOwner common.Address, requestData *RequestData) { +func (l *FunctionsListener) handleRequest(ctx context.Context, requestID RequestID, subscriptionId uint64, subscriptionOwner common.Address, flags RequestFlags, requestData *RequestData) { startTime := time.Now() defer func() { duration := time.Since(startTime) - promComputationDuration.WithLabelValues(l.oracleHexAddr).Observe(float64(duration.Milliseconds())) + promComputationDuration.WithLabelValues(l.contractAddressHex).Observe(float64(duration.Milliseconds())) }() requestIDStr := formatRequestId(requestID) l.logger.Infow("processing request", "requestID", requestIDStr) + if l.pluginConfig.ContractVersion == 1 && l.pluginConfig.EnableRequestSignatureCheck { + err := VerifyRequestSignature(subscriptionOwner, requestData) + if err != nil { + l.logger.Errorw("invalid request signature", "requestID", requestIDStr, "err", err) + l.setError(ctx, requestID, USER_ERROR, []byte(err.Error())) + return + } + } + eaClient, err := l.bridgeAccessor.NewExternalAdapterClient() if err != nil { l.logger.Errorw("failed to create ExternalAdapterClient", "requestID", requestIDStr, "err", err) @@ -370,7 +500,7 @@ func (l *FunctionsListener) handleRequest(ctx context.Context, requestID [32]byt return } - nodeProvidedSecrets, userErr, internalErr := l.getSecrets(ctx, eaClient, requestIDStr, subscriptionOwner, requestData) + nodeProvidedSecrets, userErr, internalErr := l.getSecrets(ctx, eaClient, requestID, subscriptionOwner, requestData) if internalErr != nil { l.logger.Errorw("internal error during getSecrets", "requestID", requestIDStr, "err", internalErr) l.setError(ctx, requestID, INTERNAL_ERROR, []byte(internalErr.Error())) @@ -378,12 +508,18 @@ func (l *FunctionsListener) handleRequest(ctx context.Context, requestID [32]byt } if userErr != nil { l.logger.Debugw("user error during getSecrets", "requestID", requestIDStr, "err", userErr) - fmt.Println("userError", userErr.Error()) l.setError(ctx, requestID, USER_ERROR, []byte(userErr.Error())) return } - computationResult, computationError, domains, err := eaClient.RunComputation(ctx, requestIDStr, l.job.Name.ValueOrZero(), subscriptionOwner.Hex(), subscriptionId, nodeProvidedSecrets, requestData) + maxSecretsSize := l.getMaxSecretsSize(flags) + if uint32(len(nodeProvidedSecrets)) > maxSecretsSize { + l.logger.Errorw("secrets size too big", "requestID", requestIDStr, "secretsSize", len(nodeProvidedSecrets), "maxSecretsSize", maxSecretsSize) + l.setError(ctx, requestID, USER_ERROR, []byte("secrets size too big")) + return + } + + computationResult, computationError, domains, err := eaClient.RunComputation(ctx, requestIDStr, l.job.Name.ValueOrZero(), subscriptionOwner.Hex(), subscriptionId, flags, nodeProvidedSecrets, requestData) if err != nil { l.logger.Errorw("internal adapter error", "requestID", requestIDStr, "err", err) @@ -407,10 +543,10 @@ func (l *FunctionsListener) handleRequest(ctx context.Context, requestID [32]byt } l.logger.Debugw("saving computation error", "requestID", requestIDStr) l.setError(ctx, requestID, USER_ERROR, computationError) - promComputationErrorSize.WithLabelValues(l.oracleHexAddr).Set(float64(len(computationError))) + promComputationErrorSize.WithLabelValues(l.contractAddressHex).Set(float64(len(computationError))) } else { - promRequestComputationSuccess.WithLabelValues(l.oracleHexAddr).Inc() - promComputationResultSize.WithLabelValues(l.oracleHexAddr).Set(float64(len(computationResult))) + 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 { l.logger.Errorw("call to SetResult failed", "requestID", requestIDStr, "err", err2) @@ -418,7 +554,19 @@ func (l *FunctionsListener) handleRequest(ctx context.Context, requestID [32]byt } } -func (l *FunctionsListener) handleOracleResponse(responseType string, requestID [32]byte, lb log.Broadcast) { +func (l *FunctionsListener) handleOracleResponseV1(response *evmrelayTypes.OracleResponse) { + defer l.shutdownWaitGroup.Done() + l.logger.Infow("oracle response v1 received", "requestID", formatRequestId(response.RequestId)) + + ctx, cancel := l.getNewHandlerContext() + defer cancel() + if err := l.pluginORM.SetConfirmed(response.RequestId, pg.WithParentCtx(ctx)); err != nil { + l.logger.Errorw("setting CONFIRMED state failed", "requestID", formatRequestId(response.RequestId), "err", err) + } + promRequestConfirmed.WithLabelValues(l.contractAddressHex, "OracleResponse").Inc() +} + +func (l *FunctionsListener) handleOracleResponseV0(responseType string, requestID [32]byte, lb log.Broadcast) { defer l.shutdownWaitGroup.Done() l.logger.Infow("oracle response received", "type", responseType, "requestID", formatRequestId(requestID)) @@ -427,7 +575,7 @@ func (l *FunctionsListener) handleOracleResponse(responseType string, requestID if err := l.pluginORM.SetConfirmed(requestID, pg.WithParentCtx(ctx)); err != nil { l.logger.Errorw("setting CONFIRMED state failed", "requestID", formatRequestId(requestID), "err", err) } - promRequestConfirmed.WithLabelValues(l.oracleHexAddr, responseType).Inc() + promRequestConfirmed.WithLabelValues(l.contractAddressHex, responseType).Inc() l.markLogConsumed(lb, pg.WithParentCtx(ctx)) } @@ -460,7 +608,7 @@ func (l *FunctionsListener) timeoutRequests() { break } if len(ids) > 0 { - promRequestTimeout.WithLabelValues(l.oracleHexAddr).Add(float64(len(ids))) + promRequestTimeout.WithLabelValues(l.contractAddressHex).Add(float64(len(ids))) var idStrs []string for _, id := range ids { idStrs = append(idStrs, formatRequestId(id)) @@ -506,7 +654,7 @@ func (l *FunctionsListener) pruneRequests() { break } if nPruned > 0 { - promPrunedRequests.WithLabelValues(l.oracleHexAddr).Add(float64(nPruned)) + promPrunedRequests.WithLabelValues(l.contractAddressHex).Add(float64(nPruned)) l.logger.Debugw("pruned requests from the DB", "nTotal", nTotal, "nPruned", nPruned, "elapsedMillis", elapsedMillis) } else { l.logger.Debugw("no pruned requests at this time", "nTotal", nTotal, "elapsedMillis", elapsedMillis) @@ -530,25 +678,26 @@ func (l *FunctionsListener) reportSourceCodeDomains(requestId RequestID, domains } } -func (l *FunctionsListener) getSecrets(ctx context.Context, eaClient ExternalAdapterClient, requestID string, subscriptionOwner common.Address, requestData *RequestData) (decryptedSecrets string, userError, internalError error) { +func (l *FunctionsListener) getSecrets(ctx context.Context, eaClient ExternalAdapterClient, requestID RequestID, subscriptionOwner common.Address, requestData *RequestData) (decryptedSecrets string, userError, internalError error) { if l.decryptor == nil { - l.logger.Errorf("Decryptor not configured") + l.logger.Warn("Decryptor not configured") return "", nil, nil } var secrets []byte + requestIDStr := formatRequestId(requestID) switch requestData.SecretsLocation { case LocationInline: - l.logger.Warnw("request used Inline secrets location, processing with no secrets", "requestID", requestID) + l.logger.Warnw("request used Inline secrets location, processing with no secrets", "requestID", requestIDStr) return "", nil, nil case LocationRemote: - thresholdEncSecrets, userError, err := eaClient.FetchEncryptedSecrets(ctx, requestData.Secrets, requestID, l.job.Name.ValueOrZero()) + thresholdEncSecrets, userError, err := eaClient.FetchEncryptedSecrets(ctx, requestData.Secrets, requestIDStr, l.job.Name.ValueOrZero()) if err != nil { return "", nil, errors.Wrap(err, "failed to fetch encrypted secrets") } if len(userError) != 0 { - l.logger.Debugw("no valid threshold encrypted secrets detected, falling back to legacy secrets", "requestID", requestID, "err", string(userError)) + l.logger.Debugw("no valid threshold encrypted secrets detected, falling back to legacy secrets", "requestID", requestIDStr, "err", string(userError)) } secrets = thresholdEncSecrets case LocationDONHosted: @@ -577,7 +726,7 @@ func (l *FunctionsListener) getSecrets(ctx context.Context, eaClient ExternalAda decryptCtx, cancel := context.WithTimeout(ctx, time.Duration(l.pluginConfig.DecryptionQueueConfig.DecryptRequestTimeoutSec)*time.Second) defer cancel() - decryptedSecretsBytes, err := l.decryptor.Decrypt(decryptCtx, []byte(requestID), secrets) + decryptedSecretsBytes, err := l.decryptor.Decrypt(decryptCtx, requestID[:], secrets) if err != nil { return "", errors.New("threshold decryption of secrets failed"), nil } diff --git a/core/services/functions/listener_test.go b/core/services/functions/listener_test.go index b33684d71d9..0c74b0563f4 100644 --- a/core/services/functions/listener_test.go +++ b/core/services/functions/listener_test.go @@ -1,6 +1,7 @@ package functions_test import ( + "encoding/hex" "encoding/json" "fmt" "math/big" @@ -16,6 +17,9 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" + decryptionPlugin "github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin" + + cl_cbor "github.com/smartcontractkit/chainlink/v2/core/cbor" log_mocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log/mocks" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/ocr2dr_oracle" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" @@ -32,6 +36,9 @@ import ( 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" + evmrelay_mocks "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types/mocks" s4_mocks "github.com/smartcontractkit/chainlink/v2/core/services/s4/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/srvctest" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" @@ -42,13 +49,15 @@ import ( ) type FunctionsListenerUniverse struct { - service *functions_service.FunctionsListener - bridgeAccessor *functions_mocks.BridgeAccessor - eaClient *functions_mocks.ExternalAdapterClient - pluginORM *functions_mocks.ORM - logBroadcaster *log_mocks.Broadcaster - ingressClient *sync_mocks.TelemetryIngressClient - decryptor *threshold_mocks.Decryptor + service *functions_service.FunctionsListener + bridgeAccessor *functions_mocks.BridgeAccessor + eaClient *functions_mocks.ExternalAdapterClient + pluginORM *functions_mocks.ORM + logBroadcaster *log_mocks.Broadcaster + ingressClient *sync_mocks.TelemetryIngressClient + decryptor *threshold_mocks.Decryptor + logPollerWrapper *evmrelay_mocks.LogPollerWrapper + contractVersion uint32 } func ptr[T any](t T) *T { return &t } @@ -64,9 +73,12 @@ var ( EncryptedSecretsUrls []byte = []byte{0x11, 0x22} EncryptedSecrets []byte = []byte(`{"TDH2Ctxt":"eyJHcm","SymCtxt":"+yHR","Nonce":"kgjHyT3Jar0M155E"}`) DecryptedSecrets []byte = []byte(`{"0x0":"lhcK"}`) + SignedCBORRequestHex = "a666736f75726365782172657475726e2046756e6374696f6e732e656e636f646555696e743235362831296773656372657473421234686c616e6775616765006c636f64654c6f636174696f6e006f736563726574734c6f636174696f6e0170726571756573745369676e617475726558416fb6d10871aa3865b6620dc5f4594d2a9ad9166ba6b1dbc3f508362fd27aa0461babada48979092a11ecadec9c663a2ea99da4e368408b36a3fb414acfefdd2a1c" + SubOwnerAddr common.Address = common.HexToAddress("0x2334dE553AB93c69b0ccbe278B6f5E8350Db6204") + NonSubOwnerAddr common.Address = common.HexToAddress("0x60C9CF55b9de9A956d921A97575108149b758131") ) -func NewFunctionsListenerUniverse(t *testing.T, timeoutSec int, pruneFrequencySec int) *FunctionsListenerUniverse { +func NewFunctionsListenerUniverse(t *testing.T, timeoutSec int, pruneFrequencySec int, setTiers bool, version uint32) *FunctionsListenerUniverse { cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { c.EVM[0].MinIncomingConfirmations = ptr[uint32](1) }) @@ -77,8 +89,11 @@ func NewFunctionsListenerUniverse(t *testing.T, timeoutSec int, pruneFrequencySe db := pgtest.NewSqlxDB(t) kst := cltest.NewKeyStore(t, db, cfg.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, Client: ethClient, KeyStore: kst.Eth(), LogBroadcaster: broadcaster, MailMon: mailMon}) - chain := cc.Chains()[0] + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, Client: ethClient, KeyStore: kst.Eth(), LogBroadcaster: broadcaster, MailMon: mailMon}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + + chain := legacyChains.Slice()[0] lggr := logger.TestLogger(t) pluginORM := functions_mocks.NewORM(t) @@ -91,6 +106,12 @@ func NewFunctionsListenerUniverse(t *testing.T, timeoutSec int, pruneFrequencySe "decryptionQueueConfig": map[string]interface{}{ "decryptRequestTimeoutSec": 100, }, + "contractVersion": version, + "listenerEventsCheckFrequencyMillis": 100, // only applicable to v1 + } + if setTiers { + jsonConfig["maxRequestSizesList"] = []uint32{10, 100, 1_000} + jsonConfig["maxSecretsSizesList"] = []uint32{10, 100, 200} } jb := job.Job{ Type: job.OffchainReporting2, @@ -106,32 +127,35 @@ func NewFunctionsListenerUniverse(t *testing.T, timeoutSec int, pruneFrequencySe decryptor := threshold_mocks.NewDecryptor(t) var pluginConfig config.PluginConfig - err := json.Unmarshal(jsonConfig.Bytes(), &pluginConfig) + err = json.Unmarshal(jsonConfig.Bytes(), &pluginConfig) require.NoError(t, err) - oracleContract, err := ocr2dr_oracle.NewOCR2DROracle(common.HexToAddress("0xa"), chain.Client()) - require.NoError(t, err) + contractAddress := "0xa" ingressClient := sync_mocks.NewTelemetryIngressClient(t) ingressAgent := telemetry.NewIngressAgentWrapper(ingressClient) - monEndpoint := ingressAgent.GenMonitoringEndpoint("0xa", synchronization.FunctionsRequests) + monEndpoint := ingressAgent.GenMonitoringEndpoint(contractAddress, synchronization.FunctionsRequests) s4Storage := s4_mocks.NewStorage(t) - functionsListener := functions_service.NewFunctionsListener(oracleContract, jb, bridgeAccessor, pluginORM, pluginConfig, s4Storage, broadcaster, lggr, mailMon, monEndpoint, decryptor) + client := chain.Client() + logPollerWrapper := evmrelay_mocks.NewLogPollerWrapper(t) + functionsListener := functions_service.NewFunctionsListener(jb, client, contractAddress, bridgeAccessor, pluginORM, pluginConfig, s4Storage, broadcaster, lggr, mailMon, monEndpoint, decryptor, logPollerWrapper) return &FunctionsListenerUniverse{ - service: functionsListener, - bridgeAccessor: bridgeAccessor, - eaClient: eaClient, - pluginORM: pluginORM, - logBroadcaster: broadcaster, - ingressClient: ingressClient, - decryptor: decryptor, + service: functionsListener, + bridgeAccessor: bridgeAccessor, + eaClient: eaClient, + pluginORM: pluginORM, + logBroadcaster: broadcaster, + ingressClient: ingressClient, + decryptor: decryptor, + logPollerWrapper: logPollerWrapper, + contractVersion: pluginConfig.ContractVersion, } } func PrepareAndStartFunctionsListener(t *testing.T, cbor []byte) (*FunctionsListenerUniverse, *log_mocks.Broadcast, chan struct{}) { - uni := NewFunctionsListenerUniverse(t, 0, 1_000_000) + uni := NewFunctionsListenerUniverse(t, 0, 1_000_000, false, 0) uni.logBroadcaster.On("Register", mock.Anything, mock.Anything).Return(func() {}) err := uni.service.Start(testutils.Context(t)) @@ -161,7 +185,7 @@ func TestFunctionsListener_HandleOracleRequestSuccess(t *testing.T) { uni.pluginORM.On("CreateRequest", mock.Anything, mock.Anything).Return(nil) uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil) uni.bridgeAccessor.On("NewExternalAdapterClient").Return(uni.eaClient, nil) - uni.eaClient.On("RunComputation", mock.Anything, RequestIDStr, mock.Anything, SubscriptionOwner.Hex(), SubscriptionID, mock.Anything, mock.Anything).Return(ResultBytes, nil, nil, 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) { close(doneCh) }).Return(nil) @@ -193,8 +217,8 @@ func TestFunctionsListener_ThresholdDecryptedSecrets(t *testing.T) { uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil) uni.bridgeAccessor.On("NewExternalAdapterClient").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, []byte(RequestIDStr), EncryptedSecrets).Return(DecryptedSecrets, nil) - uni.eaClient.On("RunComputation", mock.Anything, RequestIDStr, mock.Anything, SubscriptionOwner.Hex(), SubscriptionID, string(DecryptedSecrets), mock.Anything).Return(ResultBytes, nil, 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, string(DecryptedSecrets), mock.Anything).Return(ResultBytes, nil, nil, nil) uni.pluginORM.On("SetResult", RequestID, ResultBytes, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { close(doneCh) }).Return(nil) @@ -226,7 +250,7 @@ func TestFunctionsListener_ThresholdDecryptedSecretsFailure(t *testing.T) { uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil) uni.bridgeAccessor.On("NewExternalAdapterClient").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, []byte(RequestIDStr), EncryptedSecrets).Return(nil, errors.New("threshold decryption error")) + uni.decryptor.On("Decrypt", mock.Anything, decryptionPlugin.CiphertextId(RequestID[:]), EncryptedSecrets).Return(nil, errors.New("threshold decryption error")) uni.pluginORM.On("SetError", RequestID, functions_service.USER_ERROR, []byte("threshold decryption of secrets failed"), mock.Anything, true, mock.Anything).Run(func(args mock.Arguments) { close(doneCh) }).Return(nil) @@ -261,7 +285,7 @@ func TestFunctionsListener_ReportSourceCodeDomains(t *testing.T) { uni.pluginORM.On("CreateRequest", mock.Anything, mock.Anything).Return(nil) uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil) uni.bridgeAccessor.On("NewExternalAdapterClient").Return(uni.eaClient, nil) - uni.eaClient.On("RunComputation", mock.Anything, RequestIDStr, mock.Anything, SubscriptionOwner.Hex(), SubscriptionID, mock.Anything, mock.Anything).Return(ResultBytes, nil, Domains, 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) { close(doneCh) }).Return(nil) @@ -293,7 +317,7 @@ func TestFunctionsListener_HandleOracleRequestComputationError(t *testing.T) { uni.pluginORM.On("CreateRequest", mock.Anything, mock.Anything).Return(nil) uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil) uni.bridgeAccessor.On("NewExternalAdapterClient").Return(uni.eaClient, nil) - uni.eaClient.On("RunComputation", mock.Anything, RequestIDStr, mock.Anything, SubscriptionOwner.Hex(), SubscriptionID, mock.Anything, mock.Anything).Return(nil, ErrorBytes, nil, 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, functions_service.USER_ERROR, ErrorBytes, mock.Anything, true, mock.Anything).Run(func(args mock.Arguments) { close(doneCh) }).Return(nil) @@ -376,8 +400,8 @@ func TestFunctionsListener_HandleOracleRequestCBORParsingCorrect(t *testing.T) { uni.pluginORM.On("CreateRequest", mock.Anything, mock.Anything).Return(nil) uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil) uni.bridgeAccessor.On("NewExternalAdapterClient").Return(uni.eaClient, nil) - uni.eaClient.On("RunComputation", mock.Anything, RequestIDStr, mock.Anything, SubscriptionOwner.Hex(), SubscriptionID, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { - reqData := args.Get(6).(*functions_service.RequestData) + uni.eaClient.On("RunComputation", mock.Anything, RequestIDStr, mock.Anything, SubscriptionOwner.Hex(), SubscriptionID, mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { + reqData := args.Get(7).(*functions_service.RequestData) assert.Equal(t, incomingData.Source, reqData.Source) assert.Equal(t, incomingData.Language, reqData.Language) assert.Equal(t, incomingData.Secrets, reqData.Secrets) @@ -398,7 +422,7 @@ func TestFunctionsListener_RequestTimeout(t *testing.T) { reqId := newRequestID() doneCh := make(chan bool) - uni := NewFunctionsListenerUniverse(t, 1, 1_000_000) + uni := NewFunctionsListenerUniverse(t, 1, 1_000_000, false, 0) uni.logBroadcaster.On("Register", mock.Anything, mock.Anything).Return(func() {}) uni.pluginORM.On("TimeoutExpiredResults", mock.Anything, uint32(1), mock.Anything).Return([]functions_service.RequestID{reqId}, nil).Run(func(args mock.Arguments) { doneCh <- true @@ -435,7 +459,7 @@ func TestFunctionsListener_PruneRequests(t *testing.T) { t.Parallel() doneCh := make(chan bool) - uni := NewFunctionsListenerUniverse(t, 0, 1) + uni := NewFunctionsListenerUniverse(t, 0, 1, false, 0) uni.logBroadcaster.On("Register", mock.Anything, mock.Anything).Return(func() {}) uni.pluginORM.On("PruneOldestRequests", functions_service.DefaultPruneMaxStoredRequests, functions_service.DefaultPruneBatchSize, mock.Anything).Return(uint32(0), uint32(0), nil).Run(func(args mock.Arguments) { doneCh <- true @@ -446,3 +470,138 @@ func TestFunctionsListener_PruneRequests(t *testing.T) { <-doneCh uni.service.Close() } + +func TestFunctionsListener_RequestSignatureVerification(t *testing.T) { + testutils.SkipShortDB(t) + t.Parallel() + + cborBytes, err := hex.DecodeString(SignedCBORRequestHex) + require.NoError(t, err) + + var requestData functions_service.RequestData + err = cl_cbor.ParseDietCBORToStruct(cborBytes, &requestData) + require.NoError(t, err) + + err = functions_service.VerifyRequestSignature(SubOwnerAddr, &requestData) + assert.NoError(t, err) +} + +func TestFunctionsListener_RequestSignatureVerificationFailure(t *testing.T) { + testutils.SkipShortDB(t) + t.Parallel() + + cborBytes, err := hex.DecodeString(SignedCBORRequestHex) + require.NoError(t, err) + + var requestData functions_service.RequestData + err = cl_cbor.ParseDietCBORToStruct(cborBytes, &requestData) + require.NoError(t, err) + + err = functions_service.VerifyRequestSignature(NonSubOwnerAddr, &requestData) + assert.EqualError(t, err, "invalid request signature: signer's address does not match subscription owner") +} + +func getFlags(requestSizeTier int, secretSizeTier int) [32]byte { + var flags [32]byte + flags[1] = byte(requestSizeTier) + flags[2] = byte(secretSizeTier) + return flags +} + +func TestFunctionsListener_HandleOracleRequestV1_Success(t *testing.T) { + testutils.SkipShortDB(t) + t.Parallel() + + uni := NewFunctionsListenerUniverse(t, 0, 1_000_000, true, 1) + require.NoError(t, uni.service.Start(testutils.Context(t))) + doneCh := make(chan struct{}) + + request := types.OracleRequest{ + RequestId: RequestID, + SubscriptionId: uint64(SubscriptionID), + SubscriptionOwner: SubscriptionOwner, + Flags: getFlags(1, 0), // tier no 1 of request size, allows up to 100 bytes + Data: make([]byte, 12), + } + + uni.logPollerWrapper.On("LatestEvents").Return([]types.OracleRequest{request}, nil, nil).Once() + uni.logPollerWrapper.On("LatestEvents").Return(nil, nil, nil) + uni.pluginORM.On("CreateRequest", mock.Anything, mock.Anything).Return(nil) + uni.bridgeAccessor.On("NewExternalAdapterClient").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) { + close(doneCh) + }).Return(nil) + + <-doneCh + uni.service.Close() +} + +func TestFunctionsListener_HandleOracleRequestV1_ThresholdDecryptedSecrets(t *testing.T) { + testutils.SkipShortDB(t) + t.Parallel() + + reqData := &struct { + SecretsLocation int `cbor:"secretsLocation"` + Secrets []byte `cbor:"secrets"` + }{ + SecretsLocation: 1, + Secrets: EncryptedSecretsUrls, + } + cborBytes, err := cbor.Marshal(reqData) + require.NoError(t, err) + // Remove first byte (map header) to make it "diet" CBOR + cborBytes = cborBytes[1:] + request := types.OracleRequest{ + RequestId: RequestID, + SubscriptionId: uint64(SubscriptionID), + SubscriptionOwner: SubscriptionOwner, + Flags: getFlags(1, 1), // tiers no 1 of request size and secrets size, allow up to 100 bytes + Data: cborBytes, + } + + uni := NewFunctionsListenerUniverse(t, 0, 1_000_000, true, 1) + require.NoError(t, uni.service.Start(testutils.Context(t))) + doneCh := make(chan struct{}) + + uni.logPollerWrapper.On("LatestEvents").Return([]types.OracleRequest{request}, nil, nil).Once() + uni.logPollerWrapper.On("LatestEvents").Return(nil, nil, nil) + uni.pluginORM.On("CreateRequest", mock.Anything, mock.Anything).Return(nil) + uni.bridgeAccessor.On("NewExternalAdapterClient").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) { + close(doneCh) + }).Return(nil) + + <-doneCh + uni.service.Close() +} + +func TestFunctionsListener_HandleOracleRequestV1_CBORTooBig(t *testing.T) { + testutils.SkipShortDB(t) + t.Parallel() + + uni := NewFunctionsListenerUniverse(t, 0, 1_000_000, true, 1) + require.NoError(t, uni.service.Start(testutils.Context(t))) + doneCh := make(chan struct{}) + + request := types.OracleRequest{ + RequestId: RequestID, + SubscriptionId: uint64(SubscriptionID), + SubscriptionOwner: SubscriptionOwner, + Flags: getFlags(0, 0), // tier no 0 of request size, allows only for max 10 bytes + Data: make([]byte, 20), + } + + uni.logPollerWrapper.On("LatestEvents").Return([]types.OracleRequest{request}, nil, nil).Once() + uni.logPollerWrapper.On("LatestEvents").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) { + close(doneCh) + }).Return(nil) + + <-doneCh + uni.service.Close() +} diff --git a/core/services/functions/mocks/external_adapter_client.go b/core/services/functions/mocks/external_adapter_client.go index 91d0a1a24e1..2815819251b 100644 --- a/core/services/functions/mocks/external_adapter_client.go +++ b/core/services/functions/mocks/external_adapter_client.go @@ -49,43 +49,43 @@ func (_m *ExternalAdapterClient) FetchEncryptedSecrets(ctx context.Context, encr return r0, r1, r2 } -// RunComputation provides a mock function with given fields: ctx, requestId, jobName, subscriptionOwner, subscriptionId, nodeProvidedSecrets, requestData -func (_m *ExternalAdapterClient) RunComputation(ctx context.Context, requestId string, jobName string, subscriptionOwner string, subscriptionId uint64, nodeProvidedSecrets string, requestData *functions.RequestData) ([]byte, []byte, []string, error) { - ret := _m.Called(ctx, requestId, jobName, subscriptionOwner, subscriptionId, nodeProvidedSecrets, requestData) +// RunComputation provides a mock function with given fields: ctx, requestId, jobName, subscriptionOwner, subscriptionId, flags, nodeProvidedSecrets, requestData +func (_m *ExternalAdapterClient) RunComputation(ctx context.Context, requestId string, jobName string, subscriptionOwner string, subscriptionId uint64, flags functions.RequestFlags, nodeProvidedSecrets string, requestData *functions.RequestData) ([]byte, []byte, []string, error) { + ret := _m.Called(ctx, requestId, jobName, subscriptionOwner, subscriptionId, flags, nodeProvidedSecrets, requestData) var r0 []byte var r1 []byte var r2 []string var r3 error - if rf, ok := ret.Get(0).(func(context.Context, string, string, string, uint64, string, *functions.RequestData) ([]byte, []byte, []string, error)); ok { - return rf(ctx, requestId, jobName, subscriptionOwner, subscriptionId, nodeProvidedSecrets, requestData) + if rf, ok := ret.Get(0).(func(context.Context, string, string, string, uint64, functions.RequestFlags, string, *functions.RequestData) ([]byte, []byte, []string, error)); ok { + return rf(ctx, requestId, jobName, subscriptionOwner, subscriptionId, flags, nodeProvidedSecrets, requestData) } - if rf, ok := ret.Get(0).(func(context.Context, string, string, string, uint64, string, *functions.RequestData) []byte); ok { - r0 = rf(ctx, requestId, jobName, subscriptionOwner, subscriptionId, nodeProvidedSecrets, requestData) + if rf, ok := ret.Get(0).(func(context.Context, string, string, string, uint64, functions.RequestFlags, string, *functions.RequestData) []byte); ok { + r0 = rf(ctx, requestId, jobName, subscriptionOwner, subscriptionId, flags, nodeProvidedSecrets, requestData) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]byte) } } - if rf, ok := ret.Get(1).(func(context.Context, string, string, string, uint64, string, *functions.RequestData) []byte); ok { - r1 = rf(ctx, requestId, jobName, subscriptionOwner, subscriptionId, nodeProvidedSecrets, requestData) + if rf, ok := ret.Get(1).(func(context.Context, string, string, string, uint64, functions.RequestFlags, string, *functions.RequestData) []byte); ok { + r1 = rf(ctx, requestId, jobName, subscriptionOwner, subscriptionId, flags, nodeProvidedSecrets, requestData) } else { if ret.Get(1) != nil { r1 = ret.Get(1).([]byte) } } - if rf, ok := ret.Get(2).(func(context.Context, string, string, string, uint64, string, *functions.RequestData) []string); ok { - r2 = rf(ctx, requestId, jobName, subscriptionOwner, subscriptionId, nodeProvidedSecrets, requestData) + if rf, ok := ret.Get(2).(func(context.Context, string, string, string, uint64, functions.RequestFlags, string, *functions.RequestData) []string); ok { + r2 = rf(ctx, requestId, jobName, subscriptionOwner, subscriptionId, flags, nodeProvidedSecrets, requestData) } else { if ret.Get(2) != nil { r2 = ret.Get(2).([]string) } } - if rf, ok := ret.Get(3).(func(context.Context, string, string, string, uint64, string, *functions.RequestData) error); ok { - r3 = rf(ctx, requestId, jobName, subscriptionOwner, subscriptionId, nodeProvidedSecrets, requestData) + if rf, ok := ret.Get(3).(func(context.Context, string, string, string, uint64, functions.RequestFlags, string, *functions.RequestData) error); ok { + r3 = rf(ctx, requestId, jobName, subscriptionOwner, subscriptionId, flags, nodeProvidedSecrets, requestData) } else { r3 = ret.Error(3) } diff --git a/core/services/functions/request.go b/core/services/functions/request.go index 1dbc226b05e..a6715e0a87f 100644 --- a/core/services/functions/request.go +++ b/core/services/functions/request.go @@ -1,5 +1,14 @@ package functions +import ( + "encoding/json" + + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + const ( LocationInline = 0 LocationRemote = 1 @@ -7,16 +16,66 @@ const ( LanguageJavaScript = 0 ) +type RequestFlags [32]byte + type RequestData struct { - Source string `json:"source" cbor:"source"` - Language int `json:"language" cbor:"language"` - CodeLocation int `json:"codeLocation" cbor:"codeLocation"` - Secrets []byte `json:"secrets" cbor:"secrets"` - SecretsLocation int `json:"secretsLocation" cbor:"secretsLocation"` - Args []string `json:"args" cbor:"args"` + Source string `json:"source" cbor:"source"` + Language int `json:"language" cbor:"language"` + CodeLocation int `json:"codeLocation" cbor:"codeLocation"` + Secrets []byte `json:"secrets" cbor:"secrets"` + SecretsLocation int `json:"secretsLocation" cbor:"secretsLocation"` + RequestSignature []byte `json:"requestSignature,omitempty" cbor:"requestSignature"` + Args []string `json:"args,omitempty" cbor:"args"` + BytesArgs [][]byte `json:"bytesArgs,omitempty" cbor:"bytesArgs"` } type DONHostedSecrets struct { SlotID uint `json:"slotId" cbor:"slotId"` Version uint64 `json:"version" cbor:"version"` } + +type SignedRequestData struct { + CodeLocation int `json:"codeLocation" cbor:"codeLocation"` + Language int `json:"language" cbor:"language"` + Secrets []byte `json:"secrets" cbor:"secrets"` + SecretsLocation int `json:"secretsLocation" cbor:"secretsLocation"` + Source string `json:"source" cbor:"source"` +} + +// The request signature should sign the keccak256 hash of the following JSON string (without extra whitespace) +// with the corresponding Request fields in the order that they appear below: +// { +// "codeLocation": number, (0 for Location.Inline) +// "language": number, (0 for CodeLanguage.JavaScript) +// "secrets": string, (encryptedSecretsReference as base64 string, must be `null` if there are no secrets) +// "secretsLocation": number, (must be `null` if there are no secrets) (1 for Location.Remote, 2 for Location.DONHosted) +// "source": string, +// } + +func VerifyRequestSignature(subscriptionOwner common.Address, requestData *RequestData) error { + if requestData.RequestSignature == nil { + return errors.New("missing signature") + } + signedRequestData := SignedRequestData{ + CodeLocation: requestData.CodeLocation, + Language: requestData.Language, + Secrets: requestData.Secrets, + SecretsLocation: requestData.SecretsLocation, + Source: requestData.Source, + } + js, err := json.Marshal(signedRequestData) + if err != nil { + return errors.New("unable to marshal request data") + } + + signerAddr, err := utils.GetSignersEthAddress(js, requestData.RequestSignature) + if err != nil { + return errors.New("invalid request signature: unable to recover signer's address") + } + + if signerAddr != subscriptionOwner { + return errors.New("invalid request signature: signer's address does not match subscription owner") + } + + return nil +} diff --git a/core/services/gateway/common/utils.go b/core/services/gateway/common/utils.go index 5c5ab037a7d..7501504f87b 100644 --- a/core/services/gateway/common/utils.go +++ b/core/services/gateway/common/utils.go @@ -4,8 +4,9 @@ import ( "crypto/ecdsa" "encoding/binary" - "github.com/ethereum/go-ethereum/crypto" "golang.org/x/exp/slices" + + "github.com/smartcontractkit/chainlink/v2/core/utils" ) func Uint32ToBytes(val uint32) []byte { @@ -30,16 +31,22 @@ func AlignedBytesToString(data []byte) string { return string(data[:idx]) } +func flatten(data ...[]byte) []byte { + var result []byte + for _, d := range data { + result = append(result, d...) + } + return result +} + func SignData(privateKey *ecdsa.PrivateKey, data ...[]byte) ([]byte, error) { - hash := crypto.Keccak256Hash(data...) - return crypto.Sign(hash.Bytes(), privateKey) + return utils.GenerateEthSignature(privateKey, flatten(data...)) } func ExtractSigner(signature []byte, data ...[]byte) (signerAddress []byte, err error) { - hash := crypto.Keccak256Hash(data...) - ecdsaPubKey, err := crypto.SigToPub(hash.Bytes(), signature) + addr, err := utils.GetSignersEthAddress(flatten(data...), signature) if err != nil { return nil, err } - return crypto.PubkeyToAddress(*ecdsaPubKey).Bytes(), nil + return addr.Bytes(), nil } diff --git a/core/services/gateway/delegate.go b/core/services/gateway/delegate.go index bc170bd4e74..c42e61b8785 100644 --- a/core/services/gateway/delegate.go +++ b/core/services/gateway/delegate.go @@ -16,15 +16,15 @@ import ( ) type Delegate struct { - chains evm.ChainSet - ks keystore.Eth - lggr logger.Logger + legacyChains evm.LegacyChainContainer + ks keystore.Eth + lggr logger.Logger } var _ job.Delegate = (*Delegate)(nil) -func NewDelegate(chains evm.ChainSet, ks keystore.Eth, lggr logger.Logger) *Delegate { - return &Delegate{chains: chains, ks: ks, lggr: lggr} +func NewDelegate(legacyChains evm.LegacyChainContainer, ks keystore.Eth, lggr logger.Logger) *Delegate { + return &Delegate{legacyChains: legacyChains, ks: ks, lggr: lggr} } func (d *Delegate) JobType() job.Type { @@ -37,7 +37,7 @@ func (d *Delegate) BeforeJobDeleted(spec job.Job) {} func (d *Delegate) OnDeleteJob(spec job.Job, q pg.Queryer) error { return nil } // ServicesForSpec returns the scheduler to be used for running observer jobs -func (d *Delegate) ServicesForSpec(spec job.Job) (services []job.ServiceCtx, err error) { +func (d *Delegate) ServicesForSpec(spec job.Job, qopts ...pg.QOpt) (services []job.ServiceCtx, err error) { if spec.GatewaySpec == nil { return nil, errors.Errorf("services.Delegate expects a *jobSpec.GatewaySpec to be present, got %v", spec) } @@ -47,7 +47,7 @@ func (d *Delegate) ServicesForSpec(spec job.Job) (services []job.ServiceCtx, err if err2 != nil { return nil, errors.Wrap(err2, "unmarshal gateway config") } - handlerFactory := NewHandlerFactory(d.chains, d.lggr) + handlerFactory := NewHandlerFactory(d.legacyChains, d.lggr) gateway, err := NewGatewayFromConfig(&gatewayConfig, handlerFactory, d.lggr) if err != nil { return nil, err diff --git a/core/services/gateway/handler_factory.go b/core/services/gateway/handler_factory.go index a0107214a23..519de608a0f 100644 --- a/core/services/gateway/handler_factory.go +++ b/core/services/gateway/handler_factory.go @@ -17,20 +17,20 @@ const ( ) type handlerFactory struct { - chains evm.ChainSet - lggr logger.Logger + legacyChains evm.LegacyChainContainer + lggr logger.Logger } var _ HandlerFactory = (*handlerFactory)(nil) -func NewHandlerFactory(chains evm.ChainSet, lggr logger.Logger) HandlerFactory { - return &handlerFactory{chains, lggr} +func NewHandlerFactory(legacyChains evm.LegacyChainContainer, lggr logger.Logger) HandlerFactory { + return &handlerFactory{legacyChains, lggr} } func (hf *handlerFactory) NewHandler(handlerType HandlerType, handlerConfig json.RawMessage, donConfig *config.DONConfig, don handlers.DON) (handlers.Handler, error) { switch handlerType { case FunctionsHandlerType: - return functions.NewFunctionsHandlerFromConfig(handlerConfig, donConfig, don, hf.chains, hf.lggr) + return functions.NewFunctionsHandlerFromConfig(handlerConfig, donConfig, don, hf.legacyChains, hf.lggr) case DummyHandlerType: return handlers.NewDummyHandler(donConfig, don, hf.lggr) default: diff --git a/core/services/gateway/handlers/functions/allowlist.go b/core/services/gateway/handlers/functions/allowlist.go index 0ba679f3e88..f05738ade40 100644 --- a/core/services/gateway/handlers/functions/allowlist.go +++ b/core/services/gateway/handlers/functions/allowlist.go @@ -13,6 +13,7 @@ import ( "github.com/pkg/errors" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_allow_list" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/ocr2dr_oracle" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" @@ -22,6 +23,7 @@ import ( type OnchainAllowlistConfig struct { // ContractAddress is required ContractAddress common.Address `json:"contractAddress"` + ContractVersion uint32 `json:"contractVersion"` BlockConfirmations uint `json:"blockConfirmations"` // UpdateFrequencySec can be zero to disable periodic updates UpdateFrequencySec uint `json:"updateFrequencySec"` @@ -29,7 +31,8 @@ type OnchainAllowlistConfig struct { } // OnchainAllowlist maintains an allowlist of addresses fetched from the blockchain (EVM-only). -// Use UpdateFromContract() for a one-time update or set OnchainAllowlistConfig.UpdateFrequencySec for period updates. +// Use UpdateFromContract() for a one-time update or set OnchainAllowlistConfig.UpdateFrequencySec +// for repeated updates. // All methods are thread-safe. // //go:generate mockery --quiet --name OnchainAllowlist --output ./mocks/ --case=underscore @@ -46,7 +49,8 @@ type onchainAllowlist struct { config OnchainAllowlistConfig allowlist atomic.Pointer[map[common.Address]struct{}] client evmclient.Client - contract *ocr2dr_oracle.OCR2DROracle + contractV0 *ocr2dr_oracle.OCR2DROracle + contractV1 *functions_allow_list.TermsOfServiceAllowList blockConfirmations *big.Int lggr logger.Logger closeWait sync.WaitGroup @@ -60,14 +64,19 @@ func NewOnchainAllowlist(client evmclient.Client, config OnchainAllowlistConfig, if lggr == nil { return nil, errors.New("logger is nil") } - contract, err := ocr2dr_oracle.NewOCR2DROracle(config.ContractAddress, client) + contractV0, err := ocr2dr_oracle.NewOCR2DROracle(config.ContractAddress, client) if err != nil { return nil, fmt.Errorf("unexpected error during NewOCR2DROracle: %s", err) } + contractV1, err := functions_allow_list.NewTermsOfServiceAllowList(config.ContractAddress, client) + if err != nil { + return nil, fmt.Errorf("unexpected error during functions_router.NewFunctionsRouter: %s", err) + } allowlist := &onchainAllowlist{ config: config, client: client, - contract: contract, + contractV0: contractV0, + contractV1: contractV1, blockConfirmations: big.NewInt(int64(config.BlockConfirmations)), lggr: lggr.Named("OnchainAllowlist"), stopCh: make(utils.StopChan), @@ -137,7 +146,30 @@ func (a *onchainAllowlist) UpdateFromContract(ctx context.Context) error { return errors.New("LatestBlockHeight returned nil") } blockNum := big.NewInt(0).Sub(latestBlockHeight, a.blockConfirmations) - addrList, err := a.contract.GetAuthorizedSenders(&bind.CallOpts{ + if a.config.ContractVersion == 0 { + return a.updateFromContractV0(ctx, blockNum) + } else if a.config.ContractVersion == 1 { + return a.updateFromContractV1(ctx, blockNum) + } else { + return fmt.Errorf("unknown contract version %d", a.config.ContractVersion) + } +} + +func (a *onchainAllowlist) updateFromContractV0(ctx context.Context, blockNum *big.Int) error { + addrList, err := a.contractV0.GetAuthorizedSenders(&bind.CallOpts{ + Pending: false, + BlockNumber: blockNum, + Context: ctx, + }) + if err != nil { + return errors.Wrap(err, "error calling GetAuthorizedSenders") + } + a.update(addrList) + return nil +} + +func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *big.Int) error { + addrList, err := a.contractV1.GetAllAllowedSenders(&bind.CallOpts{ Pending: false, BlockNumber: blockNum, Context: ctx, @@ -145,11 +177,14 @@ func (a *onchainAllowlist) UpdateFromContract(ctx context.Context) error { if err != nil { return errors.Wrap(err, "error calling GetAuthorizedSenders") } + a.update(addrList) + return nil +} +func (a *onchainAllowlist) update(addrList []common.Address) { newAllowlist := make(map[common.Address]struct{}) for _, addr := range addrList { newAllowlist[addr] = struct{}{} } a.allowlist.Store(&newAllowlist) - a.lggr.Infow("allowlist updated successfully", "len", len(addrList), "blockNumber", blockNum) - return nil + a.lggr.Infow("allowlist updated successfully", "len", len(addrList)) } diff --git a/core/services/gateway/handlers/functions/allowlist_test.go b/core/services/gateway/handlers/functions/allowlist_test.go index e8c5a5f662a..9ec6ef30457 100644 --- a/core/services/gateway/handlers/functions/allowlist_test.go +++ b/core/services/gateway/handlers/functions/allowlist_test.go @@ -39,27 +39,31 @@ func sampleEncodedAllowlist(t *testing.T) []byte { func TestAllowlist_UpdateAndCheck(t *testing.T) { t.Parallel() - client := mocks.NewClient(t) - client.On("LatestBlockHeight", mock.Anything).Return(big.NewInt(42), nil) - client.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(sampleEncodedAllowlist(t), nil) - config := functions.OnchainAllowlistConfig{ - ContractAddress: common.Address{}, - BlockConfirmations: 1, - } - allowlist, err := functions.NewOnchainAllowlist(client, config, logger.TestLogger(t)) - require.NoError(t, err) + for _, version := range []uint32{0, 1} { + client := mocks.NewClient(t) + client.On("LatestBlockHeight", mock.Anything).Return(big.NewInt(42), nil) + // both contract versions have the same return type + client.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(sampleEncodedAllowlist(t), nil) + config := functions.OnchainAllowlistConfig{ + ContractVersion: version, + ContractAddress: common.Address{}, + BlockConfirmations: 1, + } + allowlist, err := functions.NewOnchainAllowlist(client, config, logger.TestLogger(t)) + require.NoError(t, err) - err = allowlist.Start(testutils.Context(t)) - require.NoError(t, err) - t.Cleanup(func() { - assert.NoError(t, allowlist.Close()) - }) + err = allowlist.Start(testutils.Context(t)) + require.NoError(t, err) + t.Cleanup(func() { + assert.NoError(t, allowlist.Close()) + }) - require.NoError(t, allowlist.UpdateFromContract(testutils.Context(t))) - require.False(t, allowlist.Allow(common.Address{})) - require.True(t, allowlist.Allow(common.HexToAddress(addr1))) - require.True(t, allowlist.Allow(common.HexToAddress(addr2))) - require.False(t, allowlist.Allow(common.HexToAddress(addr3))) + require.NoError(t, allowlist.UpdateFromContract(testutils.Context(t))) + require.False(t, allowlist.Allow(common.Address{})) + require.True(t, allowlist.Allow(common.HexToAddress(addr1))) + require.True(t, allowlist.Allow(common.HexToAddress(addr2))) + require.False(t, allowlist.Allow(common.HexToAddress(addr3))) + } } func TestAllowlist_UpdatePeriodically(t *testing.T) { @@ -73,6 +77,7 @@ func TestAllowlist_UpdatePeriodically(t *testing.T) { }).Return(sampleEncodedAllowlist(t), nil) config := functions.OnchainAllowlistConfig{ ContractAddress: common.Address{}, + ContractVersion: 0, BlockConfirmations: 1, UpdateFrequencySec: 1, UpdateTimeoutSec: 1, diff --git a/core/services/gateway/handlers/functions/handler.functions.go b/core/services/gateway/handlers/functions/handler.functions.go index b526112745f..aee099e6cee 100644 --- a/core/services/gateway/handlers/functions/handler.functions.go +++ b/core/services/gateway/handlers/functions/handler.functions.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "errors" - "math/big" "time" "github.com/ethereum/go-ethereum/common" @@ -52,7 +51,7 @@ type PendingSecretsRequest struct { var _ handlers.Handler = (*functionsHandler)(nil) -func NewFunctionsHandlerFromConfig(handlerConfig json.RawMessage, donConfig *config.DONConfig, don handlers.DON, chains evm.ChainSet, lggr logger.Logger) (handlers.Handler, error) { +func NewFunctionsHandlerFromConfig(handlerConfig json.RawMessage, donConfig *config.DONConfig, don handlers.DON, legacyChains evm.LegacyChainContainer, lggr logger.Logger) (handlers.Handler, error) { var cfg FunctionsHandlerConfig err := json.Unmarshal(handlerConfig, &cfg) if err != nil { @@ -60,16 +59,12 @@ func NewFunctionsHandlerFromConfig(handlerConfig json.RawMessage, donConfig *con } var allowlist OnchainAllowlist if cfg.OnchainAllowlist != nil { - chainId, ok := big.NewInt(0).SetString(cfg.OnchainAllowlistChainID, 10) - if !ok { - return nil, errors.New("invalid chain ID") - } - chain, err := chains.Get(chainId) - if err != nil { + chain, err2 := legacyChains.Get(cfg.OnchainAllowlistChainID) + if err2 != nil { return nil, err } - allowlist, err = NewOnchainAllowlist(chain.Client(), *cfg.OnchainAllowlist, lggr) - if err != nil { + allowlist, err2 = NewOnchainAllowlist(chain.Client(), *cfg.OnchainAllowlist, lggr) + if err2 != nil { return nil, err } } diff --git a/core/services/job/helpers_test.go b/core/services/job/helpers_test.go index 281a23357ba..106ba8d27c7 100644 --- a/core/services/job/helpers_test.go +++ b/core/services/job/helpers_test.go @@ -26,6 +26,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/services/ocr" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/store/models" ) @@ -218,8 +219,10 @@ func makeMinimalHTTPOracleSpec(t *testing.T, db *sqlx.DB, cfg chainlink.GeneralC } s := fmt.Sprintf(minimalNonBootstrapTemplate, contractAddress, transmitterAddress, keyBundle, fetchUrl, timeout) keyStore := cltest.NewKeyStore(t, db, pgtest.NewQConfig(true)) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, Client: evmtest.NewEthClientMockWithDefaultChain(t), GeneralConfig: cfg, KeyStore: keyStore.Eth()}) - _, err := ocr.ValidatedOracleSpecToml(cc, s) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, Client: evmtest.NewEthClientMockWithDefaultChain(t), GeneralConfig: cfg, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + _, err = ocr.ValidatedOracleSpecToml(legacyChains, s) require.NoError(t, err) err = toml.Unmarshal([]byte(s), &os) require.NoError(t, err) diff --git a/core/services/job/job_orm_test.go b/core/services/job/job_orm_test.go index ce03dbaa0e3..0f70e74b247 100644 --- a/core/services/job/job_orm_test.go +++ b/core/services/job/job_orm_test.go @@ -15,6 +15,8 @@ import ( "github.com/stretchr/testify/require" "gopkg.in/guregu/null.v4" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" + "github.com/smartcontractkit/chainlink/v2/core/assets" "github.com/smartcontractkit/chainlink/v2/core/bridges" evmcfg "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" @@ -35,6 +37,7 @@ import ( ocr2validate "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" "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/vrf/vrfcommon" "github.com/smartcontractkit/chainlink/v2/core/services/webhook" "github.com/smartcontractkit/chainlink/v2/core/testdata/testspecs" @@ -79,8 +82,10 @@ func TestORM(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: ethKeyStore}) - orm := NewTestORM(t, db, cc, pipelineORM, bridgesORM, keyStore, config.Database()) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: ethKeyStore}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) borm := bridges.NewORM(db, logger.TestLogger(t), config.Database()) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) @@ -251,9 +256,12 @@ func TestORM(t *testing.T) { require.Equal(t, jb.BlockhashStoreSpec.ID, savedJob.BlockhashStoreSpec.ID) require.Equal(t, jb.BlockhashStoreSpec.CoordinatorV1Address, savedJob.BlockhashStoreSpec.CoordinatorV1Address) require.Equal(t, jb.BlockhashStoreSpec.CoordinatorV2Address, savedJob.BlockhashStoreSpec.CoordinatorV2Address) + require.Equal(t, jb.BlockhashStoreSpec.CoordinatorV2PlusAddress, savedJob.BlockhashStoreSpec.CoordinatorV2PlusAddress) require.Equal(t, jb.BlockhashStoreSpec.WaitBlocks, savedJob.BlockhashStoreSpec.WaitBlocks) require.Equal(t, jb.BlockhashStoreSpec.LookbackBlocks, savedJob.BlockhashStoreSpec.LookbackBlocks) require.Equal(t, jb.BlockhashStoreSpec.BlockhashStoreAddress, savedJob.BlockhashStoreSpec.BlockhashStoreAddress) + require.Equal(t, jb.BlockhashStoreSpec.TrustedBlockhashStoreAddress, savedJob.BlockhashStoreSpec.TrustedBlockhashStoreAddress) + require.Equal(t, jb.BlockhashStoreSpec.TrustedBlockhashStoreBatchSize, savedJob.BlockhashStoreSpec.TrustedBlockhashStoreBatchSize) require.Equal(t, jb.BlockhashStoreSpec.PollPeriod, savedJob.BlockhashStoreSpec.PollPeriod) require.Equal(t, jb.BlockhashStoreSpec.RunTimeout, savedJob.BlockhashStoreSpec.RunTimeout) require.Equal(t, jb.BlockhashStoreSpec.EVMChainID, savedJob.BlockhashStoreSpec.EVMChainID) @@ -308,8 +316,10 @@ func TestORM_DeleteJob_DeletesAssociatedRecords(t *testing.T) { lggr := logger.TestLogger(t) pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, lggr, config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - jobORM := NewTestORM(t, db, cc, pipelineORM, bridgesORM, keyStore, config.Database()) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) scopedConfig := evmtest.NewChainScopedConfig(t, config) korm := keeper.NewORM(db, logger.TestLogger(t), scopedConfig.Database()) @@ -318,7 +328,7 @@ func TestORM_DeleteJob_DeletesAssociatedRecords(t *testing.T) { _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) _, address := cltest.MustInsertRandomKey(t, keyStore.Eth()) - jb, err := ocr.ValidatedOracleSpecToml(cc, testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{ + jb, err := ocr.ValidatedOracleSpecToml(legacyChains, testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{ TransmitterAddress: address.Hex(), DS1BridgeName: bridge.Name.String(), DS2BridgeName: bridge2.Name.String(), @@ -407,8 +417,11 @@ func TestORM_CreateJob_VRFV2(t *testing.T) { lggr := logger.TestLogger(t) pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, lggr, config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - jobORM := NewTestORM(t, db, cc, pipelineORM, bridgesORM, keyStore, config.Database()) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + + jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) fromAddresses := []string{cltest.NewEIP55Address().String(), cltest.NewEIP55Address().String()} jb, err := vrfcommon.ValidatedVRFSpec(testspecs.GenerateVRFSpec( @@ -479,6 +492,92 @@ func TestORM_CreateJob_VRFV2(t *testing.T) { cltest.AssertCount(t, db, "jobs", 0) } +func TestORM_CreateJob_VRFV2Plus(t *testing.T) { + config := configtest.NewTestGeneralConfig(t) + db := pgtest.NewSqlxDB(t) + keyStore := cltest.NewKeyStore(t, db, config.Database()) + 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()) + cc := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(cc) + require.NoError(t, err) + jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) + + fromAddresses := []string{cltest.NewEIP55Address().String(), cltest.NewEIP55Address().String()} + jb, err := vrfcommon.ValidatedVRFSpec(testspecs.GenerateVRFSpec( + testspecs.VRFSpecParams{ + VRFVersion: vrfcommon.V2Plus, + RequestedConfsDelay: 10, + FromAddresses: fromAddresses, + ChunkSize: 25, + BackoffInitialDelay: time.Minute, + BackoffMaxDelay: time.Hour, + GasLanePrice: assets.GWei(100), + }). + Toml()) + require.NoError(t, err) + + require.NoError(t, jobORM.CreateJob(&jb)) + cltest.AssertCount(t, db, "vrf_specs", 1) + cltest.AssertCount(t, db, "jobs", 1) + var requestedConfsDelay int64 + require.NoError(t, db.Get(&requestedConfsDelay, `SELECT requested_confs_delay FROM vrf_specs LIMIT 1`)) + require.Equal(t, int64(10), requestedConfsDelay) + var batchFulfillmentEnabled bool + require.NoError(t, db.Get(&batchFulfillmentEnabled, `SELECT batch_fulfillment_enabled FROM vrf_specs LIMIT 1`)) + require.False(t, batchFulfillmentEnabled) + var batchFulfillmentGasMultiplier float64 + require.NoError(t, db.Get(&batchFulfillmentGasMultiplier, `SELECT batch_fulfillment_gas_multiplier FROM vrf_specs LIMIT 1`)) + require.Equal(t, float64(1.0), batchFulfillmentGasMultiplier) + var requestTimeout time.Duration + require.NoError(t, db.Get(&requestTimeout, `SELECT request_timeout FROM vrf_specs LIMIT 1`)) + require.Equal(t, 24*time.Hour, requestTimeout) + var backoffInitialDelay time.Duration + require.NoError(t, db.Get(&backoffInitialDelay, `SELECT backoff_initial_delay FROM vrf_specs LIMIT 1`)) + require.Equal(t, time.Minute, backoffInitialDelay) + var backoffMaxDelay time.Duration + require.NoError(t, db.Get(&backoffMaxDelay, `SELECT backoff_max_delay FROM vrf_specs LIMIT 1`)) + require.Equal(t, time.Hour, backoffMaxDelay) + var chunkSize int + require.NoError(t, db.Get(&chunkSize, `SELECT chunk_size FROM vrf_specs LIMIT 1`)) + require.Equal(t, 25, chunkSize) + var gasLanePrice assets.Wei + require.NoError(t, db.Get(&gasLanePrice, `SELECT gas_lane_price FROM vrf_specs LIMIT 1`)) + require.Equal(t, jb.VRFSpec.GasLanePrice, &gasLanePrice) + var fa pq.ByteaArray + require.NoError(t, db.Get(&fa, `SELECT from_addresses FROM vrf_specs LIMIT 1`)) + var actual []string + for _, b := range fa { + actual = append(actual, common.BytesToAddress(b).String()) + } + require.ElementsMatch(t, fromAddresses, actual) + var vrfOwnerAddress ethkey.EIP55Address + require.Error(t, db.Get(&vrfOwnerAddress, `SELECT vrf_owner_address FROM vrf_specs LIMIT 1`)) + require.NoError(t, jobORM.DeleteJob(jb.ID)) + cltest.AssertCount(t, db, "vrf_specs", 0) + cltest.AssertCount(t, db, "jobs", 0) + + jb, err = vrfcommon.ValidatedVRFSpec(testspecs.GenerateVRFSpec(testspecs.VRFSpecParams{ + VRFVersion: vrfcommon.V2Plus, + RequestTimeout: 1 * time.Hour, + FromAddresses: fromAddresses, + }).Toml()) + require.NoError(t, err) + require.NoError(t, jobORM.CreateJob(&jb)) + cltest.AssertCount(t, db, "vrf_specs", 1) + cltest.AssertCount(t, db, "jobs", 1) + require.NoError(t, db.Get(&requestedConfsDelay, `SELECT requested_confs_delay FROM vrf_specs LIMIT 1`)) + require.Equal(t, int64(0), requestedConfsDelay) + require.NoError(t, db.Get(&requestTimeout, `SELECT request_timeout FROM vrf_specs LIMIT 1`)) + require.Equal(t, 1*time.Hour, requestTimeout) + require.NoError(t, jobORM.DeleteJob(jb.ID)) + cltest.AssertCount(t, db, "vrf_specs", 0) + cltest.AssertCount(t, db, "jobs", 0) +} + func TestORM_CreateJob_OCRBootstrap(t *testing.T) { config := configtest.NewTestGeneralConfig(t) db := pgtest.NewSqlxDB(t) @@ -488,8 +587,10 @@ func TestORM_CreateJob_OCRBootstrap(t *testing.T) { lggr := logger.TestLogger(t) pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, lggr, config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - jobORM := NewTestORM(t, db, cc, pipelineORM, bridgesORM, keyStore, config.Database()) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) jb, err := ocrbootstrap.ValidatedBootstrapSpecToml(testspecs.OCRBootstrapSpec) require.NoError(t, err) @@ -527,8 +628,10 @@ func TestORM_CreateJob_OCR_DuplicatedContractAddress(t *testing.T) { pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, lggr, config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - jobORM := NewTestORM(t, db, cc, pipelineORM, bridgesORM, keyStore, config.Database()) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) defaultChainID := config.DefaultChainID() @@ -545,7 +648,7 @@ func TestORM_CreateJob_OCR_DuplicatedContractAddress(t *testing.T) { TransmitterAddress: address.Hex(), }) - jb, err := ocr.ValidatedOracleSpecToml(cc, spec.Toml()) + jb, err := ocr.ValidatedOracleSpecToml(legacyChains, spec.Toml()) require.NoError(t, err) // 2nd job with no Chain ID @@ -555,7 +658,7 @@ func TestORM_CreateJob_OCR_DuplicatedContractAddress(t *testing.T) { DS2BridgeName: bridge2.Name.String(), TransmitterAddress: address.Hex(), }) - jb2, err := ocr.ValidatedOracleSpecToml(cc, spec2.Toml()) + jb2, err := ocr.ValidatedOracleSpecToml(legacyChains, spec2.Toml()) require.NoError(t, err) // Default Chain Job @@ -568,7 +671,7 @@ func TestORM_CreateJob_OCR_DuplicatedContractAddress(t *testing.T) { TransmitterAddress: address.Hex(), JobID: externalJobID.UUID.String(), }) - jb3, err := ocr.ValidatedOracleSpecToml(cc, spec3.Toml()) + jb3, err := ocr.ValidatedOracleSpecToml(legacyChains, spec3.Toml()) require.NoError(t, err) // Custom Chain Job @@ -581,7 +684,7 @@ func TestORM_CreateJob_OCR_DuplicatedContractAddress(t *testing.T) { TransmitterAddress: address.Hex(), JobID: externalJobID.UUID.String(), }) - jb4, err := ocr.ValidatedOracleSpecToml(cc, spec4.Toml()) + jb4, err := ocr.ValidatedOracleSpecToml(legacyChains, spec4.Toml()) require.NoError(t, err) t.Run("with legacy NULL chain id", func(t *testing.T) { @@ -623,7 +726,7 @@ func TestORM_CreateJob_OCR_DuplicatedContractAddress(t *testing.T) { externalJobID = uuid.NullUUID{UUID: uuid.New(), Valid: true} spec3.JobID = externalJobID.UUID.String() - jb3a, err := ocr.ValidatedOracleSpecToml(cc, spec3.Toml()) + jb3a, err := ocr.ValidatedOracleSpecToml(legacyChains, spec3.Toml()) require.NoError(t, err) err = jobORM.CreateJob(&jb3a) // Try to add duplicate job with default id require.Error(t, err) @@ -631,7 +734,7 @@ func TestORM_CreateJob_OCR_DuplicatedContractAddress(t *testing.T) { externalJobID = uuid.NullUUID{UUID: uuid.New(), Valid: true} spec4.JobID = externalJobID.UUID.String() - jb5, err := ocr.ValidatedOracleSpecToml(cc, spec4.Toml()) + jb5, err := ocr.ValidatedOracleSpecToml(legacyChains, spec4.Toml()) require.NoError(t, err) err = jobORM.CreateJob(&jb5) // Try to add duplicate job with custom id @@ -660,8 +763,10 @@ func TestORM_CreateJob_OCR2_DuplicatedContractAddress(t *testing.T) { pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, lggr, config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - jobORM := NewTestORM(t, db, cc, pipelineORM, bridgesORM, keyStore, config.Database()) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) _, address := cltest.MustInsertRandomKey(t, keyStore.Eth()) @@ -702,7 +807,7 @@ func TestORM_CreateJob_OCR2_DuplicatedContractAddress(t *testing.T) { require.Error(t, err) } -func TestORM_CreateJob_OCR2_Sending_Keys_TransmitterID_Validations(t *testing.T) { +func TestORM_CreateJob_OCR2_Sending_Keys_Transmitter_Keys_Validations(t *testing.T) { customChainID := utils.NewBig(testutils.NewRandomEVMChainID()) config := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { @@ -722,8 +827,11 @@ func TestORM_CreateJob_OCR2_Sending_Keys_TransmitterID_Validations(t *testing.T) pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, lggr, config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - jobORM := NewTestORM(t, db, cc, pipelineORM, bridgesORM, keyStore, config.Database()) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) + require.True(t, relayExtenders.Len() > 0) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) jb, err := ocr2validate.ValidatedOracleSpecToml(config.OCR2(), config.Insecure(), testspecs.OCR2EVMSpecMinimal) require.NoError(t, err) @@ -738,7 +846,7 @@ func TestORM_CreateJob_OCR2_Sending_Keys_TransmitterID_Validations(t *testing.T) jb.OCR2OracleSpec.TransmitterID = null.String{} _, address2 := cltest.MustInsertRandomKey(t, keyStore.Eth()) jb.OCR2OracleSpec.RelayConfig["sendingKeys"] = interface{}([]any{address.String(), address2.String(), common.HexToAddress("0X0").String()}) - assert.Equal(t, "CreateJobFailed: no EVM key matching: \"0x0000000000000000000000000000000000000000\": no such transmitter key exists", jobORM.CreateJob(&jb).Error()) + assert.Equal(t, "CreateJobFailed: no EVM key matching: \"0x0000000000000000000000000000000000000000\": no such sending key exists", jobORM.CreateJob(&jb).Error()) jb.OCR2OracleSpec.RelayConfig["sendingKeys"] = interface{}([]any{1, 2, 3}) assert.Equal(t, "CreateJobFailed: sending keys are of wrong type", jobORM.CreateJob(&jb).Error()) @@ -757,6 +865,71 @@ func TestORM_CreateJob_OCR2_Sending_Keys_TransmitterID_Validations(t *testing.T) }) } +func TestORM_ValidateKeyStoreMatch(t *testing.T) { + config := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) {}) + + keyStore := cltest.NewKeyStore(t, pgtest.NewSqlxDB(t), config.Database()) + require.NoError(t, keyStore.OCR2().Add(cltest.DefaultOCR2Key)) + + jb, err := ocr2validate.ValidatedOracleSpecToml(config.OCR2(), config.Insecure(), testspecs.OCR2EVMSpecMinimal) + require.NoError(t, err) + + t.Run("test ETH key validation", func(t *testing.T) { + jb.OCR2OracleSpec.Relay = relay.EVM + err = job.ValidateKeyStoreMatch(jb.OCR2OracleSpec, keyStore, "bad key") + require.EqualError(t, err, "no EVM key matching: \"bad key\"") + + _, evmKey := cltest.MustInsertRandomKey(t, keyStore.Eth()) + err = job.ValidateKeyStoreMatch(jb.OCR2OracleSpec, keyStore, evmKey.String()) + require.NoError(t, err) + }) + + t.Run("test Cosmos key validation", func(t *testing.T) { + jb.OCR2OracleSpec.Relay = relay.Cosmos + err = job.ValidateKeyStoreMatch(jb.OCR2OracleSpec, keyStore, "bad key") + require.EqualError(t, err, "no Cosmos key matching: \"bad key\"") + + cosmosKey, err := keyStore.Cosmos().Create() + require.NoError(t, err) + err = job.ValidateKeyStoreMatch(jb.OCR2OracleSpec, keyStore, cosmosKey.ID()) + require.NoError(t, err) + }) + + t.Run("test Solana key validation", func(t *testing.T) { + jb.OCR2OracleSpec.Relay = relay.Solana + + err = job.ValidateKeyStoreMatch(jb.OCR2OracleSpec, keyStore, "bad key") + require.EqualError(t, err, "no Solana key matching: \"bad key\"") + + solanaKey, err := keyStore.Solana().Create() + require.NoError(t, err) + err = job.ValidateKeyStoreMatch(jb.OCR2OracleSpec, keyStore, solanaKey.ID()) + require.NoError(t, err) + }) + + t.Run("test Starknet key validation", func(t *testing.T) { + jb.OCR2OracleSpec.Relay = relay.StarkNet + err = job.ValidateKeyStoreMatch(jb.OCR2OracleSpec, keyStore, "bad key") + require.EqualError(t, err, "no Starknet key matching: \"bad key\"") + + starkNetKey, err := keyStore.StarkNet().Create() + require.NoError(t, err) + err = job.ValidateKeyStoreMatch(jb.OCR2OracleSpec, keyStore, starkNetKey.ID()) + require.NoError(t, err) + }) + + t.Run("test Mercury ETH key validation", func(t *testing.T) { + jb.OCR2OracleSpec.PluginType = job.Mercury + err = job.ValidateKeyStoreMatch(jb.OCR2OracleSpec, keyStore, "bad key") + require.EqualError(t, err, "no CSA key matching: \"bad key\"") + + csaKey, err := keyStore.CSA().Create() + require.NoError(t, err) + err = job.ValidateKeyStoreMatch(jb.OCR2OracleSpec, keyStore, csaKey.ID()) + require.NoError(t, err) + }) +} + func Test_FindJobs(t *testing.T) { t.Parallel() @@ -768,14 +941,16 @@ func Test_FindJobs(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - orm := NewTestORM(t, db, cc, pipelineORM, bridgesORM, keyStore, config.Database()) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) _, address := cltest.MustInsertRandomKey(t, keyStore.Eth()) - jb1, err := ocr.ValidatedOracleSpecToml(cc, + jb1, err := ocr.ValidatedOracleSpecToml(legacyChains, testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{ JobID: uuid.New().String(), TransmitterAddress: address.Hex(), @@ -848,8 +1023,10 @@ func Test_FindJob(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - orm := NewTestORM(t, db, cc, pipelineORM, bridgesORM, keyStore, config.Database()) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) @@ -858,7 +1035,7 @@ func Test_FindJob(t *testing.T) { // Must uniquely name the OCR Specs to properly insert a new job in the job table. externalJobID := uuid.New() _, address := cltest.MustInsertRandomKey(t, keyStore.Eth()) - job, err := ocr.ValidatedOracleSpecToml(cc, + job, err := ocr.ValidatedOracleSpecToml(legacyChains, testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{ JobID: externalJobID.String(), Name: "orig ocr spec", @@ -869,7 +1046,7 @@ func Test_FindJob(t *testing.T) { ) require.NoError(t, err) - jobSameAddress, err := ocr.ValidatedOracleSpecToml(cc, + jobSameAddress, err := ocr.ValidatedOracleSpecToml(legacyChains, testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{ JobID: uuid.New().String(), TransmitterAddress: address.Hex(), @@ -893,8 +1070,8 @@ func Test_FindJob(t *testing.T) { jobOCR2.OCR2OracleSpec.PluginConfig["juelsPerFeeCoinSource"] = juelsPerFeeCoinSource - ocr2WithFeedID1 := "0x0000000000000000000000000000000000000000000000000000000000000001" - ocr2WithFeedID2 := "0x0000000000000000000000000000000000000000000000000000000000000002" + ocr2WithFeedID1 := "0x0001000000000000000000000000000000000000000000000000000000000001" + ocr2WithFeedID2 := "0x0001000000000000000000000000000000000000000000000000000000000002" jobOCR2WithFeedID1, err := ocr2validate.ValidatedOracleSpecToml( config.OCR2(), config.Insecure(), @@ -912,7 +1089,7 @@ func Test_FindJob(t *testing.T) { require.NoError(t, err) // Create a job with the legacy null evm chain id. - jobWithNullChain, err := ocr.ValidatedOracleSpecToml(cc, + jobWithNullChain, err := ocr.ValidatedOracleSpecToml(legacyChains, testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{ JobID: uuid.New().String(), ContractAddress: "0xB47f9a6D281B2A82F8692F8dE058E4249363A6fc", @@ -1064,8 +1241,10 @@ func Test_FindJobsByPipelineSpecIDs(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - orm := NewTestORM(t, db, cc, pipelineORM, bridgesORM, keyStore, config.Database()) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.DirectRequestSpec) require.NoError(t, err) @@ -1104,15 +1283,17 @@ func Test_FindPipelineRuns(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - orm := NewTestORM(t, db, cc, pipelineORM, bridgesORM, keyStore, config.Database()) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) externalJobID := uuid.New() _, address := cltest.MustInsertRandomKey(t, keyStore.Eth()) - jb, err := ocr.ValidatedOracleSpecToml(cc, + jb, err := ocr.ValidatedOracleSpecToml(legacyChains, testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{ JobID: externalJobID.String(), TransmitterAddress: address.Hex(), @@ -1164,15 +1345,17 @@ func Test_PipelineRunsByJobID(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - orm := NewTestORM(t, db, cc, pipelineORM, bridgesORM, keyStore, config.Database()) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) externalJobID := uuid.New() _, address := cltest.MustInsertRandomKey(t, keyStore.Eth()) - jb, err := ocr.ValidatedOracleSpecToml(cc, + jb, err := ocr.ValidatedOracleSpecToml(legacyChains, testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{ JobID: externalJobID.String(), TransmitterAddress: address.Hex(), @@ -1224,8 +1407,10 @@ func Test_FindPipelineRunIDsByJobID(t *testing.T) { lggr := logger.TestLogger(t) pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, lggr, config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - orm := NewTestORM(t, db, cc, pipelineORM, bridgesORM, keyStore, config.Database()) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) _, address := cltest.MustInsertRandomKey(t, keyStore.Eth()) @@ -1237,7 +1422,7 @@ func Test_FindPipelineRunIDsByJobID(t *testing.T) { key, err := ethkey.NewV2() require.NoError(t, err) - jb, err = ocr.ValidatedOracleSpecToml(cc, + jb, err = ocr.ValidatedOracleSpecToml(legacyChains, testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{ JobID: jobID, Name: fmt.Sprintf("Job #%v", jobID), @@ -1331,15 +1516,17 @@ func Test_FindPipelineRunsByIDs(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - orm := NewTestORM(t, db, cc, pipelineORM, bridgesORM, keyStore, config.Database()) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) externalJobID := uuid.New() _, address := cltest.MustInsertRandomKey(t, keyStore.Eth()) - jb, err := ocr.ValidatedOracleSpecToml(cc, + jb, err := ocr.ValidatedOracleSpecToml(legacyChains, testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{ JobID: externalJobID.String(), TransmitterAddress: address.Hex(), @@ -1388,8 +1575,10 @@ func Test_FindPipelineRunByID(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - orm := NewTestORM(t, db, cc, pipelineORM, bridgesORM, keyStore, config.Database()) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.DirectRequestSpec) require.NoError(t, err) @@ -1432,8 +1621,10 @@ func Test_FindJobWithoutSpecErrors(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - orm := NewTestORM(t, db, cc, pipelineORM, bridgesORM, keyStore, config.Database()) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.DirectRequestSpec) require.NoError(t, err) @@ -1470,8 +1661,10 @@ func Test_FindSpecErrorsByJobIDs(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - orm := NewTestORM(t, db, cc, pipelineORM, bridgesORM, keyStore, config.Database()) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.DirectRequestSpec) require.NoError(t, err) @@ -1505,15 +1698,17 @@ func Test_CountPipelineRunsByJobID(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - orm := NewTestORM(t, db, cc, pipelineORM, bridgesORM, keyStore, config.Database()) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database()) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) externalJobID := uuid.New() _, address := cltest.MustInsertRandomKey(t, keyStore.Eth()) - jb, err := ocr.ValidatedOracleSpecToml(cc, + jb, err := ocr.ValidatedOracleSpecToml(legacyChains, testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{ JobID: externalJobID.String(), TransmitterAddress: address.Hex(), diff --git a/core/services/job/job_pipeline_orm_integration_test.go b/core/services/job/job_pipeline_orm_integration_test.go index bc71fa4cc98..ff1cab4f3c6 100644 --- a/core/services/job/job_pipeline_orm_integration_test.go +++ b/core/services/job/job_pipeline_orm_integration_test.go @@ -17,6 +17,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/store/models" ) @@ -150,15 +151,17 @@ func TestPipelineORM_Integration(t *testing.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()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{Client: evmtest.NewEthClientMockWithDefaultChain(t), DB: db, GeneralConfig: config, KeyStore: ethKeyStore}) - runner := pipeline.NewRunner(orm, btORM, config.JobPipeline(), cfg.WebServer(), cc, nil, nil, lggr, nil, nil) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{Client: evmtest.NewEthClientMockWithDefaultChain(t), DB: db, GeneralConfig: config, KeyStore: ethKeyStore}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + runner := pipeline.NewRunner(orm, btORM, config.JobPipeline(), cfg.WebServer(), legacyChains, nil, nil, lggr, nil, nil) - jobORM := NewTestORM(t, db, cc, orm, btORM, keyStore, cfg.Database()) + jobORM := NewTestORM(t, db, legacyChains, orm, btORM, keyStore, cfg.Database()) dbSpec := makeVoterTurnoutOCRJobSpec(t, transmitterAddress, bridge.Name.String(), bridge2.Name.String()) // Need a job in order to create a run - err := jobORM.CreateJob(dbSpec) + err = jobORM.CreateJob(dbSpec) require.NoError(t, err) var pipelineSpecs []pipeline.Spec diff --git a/core/services/job/mocks/spawner.go b/core/services/job/mocks/spawner.go index 768be76dc55..6f6c3200af8 100644 --- a/core/services/job/mocks/spawner.go +++ b/core/services/job/mocks/spawner.go @@ -146,13 +146,20 @@ func (_m *Spawner) Start(_a0 context.Context) error { return r0 } -// StartService provides a mock function with given fields: ctx, spec -func (_m *Spawner) StartService(ctx context.Context, spec job.Job) error { - ret := _m.Called(ctx, spec) +// StartService provides a mock function with given fields: ctx, spec, qopts +func (_m *Spawner) StartService(ctx context.Context, spec job.Job, qopts ...pg.QOpt) error { + _va := make([]interface{}, len(qopts)) + for _i := range qopts { + _va[_i] = qopts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, spec) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) var r0 error - if rf, ok := ret.Get(0).(func(context.Context, job.Job) error); ok { - r0 = rf(ctx, spec) + if rf, ok := ret.Get(0).(func(context.Context, job.Job, ...pg.QOpt) error); ok { + r0 = rf(ctx, spec, qopts...) } else { r0 = ret.Error(0) } diff --git a/core/services/job/models.go b/core/services/job/models.go index d5e72c78514..d70afde12c2 100644 --- a/core/services/job/models.go +++ b/core/services/job/models.go @@ -298,18 +298,6 @@ func (r *JSONConfig) Scan(value interface{}) error { return json.Unmarshal(b, &r) } -func (r JSONConfig) EVMChainID() (int64, error) { - i, ok := r["chainID"] - if !ok { - return -1, fmt.Errorf("%w: chainID must be provided in relay config", ErrNoChainFromSpec) - } - f, ok := i.(float64) - if !ok { - return -1, fmt.Errorf("expected float64 chain id but got: %T", i) - } - return int64(f), nil -} - func (r JSONConfig) MercuryCredentialName() (string, error) { url, ok := r["mercuryCredentialName"] if !ok { @@ -348,10 +336,12 @@ const ( // OCR2OracleSpec defines the job spec for OCR2 jobs. // Relay config is chain specific config for a relay (chain adapter). type OCR2OracleSpec struct { - ID int32 `toml:"-"` - ContractID string `toml:"contractID"` - FeedID *common.Hash `toml:"feedID"` - Relay relay.Network `toml:"relay"` + ID int32 `toml:"-"` + ContractID string `toml:"contractID"` + FeedID *common.Hash `toml:"feedID"` + Relay relay.Network `toml:"relay"` + // TODO BCF-2442 implement ChainID as top level parameter rathe than buried in RelayConfig. + ChainID string `toml:"chainID"` RelayConfig JSONConfig `toml:"relayConfig"` P2PV2Bootstrappers pq.StringArray `toml:"p2pv2Bootstrappers"` OCRKeyBundleID null.String `toml:"ocrKeyBundleID"` @@ -365,6 +355,44 @@ type OCR2OracleSpec struct { CreatedAt time.Time `toml:"-"` UpdatedAt time.Time `toml:"-"` CaptureEATelemetry bool `toml:"captureEATelemetry"` + CaptureAutomationCustomTelemetry bool `toml:"captureAutomationCustomTelemetry"` +} + +func (s *OCR2OracleSpec) RelayID() (relay.ID, error) { + cid, err := s.getChainID() + if err != nil { + return relay.ID{}, err + } + return relay.NewID(s.Relay, cid) +} + +func (s *OCR2OracleSpec) getChainID() (relay.ChainID, error) { + if s.ChainID != "" { + return relay.ChainID(s.ChainID), nil + } + // backward compatible job spec + return s.getChainIdFromRelayConfig() +} + +func (s *OCR2OracleSpec) getChainIdFromRelayConfig() (relay.ChainID, error) { + + v, exists := s.RelayConfig["chainID"] + if !exists { + return "", fmt.Errorf("chainID does not exist") + } + switch t := v.(type) { + case string: + return relay.ChainID(t), nil + case int, int64, int32: + return relay.ChainID(fmt.Sprintf("%d", v)), nil + case float64: + // backward compatibility with JSONConfig.EVMChainID + i := int64(t) + return relay.ChainID(strconv.FormatInt(i, 10)), nil + + default: + return "", fmt.Errorf("unable to parse chainID: unexpected type %T", t) + } } // GetID is a getter function that returns the ID of the spec. @@ -552,6 +580,12 @@ type BlockhashStoreSpec struct { // into. BlockhashStoreAddress ethkey.EIP55Address `toml:"blockhashStoreAddress"` + // BatchBlockhashStoreAddress is the address of the trusted BlockhashStore contract to store blockhashes + TrustedBlockhashStoreAddress *ethkey.EIP55Address `toml:"trustedBlockhashStoreAddress"` + + // BatchBlockhashStoreBatchSize is the number of blockhashes to store in a single batch + TrustedBlockhashStoreBatchSize int32 `toml:"trustedBlockhashStoreBatchSize"` + // PollPeriod defines how often recent blocks should be scanned for blockhash storage. PollPeriod time.Duration `toml:"pollPeriod"` diff --git a/core/services/job/models_test.go b/core/services/job/models_test.go new file mode 100644 index 00000000000..277f0d7eb29 --- /dev/null +++ b/core/services/job/models_test.go @@ -0,0 +1,73 @@ +package job + +import ( + "reflect" + "testing" + + "github.com/smartcontractkit/chainlink/v2/core/services/relay" +) + +func TestOCR2OracleSpec_RelayIdentifier(t *testing.T) { + type fields struct { + Relay relay.Network + ChainID string + RelayConfig JSONConfig + } + tests := []struct { + name string + fields fields + want relay.ID + wantErr bool + }{ + {name: "err no chain id", + fields: fields{}, + want: relay.ID{}, + wantErr: true, + }, + { + name: "evm explicitly configured", + fields: fields{ + Relay: relay.EVM, + ChainID: "1", + }, + want: relay.ID{Network: relay.EVM, ChainID: relay.ChainID("1")}, + }, + { + name: "evm implicitly configured", + fields: fields{ + Relay: relay.EVM, + RelayConfig: map[string]any{"chainID": 1}, + }, + want: relay.ID{Network: relay.EVM, ChainID: relay.ChainID("1")}, + }, + { + name: "evm implicitly configured with bad value", + fields: fields{ + Relay: relay.EVM, + RelayConfig: map[string]any{"chainID": float32(1)}, + }, + want: relay.ID{}, + wantErr: true, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + s := &OCR2OracleSpec{ + Relay: tt.fields.Relay, + ChainID: tt.fields.ChainID, + RelayConfig: tt.fields.RelayConfig, + } + got, err := s.RelayID() + if (err != nil) != tt.wantErr { + t.Errorf("OCR2OracleSpec.RelayIdentifier() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("OCR2OracleSpec.RelayIdentifier() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/core/services/job/orm.go b/core/services/job/orm.go index 946efa3261f..d7cfbd0fc4a 100644 --- a/core/services/job/orm.go +++ b/core/services/job/orm.go @@ -38,6 +38,7 @@ import ( var ( ErrNoSuchKeyBundle = errors.New("no such key bundle exists") ErrNoSuchTransmitterKey = errors.New("no such transmitter key exists") + ErrNoSuchSendingKey = errors.New("no such sending key exists") ErrNoSuchPublicKey = errors.New("no such public key exists") ) @@ -82,20 +83,20 @@ type ORMConfig interface { } type orm struct { - q pg.Q - chainSet evm.ChainSet - keyStore keystore.Master - pipelineORM pipeline.ORM - lggr logger.SugaredLogger - cfg pg.QConfig - bridgeORM bridges.ORM + q pg.Q + legacyChains evm.LegacyChainContainer + keyStore keystore.Master + pipelineORM pipeline.ORM + lggr logger.SugaredLogger + cfg pg.QConfig + bridgeORM bridges.ORM } var _ ORM = (*orm)(nil) func NewORM( db *sqlx.DB, - chainSet evm.ChainSet, + legacyChains evm.LegacyChainContainer, pipelineORM pipeline.ORM, bridgeORM bridges.ORM, keyStore keystore.Master, // needed to validation key properties on new job creation @@ -104,13 +105,13 @@ func NewORM( ) *orm { namedLogger := logger.Sugared(lggr.Named("JobORM")) return &orm{ - q: pg.NewQ(db, namedLogger, cfg), - chainSet: chainSet, - keyStore: keyStore, - pipelineORM: pipelineORM, - bridgeORM: bridgeORM, - lggr: namedLogger, - cfg: cfg, + q: pg.NewQ(db, namedLogger, cfg), + legacyChains: legacyChains, + keyStore: keyStore, + pipelineORM: pipelineORM, + bridgeORM: bridgeORM, + lggr: namedLogger, + cfg: cfg, } } func (o *orm) Close() error { @@ -199,7 +200,7 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { if jb.OCROracleSpec.EVMChainID == nil { // If unspecified, assume we're creating a job intended to run on default chain id - newChain, err := o.chainSet.Default() + newChain, err := o.legacyChains.Default() if err != nil { return err } @@ -242,6 +243,10 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { } } + if jb.OCR2OracleSpec.RelayConfig["sendingKeys"] != nil && jb.OCR2OracleSpec.TransmitterID.Valid { + return errors.New("sending keys and transmitter ID can't both be defined") + } + // checks if they are present and if they are valid sendingKeysDefined, err := areSendingKeysDefined(jb, o.keyStore) if err != nil { @@ -252,13 +257,9 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { return errors.New("neither sending keys nor transmitter ID is defined") } - if sendingKeysDefined && jb.OCR2OracleSpec.TransmitterID.Valid { - return errors.New("sending keys and transmitter ID can't both be defined") - } - if !sendingKeysDefined { - if err = validateKeyStoreMatch(jb.OCR2OracleSpec, o.keyStore, jb.OCR2OracleSpec.TransmitterID.String); err != nil { - return err + if err = ValidateKeyStoreMatch(jb.OCR2OracleSpec, o.keyStore, jb.OCR2OracleSpec.TransmitterID.String); err != nil { + return errors.Wrap(ErrNoSuchTransmitterKey, err.Error()) } } @@ -374,8 +375,8 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { } case BlockhashStore: var specID int32 - sql := `INSERT INTO blockhash_store_specs (coordinator_v1_address, coordinator_v2_address, coordinator_v2_plus_address, wait_blocks, lookback_blocks, blockhash_store_address, poll_period, run_timeout, evm_chain_id, from_addresses, created_at, updated_at) - VALUES (:coordinator_v1_address, :coordinator_v2_address, :coordinator_v2_plus_address, :wait_blocks, :lookback_blocks, :blockhash_store_address, :poll_period, :run_timeout, :evm_chain_id, :from_addresses, NOW(), NOW()) + sql := `INSERT INTO blockhash_store_specs (coordinator_v1_address, coordinator_v2_address, coordinator_v2_plus_address, trusted_blockhash_store_address, trusted_blockhash_store_batch_size, wait_blocks, lookback_blocks, blockhash_store_address, poll_period, run_timeout, evm_chain_id, from_addresses, created_at, updated_at) + VALUES (:coordinator_v1_address, :coordinator_v2_address, :coordinator_v2_plus_address, :trusted_blockhash_store_address, :trusted_blockhash_store_batch_size, :wait_blocks, :lookback_blocks, :blockhash_store_address, :poll_period, :run_timeout, :evm_chain_id, :from_addresses, NOW(), NOW()) RETURNING id;` if err := pg.PrepareQueryRowx(tx, sql, &specID, toBlockhashStoreSpecRow(jb.BlockhashStoreSpec)); err != nil { return errors.Wrap(err, "failed to create BlockhashStore spec") @@ -452,34 +453,34 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { return o.findJob(jb, "id", jobID, qopts...) } -// validateKeyStoreMatch confirms that the key has a valid match in the keystore -func validateKeyStoreMatch(spec *OCR2OracleSpec, keyStore keystore.Master, key string) error { +// ValidateKeyStoreMatch confirms that the key has a valid match in the keystore +func ValidateKeyStoreMatch(spec *OCR2OracleSpec, keyStore keystore.Master, key string) error { if spec.PluginType == Mercury { _, err := keyStore.CSA().Get(key) if err != nil { - return errors.Wrapf(ErrNoSuchTransmitterKey, "no CSA key matching: %q", key) + return errors.Errorf("no CSA key matching: %q", key) } } else { switch spec.Relay { case relay.EVM: _, err := keyStore.Eth().Get(key) if err != nil { - return errors.Wrapf(ErrNoSuchTransmitterKey, "no EVM key matching: %q", key) + return errors.Errorf("no EVM key matching: %q", key) } case relay.Cosmos: _, err := keyStore.Cosmos().Get(key) if err != nil { - return errors.Wrapf(ErrNoSuchTransmitterKey, "no Cosmos key matching %q", key) + return errors.Errorf("no Cosmos key matching: %q", key) } case relay.Solana: _, err := keyStore.Solana().Get(key) if err != nil { - return errors.Wrapf(ErrNoSuchTransmitterKey, "no Solana key matching: %q", key) + return errors.Errorf("no Solana key matching: %q", key) } case relay.StarkNet: _, err := keyStore.StarkNet().Get(key) if err != nil { - return errors.Wrapf(ErrNoSuchTransmitterKey, "no Starknet key matching %q", key) + return errors.Errorf("no Starknet key matching: %q", key) } } } @@ -494,8 +495,8 @@ func areSendingKeysDefined(jb *Job, keystore keystore.Master) (bool, error) { } for _, sendingKey := range sendingKeys { - if err = validateKeyStoreMatch(jb.OCR2OracleSpec, keystore, sendingKey); err != nil { - return false, err + if err = ValidateKeyStoreMatch(jb.OCR2OracleSpec, keystore, sendingKey); err != nil { + return false, errors.Wrap(ErrNoSuchSendingKey, err.Error()) } } @@ -683,10 +684,7 @@ func (o *orm) FindJobs(offset, limit int) (jobs []Job, count int, err error) { return err } for i := range jobs { - err = o.LoadEnvConfigVars(&jobs[i]) - if err != nil { - return err - } + err = multierr.Combine(err, o.LoadEnvConfigVars(&jobs[i])) } return nil }) @@ -695,7 +693,7 @@ func (o *orm) FindJobs(offset, limit int) (jobs []Job, count int, err error) { func (o *orm) LoadEnvConfigVars(jb *Job) error { if jb.OCROracleSpec != nil { - ch, err := o.chainSet.Get(jb.OCROracleSpec.EVMChainID.ToInt()) + ch, err := o.legacyChains.Get(jb.OCROracleSpec.EVMChainID.String()) if err != nil { return err } @@ -705,13 +703,13 @@ func (o *orm) LoadEnvConfigVars(jb *Job) error { } jb.OCROracleSpec = newSpec } else if jb.VRFSpec != nil { - ch, err := o.chainSet.Get(jb.VRFSpec.EVMChainID.ToInt()) + ch, err := o.legacyChains.Get(jb.VRFSpec.EVMChainID.String()) if err != nil { return err } jb.VRFSpec = LoadEnvConfigVarsVRF(ch.Config().EVM(), *jb.VRFSpec) } else if jb.DirectRequestSpec != nil { - ch, err := o.chainSet.Get(jb.DirectRequestSpec.EVMChainID.ToInt()) + ch, err := o.legacyChains.Get(jb.DirectRequestSpec.EVMChainID.String()) if err != nil { return err } diff --git a/core/services/job/orm_test.go b/core/services/job/orm_test.go index e751065578d..15a2432f9e9 100644 --- a/core/services/job/orm_test.go +++ b/core/services/job/orm_test.go @@ -20,8 +20,8 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" ) -func NewTestORM(t *testing.T, db *sqlx.DB, chainSet evm.ChainSet, pipelineORM pipeline.ORM, bridgeORM bridges.ORM, keyStore keystore.Master, cfg pg.QConfig) job.ORM { - o := job.NewORM(db, chainSet, pipelineORM, bridgeORM, keyStore, logger.TestLogger(t), cfg) +func NewTestORM(t *testing.T, db *sqlx.DB, legacyChains evm.LegacyChainContainer, pipelineORM pipeline.ORM, bridgeORM bridges.ORM, keyStore keystore.Master, cfg pg.QConfig) job.ORM { + o := job.NewORM(db, legacyChains, pipelineORM, bridgeORM, keyStore, logger.TestLogger(t), cfg) t.Cleanup(func() { o.Close() }) return o } diff --git a/core/services/job/runner_integration_test.go b/core/services/job/runner_integration_test.go index 6baeac7e8fb..8418ae999bb 100644 --- a/core/services/job/runner_integration_test.go +++ b/core/services/job/runner_integration_test.go @@ -13,12 +13,12 @@ import ( "testing" "time" - evmmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/mocks" configtest2 "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest/v2" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/services/srvctest" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -75,18 +75,20 @@ func TestRunner(t *testing.T) { c.Insecure.OCRDevelopmentMode = ptr(true) }) - chainScopedConfig := evmtest.NewChainScopedConfig(t, config) - ethClient := cltest.NewEthMocksWithDefaultChain(t) ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(cltest.Head(10), nil) ethClient.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Maybe().Return(nil, nil) pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns()) btORM := bridges.NewORM(db, logger.TestLogger(t), config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, Client: ethClient, GeneralConfig: config, KeyStore: ethKeyStore}) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, Client: ethClient, GeneralConfig: config, KeyStore: ethKeyStore}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) c := clhttptest.NewTestLocalOnlyHTTPClient() - runner := pipeline.NewRunner(pipelineORM, btORM, config.JobPipeline(), config.WebServer(), cc, nil, nil, logger.TestLogger(t), c, c) - jobORM := NewTestORM(t, db, cc, pipelineORM, btORM, keyStore, config.Database()) + + runner := pipeline.NewRunner(pipelineORM, btORM, config.JobPipeline(), config.WebServer(), legacyChains, nil, nil, logger.TestLogger(t), c, c) + jobORM := NewTestORM(t, db, legacyChains, pipelineORM, btORM, keyStore, config.Database()) + _, placeHolderAddress := cltest.MustInsertRandomKey(t, keyStore.Eth()) require.NoError(t, runner.Start(testutils.Context(t))) @@ -192,26 +194,23 @@ func TestRunner(t *testing.T) { _, b := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database()) // Reference a different one - c := new(evmmocks.Chain) - c.On("Config").Return(chainScopedConfig) - cs := evmmocks.NewChainSet(t) - cs.On("Get", mock.Anything).Return(c, nil) + legacyChains := cltest.NewLegacyChainsWithMockChain(t, nil, config) - jb, err2 := ocr.ValidatedOracleSpecToml(cs, fmt.Sprintf(` + jb, err2 := ocr.ValidatedOracleSpecToml(legacyChains, fmt.Sprintf(` type = "offchainreporting" schemaVersion = 1 - evmChainID = 1 + evmChainID = 0 transmitterID = "%s" contractAddress = "0x613a38AC1659769640aaE063C651F48E0250454C" isBootstrapPeer = false blockchainTimeout = "1s" observationTimeout = "10s" databaseTimeout = "2s" - contractConfigTrackerPollInterval="1s" + contractConfigTrackerPollInterval="15s" contractConfigConfirmations=1 observationGracePeriod = "2s" - contractTransmitterTransmitTimeout = "500ms" - contractConfigTrackerSubscribeInterval="1s" + contractTransmitterTransmitTimeout = "5s" + contractConfigTrackerSubscribeInterval="1m" observationSource = """ ds1 [type=bridge name=blah]; ds1_parse [type=jsonparse path="one,two"]; @@ -235,7 +234,7 @@ relay = "evm" contractID = "0x613a38AC1659769640aaE063C651F48E0250454C" transmitterID = "%s" blockchainTimeout = "1s" -contractConfigTrackerPollInterval = "2s" +contractConfigTrackerPollInterval = "15s" contractConfigConfirmations = 1 observationSource = """ ds1 [type=bridge name="%s"]; @@ -270,7 +269,7 @@ relay = "evm" contractID = "0x613a38AC1659769640aaE063C651F48E0250454C" transmitterID = "%s" blockchainTimeout = "1s" -contractConfigTrackerPollInterval = "2s" +contractConfigTrackerPollInterval = "15s" contractConfigConfirmations = 1 observationSource = """ ds1 [type=bridge name="%s"]; @@ -445,7 +444,7 @@ ds1 -> ds1_parse; """ ` s = fmt.Sprintf(s, cltest.NewEIP55Address(), "http://blah.com", "") - jb, err := ocr.ValidatedOracleSpecToml(cc, s) + jb, err := ocr.ValidatedOracleSpecToml(legacyChains, s) require.NoError(t, err) err = toml.Unmarshal([]byte(s), &jb) require.NoError(t, err) @@ -459,7 +458,7 @@ ds1 -> ds1_parse; nil, nil, nil, - cc, + legacyChains, logger.TestLogger(t), config.Database(), srvctest.Start(t, utils.NewMailboxMonitor(t.Name())), @@ -477,7 +476,7 @@ ds1 -> ds1_parse; isBootstrapPeer = true ` s = fmt.Sprintf(s, cltest.NewEIP55Address()) - jb, err := ocr.ValidatedOracleSpecToml(cc, s) + jb, err := ocr.ValidatedOracleSpecToml(legacyChains, s) require.NoError(t, err) err = toml.Unmarshal([]byte(s), &jb) require.NoError(t, err) @@ -497,7 +496,7 @@ ds1 -> ds1_parse; nil, pw, monitoringEndpoint, - cc, + legacyChains, lggr, config.Database(), srvctest.Start(t, utils.NewMailboxMonitor(t.Name())), @@ -520,7 +519,7 @@ ds1 -> ds1_parse; """ ` s = fmt.Sprintf(s, cltest.NewEIP55Address(), "http://blah.com", "") - jb, err := ocr.ValidatedOracleSpecToml(cc, s) + jb, err := ocr.ValidatedOracleSpecToml(legacyChains, s) require.NoError(t, err) err = toml.Unmarshal([]byte(s), &jb) require.NoError(t, err) @@ -543,7 +542,7 @@ ds1 -> ds1_parse; nil, pw, monitoringEndpoint, - cc, + legacyChains, lggr, config.Database(), srvctest.Start(t, utils.NewMailboxMonitor(t.Name())), @@ -557,7 +556,7 @@ ds1 -> ds1_parse; require.NoError(t, err) s := fmt.Sprintf(minimalNonBootstrapTemplate, cltest.NewEIP55Address(), transmitterAddress.Hex(), kb.ID(), "http://blah.com", "") - jb, err := ocr.ValidatedOracleSpecToml(cc, s) + jb, err := ocr.ValidatedOracleSpecToml(legacyChains, s) require.NoError(t, err) err = toml.Unmarshal([]byte(s), &jb) require.NoError(t, err) @@ -577,7 +576,7 @@ ds1 -> ds1_parse; nil, pw, monitoringEndpoint, - cc, + legacyChains, lggr, config.Database(), srvctest.Start(t, utils.NewMailboxMonitor(t.Name())), @@ -588,7 +587,7 @@ ds1 -> ds1_parse; t.Run("test min bootstrap", func(t *testing.T) { s := fmt.Sprintf(minimalBootstrapTemplate, cltest.NewEIP55Address()) - jb, err := ocr.ValidatedOracleSpecToml(cc, s) + jb, err := ocr.ValidatedOracleSpecToml(legacyChains, s) require.NoError(t, err) err = toml.Unmarshal([]byte(s), &jb) require.NoError(t, err) @@ -605,7 +604,7 @@ ds1 -> ds1_parse; nil, pw, monitoringEndpoint, - cc, + legacyChains, lggr, config.Database(), srvctest.Start(t, utils.NewMailboxMonitor(t.Name())), @@ -636,7 +635,7 @@ ds1 -> ds1_parse; nil, pw, monitoringEndpoint, - cc, + legacyChains, lggr, config.Database(), srvctest.Start(t, utils.NewMailboxMonitor(t.Name())), @@ -767,7 +766,9 @@ func TestRunner_Success_Callback_AsyncJob(t *testing.T) { app := cltest.NewApplicationWithConfig(t, cfg, ethClient, cltest.UseRealExternalInitiatorManager) keyStore := cltest.NewKeyStore(t, app.GetSqlxDB(), pgtest.NewQConfig(true)) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: app.GetSqlxDB(), Client: ethClient, GeneralConfig: cfg, KeyStore: keyStore.Eth()}) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: app.GetSqlxDB(), Client: ethClient, GeneralConfig: cfg, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) require.NoError(t, app.Start(testutils.Context(t))) var ( @@ -898,7 +899,7 @@ func TestRunner_Success_Callback_AsyncJob(t *testing.T) { pipelineORM := pipeline.NewORM(app.GetSqlxDB(), logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(app.GetSqlxDB(), logger.TestLogger(t), cfg.Database()) - jobORM := NewTestORM(t, app.GetSqlxDB(), cc, pipelineORM, bridgesORM, app.KeyStore, cfg.Database()) + jobORM := NewTestORM(t, app.GetSqlxDB(), legacyChains, pipelineORM, bridgesORM, app.KeyStore, cfg.Database()) // Trigger v2/resume select { @@ -948,7 +949,10 @@ func TestRunner_Error_Callback_AsyncJob(t *testing.T) { app := cltest.NewApplicationWithConfig(t, cfg, ethClient, cltest.UseRealExternalInitiatorManager) keyStore := cltest.NewKeyStore(t, app.GetSqlxDB(), pgtest.NewQConfig(true)) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: app.GetSqlxDB(), Client: ethClient, GeneralConfig: cfg, KeyStore: keyStore.Eth()}) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: app.GetSqlxDB(), Client: ethClient, GeneralConfig: cfg, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + require.NoError(t, app.Start(testutils.Context(t))) var ( @@ -1077,7 +1081,7 @@ func TestRunner_Error_Callback_AsyncJob(t *testing.T) { pipelineORM := pipeline.NewORM(app.GetSqlxDB(), logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(app.GetSqlxDB(), logger.TestLogger(t), cfg.Database()) - jobORM := NewTestORM(t, app.GetSqlxDB(), cc, pipelineORM, bridgesORM, app.KeyStore, cfg.Database()) + jobORM := NewTestORM(t, app.GetSqlxDB(), legacyChains, pipelineORM, bridgesORM, app.KeyStore, cfg.Database()) // Trigger v2/resume select { diff --git a/core/services/job/spawner.go b/core/services/job/spawner.go index e56fc42af1f..d5c716ab5fd 100644 --- a/core/services/job/spawner.go +++ b/core/services/job/spawner.go @@ -36,7 +36,7 @@ type ( // StartService starts services for the given job spec. // NOTE: Prefer to use CreateJob, this is only publicly exposed for use in tests // to start a job that was previously manually inserted into DB - StartService(ctx context.Context, spec Job) error + StartService(ctx context.Context, spec Job, qopts ...pg.QOpt) error } spawner struct { @@ -62,7 +62,7 @@ type ( // job. In case a given job type relies upon well-defined startup/shutdown // ordering for services, they are started in the order they are given // and stopped in reverse order. - ServicesForSpec(spec Job) ([]ServiceCtx, error) + ServicesForSpec(spec Job, qopts ...pg.QOpt) ([]ServiceCtx, error) AfterJobCreated(spec Job) BeforeJobDeleted(spec Job) // OnDeleteJob will be called from within DELETE db transaction. Any db @@ -176,7 +176,7 @@ func (js *spawner) stopService(jobID int32) { delete(js.activeJobs, jobID) } -func (js *spawner) StartService(ctx context.Context, jb Job) error { +func (js *spawner) StartService(ctx context.Context, jb Job, qopts ...pg.QOpt) error { js.activeJobsMu.Lock() defer js.activeJobsMu.Unlock() @@ -199,7 +199,7 @@ func (js *spawner) StartService(ctx context.Context, jb Job) error { jb.PipelineSpec.GasLimit = &jb.GasLimit.Uint32 } - srvs, err := delegate.ServicesForSpec(jb) + srvs, err := delegate.ServicesForSpec(jb, qopts...) if err != nil { js.lggr.Errorw("Error creating services for job", "jobID", jb.ID, "err", err) cctx, cancel := js.chStop.NewCtx() @@ -250,7 +250,7 @@ func (js *spawner) CreateJob(jb *Job, qopts ...pg.QOpt) (err error) { js.lggr.Infow("Created job", "type", jb.Type, "jobID", jb.ID) delegate.BeforeJobCreated(*jb) - err = js.StartService(pctx, *jb) + err = js.StartService(pctx, *jb, pg.WithQueryer(q.Queryer)) if err != nil { js.lggr.Errorw("Error starting job services", "type", jb.Type, "jobID", jb.ID, "err", err) } else { @@ -368,7 +368,7 @@ func (n *NullDelegate) JobType() Type { } // ServicesForSpec does no-op. -func (n *NullDelegate) ServicesForSpec(spec Job) (s []ServiceCtx, err error) { +func (n *NullDelegate) ServicesForSpec(spec Job, qopts ...pg.QOpt) (s []ServiceCtx, err error) { return } diff --git a/core/services/job/spawner_test.go b/core/services/job/spawner_test.go index abaf69316d9..de6ca541e59 100644 --- a/core/services/job/spawner_test.go +++ b/core/services/job/spawner_test.go @@ -27,9 +27,11 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/job/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/ocr" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/services/relay" evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + evmrelayer "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/services/srvctest" "github.com/smartcontractkit/chainlink/v2/core/utils" "github.com/smartcontractkit/chainlink/v2/plugins" @@ -48,7 +50,7 @@ func (d delegate) JobType() job.Type { } // ServicesForSpec satisfies the job.Delegate interface. -func (d delegate) ServicesForSpec(js job.Job) ([]job.ServiceCtx, error) { +func (d delegate) ServicesForSpec(js job.Job, qopts ...pg.QOpt) ([]job.ServiceCtx, error) { if js.Type != d.jobType { return nil, nil } @@ -59,6 +61,15 @@ func clearDB(t *testing.T, db *sqlx.DB) { cltest.ClearDBTables(t, db, "jobs", "pipeline_runs", "pipeline_specs", "pipeline_task_runs") } +type relayGetter struct { + e evmrelay.EVMChainRelayerExtender + r *evmrelayer.Relayer +} + +func (g *relayGetter) Get(id relay.ID) (loop.Relayer, error) { + return evmrelayer.NewLoopRelayAdapter(g.r, g.e), nil +} + func TestSpawner_CreateJobDeleteJob(t *testing.T) { t.Parallel() @@ -81,11 +92,13 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { *head = cltest.Head(10) }). Return(nil).Maybe() - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, Client: ethClient, GeneralConfig: config, KeyStore: ethKeyStore}) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, Client: ethClient, GeneralConfig: config, KeyStore: ethKeyStore}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) t.Run("should respect its dependents", func(t *testing.T) { lggr := logger.TestLogger(t) - orm := NewTestORM(t, db, cc, pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db, lggr, config.Database()), keyStore, config.Database()) + orm := NewTestORM(t, db, legacyChains, pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db, lggr, config.Database()), keyStore, config.Database()) a := utils.NewDependentAwaiter() a.AddDependents(1) spawner := job.NewSpawner(orm, config.Database(), map[job.Type]job.Delegate{}, db, lggr, []utils.DependentAwaiter{a}) @@ -108,7 +121,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, cc, pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db, lggr, config.Database()), keyStore, config.Database()) + orm := NewTestORM(t, db, legacyChains, pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db, lggr, config.Database()), keyStore, config.Database()) eventuallyA := cltest.NewAwaiter() serviceA1 := mocks.NewServiceCtx(t) @@ -116,7 +129,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { serviceA1.On("Start", mock.Anything).Return(nil).Once() serviceA2.On("Start", mock.Anything).Return(nil).Once().Run(func(mock.Arguments) { eventuallyA.ItHappened() }) mailMon := srvctest.Start(t, utils.NewMailboxMonitor(t.Name())) - dA := ocr.NewDelegate(nil, orm, nil, nil, nil, monitoringEndpoint, cc, logger.TestLogger(t), config.Database(), mailMon) + dA := ocr.NewDelegate(nil, orm, nil, nil, nil, monitoringEndpoint, legacyChains, logger.TestLogger(t), config.Database(), mailMon) delegateA := &delegate{jobA.Type, []job.ServiceCtx{serviceA1, serviceA2}, 0, make(chan struct{}), dA} eventuallyB := cltest.NewAwaiter() @@ -124,7 +137,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { serviceB2 := mocks.NewServiceCtx(t) serviceB1.On("Start", mock.Anything).Return(nil).Once() serviceB2.On("Start", mock.Anything).Return(nil).Once().Run(func(mock.Arguments) { eventuallyB.ItHappened() }) - dB := ocr.NewDelegate(nil, orm, nil, nil, nil, monitoringEndpoint, cc, logger.TestLogger(t), config.Database(), mailMon) + dB := ocr.NewDelegate(nil, orm, nil, nil, nil, monitoringEndpoint, legacyChains, logger.TestLogger(t), config.Database(), mailMon) delegateB := &delegate{jobB.Type, []job.ServiceCtx{serviceB1, serviceB2}, 0, make(chan struct{}), dB} spawner := job.NewSpawner(orm, config.Database(), map[job.Type]job.Delegate{ @@ -173,9 +186,9 @@ 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, cc, pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db, lggr, config.Database()), keyStore, config.Database()) + orm := NewTestORM(t, db, legacyChains, pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db, lggr, config.Database()), keyStore, config.Database()) mailMon := srvctest.Start(t, utils.NewMailboxMonitor(t.Name())) - d := ocr.NewDelegate(nil, orm, nil, nil, nil, monitoringEndpoint, cc, logger.TestLogger(t), config.Database(), mailMon) + 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} spawner := job.NewSpawner(orm, config.Database(), map[job.Type]job.Delegate{ jobA.Type: delegateA, @@ -207,9 +220,9 @@ 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, cc, pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db, lggr, config.Database()), keyStore, config.Database()) + orm := NewTestORM(t, db, legacyChains, pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db, lggr, config.Database()), keyStore, config.Database()) mailMon := srvctest.Start(t, utils.NewMailboxMonitor(t.Name())) - d := ocr.NewDelegate(nil, orm, nil, nil, nil, monitoringEndpoint, cc, logger.TestLogger(t), config.Database(), mailMon) + 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} spawner := job.NewSpawner(orm, config.Database(), map[job.Type]job.Delegate{ jobA.Type: delegateA, @@ -263,31 +276,37 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { LogPoller: lp, KeyStore: ethKeyStore, } - cs := evmtest.NewChainSet(t, testopts) - chain := evmtest.MustGetDefaultChain(t, cs) + lggr := logger.TestLogger(t) + relayExtenders := evmtest.NewChainRelayExtenders(t, testopts) + assert.Equal(t, relayExtenders.Len(), 1) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + chain := evmtest.MustGetDefaultChain(t, legacyChains) + + evmRelayer := evmrelayer.NewRelayer(testopts.DB, chain, testopts.GeneralConfig.Database(), lggr, keyStore, pg.NewNullEventBroadcaster()) + testRelayGetter := &relayGetter{ + e: relayExtenders.Slice()[0], + r: evmRelayer, + } jobOCR2VRF := makeOCR2VRFJobSpec(t, keyStore, config, address, chain.ID(), 2) - lggr := logger.TestLogger(t) - orm := NewTestORM(t, db, cc, pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db, lggr, config.Database()), keyStore, config.Database()) - mailMon := srvctest.Start(t, utils.NewMailboxMonitor(t.Name())) - relayers := make(map[relay.Network]loop.Relayer) - evmRelayer := evmrelay.NewRelayer(db, cc, lggr, config.Database(), keyStore, nil) - relayers[relay.EVM] = relay.NewRelayerAdapter(evmRelayer, cc) + orm := NewTestORM(t, db, legacyChains, pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db, lggr, config.Database()), keyStore, config.Database()) + mailMon := srvctest.Start(t, utils.NewMailboxMonitor(t.Name())) processConfig := plugins.NewRegistrarConfig(loop.GRPCOpts{}, func(name string) (*plugins.RegisteredLoop, error) { return nil, nil }) ocr2DelegateConfig := ocr2.NewDelegateConfig(config.OCR2(), config.Mercury(), config.Threshold(), config.Insecure(), config.JobPipeline(), config.Database(), processConfig) - d := ocr2.NewDelegate(nil, orm, nil, nil, nil, monitoringEndpoint, cs, lggr, ocr2DelegateConfig, - keyStore.OCR2(), keyStore.DKGSign(), keyStore.DKGEncrypt(), ethKeyStore, relayers, mailMon, nil) + d := ocr2.NewDelegate(nil, orm, nil, nil, nil, nil, monitoringEndpoint, legacyChains, lggr, ocr2DelegateConfig, + keyStore.OCR2(), keyStore.DKGSign(), keyStore.DKGEncrypt(), ethKeyStore, testRelayGetter, mailMon, nil) delegateOCR2 := &delegate{jobOCR2VRF.Type, []job.ServiceCtx{}, 0, nil, d} spawner := job.NewSpawner(orm, config.Database(), map[job.Type]job.Delegate{ jobOCR2VRF.Type: delegateOCR2, }, db, lggr, nil) - err := spawner.CreateJob(jobOCR2VRF) + err = spawner.CreateJob(jobOCR2VRF) require.NoError(t, err) jobSpecID := jobOCR2VRF.ID delegateOCR2.jobID = jobOCR2VRF.ID diff --git a/core/services/job/util.go b/core/services/job/util.go index 6232dffe737..143dfed7e45 100644 --- a/core/services/job/util.go +++ b/core/services/job/util.go @@ -2,11 +2,8 @@ package job import ( "fmt" - "math/big" "github.com/pkg/errors" - - "github.com/smartcontractkit/chainlink/v2/core/chains/evm" ) var ( @@ -14,36 +11,6 @@ var ( ErrNoSendingKeysFromSpec = fmt.Errorf("could not get sending keys from spec") ) -// EVMChainForJob parses the job spec and retrieves the evm chain found. -func EVMChainForBootstrapJob(job *Job, set evm.ChainSet) (evm.Chain, error) { - chainIDInterface, ok := job.BootstrapSpec.RelayConfig["chainID"] - if !ok { - return nil, fmt.Errorf("%w: chainID must be provided in relay config", ErrNoChainFromSpec) - } - chainID := chainIDInterface.(int64) - chain, err := set.Get(big.NewInt(chainID)) - if err != nil { - return nil, fmt.Errorf("%w: %s", ErrNoChainFromSpec, err) - } - - return chain, nil -} - -// EVMChainForJob parses the job spec and retrieves the evm chain found. -func EVMChainForJob(job *Job, set evm.ChainSet) (evm.Chain, error) { - chainIDInterface, ok := job.OCR2OracleSpec.RelayConfig["chainID"] - if !ok { - return nil, fmt.Errorf("%w: chainID must be provided in relay config", ErrNoChainFromSpec) - } - chainID := chainIDInterface.(int64) - chain, err := set.Get(big.NewInt(chainID)) - if err != nil { - return nil, fmt.Errorf("%w: %s", ErrNoChainFromSpec, err) - } - - return chain, nil -} - // SendingKeysForJob parses the job spec and retrieves the sending keys found. func SendingKeysForJob(job *Job) ([]string, error) { sendingKeysInterface, ok := job.OCR2OracleSpec.RelayConfig["sendingKeys"] diff --git a/core/services/keeper/delegate.go b/core/services/keeper/delegate.go index cebb8dba368..cdb085f743e 100644 --- a/core/services/keeper/delegate.go +++ b/core/services/keeper/delegate.go @@ -16,12 +16,12 @@ import ( var _ job.Delegate = (*Delegate)(nil) type Delegate struct { - logger logger.Logger - db *sqlx.DB - jrm job.ORM - pr pipeline.Runner - chainSet evm.ChainSet - mailMon *utils.MailboxMonitor + logger logger.Logger + db *sqlx.DB + jrm job.ORM + pr pipeline.Runner + legacyChains evm.LegacyChainContainer + mailMon *utils.MailboxMonitor } // NewDelegate is the constructor of Delegate @@ -30,16 +30,16 @@ func NewDelegate( jrm job.ORM, pr pipeline.Runner, logger logger.Logger, - chainSet evm.ChainSet, + legacyChains evm.LegacyChainContainer, mailMon *utils.MailboxMonitor, ) *Delegate { return &Delegate{ - logger: logger, - db: db, - jrm: jrm, - pr: pr, - chainSet: chainSet, - mailMon: mailMon, + logger: logger, + db: db, + jrm: jrm, + pr: pr, + legacyChains: legacyChains, + mailMon: mailMon, } } @@ -54,11 +54,11 @@ func (d *Delegate) BeforeJobDeleted(spec job.Job) {} func (d *Delegate) OnDeleteJob(spec job.Job, q pg.Queryer) error { return nil } // ServicesForSpec satisfies the job.Delegate interface. -func (d *Delegate) ServicesForSpec(spec job.Job) (services []job.ServiceCtx, err error) { +func (d *Delegate) ServicesForSpec(spec job.Job, qopts ...pg.QOpt) (services []job.ServiceCtx, err error) { if spec.KeeperSpec == nil { return nil, errors.Errorf("Delegate expects a *job.KeeperSpec to be present, got %v", spec) } - chain, err := d.chainSet.Get(spec.KeeperSpec.EVMChainID.ToInt()) + chain, err := d.legacyChains.Get(spec.KeeperSpec.EVMChainID.String()) if err != nil { return nil, err } diff --git a/core/services/keeper/integration_test.go b/core/services/keeper/integration_test.go index 15577b3bb51..2177d418e53 100644 --- a/core/services/keeper/integration_test.go +++ b/core/services/keeper/integration_test.go @@ -417,7 +417,7 @@ func TestKeeperForwarderEthIntegration(t *testing.T) { _, err = forwarderORM.CreateForwarder(fwdrAddress, chainID) require.NoError(t, err) - addr, err := app.Chains.EVM.Chains()[0].TxManager().GetForwarderForEOA(nodeAddress) + addr, err := app.GetRelayers().LegacyEVMChains().Slice()[0].TxManager().GetForwarderForEOA(nodeAddress) require.NoError(t, err) require.Equal(t, addr, fwdrAddress) diff --git a/core/services/keeper/registry_synchronizer_helper_test.go b/core/services/keeper/registry_synchronizer_helper_test.go index 564bac08812..c3fadc8bcf4 100644 --- a/core/services/keeper/registry_synchronizer_helper_test.go +++ b/core/services/keeper/registry_synchronizer_helper_test.go @@ -19,6 +19,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keeper" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/services/srvctest" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -42,9 +43,11 @@ func setupRegistrySync(t *testing.T, version keeper.RegistryVersion) ( lbMock := logmocks.NewBroadcaster(t) lbMock.On("AddDependents", 1).Maybe() j := cltest.MustInsertKeeperJob(t, db, korm, cltest.NewEIP55Address(), cltest.NewEIP55Address()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, Client: ethClient, LogBroadcaster: lbMock, GeneralConfig: cfg, KeyStore: keyStore.Eth()}) - ch := evmtest.MustGetDefaultChain(t, cc) - jpv2 := cltest.NewJobPipelineV2(t, cfg.WebServer(), cfg.JobPipeline(), cfg.Database(), cc, db, keyStore, nil, nil) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, Client: ethClient, LogBroadcaster: lbMock, GeneralConfig: cfg, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + 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() switch version { diff --git a/core/services/keeper/upkeep_executer_test.go b/core/services/keeper/upkeep_executer_test.go index e30b49f961f..0f15f3949ba 100644 --- a/core/services/keeper/upkeep_executer_test.go +++ b/core/services/keeper/upkeep_executer_test.go @@ -32,6 +32,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keeper" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -74,15 +75,17 @@ func setup(t *testing.T, estimator gas.EvmFeeEstimator, overrideFn func(c *chain ethClient := evmtest.NewEthClientMockWithDefaultChain(t) ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Maybe().Return(&evmtypes.Head{Number: 1, Hash: utils.NewHash()}, nil) txm := txmmocks.NewMockEvmTxManager(t) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{TxManager: txm, DB: db, Client: ethClient, KeyStore: keyStore.Eth(), GeneralConfig: cfg, GasEstimator: estimator}) - jpv2 := cltest.NewJobPipelineV2(t, cfg.WebServer(), cfg.JobPipeline(), cfg.Database(), cc, db, keyStore, nil, nil) - ch := evmtest.MustGetDefaultChain(t, cc) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{TxManager: txm, DB: db, Client: ethClient, KeyStore: keyStore.Eth(), GeneralConfig: cfg, GasEstimator: estimator}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + 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()) registry, job := cltest.MustInsertKeeperRegistry(t, db, orm, keyStore.Eth(), 0, 1, 20) lggr := logger.TestLogger(t) executer := keeper.NewUpkeepExecuter(job, orm, jpv2.Pr, ethClient, ch.HeadBroadcaster(), ch.GasEstimator(), lggr, ch.Config().Keeper(), job.KeeperSpec.FromAddress.Address()) upkeep := cltest.MustInsertUpkeepForRegistry(t, db, ch.Config().Database(), registry) - err := executer.Start(testutils.Context(t)) + err = executer.Start(testutils.Context(t)) t.Cleanup(func() { executer.Close() }) require.NoError(t, err) return db, cfg, ethClient, executer, registry, upkeep, job, jpv2, txm, keyStore, ch, orm diff --git a/core/services/ocr/delegate.go b/core/services/ocr/delegate.go index f64acb659cb..c5ace522ccb 100644 --- a/core/services/ocr/delegate.go +++ b/core/services/ocr/delegate.go @@ -41,7 +41,7 @@ type Delegate struct { pipelineRunner pipeline.Runner peerWrapper *ocrcommon.SingletonPeerWrapper monitoringEndpointGen telemetry.MonitoringEndpointGenerator - chainSet evm.ChainSet + legacyChains evm.LegacyChainContainer lggr logger.Logger cfg Config mailMon *utils.MailboxMonitor @@ -58,22 +58,22 @@ func NewDelegate( pipelineRunner pipeline.Runner, peerWrapper *ocrcommon.SingletonPeerWrapper, monitoringEndpointGen telemetry.MonitoringEndpointGenerator, - chainSet evm.ChainSet, + legacyChains evm.LegacyChainContainer, lggr logger.Logger, cfg Config, mailMon *utils.MailboxMonitor, ) *Delegate { return &Delegate{ - db, - jobORM, - keyStore, - pipelineRunner, - peerWrapper, - monitoringEndpointGen, - chainSet, - lggr.Named("OCR"), - cfg, - mailMon, + db: db, + jobORM: jobORM, + keyStore: keyStore, + pipelineRunner: pipelineRunner, + peerWrapper: peerWrapper, + monitoringEndpointGen: monitoringEndpointGen, + legacyChains: legacyChains, + lggr: lggr.Named("OCR"), + cfg: cfg, + mailMon: mailMon, } } @@ -87,11 +87,11 @@ func (d *Delegate) BeforeJobDeleted(spec job.Job) {} func (d *Delegate) OnDeleteJob(spec job.Job, q pg.Queryer) error { return nil } // ServicesForSpec returns the OCR services that need to run for this job -func (d *Delegate) ServicesForSpec(jb job.Job) (services []job.ServiceCtx, err error) { +func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) (services []job.ServiceCtx, err error) { if jb.OCROracleSpec == nil { return nil, errors.Errorf("offchainreporting.Delegate expects an *job.OffchainreportingOracleSpec to be present, got %v", jb) } - chain, err := d.chainSet.Get(jb.OCROracleSpec.EVMChainID.ToInt()) + chain, err := d.legacyChains.Get(jb.OCROracleSpec.EVMChainID.String()) if err != nil { return nil, err } @@ -235,7 +235,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) (services []job.ServiceCtx, err e if jb.GasLimit.Valid { jsGasLimit = &jb.GasLimit.Uint32 } - gasLimit := pipeline.SelectGasLimit(chain.Config(), jb.Type.String(), jsGasLimit) + gasLimit := pipeline.SelectGasLimit(chain.Config().EVM().GasEstimator(), jb.Type.String(), jsGasLimit) // effectiveTransmitterAddress is the transmitter address registered on the ocr contract. This is by default the EOA account on the node. // In the case of forwarding, the transmitter address is the forwarder contract deployed onchain between EOA and OCR contract. diff --git a/core/services/ocr/validate.go b/core/services/ocr/validate.go index fc4547cb4e6..07fdc15912e 100644 --- a/core/services/ocr/validate.go +++ b/core/services/ocr/validate.go @@ -37,9 +37,9 @@ type insecureConfig interface { } // ValidatedOracleSpecToml validates an oracle spec that came from TOML -func ValidatedOracleSpecToml(chainSet evm.ChainSet, tomlString string) (job.Job, error) { +func ValidatedOracleSpecToml(legacyChains evm.LegacyChainContainer, tomlString string) (job.Job, error) { return ValidatedOracleSpecTomlCfg(func(id *big.Int) (evmconfig.ChainScopedConfig, error) { - c, err := chainSet.Get(id) + c, err := legacyChains.Get(id.String()) if err != nil { return nil, err } diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index c9c6d553617..39d5e939f3b 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -6,7 +6,6 @@ import ( "encoding/json" "fmt" "log" - "math/big" "time" "gopkg.in/guregu/null.v4" @@ -17,11 +16,14 @@ import ( "github.com/smartcontractkit/libocr/commontypes" libocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" - "github.com/smartcontractkit/ocr2keepers/pkg/config" - "github.com/smartcontractkit/ocr2keepers/pkg/coordinator" - "github.com/smartcontractkit/ocr2keepers/pkg/observer/polling" - "github.com/smartcontractkit/ocr2keepers/pkg/runner" + ocr2keepers20 "github.com/smartcontractkit/ocr2keepers/pkg/v2" + ocr2keepers20config "github.com/smartcontractkit/ocr2keepers/pkg/v2/config" + ocr2keepers20coordinator "github.com/smartcontractkit/ocr2keepers/pkg/v2/coordinator" + ocr2keepers20polling "github.com/smartcontractkit/ocr2keepers/pkg/v2/observer/polling" + ocr2keepers20runner "github.com/smartcontractkit/ocr2keepers/pkg/v2/runner" + ocr2keepers21config "github.com/smartcontractkit/ocr2keepers/pkg/v3/config" + ocr2keepers21 "github.com/smartcontractkit/ocr2keepers/pkg/v3/plugin" + ocr2keepers21types "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" "github.com/smartcontractkit/ocr2vrf/altbn_128" dkgpkg "github.com/smartcontractkit/ocr2vrf/dkg" "github.com/smartcontractkit/ocr2vrf/ocr2vrf" @@ -45,6 +47,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/median" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/mercury" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper" + ocr2keeper21core "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" ocr2vrfconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2vrf/config" ocr2coordinator "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2vrf/coordinator" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2vrf/juelsfeecoin" @@ -58,6 +61,9 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/relay" evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" functionsRelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/functions" + evmmercury "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" + mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" + evmrelaytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" @@ -65,10 +71,16 @@ import ( "github.com/smartcontractkit/chainlink/v2/plugins" ) +var ErrJobSpecNoRelayer = errors.New("OCR2 job spec could not get relayer id") + +type RelayGetter interface { + Get(id relay.ID) (loop.Relayer, error) +} type Delegate struct { db *sqlx.DB jobORM job.ORM bridgeORM bridges.ORM + mercuryORM evmmercury.ORM pipelineRunner pipeline.Runner peerWrapper *ocrcommon.SingletonPeerWrapper monitoringEndpointGen telemetry.MonitoringEndpointGenerator @@ -78,12 +90,12 @@ type Delegate struct { dkgSignKs keystore.DKGSign dkgEncryptKs keystore.DKGEncrypt ethKs keystore.Eth - relayers map[relay.Network]loop.Relayer - isNewlyCreatedJob bool // Set to true if this is a new job freshly added, false if job was present already on node boot. - mailMon *utils.MailboxMonitor - eventBroadcaster pg.EventBroadcaster + RelayGetter + isNewlyCreatedJob bool // Set to true if this is a new job freshly added, false if job was present already on node boot. + mailMon *utils.MailboxMonitor + eventBroadcaster pg.EventBroadcaster - chainSet evm.ChainSet // legacy: use relayers instead + legacyChains evm.LegacyChainContainer // legacy: use relayers instead } type DelegateConfig interface { @@ -177,17 +189,18 @@ func NewDelegate( db *sqlx.DB, jobORM job.ORM, bridgeORM bridges.ORM, + mercuryORM evmmercury.ORM, pipelineRunner pipeline.Runner, peerWrapper *ocrcommon.SingletonPeerWrapper, monitoringEndpointGen telemetry.MonitoringEndpointGenerator, - chainSet evm.ChainSet, + legacyChains evm.LegacyChainContainer, lggr logger.Logger, cfg DelegateConfig, ks keystore.OCR2, dkgSignKs keystore.DKGSign, dkgEncryptKs keystore.DKGEncrypt, ethKs keystore.Eth, - relayers map[relay.Network]loop.Relayer, + relayers RelayGetter, mailMon *utils.MailboxMonitor, eventBroadcaster pg.EventBroadcaster, ) *Delegate { @@ -195,17 +208,18 @@ func NewDelegate( db: db, jobORM: jobORM, bridgeORM: bridgeORM, + mercuryORM: mercuryORM, pipelineRunner: pipelineRunner, peerWrapper: peerWrapper, monitoringEndpointGen: monitoringEndpointGen, - chainSet: chainSet, + legacyChains: legacyChains, cfg: cfg, lggr: lggr, ks: ks, dkgSignKs: dkgSignKs, dkgEncryptKs: dkgEncryptKs, ethKs: ethKs, - relayers: relayers, + RelayGetter: relayers, isNewlyCreatedJob: false, mailMon: mailMon, eventBroadcaster: eventBroadcaster, @@ -224,29 +238,37 @@ func (d *Delegate) AfterJobCreated(spec job.Job) {} func (d *Delegate) BeforeJobDeleted(spec job.Job) {} func (d *Delegate) OnDeleteJob(jb job.Job, q pg.Queryer) 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. However, 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 - // an inconsistent state. This assumes UnregisterFilter will return nil if the filter wasn't found - // at all (no rows deleted). + // the job deletion itself isn't blocked. spec := jb.OCR2OracleSpec if spec == nil { d.lggr.Errorf("offchainreporting2.Delegate.OnDeleteJob called with wrong job type, ignoring non-OCR2 spec %v", jb) return nil } - if spec.Relay != relay.EVM { - return nil - } - chainID, err := spec.RelayConfig.EVMChainID() + rid, err := spec.RelayID() if err != nil { - d.lggr.Errorf("OCR2 jobs spec missing chainID") + d.lggr.Errorw("DeleteJob: "+ErrJobSpecNoRelayer.Error(), "err", err) return nil } - chain, err := d.chainSet.Get(big.NewInt(chainID)) + // we only have clean to do for the EVM + if rid.Network == relay.EVM { + return d.cleanupEVM(jb, q, rid) + } + return nil +} + +// cleanupEVM is a helper for clean up EVM specific state when a job is deleted +func (d *Delegate) cleanupEVM(jb job.Job, q pg.Queryer, 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 + // an inconsistent state. This assumes UnregisterFilter will return nil if the filter wasn't found + // at all (no rows deleted). + spec := jb.OCR2OracleSpec + chain, err := d.legacyChains.Get(relayID.ChainID.String()) if err != nil { - d.lggr.Error(err) + d.lggr.Error("cleanupEVM: failed to chain get chain %s", "err", relayID.ChainID, err) return nil } lp := chain.LogPoller() @@ -285,7 +307,7 @@ func (d *Delegate) OnDeleteJob(jb job.Job, q pg.Queryer) error { for _, filter := range filters { d.lggr.Debugf("Unregistering %s filter", filter) - err = lp.UnregisterFilter(filter, q) + err = lp.UnregisterFilter(filter, pg.WithQueryer(q)) if err != nil { return errors.Wrapf(err, "Failed to unregister filter %s", filter) } @@ -294,7 +316,7 @@ func (d *Delegate) OnDeleteJob(jb job.Job, q pg.Queryer) error { } // ServicesForSpec returns the OCR2 services that need to run for this job -func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { +func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceCtx, error) { spec := jb.OCR2OracleSpec if spec == nil { return nil, errors.Errorf("offchainreporting2.Delegate expects an *job.OCR2OracleSpec to be present, got %v", jb) @@ -310,22 +332,27 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { ContractID: spec.ContractID, TransmitterID: transmitterID, } - if spec.FeedID != nil { + if spec.FeedID != nil && (*spec.FeedID != (common.Hash{})) { lggrCtx.FeedID = *spec.FeedID spec.RelayConfig["feedID"] = spec.FeedID } lggr := logger.Sugared(d.lggr.Named("OCR2").With(lggrCtx.Args()...)) - if spec.Relay == relay.EVM { - chainID, err := spec.RelayConfig.EVMChainID() - if err != nil { - return nil, errors.Wrap(err, "ServicesForSpec failed to get chainID") - } - lggr = logger.Sugared(lggr.With("evmChainID", chainID)) + rid, err := spec.RelayID() + if err != nil { + return nil, fmt.Errorf("ServicesForSpec: %w: %w", ErrJobSpecNoRelayer, err) + } - effectiveTransmitterID, err = GetEVMEffectiveTransmitterID(&jb, d.chainSet, chainID, lggr) - if err != nil { - return nil, errors.Wrap(err, "ServicesForSpec failed to get evm transmitterID") + if rid.Network == relay.EVM { + lggr = logger.Sugared(lggr.With("evmChainID", rid.ChainID)) + + chain, err2 := d.legacyChains.Get(rid.ChainID.String()) + if err2 != nil { + return nil, fmt.Errorf("ServicesForSpec: could not get EVM chain %s: %w", rid.ChainID, err2) + } + effectiveTransmitterID, err2 = GetEVMEffectiveTransmitterID(&jb, chain, lggr) + if err2 != nil { + return nil, fmt.Errorf("ServicesForSpec failed to get evm transmitterID: %w", err2) } } spec.RelayConfig["effectiveTransmitterID"] = effectiveTransmitterID @@ -409,7 +436,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { } } -func GetEVMEffectiveTransmitterID(jb *job.Job, chainSet evm.ChainSet, chainID int64, lggr logger.SugaredLogger) (string, error) { +func GetEVMEffectiveTransmitterID(jb *job.Job, chain evm.Chain, lggr logger.SugaredLogger) (string, error) { spec := jb.OCR2OracleSpec if spec.PluginType == job.Mercury { return spec.TransmitterID.String, nil @@ -422,7 +449,6 @@ func GetEVMEffectiveTransmitterID(jb *job.Job, chainSet evm.ChainSet, chainID in if err != nil { return "", err } - if len(sendingKeys) > 1 && spec.PluginType != job.OCR2VRF { return "", errors.New("only ocr2 vrf should have more than 1 sending key") } @@ -433,11 +459,9 @@ func GetEVMEffectiveTransmitterID(jb *job.Job, chainSet evm.ChainSet, chainID in // In the case of forwarding, the transmitter address is the forwarder contract deployed onchain between EOA and OCR contract. // ForwardingAllowed cannot be set with Mercury, so this should always be false for mercury jobs if jb.ForwardingAllowed { - chain, err := chainSet.Get(big.NewInt(chainID)) - if err != nil { - return "", errors.Wrap(err, "failed to get chainset") + if chain == nil { + return "", fmt.Errorf("job forwarding requires non-nil chain") } - effectiveTransmitterID, err := chain.TxManager().GetForwarderForEOA(common.HexToAddress(spec.TransmitterID.String)) if err == nil { return effectiveTransmitterID.String(), nil @@ -463,7 +487,7 @@ func (d *Delegate) newServicesMercury( lc ocrtypes.LocalConfig, ocrLogger commontypes.Logger, ) ([]job.ServiceCtx, error) { - if jb.OCR2OracleSpec.FeedID == nil { + if jb.OCR2OracleSpec.FeedID == nil || (*jb.OCR2OracleSpec.FeedID == (common.Hash{})) { return nil, errors.Errorf("ServicesForSpec: mercury job type requires feedID") } spec := jb.OCR2OracleSpec @@ -475,10 +499,22 @@ func (d *Delegate) newServicesMercury( return nil, errors.Wrapf(err, "ServicesForSpec: mercury job type requires transmitter ID to be a 32-byte hex string, got: %q", transmitterID) } - relayer, exists := d.relayers[spec.Relay] - if !exists { - return nil, errors.Errorf("%s relay does not exist is it enabled?", spec.Relay) + rid, err := spec.RelayID() + if err != nil { + return nil, fmt.Errorf("mercury services: %w: %w", ErrJobSpecNoRelayer, err) + } + if rid.Network != relay.EVM { + return nil, fmt.Errorf("mercury services: expected EVM relayer got %s", rid.Network) + } + relayer, err := d.RelayGetter.Get(rid) + if err != nil { + return nil, fmt.Errorf("failed to get relay %s is it enabled?: %w", spec.Relay, err) } + chain, err := d.legacyChains.Get(rid.ChainID.String()) + if err != nil { + return nil, fmt.Errorf("mercury services: failed to get chain %s: %w", rid.ChainID, err) + } + mercuryProvider, err2 := relayer.NewMercuryProvider(ctx, types.RelayArgs{ ExternalJobID: jb.ExternalJobID, @@ -494,15 +530,6 @@ func (d *Delegate) newServicesMercury( return nil, err2 } - chainID, err2 := spec.RelayConfig.EVMChainID() - if err2 != nil { - return nil, errors.Wrap(err2, "ServicesForSpec failed to get chainID") - } - chain, err2 := d.chainSet.Get(big.NewInt(chainID)) - if err2 != nil { - return nil, errors.Wrap(err2, "ServicesForSpec failed to get chain") - } - oracleArgsNoPlugin := libocr2.MercuryOracleArgs{ BinaryNetworkEndpointFactory: d.peerWrapper.Peer2, V2Bootstrappers: bootstrapPeers, @@ -518,7 +545,8 @@ func (d *Delegate) newServicesMercury( } chEnhancedTelem := make(chan ocrcommon.EnhancedTelemetryMercuryData, 100) - mercuryServices, err2 := mercury.NewServices(jb, mercuryProvider, d.pipelineRunner, runResults, lggr, oracleArgsNoPlugin, d.cfg.JobPipeline(), chEnhancedTelem, chain) + + mercuryServices, err2 := mercury.NewServices(jb, mercuryProvider, d.pipelineRunner, runResults, lggr, oracleArgsNoPlugin, d.cfg.JobPipeline(), chEnhancedTelem, chain, d.mercuryORM, (mercuryutils.FeedID)(*spec.FeedID)) if ocrcommon.ShouldCollectEnhancedTelemetryMercury(&jb) { enhancedTelemService := ocrcommon.NewEnhancedTelemetryService(&jb, chEnhancedTelem, make(chan struct{}), d.monitoringEndpointGen.GenMonitoringEndpoint(spec.FeedID.String(), synchronization.EnhancedEAMercury), lggr.Named("Enhanced Telemetry Mercury")) @@ -554,10 +582,15 @@ func (d *Delegate) newServicesMedian( enhancedTelemChan := make(chan ocrcommon.EnhancedTelemetryData, 100) mConfig := median.NewMedianConfig(d.cfg.JobPipeline().MaxSuccessfulRuns(), d.cfg) - relayer, exists := d.relayers[spec.Relay] - if !exists { - return nil, errors.Errorf("%s relay does not exist is it enabled?", spec.Relay) + rid, err := spec.RelayID() + if err != nil { + return nil, fmt.Errorf("median services: %w: %w", ErrJobSpecNoRelayer, err) } + relayer, err := d.RelayGetter.Get(rid) + if err != nil { + return nil, fmt.Errorf("median services; failed to get relay %s is it enabled?: %w", spec.Relay, err) + } + medianServices, err2 := median.NewMedianServices(ctx, jb, d.isNewlyCreatedJob, relayer, d.pipelineRunner, runResults, lggr, oracleArgsNoPlugin, mConfig, enhancedTelemChan, errorLog) if ocrcommon.ShouldCollectEnhancedTelemetry(&jb) { @@ -578,13 +611,17 @@ func (d *Delegate) newServicesDKG( ocrLogger commontypes.Logger, ) ([]job.ServiceCtx, error) { spec := jb.OCR2OracleSpec - chainID, err2 := spec.RelayConfig.EVMChainID() - if err2 != nil { - return nil, err2 + rid, err := spec.RelayID() + if err != nil { + return nil, fmt.Errorf("DKG services: %w: %w", ErrJobSpecNoRelayer, err) + } + if rid.Network != relay.EVM { + return nil, fmt.Errorf("DKG services: expected EVM relayer got %s", rid.Network) } - chain, err2 := d.chainSet.Get(big.NewInt(chainID)) + + chain, err2 := d.legacyChains.Get(rid.ChainID.String()) if err2 != nil { - return nil, errors.Wrap(err2, "get chainset") + return nil, fmt.Errorf("DKG services: failed to get chain %s: %w", rid.ChainID, err2) } ocr2vrfRelayer := evmrelay.NewOCR2VRFRelayer(d.db, chain, lggr.Named("OCR2VRFRelayer"), d.ethKs) dkgProvider, err2 := ocr2vrfRelayer.NewDKGProvider( @@ -627,7 +664,7 @@ func (d *Delegate) newServicesDKG( oracleArgsNoPlugin, d.db, d.cfg.Database(), - big.NewInt(chainID), + chain.ID(), spec.Relay, ) } @@ -642,14 +679,17 @@ func (d *Delegate) newServicesOCR2VRF( lc ocrtypes.LocalConfig, ) ([]job.ServiceCtx, error) { spec := jb.OCR2OracleSpec - chainID, err2 := spec.RelayConfig.EVMChainID() - if err2 != nil { - return nil, err2 - } - chain, err2 := d.chainSet.Get(big.NewInt(chainID)) + rid, err := spec.RelayID() + if err != nil { + return nil, fmt.Errorf("VRF services: %w: %w", ErrJobSpecNoRelayer, err) + } + if rid.Network != relay.EVM { + return nil, fmt.Errorf("VRF services: expected EVM relayer got %s", rid.Network) + } + chain, err2 := d.legacyChains.Get(rid.ChainID.String()) if err2 != nil { - return nil, errors.Wrap(err2, "get chainset") + return nil, fmt.Errorf("VRF services: failed to get chain (%s): %w", rid.ChainID, err2) } if jb.ForwardingAllowed != chain.Config().EVM().Transactions().ForwardersEnabled() { return nil, errors.New("transaction forwarding settings must be consistent for ocr2vrf") @@ -793,7 +833,7 @@ func (d *Delegate) newServicesOCR2VRF( KeyID: keyID, DKGReportingPluginFactoryDecorator: dkgReportingPluginFactoryDecorator, VRFReportingPluginFactoryDecorator: vrfReportingPluginFactoryDecorator, - DKGSharePersistence: persistence.NewShareDB(d.db, lggr.Named("DKGShareDB"), d.cfg.Database(), big.NewInt(chainID), spec.Relay), + DKGSharePersistence: persistence.NewShareDB(d.db, lggr.Named("DKGShareDB"), d.cfg.Database(), chain.ID(), spec.Relay), }) if err2 != nil { return nil, errors.Wrap(err2, "new ocr2vrf") @@ -827,31 +867,183 @@ func (d *Delegate) newServicesOCR2Keepers( lc ocrtypes.LocalConfig, ocrLogger commontypes.Logger, ) ([]job.ServiceCtx, error) { - keeperProvider, rgstry, encoder, logProvider, err2 := ocr2keeper.EVMDependencies20(jb, d.db, lggr, d.chainSet, d.pipelineRunner) + spec := jb.OCR2OracleSpec + var cfg ocr2keeper.PluginConfig + if err := json.Unmarshal(spec.PluginConfig.Bytes(), &cfg); err != nil { + return nil, errors.Wrap(err, "unmarshal ocr2keepers plugin config") + } + + if err := ocr2keeper.ValidatePluginConfig(cfg); err != nil { + return nil, errors.Wrap(err, "ocr2keepers plugin config validation failure") + } + + switch cfg.ContractVersion { + case "v2.1": + return d.newServicesOCR2Keepers21(lggr, jb, runResults, bootstrapPeers, kb, ocrDB, lc, ocrLogger, cfg, spec) + case "v2.0": + return d.newServicesOCR2Keepers20(lggr, jb, runResults, bootstrapPeers, kb, ocrDB, lc, ocrLogger, cfg, spec) + default: + return d.newServicesOCR2Keepers20(lggr, jb, runResults, bootstrapPeers, kb, ocrDB, lc, ocrLogger, cfg, spec) + } +} + +func (d *Delegate) newServicesOCR2Keepers21( + lggr logger.SugaredLogger, + jb job.Job, + runResults chan pipeline.Run, + bootstrapPeers []commontypes.BootstrapperLocator, + kb ocr2key.KeyBundle, + ocrDB *db, + lc ocrtypes.LocalConfig, + ocrLogger commontypes.Logger, + cfg ocr2keeper.PluginConfig, + spec *job.OCR2OracleSpec, +) ([]job.ServiceCtx, error) { + credName, err2 := jb.OCR2OracleSpec.PluginConfig.MercuryCredentialName() + if err2 != nil { + return nil, errors.Wrap(err2, "failed to get mercury credential name") + } + + mc := d.cfg.Mercury().Credentials(credName) + rid, err := spec.RelayID() + if err != nil { + return nil, fmt.Errorf("keeper2 services: %w: %w", ErrJobSpecNoRelayer, err) + } + if rid.Network != relay.EVM { + return nil, fmt.Errorf("keeper2 services: expected EVM relayer got %s", rid.Network) + } + + chain, err2 := d.legacyChains.Get(rid.ChainID.String()) + if err2 != nil { + return nil, fmt.Errorf("keeper2 services: failed to get chain %s: %w", rid.ChainID, err2) + } + + keeperProvider, services, err2 := ocr2keeper.EVMDependencies21(jb, d.db, lggr, chain, d.pipelineRunner, mc, kb) if err2 != nil { return nil, errors.Wrap(err2, "could not build dependencies for ocr2 keepers") } + // set some defaults + conf := ocr2keepers21config.ReportingFactoryConfig{ + CacheExpiration: ocr2keepers21config.DefaultCacheExpiration, + CacheEvictionInterval: ocr2keepers21config.DefaultCacheClearInterval, + MaxServiceWorkers: ocr2keepers21config.DefaultMaxServiceWorkers, + ServiceQueueLength: ocr2keepers21config.DefaultServiceQueueLength, + } - spec := jb.OCR2OracleSpec - var cfg ocr2keeper.PluginConfig - err2 = json.Unmarshal(spec.PluginConfig.Bytes(), &cfg) + // override if set in config + if cfg.CacheExpiration.Value() != 0 { + conf.CacheExpiration = cfg.CacheExpiration.Value() + } + + if cfg.CacheEvictionInterval.Value() != 0 { + conf.CacheEvictionInterval = cfg.CacheEvictionInterval.Value() + } + + if cfg.MaxServiceWorkers != 0 { + conf.MaxServiceWorkers = cfg.MaxServiceWorkers + } + + if cfg.ServiceQueueLength != 0 { + conf.ServiceQueueLength = cfg.ServiceQueueLength + } + + dConf := ocr2keepers21.DelegateConfig{ + BinaryNetworkEndpointFactory: d.peerWrapper.Peer2, + V2Bootstrappers: bootstrapPeers, + ContractTransmitter: evmrelay.NewKeepersOCR3ContractTransmitter(keeperProvider.ContractTransmitter()), + ContractConfigTracker: keeperProvider.ContractConfigTracker(), + KeepersDatabase: ocrDB, + Logger: ocrLogger, + MonitoringEndpoint: d.monitoringEndpointGen.GenMonitoringEndpoint(spec.ContractID, synchronization.OCR2Automation), + OffchainConfigDigester: keeperProvider.OffchainConfigDigester(), + OffchainKeyring: kb, + OnchainKeyring: services.Keyring(), + LocalConfig: lc, + LogProvider: services.LogEventProvider(), + EventProvider: services.TransmitEventProvider(), + Runnable: services.Registry(), + Encoder: services.Encoder(), + BlockSubscriber: services.BlockSubscriber(), + RecoverableProvider: services.LogRecoverer(), + PayloadBuilder: services.PayloadBuilder(), + UpkeepProvider: services.UpkeepProvider(), + UpkeepStateUpdater: services.UpkeepStateStore(), + UpkeepTypeGetter: ocr2keeper21core.GetUpkeepType, + WorkIDGenerator: ocr2keeper21core.UpkeepWorkID, + // TODO: Clean up the config + CacheExpiration: cfg.CacheExpiration.Value(), + CacheEvictionInterval: cfg.CacheEvictionInterval.Value(), + MaxServiceWorkers: cfg.MaxServiceWorkers, + ServiceQueueLength: cfg.ServiceQueueLength, + } + + pluginService, err := ocr2keepers21.NewDelegate(dConf) + if err != nil { + return nil, errors.Wrap(err, "could not create new keepers ocr2 delegate") + } + + // RunResultSaver needs to be started first, so it's available + // to read odb writes. It is stopped last after the OraclePlugin is shut down + // so no further runs are enqueued, and we can drain the queue. + runResultSaver := ocrcommon.NewResultRunSaver( + runResults, + d.pipelineRunner, + make(chan struct{}), + lggr, + d.cfg.JobPipeline().MaxSuccessfulRuns(), + ) + + return []job.ServiceCtx{ + runResultSaver, + keeperProvider, + services.Registry(), + services.BlockSubscriber(), + services.LogEventProvider(), + services.LogRecoverer(), + services.UpkeepStateStore(), + services.TransmitEventProvider(), + pluginService, + }, nil +} + +func (d *Delegate) newServicesOCR2Keepers20( + lggr logger.SugaredLogger, + jb job.Job, + runResults chan pipeline.Run, + bootstrapPeers []commontypes.BootstrapperLocator, + kb ocr2key.KeyBundle, + ocrDB *db, + lc ocrtypes.LocalConfig, + ocrLogger commontypes.Logger, + cfg ocr2keeper.PluginConfig, + spec *job.OCR2OracleSpec, +) ([]job.ServiceCtx, error) { + + rid, err := spec.RelayID() + if err != nil { + return nil, fmt.Errorf("keepers2.0 services: %w: %w", ErrJobSpecNoRelayer, err) + } + if rid.Network != relay.EVM { + return nil, fmt.Errorf("keepers2.0 services: expected EVM relayer got %s", rid.Network) + } + chain, err2 := d.legacyChains.Get(rid.ChainID.String()) if err2 != nil { - return nil, errors.Wrap(err2, "unmarshal ocr2keepers plugin config") + return nil, fmt.Errorf("keepers2.0 services: failed to get chain (%s): %w", rid.ChainID, err2) } - err2 = ocr2keeper.ValidatePluginConfig(cfg) + keeperProvider, rgstry, encoder, logProvider, err2 := ocr2keeper.EVMDependencies20(jb, d.db, lggr, chain, d.pipelineRunner) if err2 != nil { - return nil, errors.Wrap(err2, "ocr2keepers plugin config validation failure") + return nil, errors.Wrap(err2, "could not build dependencies for ocr2 keepers") } w := &logWriter{log: lggr.Named("Automation Dependencies")} // set some defaults - conf := config.ReportingFactoryConfig{ - CacheExpiration: config.DefaultCacheExpiration, - CacheEvictionInterval: config.DefaultCacheClearInterval, - MaxServiceWorkers: config.DefaultMaxServiceWorkers, - ServiceQueueLength: config.DefaultServiceQueueLength, + conf := ocr2keepers20config.ReportingFactoryConfig{ + CacheExpiration: ocr2keepers20config.DefaultCacheExpiration, + CacheEvictionInterval: ocr2keepers20config.DefaultCacheClearInterval, + MaxServiceWorkers: ocr2keepers20config.DefaultMaxServiceWorkers, + ServiceQueueLength: ocr2keepers20config.DefaultServiceQueueLength, } // override if set in config @@ -871,7 +1063,7 @@ func (d *Delegate) newServicesOCR2Keepers( conf.ServiceQueueLength = cfg.ServiceQueueLength } - runr, err2 := runner.NewRunner( + runr, err2 := ocr2keepers20runner.NewRunner( log.New(w, "[automation-plugin-runner] ", log.Lshortfile), rgstry, encoder, @@ -884,7 +1076,7 @@ func (d *Delegate) newServicesOCR2Keepers( return nil, errors.Wrap(err2, "failed to create automation pipeline runner") } - condObs := &polling.PollingObserverFactory{ + condObs := &ocr2keepers20polling.PollingObserverFactory{ Logger: log.New(w, "[automation-plugin-conditional-observer] ", log.Lshortfile), Source: rgstry, Heads: rgstry, @@ -892,14 +1084,14 @@ func (d *Delegate) newServicesOCR2Keepers( Encoder: encoder, } - coord := &coordinator.CoordinatorFactory{ + coord := &ocr2keepers20coordinator.CoordinatorFactory{ Logger: log.New(w, "[automation-plugin-coordinator] ", log.Lshortfile), Encoder: encoder, Logs: logProvider, CacheClean: conf.CacheEvictionInterval, } - dConf := ocr2keepers.DelegateConfig{ + dConf := ocr2keepers20.DelegateConfig{ BinaryNetworkEndpointFactory: d.peerWrapper.Peer2, V2Bootstrappers: bootstrapPeers, ContractTransmitter: keeperProvider.ContractTransmitter(), @@ -922,7 +1114,7 @@ func (d *Delegate) newServicesOCR2Keepers( ServiceQueueLength: cfg.ServiceQueueLength, } - pluginService, err := ocr2keepers.NewDelegate(dConf) + pluginService, err := ocr2keepers20.NewDelegate(dConf) if err != nil { return nil, errors.Wrap(err, "could not create new keepers ocr2 delegate") } @@ -961,13 +1153,21 @@ func (d *Delegate) newServicesOCR2Functions( ocrLogger commontypes.Logger, ) ([]job.ServiceCtx, error) { spec := jb.OCR2OracleSpec - if spec.Relay != relay.EVM { - return nil, fmt.Errorf("unsupported relay: %s", spec.Relay) - } - createPluginProvider := func(pluginType functionsRelay.FunctionsPluginType, relayerName string) (types.PluginProvider, error) { + rid, err := spec.RelayID() + if err != nil { + return nil, fmt.Errorf("functions services: %w: %w", ErrJobSpecNoRelayer, err) + } + if rid.Network != relay.EVM { + return nil, fmt.Errorf("functions services: expected EVM relayer got %s", rid.Network) + } + chain, err := d.legacyChains.Get(rid.ChainID.String()) + if err != nil { + return nil, fmt.Errorf("functions services: failed to get chain %s: %w", rid.ChainID, err) + } + createPluginProvider := func(pluginType functionsRelay.FunctionsPluginType, relayerName string) (evmrelaytypes.FunctionsProvider, error) { return evmrelay.NewFunctionsProvider( - d.chainSet, + chain, types.RelayArgs{ ExternalJobID: jb.ExternalJobID, JobID: spec.ID, @@ -1000,16 +1200,6 @@ func (d *Delegate) newServicesOCR2Functions( return nil, err } - var relayConfig evmrelaytypes.RelayConfig - err = json.Unmarshal(spec.RelayConfig.Bytes(), &relayConfig) - if err != nil { - return nil, err - } - chain, err := d.chainSet.Get(relayConfig.ChainID.ToInt()) - if err != nil { - return nil, err - } - functionsOracleArgs := libocr2.OCR2OracleArgs{ BinaryNetworkEndpointFactory: d.peerWrapper.Peer2, V2Bootstrappers: bootstrapPeers, @@ -1081,6 +1271,7 @@ func (d *Delegate) newServicesOCR2Functions( URLsMonEndpoint: d.monitoringEndpointGen.GenMonitoringEndpoint(spec.ContractID, synchronization.FunctionsRequests), EthKeystore: d.ethKs, ThresholdKeyShare: thresholdKeyShare, + LogPollerWrapper: functionsProvider.LogPollerWrapper(), } functionsServices, err := functions.NewFunctionsServices(&functionsOracleArgs, &thresholdOracleArgs, &s4OracleArgs, &functionsServicesConfig) @@ -1099,7 +1290,7 @@ func (d *Delegate) newServicesOCR2Functions( d.cfg.JobPipeline().MaxSuccessfulRuns(), ) - return append([]job.ServiceCtx{runResultSaver, functionsProvider, s4Provider}, functionsServices...), nil + return append([]job.ServiceCtx{runResultSaver, functionsProvider, thresholdProvider, s4Provider}, functionsServices...), nil } // errorLog implements [loop.ErrorLog] @@ -1121,3 +1312,10 @@ func (l *logWriter) Write(p []byte) (n int, err error) { n = len(p) return } + +type mockRecoverableProvider struct { +} + +func (_m *mockRecoverableProvider) GetRecoveryProposals(ctx context.Context) ([]ocr2keepers21types.UpkeepPayload, error) { + return nil, nil +} diff --git a/core/services/ocr2/delegate_test.go b/core/services/ocr2/delegate_test.go index dc7d5526e16..af4c9355b0a 100644 --- a/core/services/ocr2/delegate_test.go +++ b/core/services/ocr2/delegate_test.go @@ -1,8 +1,13 @@ package ocr2_test import ( + "testing" + "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" + "github.com/stretchr/testify/require" + "gopkg.in/guregu/null.v4" + evmcfg "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" txmmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" @@ -15,11 +20,9 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2" ocr2validate "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/testdata/testspecs" "github.com/smartcontractkit/chainlink/v2/core/utils" - "github.com/stretchr/testify/require" - "gopkg.in/guregu/null.v4" - "testing" ) func TestGetEVMEffectiveTransmitterID(t *testing.T) { @@ -40,7 +43,10 @@ func TestGetEVMEffectiveTransmitterID(t *testing.T) { lggr := logger.TestLogger(t) txManager := txmmocks.NewMockEvmTxManager(t) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth(), TxManager: txManager}) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth(), TxManager: txManager}) + require.True(t, relayExtenders.Len() > 0) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) type testCase struct { name string @@ -134,7 +140,9 @@ func TestGetEVMEffectiveTransmitterID(t *testing.T) { require.NoError(t, err) jb.OCR2OracleSpec.TransmitterID = null.StringFrom("some transmitterID string") jb.OCR2OracleSpec.RelayConfig["sendingKeys"] = nil - effectiveTransmitterID, err := ocr2.GetEVMEffectiveTransmitterID(&jb, cc, customChainID.Int64(), lggr) + chain, err := legacyChains.Get(customChainID.String()) + require.NoError(t, err) + effectiveTransmitterID, err := ocr2.GetEVMEffectiveTransmitterID(&jb, chain, lggr) require.NoError(t, err) require.Equal(t, "some transmitterID string", effectiveTransmitterID) require.Equal(t, []string{"some transmitterID string"}, jb.OCR2OracleSpec.RelayConfig["sendingKeys"].([]string)) @@ -145,8 +153,10 @@ func TestGetEVMEffectiveTransmitterID(t *testing.T) { jb, err := ocr2validate.ValidatedOracleSpecToml(config.OCR2(), config.Insecure(), testspecs.OCR2EVMSpecMinimal) require.NoError(t, err) setTestCase(&jb, tc, txManager) + chain, err := legacyChains.Get(customChainID.String()) + require.NoError(t, err) - effectiveTransmitterID, err := ocr2.GetEVMEffectiveTransmitterID(&jb, cc, customChainID.Int64(), lggr) + effectiveTransmitterID, err := ocr2.GetEVMEffectiveTransmitterID(&jb, chain, lggr) if tc.expectedError { require.Error(t, err) } else { @@ -167,7 +177,9 @@ func TestGetEVMEffectiveTransmitterID(t *testing.T) { require.NoError(t, err) jb.ForwardingAllowed = true jb.OCR2OracleSpec.TransmitterID = null.StringFrom("0x7e57000000000000000000000000000000000001") - _, err = ocr2.GetEVMEffectiveTransmitterID(&jb, cc, int64(-1), lggr) - require.Equal(t, "failed to get chainset: failed to get chain with id -1: not found", err.Error()) + chain, err := legacyChains.Get("not an id") + require.Error(t, err) + _, err = ocr2.GetEVMEffectiveTransmitterID(&jb, chain, lggr) + require.Error(t, err) }) } diff --git a/core/services/ocr2/plugins/dkg/persistence/db_test.go b/core/services/ocr2/plugins/dkg/persistence/db_test.go index 3eb3eb19b03..b830a8db3bc 100644 --- a/core/services/ocr2/plugins/dkg/persistence/db_test.go +++ b/core/services/ocr2/plugins/dkg/persistence/db_test.go @@ -60,6 +60,7 @@ func TestShareDB_WriteShareRecords(t *testing.T) { for rows.Next() { require.NoError(tt, rows.Scan(&count)) } + require.NoError(tt, rows.Err()) require.Equal(tt, 3, count) }) @@ -88,6 +89,7 @@ func TestShareDB_WriteShareRecords(t *testing.T) { for rows.Next() { require.NoError(tt, rows.Scan(&count)) } + require.NoError(tt, rows.Err()) require.Equal(tt, 0, count) }) @@ -125,6 +127,7 @@ func TestShareDB_WriteShareRecords(t *testing.T) { for rows.Next() { require.NoError(tt, rows.Scan(&count)) } + require.NoError(tt, rows.Err()) require.Equal(tt, 0, count) }) diff --git a/core/services/ocr2/plugins/functions/aggregation.go b/core/services/ocr2/plugins/functions/aggregation.go index 6989e68b62d..32a2509e70e 100644 --- a/core/services/ocr2/plugins/functions/aggregation.go +++ b/core/services/ocr2/plugins/functions/aggregation.go @@ -50,8 +50,8 @@ func Aggregate(aggMethod config.AggregationMethod, observations []*encoding.Proc rawData = append(rawData, item.Result) } } - // Metadata (currently only callbackGas) is aggregated using MODE method - finalResult.CallbackGasLimit = aggregateMetadata(toAggregate) + // Metadata (CallbackGasLimit, CoordinatorContract and OnchainMetadata) is aggregated using MODE method + finalResult.CallbackGasLimit, finalResult.CoordinatorContract, finalResult.OnchainMetadata = aggregateMetadata(toAggregate) if resultIsError { // Errors are always aggregated using MODE method finalResult.Error = aggregateMode(rawData) @@ -68,14 +68,27 @@ func Aggregate(aggMethod config.AggregationMethod, observations []*encoding.Proc return &finalResult, nil } -func aggregateMetadata(items []*encoding.ProcessedRequest) (callbackGasLimit uint32) { +func aggregateMetadata(items []*encoding.ProcessedRequest) (uint32, []byte, []byte) { gasLimitBytes := make([][]byte, len(items)) + coordinatorContracts := make([][]byte, len(items)) + onchainMetadata := make([][]byte, len(items)) for i, item := range items { gasLimitBytes[i] = make([]byte, 4) binary.BigEndian.PutUint32(gasLimitBytes[i], item.CallbackGasLimit) + coordinatorContracts[i] = item.CoordinatorContract + if coordinatorContracts[i] == nil { + coordinatorContracts[i] = []byte{} + } + onchainMetadata[i] = item.OnchainMetadata + if onchainMetadata[i] == nil { + onchainMetadata[i] = []byte{} + } } - aggregated := aggregateMode(gasLimitBytes) - return binary.BigEndian.Uint32(aggregated) + aggGasLimitBytes := aggregateMode(gasLimitBytes) + aggGasLimitUint32 := binary.BigEndian.Uint32(aggGasLimitBytes) + aggCoordinatorContract := aggregateMode(coordinatorContracts) + aggOnchainMetadata := aggregateMode(onchainMetadata) + return aggGasLimitUint32, aggCoordinatorContract, aggOnchainMetadata } func aggregateMode(items [][]byte) []byte { diff --git a/core/services/ocr2/plugins/functions/aggregation_test.go b/core/services/ocr2/plugins/functions/aggregation_test.go index c6ce2ecc8e1..8a39a9b6561 100644 --- a/core/services/ocr2/plugins/functions/aggregation_test.go +++ b/core/services/ocr2/plugins/functions/aggregation_test.go @@ -13,10 +13,12 @@ import ( func req(id int, result []byte, err []byte) *encoding.ProcessedRequest { return &encoding.ProcessedRequest{ - RequestID: []byte(strconv.Itoa(id)), - Result: result, - Error: err, - CallbackGasLimit: 0, + RequestID: []byte(strconv.Itoa(id)), + Result: result, + Error: err, + CallbackGasLimit: 0, + CoordinatorContract: []byte{}, + OnchainMetadata: []byte{}, } } @@ -24,12 +26,14 @@ func reqS(id int, result string, err string) *encoding.ProcessedRequest { return req(id, []byte(result), []byte(err)) } -func reqMeta(id int, result []byte, err []byte, callbackGas uint32) *encoding.ProcessedRequest { +func reqMeta(id int, result []byte, err []byte, callbackGas uint32, coordinatorContract []byte, onchainMeta []byte) *encoding.ProcessedRequest { return &encoding.ProcessedRequest{ - RequestID: []byte(strconv.Itoa(id)), - Result: result, - Error: err, - CallbackGasLimit: callbackGas, + RequestID: []byte(strconv.Itoa(id)), + Result: result, + Error: err, + CallbackGasLimit: callbackGas, + CoordinatorContract: coordinatorContract, + OnchainMetadata: onchainMeta, } } @@ -117,23 +121,23 @@ func TestAggregate_Successful(t *testing.T) { "Metadata With Results", config.AggregationMethod_AGGREGATION_MEDIAN, []*encoding.ProcessedRequest{ - reqMeta(21, []byte{1}, []byte{}, 100), - reqMeta(21, []byte{1}, []byte{}, 90), - reqMeta(21, []byte{1}, []byte{}, 100), - reqMeta(21, []byte{1}, []byte{}, 100), + reqMeta(21, []byte{1}, []byte{}, 100, []byte{2}, []byte{4}), + reqMeta(21, []byte{1}, []byte{}, 90, []byte{2}, []byte{4}), + reqMeta(21, []byte{1}, []byte{}, 100, []byte{0}, []byte{4}), + reqMeta(21, []byte{1}, []byte{}, 100, []byte{2}, []byte{1}), }, - reqMeta(21, []byte{1}, []byte{}, 100), + reqMeta(21, []byte{1}, []byte{}, 100, []byte{2}, []byte{4}), }, { "Metadata With Errors", config.AggregationMethod_AGGREGATION_MEDIAN, []*encoding.ProcessedRequest{ - reqMeta(21, []byte{}, []byte{2}, 90), - reqMeta(21, []byte{}, []byte{2}, 100), - reqMeta(21, []byte{}, []byte{2}, 100), - reqMeta(21, []byte{}, []byte{2}, 100), + reqMeta(21, []byte{}, []byte{2}, 90, []byte{0}, []byte{4}), + reqMeta(21, []byte{}, []byte{2}, 100, []byte{2}, []byte{4}), + reqMeta(21, []byte{}, []byte{2}, 100, []byte{2}, []byte{1}), + reqMeta(21, []byte{}, []byte{2}, 100, []byte{2}, []byte{4}), }, - reqMeta(21, []byte{}, []byte{2}, 100), + reqMeta(21, []byte{}, []byte{2}, 100, []byte{2}, []byte{4}), }, } diff --git a/core/services/ocr2/plugins/functions/config/config.go b/core/services/ocr2/plugins/functions/config/config.go index 160c99e3514..d373de57376 100644 --- a/core/services/ocr2/plugins/functions/config/config.go +++ b/core/services/ocr2/plugins/functions/config/config.go @@ -19,20 +19,27 @@ import ( // This config is part of the job spec and is loaded only once on node boot/job creation. type PluginConfig struct { - MinIncomingConfirmations uint32 `json:"minIncomingConfirmations"` - RequestTimeoutSec uint32 `json:"requestTimeoutSec"` - RequestTimeoutCheckFrequencySec uint32 `json:"requestTimeoutCheckFrequencySec"` - RequestTimeoutBatchLookupSize uint32 `json:"requestTimeoutBatchLookupSize"` - PruneMaxStoredRequests uint32 `json:"pruneMaxStoredRequests"` - PruneCheckFrequencySec uint32 `json:"pruneCheckFrequencySec"` - PruneBatchSize uint32 `json:"pruneBatchSize"` - ListenerEventHandlerTimeoutSec uint32 `json:"listenerEventHandlerTimeoutSec"` - MaxRequestSizeBytes uint32 `json:"maxRequestSizeBytes"` - GatewayConnectorConfig *connector.ConnectorConfig `json:"gatewayConnectorConfig"` - OnchainAllowlist *functions.OnchainAllowlistConfig `json:"onchainAllowlist"` - RateLimiter *common.RateLimiterConfig `json:"rateLimiter"` - S4Constraints *s4.Constraints `json:"s4Constraints"` - DecryptionQueueConfig *DecryptionQueueConfig `json:"decryptionQueueConfig"` + EnableRequestSignatureCheck bool `json:"enableRequestSignatureCheck"` + DONID string `json:"donID"` + ContractVersion uint32 `json:"contractVersion"` + MinIncomingConfirmations uint32 `json:"minIncomingConfirmations"` + RequestTimeoutSec uint32 `json:"requestTimeoutSec"` + RequestTimeoutCheckFrequencySec uint32 `json:"requestTimeoutCheckFrequencySec"` + RequestTimeoutBatchLookupSize uint32 `json:"requestTimeoutBatchLookupSize"` + PruneMaxStoredRequests uint32 `json:"pruneMaxStoredRequests"` + PruneCheckFrequencySec uint32 `json:"pruneCheckFrequencySec"` + PruneBatchSize uint32 `json:"pruneBatchSize"` + ListenerEventHandlerTimeoutSec uint32 `json:"listenerEventHandlerTimeoutSec"` + ListenerEventsCheckFrequencyMillis uint32 `json:"listenerEventsCheckFrequencyMillis"` + ContractUpdateCheckFrequencySec uint32 `json:"contractUpdateCheckFrequencySec"` + MaxRequestSizeBytes uint32 `json:"maxRequestSizeBytes"` + MaxRequestSizesList []uint32 `json:"maxRequestSizesList"` + MaxSecretsSizesList []uint32 `json:"maxSecretsSizesList"` + GatewayConnectorConfig *connector.ConnectorConfig `json:"gatewayConnectorConfig"` + OnchainAllowlist *functions.OnchainAllowlistConfig `json:"onchainAllowlist"` + RateLimiter *common.RateLimiterConfig `json:"rateLimiter"` + S4Constraints *s4.Constraints `json:"s4Constraints"` + DecryptionQueueConfig *DecryptionQueueConfig `json:"decryptionQueueConfig"` } type DecryptionQueueConfig struct { @@ -106,6 +113,7 @@ func (ThresholdConfigParser) ParseConfig(config []byte) (*decryptionPluginConfig RequestCountLimit: thresholdPluginConfig.RequestCountLimit, RequestTotalBytesLimit: thresholdPluginConfig.RequestTotalBytesLimit, RequireLocalRequestCheck: thresholdPluginConfig.RequireLocalRequestCheck, + K: thresholdPluginConfig.K, }, }, nil } diff --git a/core/services/ocr2/plugins/functions/config/config_types.pb.go b/core/services/ocr2/plugins/functions/config/config_types.pb.go index b185a9176c2..b9debdcd466 100644 --- a/core/services/ocr2/plugins/functions/config/config_types.pb.go +++ b/core/services/ocr2/plugins/functions/config/config_types.pb.go @@ -66,6 +66,7 @@ func (AggregationMethod) EnumDescriptor() ([]byte, []int) { return file_core_services_ocr2_plugins_functions_config_config_types_proto_rawDescGZIP(), []int{0} } +// Has to match the corresponding proto in tdh2. type ThresholdReportingPluginConfig struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -77,6 +78,7 @@ type ThresholdReportingPluginConfig struct { RequestCountLimit uint32 `protobuf:"varint,4,opt,name=request_count_limit,json=requestCountLimit,proto3" json:"request_count_limit,omitempty"` RequestTotalBytesLimit uint32 `protobuf:"varint,5,opt,name=request_total_bytes_limit,json=requestTotalBytesLimit,proto3" json:"request_total_bytes_limit,omitempty"` RequireLocalRequestCheck bool `protobuf:"varint,6,opt,name=require_local_request_check,json=requireLocalRequestCheck,proto3" json:"require_local_request_check,omitempty"` + K uint32 `protobuf:"varint,7,opt,name=k,proto3" json:"k,omitempty"` // Number of decryption shares required for assembling plaintext. } func (x *ThresholdReportingPluginConfig) Reset() { @@ -153,6 +155,13 @@ func (x *ThresholdReportingPluginConfig) GetRequireLocalRequestCheck() bool { return false } +func (x *ThresholdReportingPluginConfig) GetK() uint32 { + if x != nil { + return x.K + } + return 0 +} + type S4ReportingPluginConfig struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -261,7 +270,9 @@ type ReportingPluginConfig struct { UniqueReports bool `protobuf:"varint,6,opt,name=uniqueReports,proto3" json:"uniqueReports,omitempty"` ThresholdPluginConfig *ThresholdReportingPluginConfig `protobuf:"bytes,7,opt,name=thresholdPluginConfig,proto3" json:"thresholdPluginConfig,omitempty"` S4PluginConfig *S4ReportingPluginConfig `protobuf:"bytes,8,opt,name=s4PluginConfig,proto3" json:"s4PluginConfig,omitempty"` - MaxReportTotalCallbackGas uint32 `protobuf:"varint,9,opt,name=maxReportTotalCallbackGas,proto3" json:"maxReportTotalCallbackGas,omitempty"` + // Needs to be set in tandem with gas estimator (e.g. [EVM.GasEstimator.LimitJobType] OCR = ) + // otherwise the report won't go through TX Manager or fail later. + MaxReportTotalCallbackGas uint32 `protobuf:"varint,9,opt,name=maxReportTotalCallbackGas,proto3" json:"maxReportTotalCallbackGas,omitempty"` } func (x *ReportingPluginConfig) Reset() { @@ -367,7 +378,7 @@ var file_core_services_ocr2_plugins_functions_config_config_types_proto_rawDesc 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x16, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x22, 0xf7, 0x02, 0x0a, 0x1e, 0x54, 0x68, 0x72, + 0x69, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x22, 0x85, 0x03, 0x0a, 0x1e, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x33, 0x0a, 0x16, 0x6d, 0x61, 0x78, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x5f, @@ -391,80 +402,81 @@ var file_core_services_ocr2_plugins_functions_config_config_types_proto_rawDesc 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x22, 0x95, 0x03, 0x0a, 0x17, 0x53, 0x34, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, - 0x6e, 0x67, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x33, - 0x0a, 0x16, 0x6d, 0x61, 0x78, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x6c, 0x65, 0x6e, 0x67, - 0x74, 0x68, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, - 0x6d, 0x61, 0x78, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x42, 0x79, - 0x74, 0x65, 0x73, 0x12, 0x3f, 0x0a, 0x1c, 0x6d, 0x61, 0x78, 0x5f, 0x6f, 0x62, 0x73, 0x65, 0x72, - 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x5f, 0x62, 0x79, - 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x19, 0x6d, 0x61, 0x78, 0x4f, 0x62, - 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x42, - 0x79, 0x74, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x17, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x14, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6e, - 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x6e, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, - 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x36, 0x0a, 0x17, 0x6d, 0x61, 0x78, 0x5f, 0x6f, - 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x69, - 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x4f, 0x62, 0x73, - 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, - 0x2c, 0x0a, 0x12, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x65, 0x6e, - 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x6d, 0x61, 0x78, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x3b, 0x0a, - 0x1a, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x69, - 0x72, 0x65, 0x64, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x17, 0x6d, 0x61, 0x78, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x78, 0x70, 0x69, - 0x72, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0xff, 0x04, 0x0a, 0x15, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x30, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x13, 0x6d, 0x61, 0x78, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4c, 0x65, 0x6e, 0x67, 0x74, - 0x68, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x19, 0x6d, 0x61, 0x78, 0x4f, 0x62, 0x73, - 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x42, 0x79, - 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x19, 0x6d, 0x61, 0x78, 0x4f, 0x62, - 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x42, - 0x79, 0x74, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x14, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x14, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4c, 0x65, 0x6e, - 0x67, 0x74, 0x68, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x53, 0x69, 0x7a, 0x65, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x65, 0x0a, 0x18, 0x64, 0x65, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x66, - 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x18, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, - 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, - 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x6c, 0x0a, 0x15, 0x74, 0x68, 0x72, 0x65, 0x73, - 0x68, 0x6f, 0x6c, 0x64, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, - 0x6e, 0x67, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x15, - 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x57, 0x0a, 0x0e, 0x73, 0x34, 0x50, 0x6c, 0x75, 0x67, 0x69, - 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x34, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, - 0x6e, 0x67, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, - 0x73, 0x34, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3c, - 0x0a, 0x19, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x6f, 0x74, 0x61, 0x6c, - 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x47, 0x61, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x19, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x6f, 0x74, 0x61, - 0x6c, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x47, 0x61, 0x73, 0x2a, 0x41, 0x0a, 0x11, - 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, - 0x64, 0x12, 0x14, 0x0a, 0x10, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x47, 0x47, 0x52, 0x45, - 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x45, 0x44, 0x49, 0x41, 0x4e, 0x10, 0x01, 0x42, - 0x2d, 0x5a, 0x2b, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x2f, 0x6f, 0x63, 0x72, 0x32, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2f, 0x66, 0x75, - 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x63, 0x6b, 0x12, 0x0c, 0x0a, 0x01, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x01, 0x6b, + 0x22, 0x95, 0x03, 0x0a, 0x17, 0x53, 0x34, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, + 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x33, 0x0a, 0x16, + 0x6d, 0x61, 0x78, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x6d, 0x61, + 0x78, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x42, 0x79, 0x74, 0x65, + 0x73, 0x12, 0x3f, 0x0a, 0x1c, 0x6d, 0x61, 0x78, 0x5f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x5f, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x19, 0x6d, 0x61, 0x78, 0x4f, 0x62, 0x73, 0x65, + 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x42, 0x79, 0x74, + 0x65, 0x73, 0x12, 0x35, 0x0a, 0x17, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x14, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6e, 0x5f, 0x73, + 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x6e, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x36, 0x0a, 0x17, 0x6d, 0x61, 0x78, 0x5f, 0x6f, 0x62, 0x73, + 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x4f, 0x62, 0x73, 0x65, 0x72, + 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2c, 0x0a, + 0x12, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x65, 0x6e, 0x74, 0x72, + 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x52, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x1a, 0x6d, + 0x61, 0x78, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, + 0x64, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x17, 0x6d, 0x61, 0x78, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, + 0x64, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0xff, 0x04, 0x0a, 0x15, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x30, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x13, 0x6d, 0x61, 0x78, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x42, + 0x79, 0x74, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x19, 0x6d, 0x61, 0x78, 0x4f, 0x62, 0x73, 0x65, 0x72, + 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x42, 0x79, 0x74, 0x65, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x19, 0x6d, 0x61, 0x78, 0x4f, 0x62, 0x73, 0x65, + 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x42, 0x79, 0x74, + 0x65, 0x73, 0x12, 0x32, 0x0a, 0x14, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x14, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x13, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x65, 0x0a, 0x18, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, + 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x18, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x41, 0x67, + 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, + 0x24, 0x0a, 0x0d, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x52, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x6c, 0x0a, 0x15, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, + 0x6c, 0x64, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x54, 0x68, + 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, + 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x15, 0x74, 0x68, + 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x57, 0x0a, 0x0e, 0x73, 0x34, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x34, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, + 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x73, 0x34, + 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3c, 0x0a, 0x19, + 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x61, + 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x47, 0x61, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x19, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x43, + 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x47, 0x61, 0x73, 0x2a, 0x41, 0x0a, 0x11, 0x41, 0x67, + 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, + 0x14, 0x0a, 0x10, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, + 0x4f, 0x44, 0x45, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x45, 0x44, 0x49, 0x41, 0x4e, 0x10, 0x01, 0x42, 0x2d, 0x5a, + 0x2b, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x6f, + 0x63, 0x72, 0x32, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2f, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/core/services/ocr2/plugins/functions/config/config_types.proto b/core/services/ocr2/plugins/functions/config/config_types.proto index bdba9843207..c0e58e45384 100644 --- a/core/services/ocr2/plugins/functions/config/config_types.proto +++ b/core/services/ocr2/plugins/functions/config/config_types.proto @@ -4,11 +4,14 @@ option go_package = "core/services/ocr2/plugins/functions/config"; package functions_config_types; +// WARNING: Any changes to protobufs must also be reflected in Gauntlet which is used to generate the OCR plugin config for production deployments + enum AggregationMethod { AGGREGATION_MODE = 0; AGGREGATION_MEDIAN = 1; } +// Has to match the corresponding proto in tdh2. message ThresholdReportingPluginConfig { uint32 max_query_length_bytes = 1; uint32 max_observation_length_bytes = 2; @@ -16,6 +19,7 @@ message ThresholdReportingPluginConfig { uint32 request_count_limit = 4; uint32 request_total_bytes_limit = 5; bool require_local_request_check = 6; + uint32 k = 7; // Number of decryption shares required for assembling plaintext. } message S4ReportingPluginConfig { diff --git a/core/services/ocr2/plugins/functions/encoding/abi_codec.go b/core/services/ocr2/plugins/functions/encoding/abi_codec.go index 1668eefa6ce..e7f62605db9 100644 --- a/core/services/ocr2/plugins/functions/encoding/abi_codec.go +++ b/core/services/ocr2/plugins/functions/encoding/abi_codec.go @@ -7,11 +7,48 @@ import ( "github.com/pkg/errors" ) -type ReportCodec struct { +type ReportCodec interface { + EncodeReport(requests []*ProcessedRequest) ([]byte, error) + DecodeReport(raw []byte) ([]*ProcessedRequest, error) +} + +type reportCodecV0 struct { reportTypes abi.Arguments } -func getReportTypes() (abi.Arguments, error) { +type reportCodecV1 struct { + reportTypes abi.Arguments +} + +func NewReportCodec(contractVersion uint32) (ReportCodec, error) { + switch contractVersion { + case 0: // deprecated + reportTypes, err := getReportTypesV0() + if err != nil { + return nil, err + } + return &reportCodecV0{reportTypes: reportTypes}, nil + case 1: + reportTypes, err := getReportTypesV1() + if err != nil { + return nil, err + } + return &reportCodecV1{reportTypes: reportTypes}, nil + default: + return nil, fmt.Errorf("unknown contract version: %d", contractVersion) + } +} + +func SliceToByte32(slice []byte) ([32]byte, error) { + if len(slice) != 32 { + return [32]byte{}, fmt.Errorf("input length is not 32 bytes: %d", len(slice)) + } + var res [32]byte + copy(res[:], slice[:32]) + return res, nil +} + +func getReportTypesV0() (abi.Arguments, error) { bytes32ArrType, err := abi.NewType("bytes32[]", "", []abi.ArgumentMarshaling{}) if err != nil { return nil, fmt.Errorf("unable to create an ABI type object for bytes32[]") @@ -27,26 +64,7 @@ func getReportTypes() (abi.Arguments, error) { }), nil } -func NewReportCodec() (*ReportCodec, error) { - reportTypes, err := getReportTypes() - if err != nil { - return nil, err - } - return &ReportCodec{ - reportTypes: reportTypes, - }, nil -} - -func SliceToByte32(slice []byte) ([32]byte, error) { - if len(slice) != 32 { - return [32]byte{}, fmt.Errorf("input length is not 32 bytes: %d", len(slice)) - } - var res [32]byte - copy(res[:], slice[:32]) - return res, nil -} - -func (c *ReportCodec) EncodeReport(requests []*ProcessedRequest) ([]byte, error) { +func (c *reportCodecV0) EncodeReport(requests []*ProcessedRequest) ([]byte, error) { size := len(requests) if size == 0 { return []byte{}, nil @@ -66,7 +84,7 @@ func (c *ReportCodec) EncodeReport(requests []*ProcessedRequest) ([]byte, error) return c.reportTypes.Pack(ids, results, errors) } -func (c *ReportCodec) DecodeReport(raw []byte) ([]*ProcessedRequest, error) { +func (c *reportCodecV0) DecodeReport(raw []byte) ([]*ProcessedRequest, error) { reportElems := map[string]interface{}{} if err := c.reportTypes.UnpackIntoMap(reportElems, raw); err != nil { return nil, errors.WithMessage(err, "unable to unpack elements from raw report") @@ -104,3 +122,92 @@ func (c *ReportCodec) DecodeReport(raw []byte) ([]*ProcessedRequest, error) { } return decoded, nil } + +func getReportTypesV1() (abi.Arguments, error) { + bytes32ArrType, err := abi.NewType("bytes32[]", "", []abi.ArgumentMarshaling{}) + if err != nil { + return nil, fmt.Errorf("unable to create an ABI type object for bytes32[]") + } + bytesArrType, err := abi.NewType("bytes[]", "", []abi.ArgumentMarshaling{}) + if err != nil { + return nil, fmt.Errorf("unable to create an ABI type object for bytes[]") + } + return abi.Arguments([]abi.Argument{ + {Name: "ids", Type: bytes32ArrType}, + {Name: "results", Type: bytesArrType}, + {Name: "errors", Type: bytesArrType}, + {Name: "onchain_metadata", Type: bytesArrType}, + {Name: "processing_metadata", Type: bytesArrType}, + }), nil +} + +func (c *reportCodecV1) EncodeReport(requests []*ProcessedRequest) ([]byte, error) { + size := len(requests) + if size == 0 { + return []byte{}, nil + } + ids := make([][32]byte, size) + results := make([][]byte, size) + errors := make([][]byte, size) + onchainMetadata := make([][]byte, size) + processingMetadata := make([][]byte, size) + for i := 0; i < size; i++ { + var err error + ids[i], err = SliceToByte32(requests[i].RequestID) + if err != nil { + return nil, err + } + results[i] = requests[i].Result + errors[i] = requests[i].Error + onchainMetadata[i] = requests[i].OnchainMetadata + processingMetadata[i] = requests[i].CoordinatorContract + // CallbackGasLimit is not ABI-encoded + } + return c.reportTypes.Pack(ids, results, errors, onchainMetadata, processingMetadata) +} + +func (c *reportCodecV1) DecodeReport(raw []byte) ([]*ProcessedRequest, error) { + reportElems := map[string]interface{}{} + if err := c.reportTypes.UnpackIntoMap(reportElems, raw); err != nil { + return nil, errors.WithMessage(err, "unable to unpack elements from raw report") + } + + idsIface, idsOK := reportElems["ids"] + resultsIface, resultsOK := reportElems["results"] + errorsIface, errorsOK := reportElems["errors"] + onchainMetaIface, onchainMetaOK := reportElems["onchain_metadata"] + processingMetaIface, processingMetaOK := reportElems["processing_metadata"] + if !idsOK || !resultsOK || !errorsOK || !onchainMetaOK || !processingMetaOK { + return nil, fmt.Errorf("missing arrays in raw report, ids: %v, results: %v, errors: %v", idsOK, resultsOK, errorsOK) + } + + ids, idsOK := idsIface.([][32]byte) + results, resultsOK := resultsIface.([][]byte) + errors, errorsOK := errorsIface.([][]byte) + onchainMeta, onchainMetaOK := onchainMetaIface.([][]byte) + processingMeta, processingMetaOK := processingMetaIface.([][]byte) + if !idsOK || !resultsOK || !errorsOK || !onchainMetaOK || !processingMetaOK { + return nil, fmt.Errorf("unable to cast part of raw report into array type, ids: %v, results: %v, errors: %v", idsOK, resultsOK, errorsOK) + } + + size := len(ids) + if len(results) != size || len(errors) != size || len(onchainMeta) != size || len(processingMeta) != size { + return nil, fmt.Errorf("unequal sizes of arrays parsed from raw report, ids: %v, results: %v, errors: %v", len(ids), len(results), len(errors)) + } + if size == 0 { + return []*ProcessedRequest{}, nil + } + + decoded := make([]*ProcessedRequest, size) + for i := 0; i < size; i++ { + decoded[i] = &ProcessedRequest{ + RequestID: ids[i][:], + Result: results[i], + Error: errors[i], + OnchainMetadata: onchainMeta[i], + CoordinatorContract: processingMeta[i], + // CallbackGasLimit is not ABI-encoded + } + } + return decoded, nil +} diff --git a/core/services/ocr2/plugins/functions/encoding/abi_codec_test.go b/core/services/ocr2/plugins/functions/encoding/abi_codec_test.go index f15dfe9a814..03c8b87af16 100644 --- a/core/services/ocr2/plugins/functions/encoding/abi_codec_test.go +++ b/core/services/ocr2/plugins/functions/encoding/abi_codec_test.go @@ -9,9 +9,9 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/encoding" ) -func TestABICodec_EncodeDecodeSuccess(t *testing.T) { +func TestABICodec_EncodeDecodeV0Success(t *testing.T) { t.Parallel() - codec, err := encoding.NewReportCodec() + codec, err := encoding.NewReportCodec(0) require.NoError(t, err) var report = []*encoding.ProcessedRequest{ @@ -40,6 +40,43 @@ func TestABICodec_EncodeDecodeSuccess(t *testing.T) { } } +func TestABICodec_EncodeDecodeV1Success(t *testing.T) { + t.Parallel() + codec, err := encoding.NewReportCodec(1) + require.NoError(t, err) + + var report = []*encoding.ProcessedRequest{ + { + RequestID: []byte(fmt.Sprintf("%032d", 123)), + Result: []byte("abcd"), + Error: []byte("err string"), + CoordinatorContract: []byte("contract_1"), + OnchainMetadata: []byte("commitment_1"), + }, + { + RequestID: []byte(fmt.Sprintf("%032d", 4321)), + Result: []byte("0xababababab"), + Error: []byte(""), + CoordinatorContract: []byte("contract_2"), + OnchainMetadata: []byte("commitment_2"), + }, + } + + encoded, err := codec.EncodeReport(report) + require.NoError(t, err) + decoded, err := codec.DecodeReport(encoded) + require.NoError(t, err) + + require.Equal(t, len(report), len(decoded)) + for i := 0; i < len(report); i++ { + require.Equal(t, report[i].RequestID, decoded[i].RequestID, "RequestIDs not equal at index %d", i) + require.Equal(t, report[i].Result, decoded[i].Result, "Results not equal at index %d", i) + require.Equal(t, report[i].Error, decoded[i].Error, "Errors not equal at index %d", i) + require.Equal(t, report[i].CoordinatorContract, decoded[i].CoordinatorContract, "Contracts not equal at index %d", i) + require.Equal(t, report[i].OnchainMetadata, decoded[i].OnchainMetadata, "Metadata not equal at index %d", i) + } +} + func TestABICodec_SliceToByte32(t *testing.T) { t.Parallel() diff --git a/core/services/ocr2/plugins/functions/encoding/ocr_types.pb.go b/core/services/ocr2/plugins/functions/encoding/ocr_types.pb.go index 58808bd5756..4022076334b 100644 --- a/core/services/ocr2/plugins/functions/encoding/ocr_types.pb.go +++ b/core/services/ocr2/plugins/functions/encoding/ocr_types.pb.go @@ -121,10 +121,12 @@ type ProcessedRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - RequestID []byte `protobuf:"bytes,1,opt,name=requestID,proto3" json:"requestID,omitempty"` - Result []byte `protobuf:"bytes,2,opt,name=result,proto3" json:"result,omitempty"` - Error []byte `protobuf:"bytes,3,opt,name=error,proto3" json:"error,omitempty"` - CallbackGasLimit uint32 `protobuf:"varint,4,opt,name=callbackGasLimit,proto3" json:"callbackGasLimit,omitempty"` + RequestID []byte `protobuf:"bytes,1,opt,name=requestID,proto3" json:"requestID,omitempty"` + Result []byte `protobuf:"bytes,2,opt,name=result,proto3" json:"result,omitempty"` + Error []byte `protobuf:"bytes,3,opt,name=error,proto3" json:"error,omitempty"` + CallbackGasLimit uint32 `protobuf:"varint,4,opt,name=callbackGasLimit,proto3" json:"callbackGasLimit,omitempty"` + CoordinatorContract []byte `protobuf:"bytes,5,opt,name=coordinatorContract,proto3" json:"coordinatorContract,omitempty"` + OnchainMetadata []byte `protobuf:"bytes,6,opt,name=onchainMetadata,proto3" json:"onchainMetadata,omitempty"` } func (x *ProcessedRequest) Reset() { @@ -187,6 +189,20 @@ func (x *ProcessedRequest) GetCallbackGasLimit() uint32 { return 0 } +func (x *ProcessedRequest) GetCoordinatorContract() []byte { + if x != nil { + return x.CoordinatorContract + } + return nil +} + +func (x *ProcessedRequest) GetOnchainMetadata() []byte { + if x != nil { + return x.OnchainMetadata + } + return nil +} + var File_core_services_ocr2_plugins_functions_encoding_ocr_types_proto protoreflect.FileDescriptor var file_core_services_ocr2_plugins_functions_encoding_ocr_types_proto_rawDesc = []byte{ @@ -202,7 +218,7 @@ var file_core_services_ocr2_plugins_functions_encoding_ocr_types_proto_rawDesc = 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x11, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, - 0x73, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0x8a, 0x01, 0x0a, 0x10, + 0x73, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0xe6, 0x01, 0x0a, 0x10, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x44, 0x12, 0x16, @@ -211,11 +227,16 @@ var file_core_services_ocr2_plugins_functions_encoding_ocr_types_proto_rawDesc = 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, - 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x42, 0x2f, 0x5a, 0x2d, 0x63, 0x6f, 0x72, 0x65, - 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x6f, 0x63, 0x72, 0x32, 0x2f, 0x70, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2f, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x30, 0x0a, 0x13, 0x63, 0x6f, 0x6f, 0x72, + 0x64, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, + 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x6f, 0x6e, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x42, 0x2f, 0x5a, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x6f, 0x63, 0x72, 0x32, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x73, 0x2f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x65, 0x6e, 0x63, + 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/core/services/ocr2/plugins/functions/encoding/ocr_types.proto b/core/services/ocr2/plugins/functions/encoding/ocr_types.proto index 4495366c526..a546f0f1b00 100644 --- a/core/services/ocr2/plugins/functions/encoding/ocr_types.proto +++ b/core/services/ocr2/plugins/functions/encoding/ocr_types.proto @@ -19,4 +19,6 @@ message ProcessedRequest { bytes result = 2; bytes error = 3; uint32 callbackGasLimit = 4; + bytes coordinatorContract = 5; + bytes onchainMetadata = 6; } diff --git a/core/services/ocr2/plugins/functions/integration_tests/functions_integration_test.go b/core/services/ocr2/plugins/functions/integration_tests/v0/functions_integration_test.go similarity index 82% rename from core/services/ocr2/plugins/functions/integration_tests/functions_integration_test.go rename to core/services/ocr2/plugins/functions/integration_tests/v0/functions_integration_test.go index 855c435f26d..011e67c77ca 100644 --- a/core/services/ocr2/plugins/functions/integration_tests/functions_integration_test.go +++ b/core/services/ocr2/plugins/functions/integration_tests/v0/functions_integration_test.go @@ -5,7 +5,7 @@ import ( "time" functionsConfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/config" - utils "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/integration_tests/internal" + utils "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/integration_tests/v0/internal" ) var ( @@ -22,7 +22,7 @@ func TestIntegration_Functions_MultipleRequests_Success(t *testing.T) { owner, b, ticker, oracleContractAddress, oracleContract, clientContracts, registryAddress, registryContract, linkToken := utils.StartNewChainWithContracts(t, nClients) defer ticker.Stop() - _, _, oracleIdentities := utils.CreateFunctionsNodes(t, owner, b, oracleContractAddress, 39999, nOracleNodes, maxGas, nil, nil) + _, _, oracleIdentities := utils.CreateFunctionsNodes(t, owner, b, oracleContractAddress, nOracleNodes, maxGas, nil, nil) // config for registry contract utils.SetRegistryConfig(t, owner, registryContract, oracleContractAddress) @@ -30,7 +30,7 @@ func TestIntegration_Functions_MultipleRequests_Success(t *testing.T) { pluginConfig := functionsConfig.ReportingPluginConfig{ MaxQueryLengthBytes: 10_000, MaxObservationLengthBytes: 10_000, - MaxReportLengthBytes: 10_000, + MaxReportLengthBytes: 15_000, MaxRequestBatchSize: uint32(batchSize), DefaultAggregationMethod: functionsConfig.AggregationMethod_AGGREGATION_MODE, UniqueReports: true, @@ -49,7 +49,7 @@ func TestIntegration_Functions_MultipleRequests_ThresholdDecryptionSuccess(t *te owner, b, ticker, oracleContractAddress, oracleContract, clientContracts, registryAddress, registryContract, linkToken := utils.StartNewChainWithContracts(t, nClients) defer ticker.Stop() - _, _, oracleIdentities := utils.CreateFunctionsNodes(t, owner, b, oracleContractAddress, 49999, nOracleNodes, maxGas, utils.ExportedOcr2Keystores, utils.MockThresholdKeyShares) + _, _, oracleIdentities := utils.CreateFunctionsNodes(t, owner, b, oracleContractAddress, nOracleNodes, maxGas, utils.ExportedOcr2Keystores, utils.MockThresholdKeyShares) // config for registry contract utils.SetRegistryConfig(t, owner, registryContract, oracleContractAddress) @@ -57,17 +57,19 @@ func TestIntegration_Functions_MultipleRequests_ThresholdDecryptionSuccess(t *te pluginConfig := functionsConfig.ReportingPluginConfig{ MaxQueryLengthBytes: 10_000, MaxObservationLengthBytes: 10_000, - MaxReportLengthBytes: 10_000, + MaxReportLengthBytes: 15_000, MaxRequestBatchSize: uint32(batchSize), DefaultAggregationMethod: functionsConfig.AggregationMethod_AGGREGATION_MODE, UniqueReports: true, ThresholdPluginConfig: &functionsConfig.ThresholdReportingPluginConfig{ - MaxQueryLengthBytes: 10_000, - MaxObservationLengthBytes: 10_000, - MaxReportLengthBytes: 10_000, - RequestCountLimit: 100, - RequestTotalBytesLimit: 1_000, + // approximately 750 bytes per test ciphertext + overhead + MaxQueryLengthBytes: 70_000, + MaxObservationLengthBytes: 70_000, + MaxReportLengthBytes: 70_000, + RequestCountLimit: 50, + RequestTotalBytesLimit: 50_000, RequireLocalRequestCheck: true, + K: 2, }, } @@ -76,5 +78,5 @@ func TestIntegration_Functions_MultipleRequests_ThresholdDecryptionSuccess(t *te utils.CommitWithFinality(b) // validate that all client contracts got correct responses to their requests - utils.ClientTestRequests(t, owner, b, linkToken, registryAddress, registryContract, clientContracts, requestLenBytes, utils.DefaultSecretsUrlsBytes, 3*time.Minute) + utils.ClientTestRequests(t, owner, b, linkToken, registryAddress, registryContract, clientContracts, requestLenBytes, utils.DefaultSecretsUrlsBytes, 1*time.Minute) } diff --git a/core/services/ocr2/plugins/functions/integration_tests/internal/testconstants.go b/core/services/ocr2/plugins/functions/integration_tests/v0/internal/testconstants.go similarity index 99% rename from core/services/ocr2/plugins/functions/integration_tests/internal/testconstants.go rename to core/services/ocr2/plugins/functions/integration_tests/v0/internal/testconstants.go index 2c53ca1eba6..62de14febfc 100644 --- a/core/services/ocr2/plugins/functions/integration_tests/internal/testconstants.go +++ b/core/services/ocr2/plugins/functions/integration_tests/v0/internal/testconstants.go @@ -7,6 +7,7 @@ var ( DefaultSecretsUrlsBase64 = "AQID" DefaultArg1 = "arg1" DefaultArg2 = "arg2" + DefaultGasPrice = 1_000_000_000 // Below are the corresponding values for the encrypted threshold keys used in the test // mockThresholdPubKey := `{"Group":"P256","G_bar":"BAnzIguQNKnA37Zh0b3Z3K5CcvxHjzfTIytt37ZgNQLaTeuiq9rrVhz+yaZcvNQ9EYw978KmmYOq6qd0NA/ERh8=","H":"BOyfKc8aowVjOK2qYf0kdeuLkPeqbjDnjDFGIj/2n7O+qHIvqKx3A07Oa92tP5DkcS5AL/tipXDIBJvVWvcvudk=","HArray":["BBhLQicdsIUgigmIW4l6Xi1jBkFFXEtm2wuvydoZCjZZdlDZt82pXtOI+vPQbd5iawQPX6u4HUrhEisqwhx5P0A=","BLTOIUViwoVJTAzCKIo2FgliIfK7w3jG6wjwf3LVkdsMYJ2ZiEJDA7YC1GwsVgutYdxrwOkAY+wnoh9j+AYF/rQ=","BH2vi5G9ftykpOJARMlziZuZKXSx5YiP131HpwWwsgFAquSpsNTRWHsjk4nc0lcQKf6x9E+7UUQpAPwDpyrh7Xc=","BHQBZMqVRvxQHtnC4tqfh9Qc632IfSCPCBDsePyLzD1nXOf/qJWrCpfsZ3T3PaRm/U30LSgnb1nsuXI9nDuTFsM="]}` diff --git a/core/services/ocr2/plugins/functions/integration_tests/internal/testutils.go b/core/services/ocr2/plugins/functions/integration_tests/v0/internal/testutils.go similarity index 94% rename from core/services/ocr2/plugins/functions/integration_tests/internal/testutils.go rename to core/services/ocr2/plugins/functions/integration_tests/v0/internal/testutils.go index 960e1ad0a46..9013620e1e6 100644 --- a/core/services/ocr2/plugins/functions/integration_tests/internal/testutils.go +++ b/core/services/ocr2/plugins/functions/integration_tests/v0/internal/testutils.go @@ -7,6 +7,7 @@ import ( "io" "math/big" "math/rand" + "net" "net/http" "net/http/httptest" "net/url" @@ -169,6 +170,7 @@ type deployedClientContract struct { func StartNewChainWithContracts(t *testing.T, nClients int) (*bind.TransactOpts, *backends.SimulatedBackend, *time.Ticker, common.Address, *ocr2dr_oracle.OCR2DROracle, []deployedClientContract, common.Address, *ocr2dr_registry.OCR2DRRegistry, *link_token_interface.LinkToken) { owner := testutils.MustNewSimTransactor(t) + owner.GasPrice = big.NewInt(int64(DefaultGasPrice)) sb := new(big.Int) sb, _ = sb.SetString("100000000000000000000", 10) // 1 eth genesisData := core.GenesisAlloc{owner.From: {Balance: sb}} @@ -257,6 +259,8 @@ func StartNewNode( c.EVM[0].LogPollInterval = models.MustNewDuration(1 * time.Second) c.EVM[0].Transactions.ForwardersEnabled = ptr(false) c.EVM[0].GasEstimator.LimitDefault = ptr(maxGas) + c.EVM[0].GasEstimator.Mode = ptr("FixedPrice") + c.EVM[0].GasEstimator.PriceDefault = assets.NewWei(big.NewInt(int64(DefaultGasPrice))) if len(thresholdKeyShare) > 0 { s.Threshold.ThresholdKeyShare = models.NewSecret(thresholdKeyShare) @@ -448,7 +452,6 @@ func CreateFunctionsNodes( owner *bind.TransactOpts, b *backends.SimulatedBackend, oracleContractAddress common.Address, - startingPort uint16, nOracleNodes int, maxGas int, ocr2Keystores [][]byte, @@ -466,7 +469,8 @@ func CreateFunctionsNodes( require.Fail(t, "ocr2Keystores and thresholdKeyShares must have the same length") } - bootstrapNode = StartNewNode(t, owner, startingPort, "bootstrap", b, uint32(maxGas), nil, nil, "") + bootstrapPort := getFreePort(t) + bootstrapNode = StartNewNode(t, owner, bootstrapPort, "bootstrap", b, uint32(maxGas), nil, nil, "") AddBootstrapJob(t, bootstrapNode.App, oracleContractAddress) // oracle nodes with jobs, bridges and mock EAs @@ -483,8 +487,9 @@ func CreateFunctionsNodes( } else { ocr2Keystore = ocr2Keystores[i] } - oracleNode := StartNewNode(t, owner, startingPort+1+uint16(i), fmt.Sprintf("oracle%d", i), b, uint32(maxGas), []commontypes.BootstrapperLocator{ - {PeerID: bootstrapNode.PeerID, Addrs: []string{fmt.Sprintf("127.0.0.1:%d", startingPort)}}, + nodePort := getFreePort(t) + oracleNode := StartNewNode(t, owner, nodePort, fmt.Sprintf("oracle%d", i), b, uint32(maxGas), []commontypes.BootstrapperLocator{ + {PeerID: bootstrapNode.PeerID, Addrs: []string{fmt.Sprintf("127.0.0.1:%d", bootstrapPort)}}, }, ocr2Keystore, thresholdKeyShare) oracleNodes = append(oracleNodes, oracleNode.App) oracleIdentites = append(oracleIdentites, oracleNode.OracleIdentity) @@ -498,6 +503,18 @@ func CreateFunctionsNodes( return bootstrapNode, oracleNodes, oracleIdentites } +// NOTE: This approach is technically incorrect because the returned port +// can still be taken by the time the caller attempts to bind to it. +// Unfortunately, we can't specify zero port in P2P.V2.ListenAddresses at the moment. +func getFreePort(t *testing.T) uint16 { + addr, err := net.ResolveTCPAddr("tcp", "localhost:0") + require.NoError(t, err) + listener, err := net.ListenTCP("tcp", addr) + require.NoError(t, err) + require.NoError(t, listener.Close()) + return uint16(listener.Addr().(*net.TCPAddr).Port) +} + func ClientTestRequests( t *testing.T, owner *bind.TransactOpts, diff --git a/core/services/ocr2/plugins/functions/integration_tests/v1/functions_integration_test.go b/core/services/ocr2/plugins/functions/integration_tests/v1/functions_integration_test.go new file mode 100644 index 00000000000..944bafadf75 --- /dev/null +++ b/core/services/ocr2/plugins/functions/integration_tests/v1/functions_integration_test.go @@ -0,0 +1,118 @@ +package functions_test + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + + functionsConfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/config" + utils "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/integration_tests/v1/internal" +) + +var ( + // a batch of 8 max-length results uses around 2M gas (assuming 70k gas per client callback - see FunctionsClientExample.sol) + nOracleNodes = 4 + nClients = 50 + requestLenBytes = 1_000 + maxGas = 1_700_000 + maxTotalReportGas = 560_000 + batchSize = 8 +) + +func TestIntegration_Functions_MultipleV1Requests_Success(t *testing.T) { + // simulated chain with all contracts + owner, b, ticker, active, proposed, clientContracts, routerAddress, routerContract, linkToken, allowListContractAddress, allowListContract := utils.StartNewChainWithContracts(t, nClients) + defer ticker.Stop() + + utils.SetupRouterRoutes(t, b, owner, routerContract, active.Address, proposed.Address, allowListContractAddress) + + _, _, oracleIdentities := utils.CreateFunctionsNodes(t, owner, b, routerAddress, nOracleNodes, maxGas, nil, nil) + + pluginConfig := functionsConfig.ReportingPluginConfig{ + MaxQueryLengthBytes: 10_000, + MaxObservationLengthBytes: 15_000, + MaxReportLengthBytes: 15_000, + MaxRequestBatchSize: uint32(batchSize), + MaxReportTotalCallbackGas: uint32(maxTotalReportGas), + DefaultAggregationMethod: functionsConfig.AggregationMethod_AGGREGATION_MODE, + UniqueReports: true, + } + + // config for oracle contract + utils.SetOracleConfig(t, b, owner, active.Contract, oracleIdentities, batchSize, &pluginConfig) + + subscriptionId := utils.CreateAndFundSubscriptions(t, b, owner, linkToken, routerAddress, routerContract, clientContracts, allowListContract) + b.Commit() + utils.ClientTestRequests(t, owner, b, linkToken, routerAddress, routerContract, allowListContract, clientContracts, requestLenBytes, utils.DefaultSecretsBytes, subscriptionId, 1*time.Minute) +} + +func TestIntegration_Functions_MultipleV1Requests_ThresholdDecryptionSuccess(t *testing.T) { + // simulated chain with all contracts + owner, b, ticker, active, proposed, clientContracts, routerAddress, routerContract, linkToken, allowListContractAddress, allowListContract := utils.StartNewChainWithContracts(t, nClients) + defer ticker.Stop() + + utils.SetupRouterRoutes(t, b, owner, routerContract, active.Address, proposed.Address, allowListContractAddress) + + _, _, oracleIdentities := utils.CreateFunctionsNodes(t, owner, b, routerAddress, nOracleNodes, maxGas, utils.ExportedOcr2Keystores, utils.MockThresholdKeyShares) + + pluginConfig := functionsConfig.ReportingPluginConfig{ + MaxQueryLengthBytes: 10_000, + MaxObservationLengthBytes: 15_000, + MaxReportLengthBytes: 15_000, + MaxRequestBatchSize: uint32(batchSize), + MaxReportTotalCallbackGas: uint32(maxTotalReportGas), + DefaultAggregationMethod: functionsConfig.AggregationMethod_AGGREGATION_MODE, + UniqueReports: true, + ThresholdPluginConfig: &functionsConfig.ThresholdReportingPluginConfig{ + // approximately 750 bytes per test ciphertext + overhead + MaxQueryLengthBytes: 70_000, + MaxObservationLengthBytes: 70_000, + MaxReportLengthBytes: 70_000, + RequestCountLimit: 50, + RequestTotalBytesLimit: 50_000, + RequireLocalRequestCheck: true, + K: 2, + }, + } + + // config for oracle contract + utils.SetOracleConfig(t, b, owner, active.Contract, oracleIdentities, batchSize, &pluginConfig) + + subscriptionId := utils.CreateAndFundSubscriptions(t, b, owner, linkToken, routerAddress, routerContract, clientContracts, allowListContract) + b.Commit() + utils.ClientTestRequests(t, owner, b, linkToken, routerAddress, routerContract, allowListContract, clientContracts, requestLenBytes, utils.DefaultSecretsUrlsBytes, subscriptionId, 1*time.Minute) +} + +func TestIntegration_Functions_MultipleV1Requests_WithUpgrade(t *testing.T) { + // simulated chain with all contracts + owner, b, ticker, active, proposed, clientContracts, routerAddress, routerContract, linkToken, allowListContractAddress, allowListContract := utils.StartNewChainWithContracts(t, nClients) + defer ticker.Stop() + + utils.SetupRouterRoutes(t, b, owner, routerContract, active.Address, proposed.Address, allowListContractAddress) + + _, _, oracleIdentities := utils.CreateFunctionsNodes(t, owner, b, routerAddress, nOracleNodes, maxGas, nil, nil) + + pluginConfig := functionsConfig.ReportingPluginConfig{ + MaxQueryLengthBytes: 10_000, + MaxObservationLengthBytes: 15_000, + MaxReportLengthBytes: 15_000, + MaxRequestBatchSize: uint32(batchSize), + MaxReportTotalCallbackGas: uint32(maxTotalReportGas), + DefaultAggregationMethod: functionsConfig.AggregationMethod_AGGREGATION_MODE, + UniqueReports: true, + } + + // set config for both coordinators + utils.SetOracleConfig(t, b, owner, active.Contract, oracleIdentities, batchSize, &pluginConfig) + utils.SetOracleConfig(t, b, owner, proposed.Contract, oracleIdentities, batchSize, &pluginConfig) + + subscriptionId := utils.CreateAndFundSubscriptions(t, b, owner, linkToken, routerAddress, routerContract, clientContracts, allowListContract) + utils.ClientTestRequests(t, owner, b, linkToken, routerAddress, routerContract, allowListContract, clientContracts, requestLenBytes, utils.DefaultSecretsBytes, subscriptionId, 1*time.Minute) + + // upgrade and send requests again + _, err := routerContract.UpdateContracts(owner) + require.NoError(t, err) + b.Commit() + utils.ClientTestRequests(t, owner, b, linkToken, routerAddress, routerContract, allowListContract, clientContracts, requestLenBytes, utils.DefaultSecretsBytes, subscriptionId, 1*time.Minute) +} diff --git a/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testconstants.go b/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testconstants.go new file mode 100644 index 00000000000..638adf99871 --- /dev/null +++ b/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testconstants.go @@ -0,0 +1,38 @@ +package testutils + +var ( + DefaultSecretsBytes = []byte{0xaa, 0xbb, 0xcc} + DefaultSecretsBase64 = "qrvM" + DefaultSecretsUrlsBytes = []byte{0x01, 0x02, 0x03} + DefaultSecretsUrlsBase64 = "AQID" + DefaultArg1 = "arg1" + DefaultArg2 = "arg2" + DefaultDONId = "1" + DefaultGasPrice = 1_000_000_000 + + // Below are the corresponding values for the encrypted threshold keys used in the test + // mockThresholdPubKey := `{"Group":"P256","G_bar":"BAnzIguQNKnA37Zh0b3Z3K5CcvxHjzfTIytt37ZgNQLaTeuiq9rrVhz+yaZcvNQ9EYw978KmmYOq6qd0NA/ERh8=","H":"BOyfKc8aowVjOK2qYf0kdeuLkPeqbjDnjDFGIj/2n7O+qHIvqKx3A07Oa92tP5DkcS5AL/tipXDIBJvVWvcvudk=","HArray":["BBhLQicdsIUgigmIW4l6Xi1jBkFFXEtm2wuvydoZCjZZdlDZt82pXtOI+vPQbd5iawQPX6u4HUrhEisqwhx5P0A=","BLTOIUViwoVJTAzCKIo2FgliIfK7w3jG6wjwf3LVkdsMYJ2ZiEJDA7YC1GwsVgutYdxrwOkAY+wnoh9j+AYF/rQ=","BH2vi5G9ftykpOJARMlziZuZKXSx5YiP131HpwWwsgFAquSpsNTRWHsjk4nc0lcQKf6x9E+7UUQpAPwDpyrh7Xc=","BHQBZMqVRvxQHtnC4tqfh9Qc632IfSCPCBDsePyLzD1nXOf/qJWrCpfsZ3T3PaRm/U30LSgnb1nsuXI9nDuTFsM="]}` + // mockPlaintextThresholdMasterKey := `{"Group":"P256","S":"MTpFRrh8F5mih+92W0l51ZVZIiGJgpHNUXb4vzkzv8A="}` + // mockPlaintextThresholdKeyShares := [][]byte{ + // []byte(`{"PublicKey":{"Group":"P256","G_bar":"BAnzIguQNKnA37Zh0b3Z3K5CcvxHjzfTIytt37ZgNQLaTeuiq9rrVhz+yaZcvNQ9EYw978KmmYOq6qd0NA/ERh8=","H":"BOyfKc8aowVjOK2qYf0kdeuLkPeqbjDnjDFGIj/2n7O+qHIvqKx3A07Oa92tP5DkcS5AL/tipXDIBJvVWvcvudk=","HArray":["BBhLQicdsIUgigmIW4l6Xi1jBkFFXEtm2wuvydoZCjZZdlDZt82pXtOI+vPQbd5iawQPX6u4HUrhEisqwhx5P0A=","BLTOIUViwoVJTAzCKIo2FgliIfK7w3jG6wjwf3LVkdsMYJ2ZiEJDA7YC1GwsVgutYdxrwOkAY+wnoh9j+AYF/rQ=","BH2vi5G9ftykpOJARMlziZuZKXSx5YiP131HpwWwsgFAquSpsNTRWHsjk4nc0lcQKf6x9E+7UUQpAPwDpyrh7Xc=","BHQBZMqVRvxQHtnC4tqfh9Qc632IfSCPCBDsePyLzD1nXOf/qJWrCpfsZ3T3PaRm/U30LSgnb1nsuXI9nDuTFsM="]},"PrivateKeyShare":{"Group":"P256","Index":0,"V":"Jzuh+h/jgm0HIp6iKVJxc/vCUOz7Ea+Y0twvRzJDheg="}}`), + // []byte(`{"PublicKey":{"Group":"P256","G_bar":"BAnzIguQNKnA37Zh0b3Z3K5CcvxHjzfTIytt37ZgNQLaTeuiq9rrVhz+yaZcvNQ9EYw978KmmYOq6qd0NA/ERh8=","H":"BOyfKc8aowVjOK2qYf0kdeuLkPeqbjDnjDFGIj/2n7O+qHIvqKx3A07Oa92tP5DkcS5AL/tipXDIBJvVWvcvudk=","HArray":["BBhLQicdsIUgigmIW4l6Xi1jBkFFXEtm2wuvydoZCjZZdlDZt82pXtOI+vPQbd5iawQPX6u4HUrhEisqwhx5P0A=","BLTOIUViwoVJTAzCKIo2FgliIfK7w3jG6wjwf3LVkdsMYJ2ZiEJDA7YC1GwsVgutYdxrwOkAY+wnoh9j+AYF/rQ=","BH2vi5G9ftykpOJARMlziZuZKXSx5YiP131HpwWwsgFAquSpsNTRWHsjk4nc0lcQKf6x9E+7UUQpAPwDpyrh7Xc=","BHQBZMqVRvxQHtnC4tqfh9Qc632IfSCPCBDsePyLzD1nXOf/qJWrCpfsZ3T3PaRm/U30LSgnb1nsuXI9nDuTFsM="]},"PrivateKeyShare":{"Group":"P256","Index":1,"V":"HTz+rYdK7UBrvU3N91tpEmIrf7hsoM1kVEFlzytTTBA="}}`), + // []byte(`{"PublicKey":{"Group":"P256","G_bar":"BAnzIguQNKnA37Zh0b3Z3K5CcvxHjzfTIytt37ZgNQLaTeuiq9rrVhz+yaZcvNQ9EYw978KmmYOq6qd0NA/ERh8=","H":"BOyfKc8aowVjOK2qYf0kdeuLkPeqbjDnjDFGIj/2n7O+qHIvqKx3A07Oa92tP5DkcS5AL/tipXDIBJvVWvcvudk=","HArray":["BBhLQicdsIUgigmIW4l6Xi1jBkFFXEtm2wuvydoZCjZZdlDZt82pXtOI+vPQbd5iawQPX6u4HUrhEisqwhx5P0A=","BLTOIUViwoVJTAzCKIo2FgliIfK7w3jG6wjwf3LVkdsMYJ2ZiEJDA7YC1GwsVgutYdxrwOkAY+wnoh9j+AYF/rQ=","BH2vi5G9ftykpOJARMlziZuZKXSx5YiP131HpwWwsgFAquSpsNTRWHsjk4nc0lcQKf6x9E+7UUQpAPwDpyrh7Xc=","BHQBZMqVRvxQHtnC4tqfh9Qc632IfSCPCBDsePyLzD1nXOf/qJWrCpfsZ3T3PaRm/U30LSgnb1nsuXI9nDuTFsM="]},"PrivateKeyShare":{"Group":"P256","Index":2,"V":"Ez5bYO6yWBPQV/z5xWRgsMiUroPeL+sv1aacVyRjEjg="}}`), + // []byte(`{"PublicKey":{"Group":"P256","G_bar":"BAnzIguQNKnA37Zh0b3Z3K5CcvxHjzfTIytt37ZgNQLaTeuiq9rrVhz+yaZcvNQ9EYw978KmmYOq6qd0NA/ERh8=","H":"BOyfKc8aowVjOK2qYf0kdeuLkPeqbjDnjDFGIj/2n7O+qHIvqKx3A07Oa92tP5DkcS5AL/tipXDIBJvVWvcvudk=","HArray":["BBhLQicdsIUgigmIW4l6Xi1jBkFFXEtm2wuvydoZCjZZdlDZt82pXtOI+vPQbd5iawQPX6u4HUrhEisqwhx5P0A=","BLTOIUViwoVJTAzCKIo2FgliIfK7w3jG6wjwf3LVkdsMYJ2ZiEJDA7YC1GwsVgutYdxrwOkAY+wnoh9j+AYF/rQ=","BH2vi5G9ftykpOJARMlziZuZKXSx5YiP131HpwWwsgFAquSpsNTRWHsjk4nc0lcQKf6x9E+7UUQpAPwDpyrh7Xc=","BHQBZMqVRvxQHtnC4tqfh9Qc632IfSCPCBDsePyLzD1nXOf/qJWrCpfsZ3T3PaRm/U30LSgnb1nsuXI9nDuTFsM="]},"PrivateKeyShare":{"Group":"P256","Index":3,"V":"CT+4FFYZwuc08qwlk21YTy793U9Pvwj7VwvS3x1y2GA="}}`), + // } + // Since the threshold public keys are encrypted with each node's public OCR2 offchain config key, the OCR2 offchain config key must be known in advance instead of regenerated every time. + ExportedOcr2Keystores = [][]byte{ + []byte(`{"keyType":"OCR2","chainType":"evm","id":"d8d0363c218526d809b8570257e7822bfde559ed532fa976118fc2d994155e55","onchainPublicKey":"e1deb8516367e7715da19134d58528778d6aff04","offchainPublicKey":"91c021d592ae5949eafaf4b74d622b13ac5784db7de9591755c3d3d2ed7a19b4","configPublicKey":"677c7ba4487eabea0f3341a095b94b6f56a1df97a165e49b8b0a7864c0f66077","crypto":{"cipher":"aes-128-ctr","ciphertext":"6d111479822c5b6e5a2b5ebde4f7ab6e6f7809e07bf6451d416f5e3082833a3b34e9aa820658c03487a3bdde5cbbfff3198a951f36a5ef91d1274211273f7af2e3e17e258530c25aebb1099395ecc1d96e567adefa727f06fcb61d0df2829737998bdd959759c62342fbd74a3f231535bb413d9c4479e33ff294d66bfc90d2b6db9d12250ef8daab309bb914373a76da24e82dce5b0da428a19efc1cdda48719f898a91f21b4fc89458d126d1023ffc0efcc8cf3e0ee249bfa0b1b55fa151d5c2630be21be2ea27964b82816ee72885f7bc59d7d4157d5333ab8324cc65a78581437a8600e8c044fabe80ae76cbe39ae332c5c0f85ac1090b13a1525caca40459082e9ca762714e50543e6aa907b7286eafc93a51c2d67265393d86ad83d431bf068aa006c36f63356","cipherparams":{"iv":"11b7b2f3c33dfff2a3125fdb10048601"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":2,"p":1,"r":8,"salt":"a3c5952aa41720097a50fea6957c994a9c39cb1dbe7bd59cff5b9354633836c1"},"mac":"df6d0d0b5f2cc95f1e1d4c9894f8487c56b814ca55d10e520d0c44e91d699012"}}`), + []byte(`{"keyType":"OCR2","chainType":"evm","id":"03a0713ffb5b506cbf12bd59fd7023c9dc3f1f56d4d2f9ed564f0361c3aa1119","onchainPublicKey":"3203c6923adc7ecff671e00632eb350fa354e957","offchainPublicKey":"c9aea40c0e5f13d9704d3051faa01718f1d4aa1419d3e6199f7deacee56a596e","configPublicKey":"23ccc8500fa3af447c7a8b3aa4e41ad7b34f6585bdc3e8c847c7ff12a8caa818","crypto":{"cipher":"aes-128-ctr","ciphertext":"5aa58bfd17209a4c9da966a1b175c74137536531ada19507434d6dbf146d71516c0ed2b52b5e664e69c4286a56f38be322206a33eacfaa854be313bade3b5876e5b40aec5be4dca761749b535ad9cd1575897d6736eb96fb9e118eb696c44d111b81757bd73a6d33c170febaf57705590f279625ec536d1656eac96a953de915693a9cd040a5d5948f3b288ebdbb178c955b5f0faa432d68e744f39dc621cbc4c5853627addc3dd2ed5e1ba4a514278d56d0cdef2e57688ad0752f3077656f16fa3144c33f3ed96ebdeb3009139f327d6c12d344a047147e71a95d5b08582bd8ee86c86e308d81f16357c79b50a48041994d98490a4b9d965525187901a2862d41bcc6822046f99ad481ae104aa75b816c5abac876bce0b07b2b73bb459830a5bc70f20c34b87ed6fc","cipherparams":{"iv":"d8fcf50fff54dfa082d40c0de90b6ab4"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":2,"p":1,"r":8,"salt":"64ba7faf39b49c46d5360109ef23e3f4198a3f402cbb975686fe4b52cc7c0b1f"},"mac":"09520656cc08b5743f95d386a5b7c3d164ecaa2002a0b83f2cd8d44c97d99b8a"}}`), + []byte(`{"keyType":"OCR2","chainType":"evm","id":"ace8972c126601fdc5f9ed42c909a57d2a19dff2be7ce341913c01a4921c829f","onchainPublicKey":"d8699a99d2a3ab4ccfc61bc7df72b30605a05b7c","offchainPublicKey":"9c1fa3ce9d355a73ce2dcdece70e7314af8da13f5ca30ee251dbed201dc904ed","configPublicKey":"9a2b9087af305c187d1292842072e50d2c4e98cb4e26c6328021fdd992e78926","crypto":{"cipher":"aes-128-ctr","ciphertext":"c7d2da9c60779ad33dce870b1f8af94082dfdfe51d4f04f27cf505bba21b17e287c685880614e22df92ce7549230e8b1a327de0686d892f5c4dda546132b044bde2a58d60bf335931b78e42342e2578e54111592cad4301d22c192c87809e3cef6e6dd1a30a7a208c78461154d856213466c1afad4023001c1b45fdf7804c6a9a4eb64ac1ea59775a1e694c79fc492b4d7422cd777778549c817e735e8e5e5f45aea9c9e9a5a7ff1c71b7879af120a4aa467a3ac0cdb1ba04f893283cad533c4ac9723969a64bbfd69bb7ef88d88d8d96c5293fee35c14a00a8e6c0cb2e7cfa918d05ec9e092e4fdad2a41edf7a1cb9e1a1a12ec6fbb594eb1e07d5dbb79eda390b826aa7ca8ccfda1cee9c125eb8a1d07d9e899cf6e9c1ec0fd40d83a50656674cc5c9d0a88710c65","cipherparams":{"iv":"5b6fca38ff8c03e38fb6f56f9d90fe8d"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":2,"p":1,"r":8,"salt":"6bfc5f03e8bd10efea3808d025c5769a49ade8bee6c608d713a6bf3f940a37ba"},"mac":"e1e4bcbe67a80d73ee12c8080ddd99bba9ca8774349a9cb5c5b9821983e460ca"}}`), + []byte(`{"keyType":"OCR2","chainType":"evm","id":"5b09af3b5a5a420436fa206eb266b6a4d796406030d022d4beaf6609e9da9274","onchainPublicKey":"c27e7957c243e061cc17d8f30e8f894280235499","offchainPublicKey":"f6c2fd84bb73252d49852b50420f5983b488609d9f73ef601e7641df24794dec","configPublicKey":"45a96a32b7339cd22da1a1c42c2ee71e698dd7dfbe7fd997949f1cdb3f2ba518","crypto":{"cipher":"aes-128-ctr","ciphertext":"f842a872d8a0033fc9b91673a1c2f095eda18c4716b53c743d04b82710f2bfa2c950356e50ea085b05975c36176a3dd2b10901508f297e3ff966cde02cf6ba077eebdb8708117c4c9f4498358e74fdc98bc1130a32bfa6bf8f46d9ea77d4e56952cc1ccbbf2bde05a48acf13fbb238675d640b6a74af70dfbaa63cad57108480238ce946a5af5f60b09794ff5b40bde982f32d7b48f5e9a51830a46cce1cf2f9a0c0ec220c062eb90602b2abbaf2a6a2da2d8b3dbc211db17d599789654a2a26f1fad52e22d7eed91365ce7d964731936307c39e66bd9a9ffc999f3174317786077ab83224d06e025b7de5974293b96eabcb3b9ffb17d2d0b49743cd7b4f1b222e32be3f32b9d2177b1c20cb7d56c10ae0789f8586ee99ccd9ac8b626df058b454686b2d8a663635b8","cipherparams":{"iv":"21a5417a99f37507bc2fbdda83c5856f"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":2,"p":1,"r":8,"salt":"c98ac207e897658d7c42029c2858ba29f03abe9298745b0b909377085806895a"},"mac":"dc1ef1c284e1d001b63f1d545e308c4ef194757605a4b57b8c565c5c40e64146"}}`), + } + // Threshold key shares have been generated with the Functions admin tooling (https://github.com/smartcontractkit/functions-admin-tooling/tree/main/threshold_key_manager) + MockThresholdKeyShares = []string{ + "40e99151aaa2002631cfdac741a0f206b9ebc492a2c5bd56deac64118148df6e3829a6f81b6df54694ca241f5bc12fd2b58bce9106767f4adbf7250e0a033386b56eb93159c3cf14748b6a0d1996a51039ce9ff98acaba758913fa2d671e86b909edbe27bdf441b68be2c2debbe8a29d814a04accd996b4df0fa8e0cea65ef47922c4aca8132fe4f2d6def9c4683b031267f60ccf896b6bf6b1957786deafebb5bc1663778ee893511306dda7833d01efe0d63224d0da0cea6d728953793e6b3e97f81cb64f80ed4ff4f3c349b90f11290adb0eff07f8ccb9b97d098903ce194f33f284d38832e12902354c3cda72189b3ac31b8206575391c1618dee6530b99fc60d667052e0065365842176b6b5d9b779be0be4f7fa27115d65e08d01f13db695581c1be4a1f96b980cba45bd528aaee23809fa9a601a229c7018eb6755f43a0d38125a872fcf8e109ca92abc55348cccc4f83beae8412425570b8aa9b6526a9ddd05a41e5c6d6865cf91ff1912490d67e6a99c3a91db433120b13768affef6b0cdeb33d085078fa27b90ef2663c69fcf9f3dad9a1fb67b9605f035b2cebf7808801e9ccd3eb83015aaefecf1fa97674923219c543accdc23d5f624cdbd673eba5f29cc66c647e1fe454e0c73efe8ff6605f78243e01aa42c14241f890388d6d35e3071ee89130f62317b8d624fc2b7c270769cf8e5c054cf3ed4163917f0af7372ab0eafdc4dd4faaf3cc30d406041404eae2ba942c800e4d9726e8e0d27e1488c5aaf47d977665c86d8574c17b69c8b31783ec479929e6b858ef57b072bcfaa3a747362235e142e9b73f19192d8878b832ff25b8cf29f0b5c130cb1d505ec1830a0901c0ac1f9b5542db33a9c39afc6ffa68d32a91dbb525cec9536647020cd22925baf63d173cd9b377fbcb509efcbf7830df459e080f5794186d628be938e9a53d3ea3182eb328d9956905dc6c22061c76118b208cdd7f063522d81ab4e404ef6d4a53b2099d2c94b8c05526b8367cfff6f08340bbe53cf2fbe6e7fae3b7062d27722085", + "9956a87c447eb15b82906742ef84980ca1dc6846b2234468ed7399af5392243b14226ab2a6ff6220776d1b5a591cacfde0bd583f48683d4f38186300f919681aa0a886e7eddc556e1bb434c18994df214a5b6fe4bfcb09ae9fc5dba4cb7e027ce01121dbad0621fe35311e1015c7d4d006ababd5c7377a0f70aecafaf3f709c0571ca2dd89b6cd83867bd299e8ce01e04ecafc1230ab0aeb2812a693fadcba7b479a00da357e75876d0cd2a3d85774e056d63436623ff400c9fd76446f5b7fd90902bf4d4268fb5775e326a887bd59136692bb5b0400790dd7908f9d5c7e422c76831ac3876e67a8b6d66ceb49c9c0835660bbd90a1e18ab8486dc464b6fd4044c580d3082842ab655169cf46abe25ad4de04d0bdefc74fee9c2009b43eea48f976a449ceb805993383b06ddfaf5a3df112a1c5e72ea121b9fbeafe8b7666500abeb52f2bad6035295b66994c0d239ced38f32af4df161b7bd66886703c050531173ae6ace942a311a0077b601c025bb59a78b43558c09ae55a6ce70d408b7e0ae439542971b33fdf14a7c5a36fed8d310e8cd08fe7c6b45d1bffd351bad2fd1cfc8d964f8ec39db82a7fd4095771f6d5e84516598364bd0532d3b8ccd660fa73bc1e5840087eeac18c7fd52611deac5aa50a6a033d2aecd79ec8bba8045615ff4d7b77e0d087110b888426d138107236ed4a6a6b6a5b51e54149e2272896d0180a46cde8955a8adeb969c35c5b58a0958ce955f2634723d8bf38c2d1c3efe0ce2494b00947d3958ec3b5b9f5445acad30296a34060bd688c7b91e818f49ddfa560541682ce0ff6d245b9df5adee989ea6b9eedcf58b3d47fdc64e8c046efaad51e169a81fc22419be8666897f18d7c913d806764714c9a735cce3698da8ecb3b16c1a88f6ef2b4a52686d4d1b5cfc5859422a1b39f7fe46691ccd28050a8edf040f438b407bfa4cc48641155e3c7531301d5192148ab2ccba064afeed1ae8723702ea9793317a1989a2601a958fda5bb23222a983842a31553930c4364b661e03376fff2471ae", + "4c19996b1ed254aba3f5d36a24a3a24a008cc864562610e15523087c2c05e63c57bc6c386d4f1b3cb53eb10ae26ab594a6693fa8ee5783ab4b4b040a0e4f27beda68405b72cbcbeee762114b23d1fe69aaf72bc81f70e76251df20b83fe6b82240fbe64be3b1a238bf3c5a8b7c8bac945fd25348b5618ff2409940f64bd86afb64695706c57340e72741af4e0d2d47407b041c57aac7ba9d35ce2316d6bff28ee5c22b007ec2c9b5914cb5baaa9e2ce6aafeb976c681dc08e1eb28514a7b7adfa0536ced06e3e23e9a14bad3f68b836442a952c39bfcaabdae0d3226dde590f3ba927b49a0c6f011b02abd14e5db8bf355432e3d3286c9aa5fcf2b6620cda13d56753a420555d0300de04c008d6cb9b62e4c7c44ea563445cccfc8266b06192c2981ce5b1157b6c16ca38e6b7036dd2e21e75646bbffc0be2f6c23257666a5679b8e35ac4382e31c05e4ef1170293617e6f77bd32b57f5ac617a7cbafa345c2137d8a7b70bf4a3b5c4010d73e7f064a9e5e51eaecf600bb837e0a648359aa4857b0875f14a62c648e7a7a13fac7e466bdd9ac89cf7f1f46081f5d107a6fffa5a0d8c70aa5aeaed3df35e9a5b33cabb98b22bf62d84cf4e57d7683457dbff3542a9299f9acd291225e4e8fc1255b305ca0e1404707053e50d55f69d8b709d9350db4f6f36ecf63037c6e00073df67b610c322e79ae4616314dc47d296b4570b659c21d659375fd1006af4d42838eb20f1682ffd19cf88b603790005b8c5ae4ab9c0415bcb0c8ce4a04d1f7d18fef5e16e9061aa56bc596bcdeae74ccdd1c95ab1607280602f75ddbb3a25cbe9af99197b0dab671a2e1069340cefcefef75e24e222c9e3d1563634eb3f3a8319bfd6f95b3a995d9dcad5a9aa2aea6bf46e6253080d8e4ec3b918d0012fe500edfba67e49d0520be57e7414629bb40e64312fb1d3e26bdef31cc8ec2426f71f91cfee0d3cd9390dceafe615106fd56703b85b377b812b8a6c24c9fc5d0c68464565d9b421a4cd296f00ddd7a062ea16c56232a4d2a69c2817bfa882", + "ba1edea16bd7223b3a413af6b392662b9b01eb18f67d41defe1cc4190160cf12c462414df90299b0ca5fbe7e2cf11f902a23de8340d9a190f32de0199ce150f15c6ed658638fe33701e3cee11574865efe768ecefd53ba20833e1300d4cc84bf0291852031fe5ce6b7dbd1bfe46d6887e39b6466b6ef76cd5743349c4109176bd0e60074bb7d8ba1cf47609b628045ed64743be510d90a21b7022f88a08dcabd7bc600c26b228b94ee175268f8206df72f7a708c014d162231e9009af0acacfb115674eb6fbb873e0c47b7b66820c7999143da38a871610614c8fe45a0c0d83020ed7c1e3eb5ee14e3e3bf70917a7d7a96e356e52c3bb33607448f61f592142de315fd29a172ce686b028c47cfb936780e1beebbbd2fca706534060e8d7f2de973005229183cd5ceaef3ceb944ca98562f22deec110ff6993ff9512f9b8e1aac17c08fa0295315229596a87eb0935e9b28ff1aff4d71889fed76fa7021e3494155b3b34f28cf5e717b46351bd9b11b0ddceac9ff3bd0c962ac003f5062acdb50058d50546d71fbb50e21221addd61a36f9ef98611f77d1c3c3ecc344fcdd9008d37ebe15944375ab767b1f937cb647dea26d7c6c8f9832b4f8632febba8abb107c39ba85ce09719eb7d7607ca6d0cc491419f6d3863e5d6f446a3c291da01c16e58e65b4428f8e0c024df391e6864e879bfc749d9175654c04413cbe4a65a35cea5596d6dc2d81800b2458fc75bfec6fedbbba857c24a19a0e747dc1d089b9eebb9b5098b2bcd2720f52d28055611ceb7b26d0c4b2a20c3b3aa9da50872bd95ef8154d6fd28669ffb48792e234a6f8eba3e53b57d994b8efd594045e0b6afb764013c28a23934a1502d0a90fe853e0a95738f1cdff79c7ee4e91d57824cd5cea56e8a45d95ee0cb1fa8911ccbd1e14883873817109f9ca4d21be60e3966541d1e1aaa7de0a57a3437f8a24e41a941d20f03055cd74f4b3048d2d9da7406da46ea82b65fd7b18e9004474583ecc9a2759b12fdd770f47222ef2c02d42ed0d18837a3e259f009d1e", + } + // This has been generated using the Functions Toolkit (https://github.com/smartcontractkit/functions-toolkit/blob/main/src/SecretsManager.ts) and decrypts to the JSON string `{"0x0":"qrvM"}` + DefaultThresholdSecretsHex = "0x7b225444483243747874223a2265794a48636d393163434936496c41794e5459694c434a44496a6f69533035305a5559325448593056553168543341766148637955584a4b65545a68626b3177527939794f464e78576a59356158646d636a6c4f535430694c434a4d59574a6c62434936496b464251554642515546425155464251554642515546425155464251554642515546425155464251554642515546425155464251554642515545394969776956534936496b4a45536c6c7a51334e7a623055334d6e6444574846474e557056634770585a573157596e565265544d796431526d4d32786c636c705a647a4671536e6c47627a5256615735744e6d773355456855546e6b7962324e746155686f626c51354d564a6a4e6e5230656c70766147644255326372545430694c434a5658324a6863694936496b4a4961544e69627a5a45536d396a4d324d344d6c46614d5852724c325645536b4a484d336c5a556d783555306834576d684954697472623264575a306f33546e4e456232314b5931646853544979616d63305657644f556c526e57465272655570325458706952306c4a617a466e534851314f4430694c434a46496a6f694d7a524956466c354d544e474b307836596e5a584e7a6c314d6d356c655574514e6b397a656e467859335253513239705a315534534652704e4430694c434a47496a6f69557a5132596d6c6952545a584b314176546d744252445677575459796148426862316c6c6330684853556869556c56614e303155556c6f345554306966513d3d222c2253796d43747874223a2253764237652f4a556a552b433358757873384e5378316967454e517759755051623730306a4a6144222c224e6f6e6365223a224d31714b557a6b306b77374767593538227d" +) 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 new file mode 100644 index 00000000000..f25abf9c1d4 --- /dev/null +++ b/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go @@ -0,0 +1,648 @@ +package testutils + +import ( + "encoding/hex" + "encoding/json" + "fmt" + "io" + "math/big" + "math/rand" + "net" + "net/http" + "net/http/httptest" + "net/url" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/onsi/gomega" + "github.com/smartcontractkit/libocr/commontypes" + confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/assets" + "github.com/smartcontractkit/chainlink/v2/core/bridges" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_allow_list" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_client_example" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_coordinator" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_v3_aggregator_contract" + "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/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/functions" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" + functionsConfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" + "github.com/smartcontractkit/chainlink/v2/core/store/models" + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +var nilOpts *bind.CallOpts + +func ptr[T any](v T) *T { return &v } + +var allowListPrivateKey = "0xae78c8b502571dba876742437f8bc78b689cf8518356c0921393d89caaf284ce" + +func SetOracleConfig(t *testing.T, b *backends.SimulatedBackend, owner *bind.TransactOpts, coordinatorContract *functions_coordinator.FunctionsCoordinator, oracles []confighelper2.OracleIdentityExtra, batchSize int, functionsPluginConfig *functionsConfig.ReportingPluginConfig) { + S := make([]int, len(oracles)) + for i := 0; i < len(S); i++ { + S[i] = 1 + } + + reportingPluginConfigBytes, err := functionsConfig.EncodeReportingPluginConfig(&functionsConfig.ReportingPluginConfigWrapper{ + Config: functionsPluginConfig, + }) + require.NoError(t, err) + + signersKeys, transmittersAccounts, f, onchainConfig, offchainConfigVersion, offchainConfig, err := confighelper2.ContractSetConfigArgsForTests( + 2*time.Second, // deltaProgress + 1*time.Second, // deltaResend + 1*time.Second, // deltaRound + 500*time.Millisecond, // deltaGrace + 2*time.Second, // deltaStage + 5, // RMax (maxRounds) + S, // S (schedule of randomized transmission order) + oracles, + reportingPluginConfigBytes, + 200*time.Millisecond, // maxDurationQuery + 200*time.Millisecond, // maxDurationObservation + 200*time.Millisecond, // maxDurationReport + 200*time.Millisecond, // maxDurationAccept + 200*time.Millisecond, // maxDurationTransmit + 1, // f (max faulty oracles) + nil, // empty onChain config + ) + + var signers []common.Address + var transmitters []common.Address + for i := range signersKeys { + signers = append(signers, common.BytesToAddress(signersKeys[i])) + transmitters = append(transmitters, common.HexToAddress(string(transmittersAccounts[i]))) + } + require.NoError(t, err) + + _, err = coordinatorContract.SetConfig( + owner, + signers, + transmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig, + ) + require.NoError(t, err) + CommitWithFinality(b) +} + +func CreateAndFundSubscriptions(t *testing.T, b *backends.SimulatedBackend, owner *bind.TransactOpts, linkToken *link_token_interface.LinkToken, routerContractAddress common.Address, routerContract *functions_router.FunctionsRouter, clientContracts []deployedClientContract, allowListContract *functions_allow_list.TermsOfServiceAllowList) (subscriptionId uint64) { + allowed, err := allowListContract.HasAccess(nilOpts, owner.From, []byte{}) + require.NoError(t, err) + if !allowed { + message, err := allowListContract.GetMessage(nilOpts, owner.From, owner.From) + require.NoError(t, err) + privateKey, err := crypto.HexToECDSA(allowListPrivateKey[2:]) + require.NoError(t, err) + flatSignature, err := crypto.Sign(message[:], privateKey) + require.NoError(t, err) + var r [32]byte + copy(r[:], flatSignature[:32]) + var s [32]byte + copy(s[:], flatSignature[32:64]) + v := flatSignature[65] + allowListContract.AcceptTermsOfService(owner, owner.From, owner.From, r, s, v) + } + + _, err = routerContract.CreateSubscription(owner) + require.NoError(t, err) + + subscriptionID := uint64(1) + + numContracts := len(clientContracts) + for i := 0; i < numContracts; i++ { + _, err = routerContract.AddConsumer(owner, subscriptionID, clientContracts[i].Address) + require.NoError(t, err) + } + + data, err := utils.ABIEncode(`[{"type":"uint64"}]`, subscriptionID) + require.NoError(t, err) + + amount := big.NewInt(0).Mul(big.NewInt(int64(numContracts)), big.NewInt(2e18)) // 2 LINK per client + _, err = linkToken.TransferAndCall(owner, routerContractAddress, amount, data) + require.NoError(t, err) + b.Commit() + + return subscriptionID +} + +const finalityDepth int = 4 + +func CommitWithFinality(b *backends.SimulatedBackend) { + for i := 0; i < finalityDepth; i++ { + b.Commit() + } +} + +type deployedClientContract struct { + Address common.Address + Contract *functions_client_example.FunctionsClientExample +} + +type Coordinator struct { + Address common.Address + Contract *functions_coordinator.FunctionsCoordinator +} + +func StartNewChainWithContracts(t *testing.T, nClients int) (*bind.TransactOpts, *backends.SimulatedBackend, *time.Ticker, Coordinator, Coordinator, []deployedClientContract, common.Address, *functions_router.FunctionsRouter, *link_token_interface.LinkToken, common.Address, *functions_allow_list.TermsOfServiceAllowList) { + owner := testutils.MustNewSimTransactor(t) + owner.GasPrice = big.NewInt(int64(DefaultGasPrice)) + sb := new(big.Int) + sb, _ = sb.SetString("100000000000000000000", 10) // 1 eth + genesisData := core.GenesisAlloc{owner.From: {Balance: sb}} + gasLimit := ethconfig.Defaults.Miner.GasCeil * 2 // 60 M blocks + b := backends.NewSimulatedBackend(genesisData, gasLimit) + b.Commit() + + // Deploy LINK token + linkAddr, _, linkToken, err := link_token_interface.DeployLinkToken(owner, b) + require.NoError(t, err) + + // Deploy mock LINK/ETH price feed + linkEthFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(owner, b, 18, big.NewInt(5_000_000_000_000_000)) + require.NoError(t, err) + + // Deploy Router contract + handleOracleFulfillmentSelectorSlice, err := hex.DecodeString("0ca76175") + require.NoError(t, err) + var handleOracleFulfillmentSelector [4]byte + copy(handleOracleFulfillmentSelector[:], handleOracleFulfillmentSelectorSlice[:4]) + functionsRouterConfig := functions_router.FunctionsRouterConfig{ + MaxConsumersPerSubscription: uint16(100), + AdminFee: big.NewInt(0), + HandleOracleFulfillmentSelector: handleOracleFulfillmentSelector, + MaxCallbackGasLimits: []uint32{300_000, 500_000, 1_000_000}, + GasForCallExactCheck: 5000, + } + routerAddress, _, routerContract, err := functions_router.DeployFunctionsRouter(owner, b, linkAddr, functionsRouterConfig) + require.NoError(t, err) + + // Deploy Allow List contract + privateKey, err := crypto.HexToECDSA(allowListPrivateKey[2:]) + proofSignerPublicKey := crypto.PubkeyToAddress(privateKey.PublicKey) + require.NoError(t, err) + allowListConfig := functions_allow_list.TermsOfServiceAllowListConfig{ + Enabled: false, // TODO: true + SignerPublicKey: proofSignerPublicKey, + } + allowListAddress, _, allowListContract, err := functions_allow_list.DeployTermsOfServiceAllowList(owner, b, allowListConfig) + require.NoError(t, err) + + // Deploy Coordinator contract (matches updateConfig() in FunctionsBilling.sol) + coordinatorConfig := functions_coordinator.FunctionsBillingConfig{ + MaxCallbackGasLimit: uint32(450_000), + FeedStalenessSeconds: uint32(86_400), + GasOverheadBeforeCallback: uint32(325_000), + GasOverheadAfterCallback: uint32(50_000), + RequestTimeoutSeconds: uint32(300), + DonFee: big.NewInt(0), + MaxSupportedRequestDataVersion: uint16(1), + FulfillmentGasPriceOverEstimationBP: uint32(1_000), + FallbackNativePerUnitLink: big.NewInt(5_000_000_000_000_000), + } + require.NoError(t, err) + coordinatorAddress, _, coordinatorContract, err := functions_coordinator.DeployFunctionsCoordinator(owner, b, routerAddress, coordinatorConfig, linkEthFeedAddr) + require.NoError(t, err) + proposalAddress, _, proposalContract, err := functions_coordinator.DeployFunctionsCoordinator(owner, b, routerAddress, coordinatorConfig, linkEthFeedAddr) + require.NoError(t, err) + + // Deploy Client contracts + clientContracts := []deployedClientContract{} + for i := 0; i < nClients; i++ { + clientContractAddress, _, clientContract, err := functions_client_example.DeployFunctionsClientExample(owner, b, routerAddress) + require.NoError(t, err) + clientContracts = append(clientContracts, deployedClientContract{ + Address: clientContractAddress, + Contract: clientContract, + }) + if i%10 == 0 { + // Max 10 requests per block + b.Commit() + } + } + + CommitWithFinality(b) + ticker := time.NewTicker(1 * time.Second) + go func() { + for range ticker.C { + b.Commit() + } + }() + + active := Coordinator{ + Contract: coordinatorContract, + Address: coordinatorAddress, + } + proposed := Coordinator{ + Contract: proposalContract, + Address: proposalAddress, + } + return owner, b, ticker, active, proposed, clientContracts, routerAddress, routerContract, linkToken, allowListAddress, allowListContract +} + +func SetupRouterRoutes(t *testing.T, b *backends.SimulatedBackend, owner *bind.TransactOpts, routerContract *functions_router.FunctionsRouter, coordinatorAddress common.Address, proposedCoordinatorAddress common.Address, allowListAddress common.Address) { + allowListId, err := routerContract.GetAllowListId(nilOpts) + require.NoError(t, err) + var donId [32]byte + copy(donId[:], DefaultDONId) + proposedContractSetIds := []([32]byte){allowListId, donId} + proposedContractSetAddresses := []common.Address{allowListAddress, coordinatorAddress} + _, err = routerContract.ProposeContractsUpdate(owner, proposedContractSetIds, proposedContractSetAddresses) + require.NoError(t, err) + + b.Commit() + + _, err = routerContract.UpdateContracts(owner) + require.NoError(t, err) + b.Commit() + + // prepare next coordinator + proposedContractSetIds = []([32]byte){donId} + proposedContractSetAddresses = []common.Address{proposedCoordinatorAddress} + _, err = routerContract.ProposeContractsUpdate(owner, proposedContractSetIds, proposedContractSetAddresses) + require.NoError(t, err) + b.Commit() +} + +type Node struct { + App *cltest.TestApplication + PeerID string + Transmitter common.Address + Keybundle ocr2key.KeyBundle + OracleIdentity confighelper2.OracleIdentityExtra +} + +func StartNewNode( + t *testing.T, + owner *bind.TransactOpts, + port uint16, + dbName string, + b *backends.SimulatedBackend, + maxGas uint32, + p2pV2Bootstrappers []commontypes.BootstrapperLocator, + ocr2Keystore []byte, + thresholdKeyShare string, +) *Node { + p2pKey, err := p2pkey.NewV2() + require.NoError(t, err) + config, _ := heavyweight.FullTestDBV2(t, fmt.Sprintf("%s%d", dbName, port), func(c *chainlink.Config, s *chainlink.Secrets) { + c.Insecure.OCRDevelopmentMode = ptr(true) + + c.Feature.LogPoller = ptr(true) + + c.OCR.Enabled = ptr(false) + c.OCR2.Enabled = ptr(true) + + c.P2P.PeerID = ptr(p2pKey.PeerID()) + c.P2P.V1.Enabled = ptr(false) + c.P2P.V2.Enabled = ptr(true) + c.P2P.V2.DeltaDial = models.MustNewDuration(500 * time.Millisecond) + c.P2P.V2.DeltaReconcile = models.MustNewDuration(5 * time.Second) + c.P2P.V2.ListenAddresses = &[]string{fmt.Sprintf("127.0.0.1:%d", port)} + if len(p2pV2Bootstrappers) > 0 { + c.P2P.V2.DefaultBootstrappers = &p2pV2Bootstrappers + } + + c.EVM[0].LogPollInterval = models.MustNewDuration(1 * time.Second) + c.EVM[0].Transactions.ForwardersEnabled = ptr(false) + c.EVM[0].GasEstimator.LimitDefault = ptr(maxGas) + c.EVM[0].GasEstimator.Mode = ptr("FixedPrice") + c.EVM[0].GasEstimator.PriceDefault = assets.NewWei(big.NewInt(int64(DefaultGasPrice))) + + if len(thresholdKeyShare) > 0 { + s.Threshold.ThresholdKeyShare = models.NewSecret(thresholdKeyShare) + } + }) + + app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, b, p2pKey) + + sendingKeys, err := app.KeyStore.Eth().EnabledKeysForChain(testutils.SimulatedChainID) + require.NoError(t, err) + require.Len(t, sendingKeys, 1) + transmitter := sendingKeys[0].Address + + // fund the transmitter address + n, err := b.NonceAt(testutils.Context(t), owner.From, nil) + require.NoError(t, err) + + tx := types.NewTransaction( + n, transmitter, + assets.Ether(1).ToInt(), + 21000, + assets.GWei(1).ToInt(), + nil) + signedTx, err := owner.Signer(owner.From, tx) + require.NoError(t, err) + err = b.SendTransaction(testutils.Context(t), signedTx) + require.NoError(t, err) + b.Commit() + + var kb ocr2key.KeyBundle + if ocr2Keystore != nil { + kb, err = app.GetKeyStore().OCR2().Import(ocr2Keystore, "testPassword") + } else { + kb, err = app.GetKeyStore().OCR2().Create("evm") + } + require.NoError(t, err) + + err = app.Start(testutils.Context(t)) + require.NoError(t, err) + + return &Node{ + App: app, + PeerID: p2pKey.PeerID().Raw(), + Transmitter: transmitter, + Keybundle: kb, + OracleIdentity: confighelper2.OracleIdentityExtra{ + OracleIdentity: confighelper2.OracleIdentity{ + OnchainPublicKey: kb.PublicKey(), + TransmitAccount: ocrtypes2.Account(transmitter.String()), + OffchainPublicKey: kb.OffchainPublicKey(), + PeerID: p2pKey.PeerID().Raw(), + }, + ConfigEncryptionPublicKey: kb.ConfigEncryptionPublicKey(), + }, + } +} + +func AddBootstrapJob(t *testing.T, app *cltest.TestApplication, contractAddress common.Address) job.Job { + job, err := ocrbootstrap.ValidatedBootstrapSpecToml(fmt.Sprintf(` + type = "bootstrap" + name = "functions-bootstrap" + schemaVersion = 1 + relay = "evm" + contractConfigConfirmations = 1 + contractConfigTrackerPollInterval = "1s" + contractID = "%s" + + [relayConfig] + chainID = 1337 + fromBlock = 1 + donID = "%s" + contractVersion = 1 + contractUpdateCheckFrequencySec = 1 + + `, contractAddress, DefaultDONId)) + require.NoError(t, err) + err = app.AddJobV2(testutils.Context(t), &job) + require.NoError(t, err) + return job +} + +func AddOCR2Job(t *testing.T, app *cltest.TestApplication, contractAddress common.Address, keyBundleID string, transmitter common.Address, bridgeURL string) job.Job { + u, err := url.Parse(bridgeURL) + require.NoError(t, err) + require.NoError(t, app.BridgeORM().CreateBridgeType(&bridges.BridgeType{ + Name: "ea_bridge", + URL: models.WebURL(*u), + })) + job, err := validate.ValidatedOracleSpecToml(app.Config.OCR2(), app.Config.Insecure(), fmt.Sprintf(` + type = "offchainreporting2" + name = "functions-node" + schemaVersion = 1 + relay = "evm" + contractID = "%s" + ocrKeyBundleID = "%s" + transmitterID = "%s" + contractConfigConfirmations = 1 + contractConfigTrackerPollInterval = "1s" + pluginType = "functions" + observationSource = """ + run_computation [type="bridge" name="ea_bridge" requestData="{\\"note\\": \\"observationSource is unused but the bridge is required\\"}"] + run_computation + """ + + [relayConfig] + chainID = 1337 + fromBlock = 1 + + [pluginConfig] + donID = "%s" + contractVersion = 1 + minIncomingConfirmations = 3 + requestTimeoutSec = 300 + requestTimeoutCheckFrequencySec = 10 + requestTimeoutBatchLookupSize = 20 + listenerEventHandlerTimeoutSec = 120 + listenerEventsCheckFrequencyMillis = 1000 + maxRequestSizeBytes = 30720 + contractUpdateCheckFrequencySec = 1 + + [pluginConfig.decryptionQueueConfig] + completedCacheTimeoutSec = 300 + maxCiphertextBytes = 10_000 + maxCiphertextIdLength = 100 + maxQueueLength = 100 + decryptRequestTimeoutSec = 100 + + [pluginConfig.s4Constraints] + maxPayloadSizeBytes = 10_1000 + maxSlotsPerUser = 10 + `, contractAddress, keyBundleID, transmitter, DefaultDONId)) + require.NoError(t, err) + err = app.AddJobV2(testutils.Context(t), &job) + require.NoError(t, err) + return job +} + +func StartNewMockEA(t *testing.T) *httptest.Server { + return httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { + b, err := io.ReadAll(req.Body) + require.NoError(t, err) + var jsonMap map[string]any + require.NoError(t, json.Unmarshal(b, &jsonMap)) + var responsePayload []byte + if jsonMap["endpoint"].(string) == "lambda" { + responsePayload = mockEALambdaExecutionResponse(t, jsonMap) + } else if jsonMap["endpoint"].(string) == "fetcher" { + responsePayload = mockEASecretsFetchResponse(t, jsonMap) + } else { + require.Fail(t, "unknown external adapter endpoint '%s'", jsonMap["endpoint"].(string)) + } + res.WriteHeader(http.StatusOK) + _, err = res.Write(responsePayload) + require.NoError(t, err) + })) +} + +func mockEALambdaExecutionResponse(t *testing.T, request map[string]any) []byte { + data := request["data"].(map[string]any) + require.Equal(t, functions.LanguageJavaScript, int(data["language"].(float64))) + require.Equal(t, functions.LocationInline, int(data["codeLocation"].(float64))) + require.Equal(t, functions.LocationRemote, int(data["secretsLocation"].(float64))) + if data["secrets"] != DefaultSecretsBase64 && request["nodeProvidedSecrets"] != fmt.Sprintf(`{"0x0":"%s"}`, DefaultSecretsBase64) { + assert.Fail(t, "expected secrets or nodeProvidedSecrets to be '%s'", DefaultSecretsBase64) + } + args := data["args"].([]interface{}) + require.Equal(t, 2, len(args)) + require.Equal(t, DefaultArg1, args[0].(string)) + require.Equal(t, DefaultArg2, args[1].(string)) + source := data["source"].(string) + // prepend "0xab" to source and return as result + return []byte(fmt.Sprintf(`{"result": "success", "statusCode": 200, "data": {"result": "0xab%s", "error": ""}}`, source)) +} + +func mockEASecretsFetchResponse(t *testing.T, request map[string]any) []byte { + data := request["data"].(map[string]any) + require.Equal(t, "fetchThresholdEncryptedSecrets", data["requestType"]) + require.Equal(t, DefaultSecretsUrlsBase64, data["encryptedSecretsUrls"]) + return []byte(fmt.Sprintf(`{"result": "success", "statusCode": 200, "data": {"result": "%s", "error": ""}}`, DefaultThresholdSecretsHex)) +} + +// Mock EA prepends 0xab to source and user contract crops the answer to first 32 bytes +func GetExpectedResponse(source []byte) [32]byte { + var resp [32]byte + resp[0] = 0xab + for j := 0; j < 31; j++ { + if j >= len(source) { + break + } + resp[j+1] = source[j] + } + return resp +} + +func CreateFunctionsNodes( + t *testing.T, + owner *bind.TransactOpts, + b *backends.SimulatedBackend, + routerAddress common.Address, + nOracleNodes int, + maxGas int, + ocr2Keystores [][]byte, + thresholdKeyShares []string, +) (bootstrapNode *Node, oracleNodes []*cltest.TestApplication, oracleIdentites []confighelper2.OracleIdentityExtra) { + t.Helper() + + if len(thresholdKeyShares) != 0 && len(thresholdKeyShares) != nOracleNodes { + require.Fail(t, "thresholdKeyShares must be empty or have length equal to nOracleNodes") + } + if len(ocr2Keystores) != 0 && len(ocr2Keystores) != nOracleNodes { + require.Fail(t, "ocr2Keystores must be empty or have length equal to nOracleNodes") + } + if len(ocr2Keystores) != len(thresholdKeyShares) { + require.Fail(t, "ocr2Keystores and thresholdKeyShares must have the same length") + } + + bootstrapPort := getFreePort(t) + bootstrapNode = StartNewNode(t, owner, bootstrapPort, "bootstrap", b, uint32(maxGas), nil, nil, "") + AddBootstrapJob(t, bootstrapNode.App, routerAddress) + + // oracle nodes with jobs, bridges and mock EAs + for i := 0; i < nOracleNodes; i++ { + var thresholdKeyShare string + if len(thresholdKeyShares) == 0 { + thresholdKeyShare = "" + } else { + thresholdKeyShare = thresholdKeyShares[i] + } + var ocr2Keystore []byte + if len(ocr2Keystores) == 0 { + ocr2Keystore = nil + } else { + ocr2Keystore = ocr2Keystores[i] + } + nodePort := getFreePort(t) + oracleNode := StartNewNode(t, owner, nodePort, fmt.Sprintf("oracle%d", i), b, uint32(maxGas), []commontypes.BootstrapperLocator{ + {PeerID: bootstrapNode.PeerID, Addrs: []string{fmt.Sprintf("127.0.0.1:%d", bootstrapPort)}}, + }, ocr2Keystore, thresholdKeyShare) + oracleNodes = append(oracleNodes, oracleNode.App) + oracleIdentites = append(oracleIdentites, oracleNode.OracleIdentity) + + ea := StartNewMockEA(t) + t.Cleanup(ea.Close) + + _ = AddOCR2Job(t, oracleNodes[i], routerAddress, oracleNode.Keybundle.ID(), oracleNode.Transmitter, ea.URL) + } + + return bootstrapNode, oracleNodes, oracleIdentites +} + +// NOTE: This approach is technically incorrect because the returned port +// can still be taken by the time the caller attempts to bind to it. +// Unfortunately, we can't specify zero port in P2P.V2.ListenAddresses at the moment. +func getFreePort(t *testing.T) uint16 { + addr, err := net.ResolveTCPAddr("tcp", "localhost:0") + require.NoError(t, err) + listener, err := net.ListenTCP("tcp", addr) + require.NoError(t, err) + require.NoError(t, listener.Close()) + return uint16(listener.Addr().(*net.TCPAddr).Port) +} + +func ClientTestRequests( + t *testing.T, + owner *bind.TransactOpts, + b *backends.SimulatedBackend, + linkToken *link_token_interface.LinkToken, + routerAddress common.Address, + routerContract *functions_router.FunctionsRouter, + allowListContract *functions_allow_list.TermsOfServiceAllowList, + clientContracts []deployedClientContract, + requestLenBytes int, + expectedSecrets []byte, + subscriptionId uint64, + timeout time.Duration, +) { + t.Helper() + var donId [32]byte + copy(donId[:], []byte(DefaultDONId)) + // send requests + requestSources := make([][]byte, len(clientContracts)) + rnd := rand.New(rand.NewSource(666)) + for i, client := range clientContracts { + requestSources[i] = make([]byte, requestLenBytes) + for j := 0; j < requestLenBytes; j++ { + requestSources[i][j] = byte(rnd.Uint32() % 256) + } + _, err := client.Contract.SendRequest( + owner, + hex.EncodeToString(requestSources[i]), + expectedSecrets, + []string{DefaultArg1, DefaultArg2}, + subscriptionId, + donId, + ) + require.NoError(t, err) + } + CommitWithFinality(b) + + // validate that all client contracts got correct responses to their requests + var wg sync.WaitGroup + for i := 0; i < len(clientContracts); i++ { + ic := i + wg.Add(1) + go func() { + defer wg.Done() + gomega.NewGomegaWithT(t).Eventually(func() [32]byte { + answer, err := clientContracts[ic].Contract.SLastResponse(nil) + require.NoError(t, err) + return answer + }, timeout, 1*time.Second).Should(gomega.Equal(GetExpectedResponse(requestSources[ic]))) + }() + } + wg.Wait() +} diff --git a/core/services/ocr2/plugins/functions/plugin.go b/core/services/ocr2/plugins/functions/plugin.go index cdb0f0111c9..3a13c0caba8 100644 --- a/core/services/ocr2/plugins/functions/plugin.go +++ b/core/services/ocr2/plugins/functions/plugin.go @@ -15,7 +15,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/chains/evm" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/ocr2dr_oracle" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/functions" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/connector" @@ -28,6 +27,7 @@ import ( 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" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -45,6 +45,7 @@ type FunctionsServicesConfig struct { URLsMonEndpoint commontypes.MonitoringEndpoint EthKeystore keystore.Eth ThresholdKeyShare []byte + LogPollerWrapper evmrelayTypes.LogPollerWrapper } const ( @@ -67,11 +68,6 @@ func NewFunctionsServices(functionsOracleArgs, thresholdOracleArgs, s4OracleArgs } allServices := []job.ServiceCtx{} - contractAddress := common.HexToAddress(conf.Job.OCR2OracleSpec.ContractID) - oracleContract, err := ocr2dr_oracle.NewOCR2DROracle(contractAddress, conf.Chain.Client()) - if err != nil { - return nil, errors.Wrapf(err, "Functions: failed to create a FunctionsOracle wrapper for address: %v", contractAddress) - } var decryptor threshold.Decryptor // thresholdOracleArgs nil check will be removed once the Threshold plugin is fully integrated w/ Functions @@ -106,8 +102,9 @@ func NewFunctionsServices(functionsOracleArgs, thresholdOracleArgs, s4OracleArgs listenerLogger := conf.Logger.Named("FunctionsListener") bridgeAccessor := functions.NewBridgeAccessor(conf.BridgeORM, FunctionsBridgeName, MaxAdapterResponseBytes) functionsListener := functions.NewFunctionsListener( - oracleContract, conf.Job, + conf.Chain.Client(), + conf.Job.OCR2OracleSpec.ContractID, bridgeAccessor, pluginORM, pluginConfig, @@ -117,13 +114,15 @@ func NewFunctionsServices(functionsOracleArgs, thresholdOracleArgs, s4OracleArgs conf.MailMon, conf.URLsMonEndpoint, decryptor, + conf.LogPollerWrapper, ) allServices = append(allServices, functionsListener) functionsOracleArgs.ReportingPluginFactory = FunctionsReportingPluginFactory{ - Logger: functionsOracleArgs.Logger, - PluginORM: pluginORM, - JobID: conf.Job.ExternalJobID, + Logger: functionsOracleArgs.Logger, + PluginORM: pluginORM, + JobID: conf.Job.ExternalJobID, + ContractVersion: pluginConfig.ContractVersion, } functionsReportingPluginOracle, err := libocr2.NewOracle(*functionsOracleArgs) if err != nil { diff --git a/core/services/ocr2/plugins/functions/reporting.go b/core/services/ocr2/plugins/functions/reporting.go index 2246cff4ba0..7f532439c6a 100644 --- a/core/services/ocr2/plugins/functions/reporting.go +++ b/core/services/ocr2/plugins/functions/reporting.go @@ -19,20 +19,22 @@ import ( ) type FunctionsReportingPluginFactory struct { - Logger commontypes.Logger - PluginORM functions.ORM - JobID uuid.UUID + Logger commontypes.Logger + PluginORM functions.ORM + JobID uuid.UUID + ContractVersion uint32 } var _ types.ReportingPluginFactory = (*FunctionsReportingPluginFactory)(nil) type functionsReporting struct { - logger commontypes.Logger - pluginORM functions.ORM - jobID uuid.UUID - reportCodec *encoding.ReportCodec - genericConfig *types.ReportingPluginConfig - specificConfig *config.ReportingPluginConfigWrapper + logger commontypes.Logger + pluginORM functions.ORM + jobID uuid.UUID + reportCodec encoding.ReportCodec + genericConfig *types.ReportingPluginConfig + specificConfig *config.ReportingPluginConfigWrapper + contractVersion uint32 } var _ types.ReportingPlugin = &functionsReporting{} @@ -88,7 +90,7 @@ func (f FunctionsReportingPluginFactory) NewReportingPlugin(rpConfig types.Repor }) return nil, types.ReportingPluginInfo{}, err } - codec, err := encoding.NewReportCodec() + codec, err := encoding.NewReportCodec(f.ContractVersion) if err != nil { f.Logger.Error("unable to create a report codec object", commontypes.LogFields{}) return nil, types.ReportingPluginInfo{}, err @@ -103,12 +105,13 @@ func (f FunctionsReportingPluginFactory) NewReportingPlugin(rpConfig types.Repor }, } plugin := functionsReporting{ - logger: f.Logger, - pluginORM: f.PluginORM, - jobID: f.JobID, - reportCodec: codec, - genericConfig: &rpConfig, - specificConfig: pluginConfig, + logger: f.Logger, + pluginORM: f.PluginORM, + jobID: f.JobID, + reportCodec: codec, + genericConfig: &rpConfig, + specificConfig: pluginConfig, + contractVersion: f.ContractVersion, } promReportingPlugins.WithLabelValues(f.JobID.String()).Inc() return &plugin, info, nil @@ -193,12 +196,20 @@ func (r *functionsReporting) Observation(ctx context.Context, ts types.ReportTim // NOTE: ignoring TIMED_OUT requests, which potentially had ready results if localResult.State == functions.RESULT_READY { resultProto := encoding.ProcessedRequest{ - RequestID: localResult.RequestID[:], - Result: localResult.Result, - Error: localResult.Error, + RequestID: localResult.RequestID[:], + Result: localResult.Result, + Error: localResult.Error, + OnchainMetadata: localResult.OnchainMetadata, } - if localResult.CallbackGasLimit != nil { + if r.contractVersion == 1 { + if localResult.CallbackGasLimit == nil || localResult.CoordinatorContractAddress == nil { + r.logger.Error("FunctionsReporting Observation missing required v1 fields", commontypes.LogFields{ + "requestID": formatRequestId(id[:]), + }) + continue + } resultProto.CallbackGasLimit = *localResult.CallbackGasLimit + resultProto.CoordinatorContract = localResult.CoordinatorContractAddress[:] } observationProto.ProcessedRequests = append(observationProto.ProcessedRequests, &resultProto) idStrs = append(idStrs, formatRequestId(localResult.RequestID[:])) @@ -428,12 +439,12 @@ func (r *functionsReporting) ShouldTransmitAcceptedReport(ctx context.Context, t needTransmissionIds = append(needTransmissionIds, reqIdStr) continue } - if request.State == functions.TIMED_OUT || request.State == functions.CONFIRMED { - r.logger.Debug("FunctionsReporting ShouldTransmitAcceptedReport: request is not FINALIZED any more. Not transmitting.", - commontypes.LogFields{ - "requestID": reqIdStr, - "state": request.State.String(), - }) + if request.State == functions.CONFIRMED { + r.logger.Debug("FunctionsReporting ShouldTransmitAcceptedReport: request already CONFIRMED. Not transmitting.", commontypes.LogFields{"requestID": reqIdStr}) + continue + } + if request.State == functions.TIMED_OUT { + r.logger.Debug("FunctionsReporting ShouldTransmitAcceptedReport: request already TIMED_OUT. Not transmitting.", commontypes.LogFields{"requestID": reqIdStr}) continue } if request.State == functions.IN_PROGRESS || request.State == functions.RESULT_READY { diff --git a/core/services/ocr2/plugins/functions/reporting_test.go b/core/services/ocr2/plugins/functions/reporting_test.go index bb0a5239375..e08a0aca7a0 100644 --- a/core/services/ocr2/plugins/functions/reporting_test.go +++ b/core/services/ocr2/plugins/functions/reporting_test.go @@ -4,6 +4,7 @@ import ( "errors" "testing" + "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" @@ -21,18 +22,20 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/encoding" ) -func preparePlugin(t *testing.T, batchSize uint32) (types.ReportingPlugin, *functions_mocks.ORM, *encoding.ReportCodec) { +func preparePlugin(t *testing.T, batchSize uint32, contractVersion uint32, maxTotalGasLimit uint32) (types.ReportingPlugin, *functions_mocks.ORM, encoding.ReportCodec) { lggr := logger.TestLogger(t) ocrLogger := relaylogger.NewOCRWrapper(lggr, true, func(msg string) {}) orm := functions_mocks.NewORM(t) factory := functions.FunctionsReportingPluginFactory{ - Logger: ocrLogger, - PluginORM: orm, + Logger: ocrLogger, + PluginORM: orm, + ContractVersion: contractVersion, } pluginConfig := config.ReportingPluginConfigWrapper{ Config: &config.ReportingPluginConfig{ - MaxRequestBatchSize: batchSize, + MaxRequestBatchSize: batchSize, + MaxReportTotalCallbackGas: maxTotalGasLimit, }, } pluginConfigBytes, err := config.EncodeReportingPluginConfig(&pluginConfig) @@ -43,7 +46,7 @@ func preparePlugin(t *testing.T, batchSize uint32) (types.ReportingPlugin, *func OffchainConfig: pluginConfigBytes, }) require.NoError(t, err) - codec, err := encoding.NewReportCodec() + codec, err := encoding.NewReportCodec(contractVersion) require.NoError(t, err) return plugin, orm, codec } @@ -92,6 +95,17 @@ func newProcessedRequest(requestId functions_srv.RequestID, compResult []byte, c } } +func newProcessedRequestWithMeta(requestId functions_srv.RequestID, compResult []byte, compError []byte, callbackGasLimit uint32, coordinatorContract []byte, onchainMetadata []byte) *encoding.ProcessedRequest { + return &encoding.ProcessedRequest{ + RequestID: requestId[:], + Result: compResult, + Error: compError, + CallbackGasLimit: callbackGasLimit, + CoordinatorContract: coordinatorContract, + OnchainMetadata: onchainMetadata, + } +} + func newObservation(t *testing.T, observerId uint8, requests ...*encoding.ProcessedRequest) types.AttributedObservation { observationProto := encoding.Observation{ProcessedRequests: requests} raw, err := proto.Marshal(&observationProto) @@ -102,10 +116,10 @@ func newObservation(t *testing.T, observerId uint8, requests ...*encoding.Proces } } -func TestDRReporting_Query(t *testing.T) { +func TestFunctionsReporting_Query(t *testing.T) { t.Parallel() const batchSize = 10 - plugin, orm, _ := preparePlugin(t, batchSize) + plugin, orm, _ := preparePlugin(t, batchSize, 0, 0) reqs := []functions_srv.Request{newRequest(), newRequest()} orm.On("FindOldestEntriesByState", functions_srv.RESULT_READY, uint32(batchSize), mock.Anything).Return(reqs, nil) @@ -120,9 +134,9 @@ func TestDRReporting_Query(t *testing.T) { require.Equal(t, reqs[1].RequestID[:], queryProto.RequestIDs[1]) } -func TestDRReporting_Observation(t *testing.T) { +func TestFunctionsReporting_Observation(t *testing.T) { t.Parallel() - plugin, orm, _ := preparePlugin(t, 10) + plugin, orm, _ := preparePlugin(t, 10, 0, 0) req1 := newRequestWithResult([]byte("abc")) req2 := newRequest() @@ -155,9 +169,9 @@ func TestDRReporting_Observation(t *testing.T) { require.Equal(t, observationProto.ProcessedRequests[1].Result, []byte("def")) } -func TestDRReporting_Observation_IncorrectQuery(t *testing.T) { +func TestFunctionsReporting_Observation_IncorrectQuery(t *testing.T) { t.Parallel() - plugin, orm, _ := preparePlugin(t, 10) + plugin, orm, _ := preparePlugin(t, 10, 0, 0) req1 := newRequestWithResult([]byte("abc")) invalidId := []byte("invalid") @@ -182,9 +196,9 @@ func TestDRReporting_Observation_IncorrectQuery(t *testing.T) { require.Equal(t, observationProto.ProcessedRequests[0].Result, []byte("abc")) } -func TestDRReporting_Report(t *testing.T) { +func TestFunctionsReporting_Report(t *testing.T) { t.Parallel() - plugin, _, codec := preparePlugin(t, 10) + plugin, _, codec := preparePlugin(t, 10, 0, 0) reqId1, reqId2, reqId3 := newRequestID(), newRequestID(), newRequestID() compResult := []byte("aaa") procReq1 := newProcessedRequest(reqId1, compResult, []byte{}) @@ -219,9 +233,81 @@ func TestDRReporting_Report(t *testing.T) { require.Equal(t, []byte{}, decoded[1].Error) } -func TestDRReporting_Report_DeterministicOrderOfRequests(t *testing.T) { +func TestFunctionsReporting_Report_WithGasLimitAndMetadata(t *testing.T) { + t.Parallel() + plugin, _, codec := preparePlugin(t, 10, 1, 300000) + reqId1, reqId2, reqId3 := newRequestID(), newRequestID(), newRequestID() + compResult := []byte("aaa") + gasLimit1, gasLimit2 := uint32(100_000), uint32(200_000) + coordinatorContract1, coordinatorContract2 := common.Address{1}, common.Address{2} + meta1, meta2 := []byte("meta1"), []byte("meta2") + procReq1 := newProcessedRequestWithMeta(reqId1, compResult, []byte{}, gasLimit1, coordinatorContract1[:], meta1) + procReq2 := newProcessedRequestWithMeta(reqId2, compResult, []byte{}, gasLimit2, coordinatorContract2[:], meta2) + + query := newMarshalledQuery(t, reqId1, reqId2, reqId3, reqId1, reqId2) // duplicates should be ignored + obs := []types.AttributedObservation{ + newObservation(t, 1, procReq2, procReq1), + newObservation(t, 2, procReq1, procReq2), + newObservation(t, 3, procReq1, procReq2), + } + + produced, reportBytes, err := plugin.Report(testutils.Context(t), types.ReportTimestamp{}, query, obs) + require.True(t, produced) + require.NoError(t, err) + + decoded, err := codec.DecodeReport(reportBytes) + require.NoError(t, err) + require.Equal(t, 2, len(decoded)) + + require.Equal(t, reqId1[:], decoded[0].RequestID) + require.Equal(t, compResult, decoded[0].Result) + require.Equal(t, []byte{}, decoded[0].Error) + require.Equal(t, coordinatorContract1[:], decoded[0].CoordinatorContract) + require.Equal(t, meta1, decoded[0].OnchainMetadata) + // CallbackGasLimit is not ABI-encoded + + require.Equal(t, reqId2[:], decoded[1].RequestID) + require.Equal(t, compResult, decoded[1].Result) + require.Equal(t, []byte{}, decoded[1].Error) + require.Equal(t, coordinatorContract2[:], decoded[1].CoordinatorContract) + require.Equal(t, meta2, decoded[1].OnchainMetadata) + // CallbackGasLimit is not ABI-encoded +} + +func TestFunctionsReporting_Report_CallbackGasLimitExceeded(t *testing.T) { + t.Parallel() + plugin, _, codec := preparePlugin(t, 10, 1, 200000) + reqId1, reqId2 := newRequestID(), newRequestID() + compResult := []byte("aaa") + gasLimit1, gasLimit2 := uint32(100_000), uint32(200_000) + coordinatorContract1, coordinatorContract2 := common.Address{1}, common.Address{2} + procReq1 := newProcessedRequestWithMeta(reqId1, compResult, []byte{}, gasLimit1, coordinatorContract1[:], []byte{}) + procReq2 := newProcessedRequestWithMeta(reqId2, compResult, []byte{}, gasLimit2, coordinatorContract2[:], []byte{}) + + query := newMarshalledQuery(t, reqId1, reqId2) + obs := []types.AttributedObservation{ + newObservation(t, 1, procReq2, procReq1), + newObservation(t, 2, procReq1, procReq2), + newObservation(t, 3, procReq1, procReq2), + } + + produced, reportBytes, err := plugin.Report(testutils.Context(t), types.ReportTimestamp{}, query, obs) + require.True(t, produced) + require.NoError(t, err) + + decoded, err := codec.DecodeReport(reportBytes) + require.NoError(t, err) + // Gas limit is set to 200k per report so we can only fit the first request + require.Equal(t, 1, len(decoded)) + require.Equal(t, reqId1[:], decoded[0].RequestID) + require.Equal(t, compResult, decoded[0].Result) + require.Equal(t, []byte{}, decoded[0].Error) + require.Equal(t, coordinatorContract1[:], decoded[0].CoordinatorContract) +} + +func TestFunctionsReporting_Report_DeterministicOrderOfRequests(t *testing.T) { t.Parallel() - plugin, _, codec := preparePlugin(t, 10) + plugin, _, codec := preparePlugin(t, 10, 0, 0) reqId1, reqId2, reqId3 := newRequestID(), newRequestID(), newRequestID() compResult := []byte("aaa") @@ -248,9 +334,9 @@ func TestDRReporting_Report_DeterministicOrderOfRequests(t *testing.T) { require.Equal(t, 3, len(decoded)) } -func TestDRReporting_Report_IncorrectObservation(t *testing.T) { +func TestFunctionsReporting_Report_IncorrectObservation(t *testing.T) { t.Parallel() - plugin, _, _ := preparePlugin(t, 10) + plugin, _, _ := preparePlugin(t, 10, 0, 0) reqId1 := newRequestID() compResult := []byte("aaa") @@ -265,7 +351,7 @@ func TestDRReporting_Report_IncorrectObservation(t *testing.T) { require.NoError(t, err) } -func getReportBytes(t *testing.T, codec *encoding.ReportCodec, reqs ...functions_srv.Request) []byte { +func getReportBytes(t *testing.T, codec encoding.ReportCodec, reqs ...functions_srv.Request) []byte { var report []*encoding.ProcessedRequest for _, req := range reqs { req := req @@ -276,9 +362,9 @@ func getReportBytes(t *testing.T, codec *encoding.ReportCodec, reqs ...functions return reportBytes } -func TestDRReporting_ShouldAcceptFinalizedReport(t *testing.T) { +func TestFunctionsReporting_ShouldAcceptFinalizedReport(t *testing.T) { t.Parallel() - plugin, orm, codec := preparePlugin(t, 10) + plugin, orm, codec := preparePlugin(t, 10, 0, 0) req1 := newRequestWithResult([]byte("xxx")) // nonexistent req2 := newRequestWithResult([]byte("abc")) @@ -315,9 +401,9 @@ func TestDRReporting_ShouldAcceptFinalizedReport(t *testing.T) { require.True(t, should) } -func TestDRReporting_ShouldTransmitAcceptedReport(t *testing.T) { +func TestFunctionsReporting_ShouldTransmitAcceptedReport(t *testing.T) { t.Parallel() - plugin, orm, codec := preparePlugin(t, 10) + plugin, orm, codec := preparePlugin(t, 10, 0, 0) req1 := newRequestWithResult([]byte("xxx")) // nonexistent req2 := newRequestWithResult([]byte("abc")) diff --git a/core/services/ocr2/plugins/median/services.go b/core/services/ocr2/plugins/median/services.go index 6f5f1417152..8ff97c2cc56 100644 --- a/core/services/ocr2/plugins/median/services.go +++ b/core/services/ocr2/plugins/median/services.go @@ -125,7 +125,7 @@ func NewMedianServices(ctx context.Context, } } - var oracle *libocr.Oracle + var oracle libocr.Oracle oracle, err = libocr.NewOracle(argsNoPlugin) if err != nil { abort() diff --git a/core/services/ocr2/plugins/mercury/config/config.go b/core/services/ocr2/plugins/mercury/config/config.go index 69b2e846686..fc5d0a6a20d 100644 --- a/core/services/ocr2/plugins/mercury/config/config.go +++ b/core/services/ocr2/plugins/mercury/config/config.go @@ -12,6 +12,7 @@ import ( pkgerrors "github.com/pkg/errors" "github.com/smartcontractkit/chainlink/v2/core/null" + mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -23,11 +24,14 @@ type PluginConfig struct { // server does not have any previous reports. For a brand new feed, this // effectively sets the "first" validFromBlockNumber. InitialBlockNumber null.Int64 `json:"initialBlockNumber" toml:"initialBlockNumber"` + + LinkFeedID *mercuryutils.FeedID `json:"linkFeedID" toml:"linkFeedID"` + NativeFeedID *mercuryutils.FeedID `json:"nativeFeedID" toml:"nativeFeedID"` } -func ValidatePluginConfig(config PluginConfig) (merr error) { +func ValidatePluginConfig(config PluginConfig, feedID mercuryutils.FeedID) (merr error) { if config.RawServerURL == "" { - merr = errors.New("Mercury: ServerURL must be specified") + merr = errors.New("mercury: ServerURL must be specified") } else { var normalizedURI string if schemeRegexp.MatchString(config.RawServerURL) { @@ -42,9 +46,33 @@ func ValidatePluginConfig(config PluginConfig) (merr error) { merr = pkgerrors.Errorf(`Mercury: invalid scheme specified for MercuryServer, got: %q (scheme: %q) but expected a websocket url e.g. "192.0.2.2:4242" or "wss://192.0.2.2:4242"`, config.RawServerURL, uri.Scheme) } } + if len(config.ServerPubKey) != 32 { - merr = errors.Join(merr, errors.New("Mercury: ServerPubKey is required and must be a 32-byte hex string")) + merr = errors.Join(merr, errors.New("mercury: ServerPubKey is required and must be a 32-byte hex string")) + } + + switch feedID.Version() { + case 1: + if config.LinkFeedID != nil { + merr = errors.Join(merr, errors.New("linkFeedID may not be specified for v1 jobs")) + } + if config.NativeFeedID != nil { + merr = errors.Join(merr, errors.New("nativeFeedID may not be specified for v1 jobs")) + } + case 2, 3: + if config.LinkFeedID == nil { + merr = errors.Join(merr, fmt.Errorf("linkFeedID must be specified for v%d jobs", feedID.Version())) + } + if config.NativeFeedID == nil { + merr = errors.Join(merr, fmt.Errorf("nativeFeedID must be specified for v%d jobs", feedID.Version())) + } + if config.InitialBlockNumber.Valid { + merr = errors.Join(merr, fmt.Errorf("initialBlockNumber may not be specified for v%d jobs", feedID.Version())) + } + default: + merr = errors.Join(merr, fmt.Errorf("got unsupported schema version %d; supported versions are 1,2,3", feedID.Version())) } + return merr } diff --git a/core/services/ocr2/plugins/mercury/config/config_test.go b/core/services/ocr2/plugins/mercury/config/config_test.go index 2b0413d3990..60cc548f1fa 100644 --- a/core/services/ocr2/plugins/mercury/config/config_test.go +++ b/core/services/ocr2/plugins/mercury/config/config_test.go @@ -8,38 +8,130 @@ import ( "github.com/stretchr/testify/require" ) +var v1FeedId = [32]uint8{00, 01, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114} +var v2FeedId = [32]uint8{00, 02, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114} + func Test_PluginConfig(t *testing.T) { - t.Run("with valid values", func(t *testing.T) { - rawToml := ` -ServerURL = "example.com:80" -ServerPubKey = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93" -` + t.Run("Mercury v1", func(t *testing.T) { + t.Run("with valid values", func(t *testing.T) { + rawToml := ` + ServerURL = "example.com:80" + ServerPubKey = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93" + InitialBlockNumber = 1234 + ` + + var mc PluginConfig + err := toml.Unmarshal([]byte(rawToml), &mc) + require.NoError(t, err) + + assert.Equal(t, "example.com:80", mc.RawServerURL) + assert.Equal(t, "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93", mc.ServerPubKey.String()) + assert.Equal(t, int64(1234), mc.InitialBlockNumber.Int64) + + err = ValidatePluginConfig(mc, v1FeedId) + require.NoError(t, err) + }) + + t.Run("with invalid values", func(t *testing.T) { + rawToml := ` + InitialBlockNumber = "invalid" + ` - var mc PluginConfig - err := toml.Unmarshal([]byte(rawToml), &mc) - require.NoError(t, err) + var mc PluginConfig + err := toml.Unmarshal([]byte(rawToml), &mc) + require.Error(t, err) + assert.EqualError(t, err, `toml: strconv.ParseInt: parsing "invalid": invalid syntax`) - assert.Equal(t, "example.com:80", mc.RawServerURL) - assert.Equal(t, "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93", mc.ServerPubKey.String()) + rawToml = ` + ServerURL = "http://example.com" + ServerPubKey = "4242" + ` - err = ValidatePluginConfig(mc) - require.NoError(t, err) + err = toml.Unmarshal([]byte(rawToml), &mc) + require.NoError(t, err) + + err = ValidatePluginConfig(mc, v1FeedId) + require.Error(t, err) + assert.Contains(t, err.Error(), `Mercury: invalid scheme specified for MercuryServer, got: "http://example.com" (scheme: "http") but expected a websocket url e.g. "192.0.2.2:4242" or "wss://192.0.2.2:4242"`) + assert.Contains(t, err.Error(), `mercury: ServerPubKey is required and must be a 32-byte hex string`) + }) + + t.Run("with unnecessary values", func(t *testing.T) { + rawToml := ` + ServerURL = "example.com:80" + ServerPubKey = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93" + LinkFeedID = "0x00026b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472" + ` + + var mc PluginConfig + err := toml.Unmarshal([]byte(rawToml), &mc) + require.NoError(t, err) + + err = ValidatePluginConfig(mc, v1FeedId) + assert.Contains(t, err.Error(), `linkFeedID may not be specified for v1 jobs`) + }) }) - t.Run("invalid values", func(t *testing.T) { - rawToml := ` -ServerURL = "http://example.com" -ServerPubKey = "4242" -` + t.Run("Mercury v2/v3", func(t *testing.T) { + t.Run("with valid values", func(t *testing.T) { + rawToml := ` + ServerURL = "example.com:80" + ServerPubKey = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93" + LinkFeedID = "0x00026b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472" + NativeFeedID = "0x00036b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472" + ` + + var mc PluginConfig + err := toml.Unmarshal([]byte(rawToml), &mc) + require.NoError(t, err) + + err = ValidatePluginConfig(mc, v2FeedId) + require.NoError(t, err) + + require.NotNil(t, mc.LinkFeedID) + require.NotNil(t, mc.NativeFeedID) + assert.Equal(t, "0x00026b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472", (*mc.LinkFeedID).String()) + assert.Equal(t, "0x00036b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472", (*mc.NativeFeedID).String()) + + }) + + t.Run("with invalid values", func(t *testing.T) { + var mc PluginConfig + + rawToml := `LinkFeedID = "test"` + err := toml.Unmarshal([]byte(rawToml), &mc) + assert.Contains(t, err.Error(), "toml: hash: expected a hex string starting with '0x'") + + rawToml = `LinkFeedID = "0xtest"` + err = toml.Unmarshal([]byte(rawToml), &mc) + assert.Contains(t, err.Error(), `toml: hash: UnmarshalText failed: encoding/hex: invalid byte: U+0074 't'`) + + rawToml = ` + ServerURL = "example.com:80" + ServerPubKey = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93" + LinkFeedID = "0x00026b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472" + ` + err = toml.Unmarshal([]byte(rawToml), &mc) + require.NoError(t, err) + + err = ValidatePluginConfig(mc, v2FeedId) + assert.Contains(t, err.Error(), "nativeFeedID must be specified for v2 jobs") + }) + + t.Run("with unnecessary values", func(t *testing.T) { + rawToml := ` + ServerURL = "example.com:80" + ServerPubKey = "724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93" + InitialBlockNumber = 1234 + ` - var mc PluginConfig - err := toml.Unmarshal([]byte(rawToml), &mc) - require.NoError(t, err) + var mc PluginConfig + err := toml.Unmarshal([]byte(rawToml), &mc) + require.NoError(t, err) - err = ValidatePluginConfig(mc) - require.Error(t, err) - assert.Contains(t, err.Error(), `Mercury: invalid scheme specified for MercuryServer, got: "http://example.com" (scheme: "http") but expected a websocket url e.g. "192.0.2.2:4242" or "wss://192.0.2.2:4242"`) - assert.Contains(t, err.Error(), `Mercury: ServerPubKey is required and must be a 32-byte hex string`) + err = ValidatePluginConfig(mc, v2FeedId) + assert.Contains(t, err.Error(), `initialBlockNumber may not be specified for v2 jobs`) + }) }) } diff --git a/core/services/ocr2/plugins/mercury/helpers_test.go b/core/services/ocr2/plugins/mercury/helpers_test.go new file mode 100644 index 00000000000..e93f161916a --- /dev/null +++ b/core/services/ocr2/plugins/mercury/helpers_test.go @@ -0,0 +1,465 @@ +package mercury_test + +import ( + "context" + "crypto/ed25519" + "encoding/binary" + "errors" + "fmt" + "math/big" + "net" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/wsrpc" + "github.com/smartcontractkit/wsrpc/credentials" + "github.com/smartcontractkit/wsrpc/peer" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + "go.uber.org/zap/zaptest/observer" + + "github.com/smartcontractkit/libocr/commontypes" + + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/csakey" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" + "github.com/smartcontractkit/chainlink/v2/core/utils" + + relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" + + "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/keystest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/store/models" +) + +var _ pb.MercuryServer = &mercuryServer{} + +type request struct { + pk credentials.StaticSizedPublicKey + req *pb.TransmitRequest +} + +type mercuryServer struct { + privKey ed25519.PrivateKey + reqsCh chan request + t *testing.T +} + +func NewMercuryServer(t *testing.T, privKey ed25519.PrivateKey, reqsCh chan request) *mercuryServer { + return &mercuryServer{privKey, reqsCh, t} +} + +func (s *mercuryServer) Transmit(ctx context.Context, req *pb.TransmitRequest) (*pb.TransmitResponse, error) { + p, ok := peer.FromContext(ctx) + if !ok { + return nil, errors.New("could not extract public key") + } + r := request{p.PublicKey, req} + s.reqsCh <- r + + return &pb.TransmitResponse{ + Code: 1, + Error: "", + }, nil +} + +func (s *mercuryServer) LatestReport(ctx context.Context, lrr *pb.LatestReportRequest) (*pb.LatestReportResponse, error) { + p, ok := peer.FromContext(ctx) + if !ok { + return nil, errors.New("could not extract public key") + } + s.t.Logf("mercury server got latest report from %x for feed id 0x%x", p.PublicKey, lrr.FeedId) + + out := new(pb.LatestReportResponse) + out.Report = new(pb.Report) + out.Report.FeedId = lrr.FeedId + + price := big.NewInt(123456789) + encodedPrice, _ := relaymercury.EncodeValueInt192(price) + out.Report.Price = encodedPrice + return out, nil +} + +func startMercuryServer(t *testing.T, srv *mercuryServer, pubKeys []ed25519.PublicKey) (serverURL string) { + // Set up the wsrpc server + lis, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatalf("[MAIN] failed to listen: %v", err) + } + serverURL = lis.Addr().String() + s := wsrpc.NewServer(wsrpc.Creds(srv.privKey, pubKeys)) + + // Register mercury implementation with the wsrpc server + pb.RegisterMercuryServer(s, srv) + + // Start serving + go s.Serve(lis) + t.Cleanup(s.Stop) + + return +} + +type Feed struct { + name string + id [32]byte + baseBenchmarkPrice *big.Int + baseBid *big.Int + baseAsk *big.Int +} + +func randomFeedID(version uint16) [32]byte { + id := [32]byte(utils.NewHash()) + binary.BigEndian.PutUint16(id[:2], version) + return id +} + +type Node struct { + App chainlink.Application + ClientPubKey credentials.StaticSizedPublicKey + KeyBundle ocr2key.KeyBundle +} + +func (node *Node) AddJob(t *testing.T, spec string) { + c := node.App.GetConfig() + job, err := validate.ValidatedOracleSpecToml(c.OCR2(), c.Insecure(), spec) + require.NoError(t, err) + err = node.App.AddJobV2(context.Background(), &job) + require.NoError(t, err) +} + +func (node *Node) AddBootstrapJob(t *testing.T, spec string) { + job, err := ocrbootstrap.ValidatedBootstrapSpecToml(spec) + require.NoError(t, err) + err = node.App.AddJobV2(context.Background(), &job) + require.NoError(t, err) +} + +func setupNode( + t *testing.T, + port int64, + dbName string, + p2pV2Bootstrappers []commontypes.BootstrapperLocator, + backend *backends.SimulatedBackend, + csaKey csakey.KeyV2, +) (app chainlink.Application, peerID string, clientPubKey credentials.StaticSizedPublicKey, ocr2kb ocr2key.KeyBundle, observedLogs *observer.ObservedLogs) { + k := big.NewInt(port) // keys unique to port + p2pKey := p2pkey.MustNewV2XXXTestingOnly(k) + rdr := keystest.NewRandReaderFromSeed(port) + ocr2kb = ocr2key.MustNewInsecure(rdr, chaintype.EVM) + + p2paddresses := []string{fmt.Sprintf("127.0.0.1:%d", port)} + + config, _ := heavyweight.FullTestDBV2(t, fmt.Sprintf("%s%d", dbName, port), func(c *chainlink.Config, s *chainlink.Secrets) { + // [JobPipeline] + // MaxSuccessfulRuns = 0 + c.JobPipeline.MaxSuccessfulRuns = ptr(uint64(0)) + + // [Feature] + // UICSAKeys=true + // LogPoller = true + // FeedsManager = false + c.Feature.UICSAKeys = ptr(true) + c.Feature.LogPoller = ptr(true) + c.Feature.FeedsManager = ptr(false) + + // [OCR] + // Enabled = false + c.OCR.Enabled = ptr(false) + + // [OCR2] + // Enabled = true + c.OCR2.Enabled = ptr(true) + + // [P2P] + // PeerID = '$PEERID' + // TraceLogging = true + c.P2P.PeerID = ptr(p2pKey.PeerID()) + c.P2P.TraceLogging = ptr(true) + + // [P2P.V1] + // Enabled = false + c.P2P.V1.Enabled = ptr(false) + + // [P2P.V2] + // Enabled = true + // AnnounceAddresses = ['$EXT_IP:17775'] + // ListenAddresses = ['127.0.0.1:17775'] + // DeltaDial = 500ms + // DeltaReconcile = 5s + c.P2P.V2.Enabled = ptr(true) + c.P2P.V2.AnnounceAddresses = &p2paddresses + c.P2P.V2.ListenAddresses = &p2paddresses + c.P2P.V2.DeltaDial = models.MustNewDuration(500 * time.Millisecond) + c.P2P.V2.DeltaReconcile = models.MustNewDuration(5 * time.Second) + }) + + lggr, observedLogs := logger.TestLoggerObserved(t, zapcore.DebugLevel) + app = cltest.NewApplicationWithConfigV2OnSimulatedBlockchain(t, config, backend, p2pKey, ocr2kb, csaKey, lggr.Named(dbName)) + err := app.Start(testutils.Context(t)) + require.NoError(t, err) + + t.Cleanup(func() { + assert.NoError(t, app.Stop()) + }) + + return app, p2pKey.PeerID().Raw(), csaKey.StaticSizedPublicKey(), ocr2kb, observedLogs +} + +func ptr[T any](t T) *T { return &t } + +func addBootstrapJob(t *testing.T, bootstrapNode Node, chainID *big.Int, verifierAddress common.Address, feedName string, feedID [32]byte) { + bootstrapNode.AddBootstrapJob(t, fmt.Sprintf(` +type = "bootstrap" +relay = "evm" +schemaVersion = 1 +name = "boot-%s" +contractID = "%s" +feedID = "0x%x" +contractConfigTrackerPollInterval = "1s" + +[relayConfig] +chainID = %d + `, feedName, verifierAddress, feedID, chainID)) +} + +func addV1MercuryJob( + t *testing.T, + node Node, + i int, + verifierAddress common.Address, + bootstrapPeerID string, + bootstrapNodePort int64, + bmBridge, + bidBridge, + askBridge, + serverURL string, + serverPubKey, + clientPubKey ed25519.PublicKey, + feedName string, + feedID [32]byte, + chainID *big.Int, + fromBlock int, +) { + node.AddJob(t, fmt.Sprintf(` +type = "offchainreporting2" +schemaVersion = 1 +name = "mercury-%[1]d-%[14]s" +forwardingAllowed = false +maxTaskDuration = "1s" +contractID = "%[2]s" +feedID = "0x%[11]x" +contractConfigTrackerPollInterval = "1s" +ocrKeyBundleID = "%[3]s" +p2pv2Bootstrappers = [ + "%[4]s" +] +relay = "evm" +pluginType = "mercury" +transmitterID = "%[10]x" +observationSource = """ + // Benchmark Price + price1 [type=bridge name="%[5]s" timeout="50ms" requestData="{\\"data\\":{\\"from\\":\\"ETH\\",\\"to\\":\\"USD\\"}}"]; + price1_parse [type=jsonparse path="result"]; + price1_multiply [type=multiply times=100000000 index=0]; + + price1 -> price1_parse -> price1_multiply; + + // Bid + bid [type=bridge name="%[6]s" timeout="50ms" requestData="{\\"data\\":{\\"from\\":\\"ETH\\",\\"to\\":\\"USD\\"}}"]; + bid_parse [type=jsonparse path="result"]; + bid_multiply [type=multiply times=100000000 index=1]; + + bid -> bid_parse -> bid_multiply; + + // Ask + ask [type=bridge name="%[7]s" timeout="50ms" requestData="{\\"data\\":{\\"from\\":\\"ETH\\",\\"to\\":\\"USD\\"}}"]; + ask_parse [type=jsonparse path="result"]; + ask_multiply [type=multiply times=100000000 index=2]; + + ask -> ask_parse -> ask_multiply; +""" + +[pluginConfig] +serverURL = "%[8]s" +serverPubKey = "%[9]x" +initialBlockNumber = %[13]d + +[relayConfig] +chainID = %[12]d + + `, + i, + verifierAddress, + node.KeyBundle.ID(), + fmt.Sprintf("%s@127.0.0.1:%d", bootstrapPeerID, bootstrapNodePort), + bmBridge, + bidBridge, + askBridge, + serverURL, + serverPubKey, + clientPubKey, + feedID, + chainID, + fromBlock, + feedName, + )) +} + +func addV2MercuryJob( + t *testing.T, + node Node, + i int, + verifierAddress common.Address, + bootstrapPeerID string, + bootstrapNodePort int64, + bmBridge, + serverURL string, + serverPubKey, + clientPubKey ed25519.PublicKey, + feedName string, + feedID [32]byte, + linkFeedID [32]byte, + nativeFeedID [32]byte, +) { + node.AddJob(t, fmt.Sprintf(` +type = "offchainreporting2" +schemaVersion = 1 +name = "mercury-%[1]d-%[10]s" +forwardingAllowed = false +maxTaskDuration = "1s" +contractID = "%[2]s" +feedID = "0x%[9]x" +contractConfigTrackerPollInterval = "1s" +ocrKeyBundleID = "%[3]s" +p2pv2Bootstrappers = [ + "%[4]s" +] +relay = "evm" +pluginType = "mercury" +transmitterID = "%[8]x" +observationSource = """ + // Benchmark Price + price1 [type=bridge name="%[5]s" timeout="50ms" requestData="{\\"data\\":{\\"from\\":\\"ETH\\",\\"to\\":\\"USD\\"}}"]; + price1_parse [type=jsonparse path="result"]; + price1_multiply [type=multiply times=100000000 index=0]; + + price1 -> price1_parse -> price1_multiply; +""" + +[pluginConfig] +serverURL = "%[6]s" +serverPubKey = "%[7]x" +linkFeedID = "0x%[11]x" +nativeFeedID = "0x%[12]x" + +[relayConfig] +chainID = 1337 + `, + i, + verifierAddress, + node.KeyBundle.ID(), + fmt.Sprintf("%s@127.0.0.1:%d", bootstrapPeerID, bootstrapNodePort), + bmBridge, + serverURL, + serverPubKey, + clientPubKey, + feedID, + feedName, + linkFeedID, + nativeFeedID, + )) +} + +func addV3MercuryJob( + t *testing.T, + node Node, + i int, + verifierAddress common.Address, + bootstrapPeerID string, + bootstrapNodePort int64, + bmBridge, + bidBridge, + askBridge, + serverURL string, + serverPubKey, + clientPubKey ed25519.PublicKey, + feedName string, + feedID [32]byte, + linkFeedID [32]byte, + nativeFeedID [32]byte, +) { + node.AddJob(t, fmt.Sprintf(` +type = "offchainreporting2" +schemaVersion = 1 +name = "mercury-%[1]d-%[12]s" +forwardingAllowed = false +maxTaskDuration = "1s" +contractID = "%[2]s" +feedID = "0x%[11]x" +contractConfigTrackerPollInterval = "1s" +ocrKeyBundleID = "%[3]s" +p2pv2Bootstrappers = [ + "%[4]s" +] +relay = "evm" +pluginType = "mercury" +transmitterID = "%[10]x" +observationSource = """ + // Benchmark Price + price1 [type=bridge name="%[5]s" timeout="50ms" requestData="{\\"data\\":{\\"from\\":\\"ETH\\",\\"to\\":\\"USD\\"}}"]; + price1_parse [type=jsonparse path="result"]; + price1_multiply [type=multiply times=100000000 index=0]; + + price1 -> price1_parse -> price1_multiply; + + // Bid + bid [type=bridge name="%[6]s" timeout="50ms" requestData="{\\"data\\":{\\"from\\":\\"ETH\\",\\"to\\":\\"USD\\"}}"]; + bid_parse [type=jsonparse path="result"]; + bid_multiply [type=multiply times=100000000 index=1]; + + bid -> bid_parse -> bid_multiply; + + // Ask + ask [type=bridge name="%[7]s" timeout="50ms" requestData="{\\"data\\":{\\"from\\":\\"ETH\\",\\"to\\":\\"USD\\"}}"]; + ask_parse [type=jsonparse path="result"]; + ask_multiply [type=multiply times=100000000 index=2]; + + ask -> ask_parse -> ask_multiply; +""" + +[pluginConfig] +serverURL = "%[8]s" +serverPubKey = "%[9]x" +linkFeedID = "0x%[13]x" +nativeFeedID = "0x%[14]x" + +[relayConfig] +chainID = 1337 + `, + i, + verifierAddress, + node.KeyBundle.ID(), + fmt.Sprintf("%s@127.0.0.1:%d", bootstrapPeerID, bootstrapNodePort), + bmBridge, + bidBridge, + askBridge, + serverURL, + serverPubKey, + clientPubKey, + feedID, + feedName, + linkFeedID, + nativeFeedID, + )) +} diff --git a/core/services/ocr2/plugins/mercury/integration_test.go b/core/services/ocr2/plugins/mercury/integration_test.go index 5671b25be78..b75855b8db5 100644 --- a/core/services/ocr2/plugins/mercury/integration_test.go +++ b/core/services/ocr2/plugins/mercury/integration_test.go @@ -1,16 +1,14 @@ package mercury_test import ( - "context" "crypto/ed25519" "encoding/hex" - "errors" + "encoding/json" "fmt" "io" "math" "math/big" "math/rand" - "net" "net/http" "net/http/httptest" "net/url" @@ -19,6 +17,7 @@ import ( "testing" "time" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" @@ -26,10 +25,9 @@ import ( "github.com/shopspring/decimal" "github.com/smartcontractkit/libocr/commontypes" "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + ocr3confighelper "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - "github.com/smartcontractkit/wsrpc" "github.com/smartcontractkit/wsrpc/credentials" - "github.com/smartcontractkit/wsrpc/peer" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" @@ -39,48 +37,98 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/assets" "github.com/smartcontractkit/chainlink/v2/core/bridges" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mercury_verifier" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mercury_verifier_proxy" + token "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/fee_manager" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/reward_manager" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/verifier" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/verifier_proxy" "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/keystest" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/csakey" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" - "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/reportcodec" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" + reportcodecv1 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v1/reportcodec" + reportcodecv2 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v2/reportcodec" + reportcodecv3 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/reportcodec" "github.com/smartcontractkit/chainlink/v2/core/store/models" - "github.com/smartcontractkit/chainlink/v2/core/utils" ) -type Feed struct { - name string - id [32]byte - baseBenchmarkPrice *big.Int - baseBid *big.Int - baseAsk *big.Int +var ( + f = uint8(1) + n = 4 // number of nodes + multiplier int64 = 100000000 + rawOnchainConfig = relaymercury.OnchainConfig{ + Min: big.NewInt(0), + Max: big.NewInt(math.MaxInt64), + } + rawReportingPluginConfig = relaymercury.OffchainConfig{ + ExpirationWindow: 1, + BaseUSDFeeCents: 100, + } +) + +func detectPanicLogs(t *testing.T, logObservers []*observer.ObservedLogs) { + var panicLines []string + for _, observedLogs := range logObservers { + panicLogs := observedLogs.Filter(func(e observer.LoggedEntry) bool { + return e.Level >= zapcore.DPanicLevel + }) + for _, log := range panicLogs.All() { + line := fmt.Sprintf("%v\t%s\t%s\t%s\t%s", log.Time.Format(time.RFC3339), log.Level.CapitalString(), log.LoggerName, log.Caller.TrimmedPath(), log.Message) + panicLines = append(panicLines, line) + } + } + if len(panicLines) > 0 { + t.Errorf("Found logs with DPANIC or higher level:\n%s", strings.Join(panicLines, "\n")) + } } -func randomFeedID() [32]byte { - return [32]byte(utils.NewHash()) +func setupBlockchain(t *testing.T) (*bind.TransactOpts, *backends.SimulatedBackend, *verifier.Verifier, common.Address) { + steve := testutils.MustNewSimTransactor(t) // config contract deployer and owner + genesisData := core.GenesisAlloc{steve.From: {Balance: assets.Ether(1000).ToInt()}} + backend := cltest.NewSimulatedBackend(t, genesisData, uint32(ethconfig.Defaults.Miner.GasCeil)) + backend.Commit() // ensure starting block number at least 1 + stopMining := cltest.Mine(backend, 1*time.Second) // Should be greater than deltaRound since we cannot access old blocks on simulated blockchain + t.Cleanup(stopMining) + + // Deploy contracts + linkTokenAddress, _, linkToken, err := token.DeployLinkToken(steve, backend) + require.NoError(t, err) + _, err = linkToken.Transfer(steve, steve.From, big.NewInt(1000)) + require.NoError(t, err) + nativeTokenAddress, _, nativeToken, err := token.DeployLinkToken(steve, backend) + require.NoError(t, err) + _, err = nativeToken.Transfer(steve, steve.From, big.NewInt(1000)) + require.NoError(t, err) + verifierProxyAddr, _, verifierProxy, err := verifier_proxy.DeployVerifierProxy(steve, backend, common.Address{}) // zero address for access controller disables access control + require.NoError(t, err) + verifierAddress, _, verifier, err := verifier.DeployVerifier(steve, backend, verifierProxyAddr) + require.NoError(t, err) + _, err = verifierProxy.InitializeVerifier(steve, verifierAddress) + require.NoError(t, err) + rewardManagerAddr, _, rewardManager, err := reward_manager.DeployRewardManager(steve, backend, linkTokenAddress) + require.NoError(t, err) + feeManagerAddr, _, _, err := fee_manager.DeployFeeManager(steve, backend, linkTokenAddress, nativeTokenAddress, verifierProxyAddr, rewardManagerAddr) + require.NoError(t, err) + _, err = verifierProxy.SetFeeManager(steve, feeManagerAddr) + require.NoError(t, err) + _, err = rewardManager.SetFeeManager(steve, feeManagerAddr) + require.NoError(t, err) + backend.Commit() + + return steve, backend, verifier, verifierAddress } -func TestIntegration_Mercury(t *testing.T) { +func TestIntegration_MercuryV1(t *testing.T) { t.Parallel() - // test constants - const f = uint8(1) - const n = 4 // number of nodes + var logObservers []*observer.ObservedLogs + t.Cleanup(func() { + detectPanicLogs(t, logObservers) + }) + lggr := logger.TestLogger(t) const fromBlock = 1 // cannot use zero, start from block 1 - const multiplier = 100000000 testStartTimeStamp := uint32(time.Now().Unix()) // test vars @@ -89,24 +137,19 @@ func TestIntegration_Mercury(t *testing.T) { pError := atomic.Int64{} // feeds - btcFeed := Feed{"BTC/USD", randomFeedID(), big.NewInt(20_000 * multiplier), big.NewInt(19_997 * multiplier), big.NewInt(20_004 * multiplier)} - ethFeed := Feed{"ETH/USD", randomFeedID(), big.NewInt(1_568 * multiplier), big.NewInt(1_566 * multiplier), big.NewInt(1_569 * multiplier)} - linkFeed := Feed{"LINK/USD", randomFeedID(), big.NewInt(7150 * multiplier / 1000), big.NewInt(7123 * multiplier / 1000), big.NewInt(7177 * multiplier / 1000)} + btcFeed := Feed{"BTC/USD", randomFeedID(1), big.NewInt(20_000 * multiplier), big.NewInt(19_997 * multiplier), big.NewInt(20_004 * multiplier)} + ethFeed := Feed{"ETH/USD", randomFeedID(1), big.NewInt(1_568 * multiplier), big.NewInt(1_566 * multiplier), big.NewInt(1_569 * multiplier)} + linkFeed := Feed{"LINK/USD", randomFeedID(1), big.NewInt(7150 * multiplier / 1000), big.NewInt(7123 * multiplier / 1000), big.NewInt(7177 * multiplier / 1000)} feeds := []Feed{btcFeed, ethFeed, linkFeed} feedM := make(map[[32]byte]Feed, len(feeds)) for i := range feeds { feedM[feeds[i].id] = feeds[i] } - lggr := logger.TestLogger(t) - reqs := make(chan request) serverKey := csakey.MustNewV2XXXTestingOnly(big.NewInt(-1)) serverPubKey := serverKey.PublicKey srv := NewMercuryServer(t, ed25519.PrivateKey(serverKey.Raw()), reqs) - min := big.NewInt(0) - max := big.NewInt(math.MaxInt64) - clientCSAKeys := make([]csakey.KeyV2, n+1) clientPubKeys := make([]ed25519.PublicKey, n+1) for i := 0; i < n+1; i++ { @@ -118,39 +161,7 @@ func TestIntegration_Mercury(t *testing.T) { serverURL := startMercuryServer(t, srv, clientPubKeys) chainID := testutils.SimulatedChainID - // Setup blockchain - steve := testutils.MustNewSimTransactor(t) // config contract deployer and owner - genesisData := core.GenesisAlloc{steve.From: {Balance: assets.Ether(1000).ToInt()}} - backend := cltest.NewSimulatedBackend(t, genesisData, uint32(ethconfig.Defaults.Miner.GasCeil)) - backend.Commit() // ensure starting block number at least 1 - stopMining := cltest.Mine(backend, 1*time.Second) // Should be greater than deltaRound since we cannot access old blocks on simulated blockchain - t.Cleanup(stopMining) - - // Deploy config contract - verifierProxyAddr, _, verifierProxy, err := mercury_verifier_proxy.DeployMercuryVerifierProxy(steve, backend, common.Address{}) // zero address for access controller disables access control - require.NoError(t, err) - verifierAddress, _, verifier, err := mercury_verifier.DeployMercuryVerifier(steve, backend, verifierProxyAddr) - require.NoError(t, err) - _, err = verifierProxy.InitializeVerifier(steve, verifierAddress) - require.NoError(t, err) - backend.Commit() - - var logObservers []*observer.ObservedLogs - t.Cleanup(func() { - var panicLines []string - for _, observedLogs := range logObservers { - panicLogs := observedLogs.Filter(func(e observer.LoggedEntry) bool { - return e.Level >= zapcore.DPanicLevel - }) - for _, log := range panicLogs.All() { - line := fmt.Sprintf("%v\t%s\t%s\t%s\t%s", log.Time.Format(time.RFC3339), log.Level.CapitalString(), log.LoggerName, log.Caller.TrimmedPath(), log.Message) - panicLines = append(panicLines, line) - } - } - if len(panicLines) > 0 { - t.Errorf("Found logs with DPANIC or higher level:\n%s", strings.Join(panicLines, "\n")) - } - }) + steve, backend, verifier, verifierAddress := setupBlockchain(t) // Setup bootstrap + oracle nodes bootstrapNodePort := int64(19700) @@ -204,7 +215,7 @@ func TestIntegration_Mercury(t *testing.T) { require.NoError(t, err) } else { res.WriteHeader(http.StatusInternalServerError) - resp := fmt.Sprintf(`{"error": "pError test error"}`) + resp := `{"error": "pError test error"}` _, err := res.Write([]byte(resp)) require.NoError(t, err) } @@ -227,7 +238,7 @@ func TestIntegration_Mercury(t *testing.T) { askBridge := createBridge(fmt.Sprintf("ask-%d", j), i, feed.baseAsk, node.App.BridgeORM()) bidBridge := createBridge(fmt.Sprintf("bid-%d", j), i, feed.baseBid, node.App.BridgeORM()) - addMercuryJob( + addV1MercuryJob( t, node, i, @@ -249,24 +260,29 @@ func TestIntegration_Mercury(t *testing.T) { } // Setup config on contract - c := relaymercury.OnchainConfig{Min: min, Max: max} - onchainConfig, err := (relaymercury.StandardOnchainConfigCodec{}).Encode(c) + onchainConfig, err := (relaymercury.StandardOnchainConfigCodec{}).Encode(rawOnchainConfig) require.NoError(t, err) - signers, _, _, onchainConfig, offchainConfigVersion, offchainConfig, err := confighelper.ContractSetConfigArgsForTestsMercuryV02( + reportingPluginConfig, err := json.Marshal(rawReportingPluginConfig) + require.NoError(t, err) + + signers, _, _, onchainConfig, offchainConfigVersion, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsForTestsMercuryV02( 2*time.Second, // DeltaProgress 20*time.Second, // DeltaResend + 400*time.Millisecond, // DeltaInitial 100*time.Millisecond, // DeltaRound 0, // DeltaGrace + 300*time.Millisecond, // DeltaCertifiedCommitRequest 1*time.Minute, // DeltaStage 100, // rMax []int{len(nodes)}, // S oracles, - []byte{}, // reportingPluginConfig []byte, - 250*time.Millisecond, // Max duration observation - int(f), // f + reportingPluginConfig, // reportingPluginConfig []byte, + 250*time.Millisecond, // Max duration observation + int(f), // f onchainConfig, ) + require.NoError(t, err) signerAddresses, err := evm.OnchainPublicKeyToAddress(signers) require.NoError(t, err) @@ -298,13 +314,14 @@ func TestIntegration_Mercury(t *testing.T) { onchainConfig, offchainConfigVersion, offchainConfig, + nil, ) require.NoError(t, err) backend.Commit() } // Bury it with finality depth - ch, err := bootstrapNode.App.GetChains().EVM.Get(testutils.SimulatedChainID) + ch, err := bootstrapNode.App.GetRelayers().LegacyEVMChains().Get(testutils.SimulatedChainID.String()) require.NoError(t, err) finalityDepth := ch.Config().EVM().FinalityDepth() for i := 0; i < int(finalityDepth); i++ { @@ -328,7 +345,7 @@ func TestIntegration_Mercury(t *testing.T) { t.Fatalf("expected payload %#v to contain 'report'", v) } reportElems := make(map[string]interface{}) - err = reportcodec.ReportTypes.UnpackIntoMap(reportElems, report.([]byte)) + err = reportcodecv1.ReportTypes.UnpackIntoMap(reportElems, report.([]byte)) require.NoError(t, err) feedID := ([32]byte)(reportElems["feedId"].([32]uint8)) @@ -339,7 +356,7 @@ func TestIntegration_Mercury(t *testing.T) { continue // already saw all oracles for this feed } - num, err := (&reportcodec.EVMReportCodec{}).CurrentBlockNumFromReport(ocr2types.Report(report.([]byte))) + num, err := (&reportcodecv1.ReportCodec{}).CurrentBlockNumFromReport(ocr2types.Report(report.([]byte))) require.NoError(t, err) currentBlock, err := backend.BlockByNumber(testutils.Context(t), nil) require.NoError(t, err) @@ -392,7 +409,7 @@ func TestIntegration_Mercury(t *testing.T) { t.Fatalf("expected payload %#v to contain 'report'", v) } reportElems := make(map[string]interface{}) - err = reportcodec.ReportTypes.UnpackIntoMap(reportElems, report.([]byte)) + err = reportcodecv1.ReportTypes.UnpackIntoMap(reportElems, report.([]byte)) require.NoError(t, err) feedID := ([32]byte)(reportElems["feedId"].([32]uint8)) @@ -403,7 +420,7 @@ func TestIntegration_Mercury(t *testing.T) { continue // already saw all oracles for this feed } - num, err := (&reportcodec.EVMReportCodec{}).CurrentBlockNumFromReport(ocr2types.Report(report.([]byte))) + num, err := (&reportcodecv1.ReportCodec{}).CurrentBlockNumFromReport(ocr2types.Report(report.([]byte))) require.NoError(t, err) currentBlock, err := backend.BlockByNumber(testutils.Context(t), nil) require.NoError(t, err) @@ -437,253 +454,546 @@ func TestIntegration_Mercury(t *testing.T) { }) } -var _ pb.MercuryServer = &mercuryServer{} +func TestIntegration_MercuryV2(t *testing.T) { + t.Parallel() -type request struct { - pk credentials.StaticSizedPublicKey - req *pb.TransmitRequest -} + var logObservers []*observer.ObservedLogs + t.Cleanup(func() { + detectPanicLogs(t, logObservers) + }) -type mercuryServer struct { - privKey ed25519.PrivateKey - reqsCh chan request - t *testing.T -} + testStartTimeStamp := uint32(time.Now().Unix()) -func NewMercuryServer(t *testing.T, privKey ed25519.PrivateKey, reqsCh chan request) *mercuryServer { - return &mercuryServer{privKey, reqsCh, t} -} + // test vars + // pError is the probability that an EA will return an error instead of a result, as integer percentage + // pError = 0 means it will never return error + pError := atomic.Int64{} -func (s *mercuryServer) Transmit(ctx context.Context, req *pb.TransmitRequest) (*pb.TransmitResponse, error) { - p, ok := peer.FromContext(ctx) - if !ok { - return nil, errors.New("could not extract public key") + // feeds + btcFeed := Feed{ + name: "BTC/USD", + id: randomFeedID(2), + baseBenchmarkPrice: big.NewInt(20_000 * multiplier), + } + ethFeed := Feed{ + name: "ETH/USD", + id: randomFeedID(2), + baseBenchmarkPrice: big.NewInt(1_568 * multiplier), + } + linkFeed := Feed{ + name: "LINK/USD", + id: randomFeedID(2), + baseBenchmarkPrice: big.NewInt(7150 * multiplier / 1000), + } + feeds := []Feed{btcFeed, ethFeed, linkFeed} + feedM := make(map[[32]byte]Feed, len(feeds)) + for i := range feeds { + feedM[feeds[i].id] = feeds[i] } - r := request{p.PublicKey, req} - s.reqsCh <- r - return &pb.TransmitResponse{ - Code: 1, - Error: "", - }, nil -} + reqs := make(chan request) + serverKey := csakey.MustNewV2XXXTestingOnly(big.NewInt(-1)) + serverPubKey := serverKey.PublicKey + srv := NewMercuryServer(t, ed25519.PrivateKey(serverKey.Raw()), reqs) + clientCSAKeys := make([]csakey.KeyV2, n+1) + clientPubKeys := make([]ed25519.PublicKey, n+1) + for i := 0; i < n+1; i++ { + k := big.NewInt(int64(i)) + key := csakey.MustNewV2XXXTestingOnly(k) + clientCSAKeys[i] = key + clientPubKeys[i] = key.PublicKey + } + serverURL := startMercuryServer(t, srv, clientPubKeys) + chainID := testutils.SimulatedChainID -func (s *mercuryServer) LatestReport(ctx context.Context, lrr *pb.LatestReportRequest) (*pb.LatestReportResponse, error) { - // not implemented in test - p, ok := peer.FromContext(ctx) - if !ok { - return nil, errors.New("could not extract public key") + steve, backend, verifier, verifierAddress := setupBlockchain(t) + + // Setup bootstrap + oracle nodes + bootstrapNodePort := int64(20700) + appBootstrap, bootstrapPeerID, _, bootstrapKb, observedLogs := setupNode(t, bootstrapNodePort, "bootstrap_mercury", nil, backend, clientCSAKeys[n]) + bootstrapNode := Node{App: appBootstrap, KeyBundle: bootstrapKb} + logObservers = append(logObservers, observedLogs) + + // Set up n oracles + var ( + oracles []confighelper.OracleIdentityExtra + nodes []Node + ) + for i := int64(0); i < int64(n); i++ { + app, peerID, transmitter, kb, observedLogs := setupNode(t, bootstrapNodePort+i+1, fmt.Sprintf("oracle_mercury%d", i), []commontypes.BootstrapperLocator{ + // Supply the bootstrap IP and port as a V2 peer address + {PeerID: bootstrapPeerID, Addrs: []string{fmt.Sprintf("127.0.0.1:%d", bootstrapNodePort)}}, + }, backend, clientCSAKeys[i]) + + nodes = append(nodes, Node{ + app, transmitter, kb, + }) + + offchainPublicKey, _ := hex.DecodeString(strings.TrimPrefix(kb.OnChainPublicKey(), "0x")) + oracles = append(oracles, confighelper.OracleIdentityExtra{ + OracleIdentity: confighelper.OracleIdentity{ + OnchainPublicKey: offchainPublicKey, + TransmitAccount: ocr2types.Account(fmt.Sprintf("%x", transmitter[:])), + OffchainPublicKey: kb.OffchainPublicKey(), + PeerID: peerID, + }, + ConfigEncryptionPublicKey: kb.ConfigEncryptionPublicKey(), + }) + logObservers = append(logObservers, observedLogs) } - s.t.Logf("mercury server got latest report from %x for feed id 0x%x", p.PublicKey, lrr.FeedId) - return nil, nil -} -func startMercuryServer(t *testing.T, srv *mercuryServer, pubKeys []ed25519.PublicKey) (serverURL string) { - // Set up the wsrpc server - lis, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - t.Fatalf("[MAIN] failed to listen: %v", err) + for _, feed := range feeds { + addBootstrapJob(t, bootstrapNode, chainID, verifierAddress, feed.name, feed.id) } - serverURL = fmt.Sprintf("%s", lis.Addr().String()) - s := wsrpc.NewServer(wsrpc.Creds(srv.privKey, pubKeys)) - // Register mercury implementation with the wsrpc server - pb.RegisterMercuryServer(s, srv) + 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) + require.NoError(t, err) + require.Equal(t, `{"data":{"from":"ETH","to":"USD"}}`, string(b)) - // Start serving - go s.Serve(lis) - t.Cleanup(s.Stop) + r := rand.Int63n(101) + if r > pError.Load() { + res.WriteHeader(http.StatusOK) + val := decimal.NewFromBigInt(p, 0).Div(decimal.NewFromInt(multiplier)).Add(decimal.NewFromInt(int64(i)).Div(decimal.NewFromInt(100))).String() + resp := fmt.Sprintf(`{"result": %s}`, val) + _, err := res.Write([]byte(resp)) + require.NoError(t, err) + } else { + res.WriteHeader(http.StatusInternalServerError) + resp := `{"error": "pError test error"}` + _, err := res.Write([]byte(resp)) + require.NoError(t, err) + } + })) + t.Cleanup(bridge.Close) + u, _ := url.Parse(bridge.URL) + bridgeName = fmt.Sprintf("bridge-%s-%d", name, i) + require.NoError(t, borm.CreateBridgeType(&bridges.BridgeType{ + Name: bridges.BridgeName(bridgeName), + URL: models.WebURL(*u), + })) - return -} + return bridgeName + } -type Node struct { - App chainlink.Application - ClientPubKey credentials.StaticSizedPublicKey - KeyBundle ocr2key.KeyBundle -} + // Add OCR jobs - one per feed on each node + for i, node := range nodes { + for j, feed := range feeds { + bmBridge := createBridge(fmt.Sprintf("benchmarkprice-%d", j), i, feed.baseBenchmarkPrice, node.App.BridgeORM()) + + addV2MercuryJob( + t, + node, + i, + verifierAddress, + bootstrapPeerID, + bootstrapNodePort, + bmBridge, + serverURL, + serverPubKey, + clientPubKeys[i], + feed.name, + feed.id, + randomFeedID(2), + randomFeedID(2), + ) + } + } -func (node *Node) AddJob(t *testing.T, spec string) { - c := node.App.GetConfig() - job, err := validate.ValidatedOracleSpecToml(c.OCR2(), c.Insecure(), spec) + // Setup config on contract + onchainConfig, err := (relaymercury.StandardOnchainConfigCodec{}).Encode(rawOnchainConfig) require.NoError(t, err) - err = node.App.AddJobV2(context.Background(), &job) + + reportingPluginConfig, err := json.Marshal(rawReportingPluginConfig) require.NoError(t, err) -} -func (node *Node) AddBootstrapJob(t *testing.T, spec string) { - job, err := ocrbootstrap.ValidatedBootstrapSpecToml(spec) + signers, _, _, onchainConfig, offchainConfigVersion, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsForTestsMercuryV02( + 2*time.Second, // DeltaProgress + 20*time.Second, // DeltaResend + 400*time.Millisecond, // DeltaInitial + 100*time.Millisecond, // DeltaRound + 0, // DeltaGrace + 300*time.Millisecond, // DeltaCertifiedCommitRequest + 1*time.Minute, // DeltaStage + 100, // rMax + []int{len(nodes)}, // S + oracles, + reportingPluginConfig, // reportingPluginConfig []byte, + 250*time.Millisecond, // Max duration observation + int(f), // f + onchainConfig, + ) + require.NoError(t, err) - err = node.App.AddJobV2(context.Background(), &job) + signerAddresses, err := evm.OnchainPublicKeyToAddress(signers) require.NoError(t, err) -} -func setupNode( - t *testing.T, - port int64, - dbName string, - p2pV2Bootstrappers []commontypes.BootstrapperLocator, - backend *backends.SimulatedBackend, - csaKey csakey.KeyV2, -) (app chainlink.Application, peerID string, clientPubKey credentials.StaticSizedPublicKey, ocr2kb ocr2key.KeyBundle, observedLogs *observer.ObservedLogs) { - k := big.NewInt(port) // keys unique to port - p2pKey := p2pkey.MustNewV2XXXTestingOnly(k) - rdr := keystest.NewRandReaderFromSeed(port) - ocr2kb = ocr2key.MustNewInsecure(rdr, chaintype.EVM) - - p2paddresses := []string{fmt.Sprintf("127.0.0.1:%d", port)} - - config, _ := heavyweight.FullTestDBV2(t, fmt.Sprintf("%s%d", dbName, port), func(c *chainlink.Config, s *chainlink.Secrets) { - // [JobPipeline] - // MaxSuccessfulRuns = 0 - c.JobPipeline.MaxSuccessfulRuns = ptr(uint64(0)) - - // [Feature] - // UICSAKeys=true - // LogPoller = true - // FeedsManager = false - c.Feature.UICSAKeys = ptr(true) - c.Feature.LogPoller = ptr(true) - c.Feature.FeedsManager = ptr(false) - - // [OCR] - // Enabled = false - c.OCR.Enabled = ptr(false) - - // [OCR2] - // Enabled = true - c.OCR2.Enabled = ptr(true) - - // [P2P] - // PeerID = '$PEERID' - // TraceLogging = true - c.P2P.PeerID = ptr(p2pKey.PeerID()) - c.P2P.TraceLogging = ptr(true) - - // [P2P.V1] - // Enabled = false - c.P2P.V1.Enabled = ptr(false) - - // [P2P.V2] - // Enabled = true - // AnnounceAddresses = ['$EXT_IP:17775'] - // ListenAddresses = ['127.0.0.1:17775'] - // DeltaDial = 500ms - // DeltaReconcile = 5s - c.P2P.V2.Enabled = ptr(true) - c.P2P.V2.AnnounceAddresses = &p2paddresses - c.P2P.V2.ListenAddresses = &p2paddresses - c.P2P.V2.DeltaDial = models.MustNewDuration(500 * time.Millisecond) - c.P2P.V2.DeltaReconcile = models.MustNewDuration(5 * time.Second) - }) + offchainTransmitters := make([][32]byte, n) + for i := 0; i < n; i++ { + offchainTransmitters[i] = nodes[i].ClientPubKey + } - lggr, observedLogs := logger.TestLoggerObserved(t, zapcore.DebugLevel) - app = cltest.NewApplicationWithConfigV2OnSimulatedBlockchain(t, config, backend, p2pKey, ocr2kb, csaKey, lggr.Named(dbName)) - err := app.Start(testutils.Context(t)) + for _, feed := range feeds { + _, err = verifier.SetConfig( + steve, + feed.id, + signerAddresses, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig, + nil, + ) + require.NoError(t, err) + backend.Commit() + } + + // Bury it with finality depth + ch, err := bootstrapNode.App.GetRelayers().LegacyEVMChains().Get(testutils.SimulatedChainID.String()) require.NoError(t, err) + finalityDepth := ch.Config().EVM().FinalityDepth() + for i := 0; i < int(finalityDepth); i++ { + backend.Commit() + } - t.Cleanup(func() { - assert.NoError(t, app.Stop()) + runTestSetup := func() { + // Expect at least one report per feed from each oracle + seen := make(map[[32]byte]map[credentials.StaticSizedPublicKey]struct{}) + for i := range feeds { + // feedID will be deleted when all n oracles have reported + seen[feeds[i].id] = make(map[credentials.StaticSizedPublicKey]struct{}, n) + } + + for req := range reqs { + v := make(map[string]interface{}) + err := mercury.PayloadTypes.UnpackIntoMap(v, req.req.Payload) + require.NoError(t, err) + report, exists := v["report"] + if !exists { + t.Fatalf("expected payload %#v to contain 'report'", v) + } + reportElems := make(map[string]interface{}) + err = reportcodecv2.ReportTypes.UnpackIntoMap(reportElems, report.([]byte)) + require.NoError(t, err) + + feedID := ([32]byte)(reportElems["feedId"].([32]uint8)) + feed, exists := feedM[feedID] + require.True(t, exists) + + if _, exists := seen[feedID]; !exists { + continue // already saw all oracles for this feed + } + + expectedFee := relaymercury.CalculateFee(big.NewInt(123456789), rawReportingPluginConfig.BaseUSDFeeCents) + expectedExpiresAt := reportElems["observationsTimestamp"].(uint32) + rawReportingPluginConfig.ExpirationWindow + + assert.GreaterOrEqual(t, int(reportElems["observationsTimestamp"].(uint32)), int(testStartTimeStamp)) + assert.InDelta(t, feed.baseBenchmarkPrice.Int64(), reportElems["benchmarkPrice"].(*big.Int).Int64(), 5000000) + assert.NotZero(t, reportElems["validFromTimestamp"].(uint32)) + assert.GreaterOrEqual(t, reportElems["observationsTimestamp"].(uint32), reportElems["validFromTimestamp"].(uint32)) + assert.Equal(t, expectedExpiresAt, reportElems["expiresAt"].(uint32)) + assert.Equal(t, expectedFee, reportElems["linkFee"].(*big.Int)) + assert.Equal(t, expectedFee, reportElems["nativeFee"].(*big.Int)) + + t.Logf("oracle %x reported for feed %s (0x%x)", req.pk, feed.name, feed.id) + + seen[feedID][req.pk] = struct{}{} + if len(seen[feedID]) == n { + t.Logf("all oracles reported for feed %s (0x%x)", feed.name, feed.id) + delete(seen, feedID) + if len(seen) == 0 { + break // saw all oracles; success! + } + } + } + } + + t.Run("receives at least one report per feed from each oracle when EAs are at 100% reliability", func(t *testing.T) { + runTestSetup() }) - return app, p2pKey.PeerID().Raw(), csaKey.StaticSizedPublicKey(), ocr2kb, observedLogs + t.Run("receives at least one report per feed from each oracle when EAs are at 80% reliability", func(t *testing.T) { + pError.Store(20) + runTestSetup() + }) } -func ptr[T any](t T) *T { return &t } - -func addBootstrapJob(t *testing.T, bootstrapNode Node, chainID *big.Int, verifierAddress common.Address, feedName string, feedID [32]byte) { - bootstrapNode.AddBootstrapJob(t, fmt.Sprintf(` -type = "bootstrap" -relay = "evm" -schemaVersion = 1 -name = "boot-%s" -contractID = "%s" -feedID = "0x%x" -contractConfigTrackerPollInterval = "1s" - -[relayConfig] -chainID = %d - `, feedName, verifierAddress, feedID, chainID)) -} +func TestIntegration_MercuryV3(t *testing.T) { + t.Parallel() + + var logObservers []*observer.ObservedLogs + t.Cleanup(func() { + detectPanicLogs(t, logObservers) + }) + + testStartTimeStamp := uint32(time.Now().Unix()) + + // test vars + // pError is the probability that an EA will return an error instead of a result, as integer percentage + // pError = 0 means it will never return error + pError := atomic.Int64{} + + // feeds + btcFeed := Feed{ + name: "BTC/USD", + id: randomFeedID(3), + baseBenchmarkPrice: big.NewInt(20_000 * multiplier), + baseBid: big.NewInt(19_997 * multiplier), + baseAsk: big.NewInt(20_004 * multiplier), + } + ethFeed := Feed{ + name: "ETH/USD", + id: randomFeedID(3), + baseBenchmarkPrice: big.NewInt(1_568 * multiplier), + baseBid: big.NewInt(1_566 * multiplier), + baseAsk: big.NewInt(1_569 * multiplier), + } + linkFeed := Feed{ + name: "LINK/USD", + id: randomFeedID(3), + baseBenchmarkPrice: big.NewInt(7150 * multiplier / 1000), + baseBid: big.NewInt(7123 * multiplier / 1000), + baseAsk: big.NewInt(7177 * multiplier / 1000), + } + feeds := []Feed{btcFeed, ethFeed, linkFeed} + feedM := make(map[[32]byte]Feed, len(feeds)) + for i := range feeds { + feedM[feeds[i].id] = feeds[i] + } + + reqs := make(chan request) + serverKey := csakey.MustNewV2XXXTestingOnly(big.NewInt(-1)) + serverPubKey := serverKey.PublicKey + srv := NewMercuryServer(t, ed25519.PrivateKey(serverKey.Raw()), reqs) + clientCSAKeys := make([]csakey.KeyV2, n+1) + clientPubKeys := make([]ed25519.PublicKey, n+1) + for i := 0; i < n+1; i++ { + k := big.NewInt(int64(i)) + key := csakey.MustNewV2XXXTestingOnly(k) + clientCSAKeys[i] = key + clientPubKeys[i] = key.PublicKey + } + serverURL := startMercuryServer(t, srv, clientPubKeys) + chainID := testutils.SimulatedChainID + + steve, backend, verifier, verifierAddress := setupBlockchain(t) + + // Setup bootstrap + oracle nodes + bootstrapNodePort := int64(21700) + appBootstrap, bootstrapPeerID, _, bootstrapKb, observedLogs := setupNode(t, bootstrapNodePort, "bootstrap_mercury", nil, backend, clientCSAKeys[n]) + bootstrapNode := Node{App: appBootstrap, KeyBundle: bootstrapKb} + logObservers = append(logObservers, observedLogs) + + // Set up n oracles + var ( + oracles []confighelper.OracleIdentityExtra + nodes []Node + ) + for i := int64(0); i < int64(n); i++ { + app, peerID, transmitter, kb, observedLogs := setupNode(t, bootstrapNodePort+i+1, fmt.Sprintf("oracle_mercury%d", i), []commontypes.BootstrapperLocator{ + // Supply the bootstrap IP and port as a V2 peer address + {PeerID: bootstrapPeerID, Addrs: []string{fmt.Sprintf("127.0.0.1:%d", bootstrapNodePort)}}, + }, backend, clientCSAKeys[i]) + + nodes = append(nodes, Node{ + app, transmitter, kb, + }) + + offchainPublicKey, _ := hex.DecodeString(strings.TrimPrefix(kb.OnChainPublicKey(), "0x")) + oracles = append(oracles, confighelper.OracleIdentityExtra{ + OracleIdentity: confighelper.OracleIdentity{ + OnchainPublicKey: offchainPublicKey, + TransmitAccount: ocr2types.Account(fmt.Sprintf("%x", transmitter[:])), + OffchainPublicKey: kb.OffchainPublicKey(), + PeerID: peerID, + }, + ConfigEncryptionPublicKey: kb.ConfigEncryptionPublicKey(), + }) + logObservers = append(logObservers, observedLogs) + } + + for _, feed := range feeds { + addBootstrapJob(t, bootstrapNode, chainID, verifierAddress, feed.name, feed.id) + } + + 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) + require.NoError(t, err) + require.Equal(t, `{"data":{"from":"ETH","to":"USD"}}`, string(b)) + + r := rand.Int63n(101) + if r > pError.Load() { + res.WriteHeader(http.StatusOK) + val := decimal.NewFromBigInt(p, 0).Div(decimal.NewFromInt(multiplier)).Add(decimal.NewFromInt(int64(i)).Div(decimal.NewFromInt(100))).String() + resp := fmt.Sprintf(`{"result": %s}`, val) + _, err := res.Write([]byte(resp)) + require.NoError(t, err) + } else { + res.WriteHeader(http.StatusInternalServerError) + resp := `{"error": "pError test error"}` + _, err := res.Write([]byte(resp)) + require.NoError(t, err) + } + })) + t.Cleanup(bridge.Close) + u, _ := url.Parse(bridge.URL) + bridgeName = fmt.Sprintf("bridge-%s-%d", name, i) + require.NoError(t, borm.CreateBridgeType(&bridges.BridgeType{ + Name: bridges.BridgeName(bridgeName), + URL: models.WebURL(*u), + })) -func addMercuryJob( - t *testing.T, - node Node, - i int, - verifierAddress common.Address, - bootstrapPeerID string, - bootstrapNodePort int64, - bmBridge, - bidBridge, - askBridge, - serverURL string, - serverPubKey, - clientPubKey ed25519.PublicKey, - feedName string, - feedID [32]byte, - chainID *big.Int, - fromBlock int, -) { - node.AddJob(t, fmt.Sprintf(` -type = "offchainreporting2" -schemaVersion = 1 -name = "mercury-%[1]d-%[14]s" -forwardingAllowed = false -maxTaskDuration = "1s" -contractID = "%[2]s" -feedID = "0x%[11]x" -contractConfigTrackerPollInterval = "1s" -ocrKeyBundleID = "%[3]s" -p2pv2Bootstrappers = [ - "%[4]s" -] -relay = "evm" -pluginType = "mercury" -transmitterID = "%[10]x" -observationSource = """ - // Benchmark Price - price1 [type=bridge name="%[5]s" timeout="50ms" requestData="{\\"data\\":{\\"from\\":\\"ETH\\",\\"to\\":\\"USD\\"}}"]; - price1_parse [type=jsonparse path="result"]; - price1_multiply [type=multiply times=100000000 index=0]; - - price1 -> price1_parse -> price1_multiply; - - // Bid - bid [type=bridge name="%[6]s" timeout="50ms" requestData="{\\"data\\":{\\"from\\":\\"ETH\\",\\"to\\":\\"USD\\"}}"]; - bid_parse [type=jsonparse path="result"]; - bid_multiply [type=multiply times=100000000 index=1]; - - bid -> bid_parse -> bid_multiply; - - // Ask - ask [type=bridge name="%[7]s" timeout="50ms" requestData="{\\"data\\":{\\"from\\":\\"ETH\\",\\"to\\":\\"USD\\"}}"]; - ask_parse [type=jsonparse path="result"]; - ask_multiply [type=multiply times=100000000 index=2]; - - ask -> ask_parse -> ask_multiply; -""" - -[pluginConfig] -serverURL = "%[8]s" -serverPubKey = "%[9]x" - -[relayConfig] -chainID = %[12]d -fromBlock = %[13]d - `, - i, - verifierAddress, - node.KeyBundle.ID(), - fmt.Sprintf("%s@127.0.0.1:%d", bootstrapPeerID, bootstrapNodePort), - bmBridge, - bidBridge, - askBridge, - serverURL, - serverPubKey, - clientPubKey, - feedID, - chainID, - fromBlock, - feedName, - )) + return bridgeName + } + + // Add OCR jobs - one per feed on each node + for i, node := range nodes { + for j, feed := range feeds { + bmBridge := createBridge(fmt.Sprintf("benchmarkprice-%d", j), i, feed.baseBenchmarkPrice, node.App.BridgeORM()) + bidBridge := createBridge(fmt.Sprintf("bid-%d", j), i, feed.baseBid, node.App.BridgeORM()) + askBridge := createBridge(fmt.Sprintf("ask-%d", j), i, feed.baseAsk, node.App.BridgeORM()) + + addV3MercuryJob( + t, + node, + i, + verifierAddress, + bootstrapPeerID, + bootstrapNodePort, + bmBridge, + bidBridge, + askBridge, + serverURL, + serverPubKey, + clientPubKeys[i], + feed.name, + feed.id, + randomFeedID(2), + randomFeedID(2), + ) + } + } + + // Setup config on contract + onchainConfig, err := (relaymercury.StandardOnchainConfigCodec{}).Encode(rawOnchainConfig) + require.NoError(t, err) + + reportingPluginConfig, err := json.Marshal(rawReportingPluginConfig) + require.NoError(t, err) + + signers, _, _, onchainConfig, offchainConfigVersion, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsForTestsMercuryV02( + 2*time.Second, // DeltaProgress + 20*time.Second, // DeltaResend + 400*time.Millisecond, // DeltaInitial + 100*time.Millisecond, // DeltaRound + 0, // DeltaGrace + 300*time.Millisecond, // DeltaCertifiedCommitRequest + 1*time.Minute, // DeltaStage + 100, // rMax + []int{len(nodes)}, // S + oracles, + reportingPluginConfig, // reportingPluginConfig []byte, + 250*time.Millisecond, // Max duration observation + int(f), // f + onchainConfig, + ) + + require.NoError(t, err) + signerAddresses, err := evm.OnchainPublicKeyToAddress(signers) + require.NoError(t, err) + + offchainTransmitters := make([][32]byte, n) + for i := 0; i < n; i++ { + offchainTransmitters[i] = nodes[i].ClientPubKey + } + + for _, feed := range feeds { + _, err = verifier.SetConfig( + steve, + feed.id, + signerAddresses, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig, + nil, + ) + require.NoError(t, err) + backend.Commit() + } + + // Bury it with finality depth + ch, err := bootstrapNode.App.GetRelayers().LegacyEVMChains().Get(testutils.SimulatedChainID.String()) + require.NoError(t, err) + finalityDepth := ch.Config().EVM().FinalityDepth() + for i := 0; i < int(finalityDepth); i++ { + backend.Commit() + } + + runTestSetup := func() { + // Expect at least one report per feed from each oracle + seen := make(map[[32]byte]map[credentials.StaticSizedPublicKey]struct{}) + for i := range feeds { + // feedID will be deleted when all n oracles have reported + seen[feeds[i].id] = make(map[credentials.StaticSizedPublicKey]struct{}, n) + } + + for req := range reqs { + v := make(map[string]interface{}) + err := mercury.PayloadTypes.UnpackIntoMap(v, req.req.Payload) + require.NoError(t, err) + report, exists := v["report"] + if !exists { + t.Fatalf("expected payload %#v to contain 'report'", v) + } + reportElems := make(map[string]interface{}) + err = reportcodecv3.ReportTypes.UnpackIntoMap(reportElems, report.([]byte)) + require.NoError(t, err) + + feedID := ([32]byte)(reportElems["feedId"].([32]uint8)) + feed, exists := feedM[feedID] + require.True(t, exists) + + if _, exists := seen[feedID]; !exists { + continue // already saw all oracles for this feed + } + + expectedFee := relaymercury.CalculateFee(big.NewInt(123456789), rawReportingPluginConfig.BaseUSDFeeCents) + expectedExpiresAt := reportElems["observationsTimestamp"].(uint32) + rawReportingPluginConfig.ExpirationWindow + + assert.GreaterOrEqual(t, int(reportElems["observationsTimestamp"].(uint32)), int(testStartTimeStamp)) + assert.InDelta(t, feed.baseBenchmarkPrice.Int64(), reportElems["benchmarkPrice"].(*big.Int).Int64(), 5000000) + assert.InDelta(t, feed.baseBid.Int64(), reportElems["bid"].(*big.Int).Int64(), 5000000) + assert.InDelta(t, feed.baseAsk.Int64(), reportElems["ask"].(*big.Int).Int64(), 5000000) + assert.NotZero(t, reportElems["validFromTimestamp"].(uint32)) + assert.GreaterOrEqual(t, reportElems["observationsTimestamp"].(uint32), reportElems["validFromTimestamp"].(uint32)) + assert.Equal(t, expectedExpiresAt, reportElems["expiresAt"].(uint32)) + assert.Equal(t, expectedFee, reportElems["linkFee"].(*big.Int)) + assert.Equal(t, expectedFee, reportElems["nativeFee"].(*big.Int)) + + t.Logf("oracle %x reported for feed %s (0x%x)", req.pk, feed.name, feed.id) + + seen[feedID][req.pk] = struct{}{} + if len(seen[feedID]) == n { + t.Logf("all oracles reported for feed %s (0x%x)", feed.name, feed.id) + delete(seen, feedID) + if len(seen) == 0 { + break // saw all oracles; success! + } + } + } + } + + t.Run("receives at least one report per feed from each oracle when EAs are at 100% reliability", func(t *testing.T) { + runTestSetup() + }) + + t.Run("receives at least one report per feed from each oracle when EAs are at 80% reliability", func(t *testing.T) { + pError.Store(20) + runTestSetup() + }) } diff --git a/core/services/ocr2/plugins/mercury/plugin.go b/core/services/ocr2/plugins/mercury/plugin.go index fc3c702b894..557c83fd11e 100644 --- a/core/services/ocr2/plugins/mercury/plugin.go +++ b/core/services/ocr2/plugins/mercury/plugin.go @@ -7,7 +7,9 @@ import ( libocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus" - relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" + relaymercuryv1 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v1" + relaymercuryv2 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v2" + relaymercuryv3 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v3" relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -15,7 +17,11 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/mercury/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/types" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" + mercuryv1 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v1" + mercuryv2 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v2" + mercuryv3 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3" ) type Config interface { @@ -31,38 +37,89 @@ func NewServices( argsNoPlugin libocr2.MercuryOracleArgs, cfg Config, chEnhancedTelem chan ocrcommon.EnhancedTelemetryMercuryData, - chainHeadTracker mercury.ChainHeadTracker, + chainHeadTracker types.ChainHeadTracker, + orm types.DataSourceORM, + feedID utils.FeedID, ) ([]job.ServiceCtx, error) { if jb.PipelineSpec == nil { return nil, errors.New("expected job to have a non-nil PipelineSpec") } + var pluginConfig config.PluginConfig err := json.Unmarshal(jb.OCR2OracleSpec.PluginConfig.Bytes(), &pluginConfig) if err != nil { return nil, errors.WithStack(err) } - err = config.ValidatePluginConfig(pluginConfig) + err = config.ValidatePluginConfig(pluginConfig, feedID) if err != nil { return nil, err } lggr = lggr.Named("MercuryPlugin").With("jobID", jb.ID, "jobName", jb.Name.ValueOrZero()) - ds := mercury.NewDataSource( - pipelineRunner, - jb, - *jb.PipelineSpec, - lggr, - runResults, - chEnhancedTelem, - chainHeadTracker, - ocr2Provider.ContractTransmitter(), - pluginConfig.InitialBlockNumber.Ptr(), - ) - argsNoPlugin.MercuryPluginFactory = relaymercury.NewFactory( - ds, - lggr, - ocr2Provider.OnchainConfigCodec(), - ocr2Provider.ReportCodec(), - ) + + switch feedID.Version() { + case 1: + ds := mercuryv1.NewDataSource( + orm, + pipelineRunner, + jb, + *jb.PipelineSpec, + lggr, + runResults, + chEnhancedTelem, + chainHeadTracker, + ocr2Provider.ContractTransmitter(), + pluginConfig.InitialBlockNumber.Ptr(), + feedID, + ) + argsNoPlugin.MercuryPluginFactory = relaymercuryv1.NewFactory( + ds, + lggr, + ocr2Provider.OnchainConfigCodec(), + ocr2Provider.ReportCodecV1(), + ) + case 2: + ds := mercuryv2.NewDataSource( + // TODO: Needs ORM to carry timestamps over + pipelineRunner, + jb, + *jb.PipelineSpec, + feedID, + lggr, + runResults, + chEnhancedTelem, + ocr2Provider.ContractTransmitter(), + *pluginConfig.LinkFeedID, + *pluginConfig.NativeFeedID, + ) + argsNoPlugin.MercuryPluginFactory = relaymercuryv2.NewFactory( + ds, + lggr, + ocr2Provider.OnchainConfigCodec(), + ocr2Provider.ReportCodecV2(), + ) + case 3: + ds := mercuryv3.NewDataSource( + pipelineRunner, + jb, + *jb.PipelineSpec, + feedID, + lggr, + runResults, + chEnhancedTelem, + ocr2Provider.ContractTransmitter(), + *pluginConfig.LinkFeedID, + *pluginConfig.NativeFeedID, + ) + argsNoPlugin.MercuryPluginFactory = relaymercuryv3.NewFactory( + ds, + lggr, + ocr2Provider.OnchainConfigCodec(), + ocr2Provider.ReportCodecV3(), + ) + default: + return nil, errors.Errorf("unknown Mercury report schema version: %d", feedID.Version()) + } + oracle, err := libocr2.NewOracle(argsNoPlugin) if err != nil { return nil, errors.WithStack(err) diff --git a/core/services/ocr2/plugins/ocr2keeper/config.go b/core/services/ocr2/plugins/ocr2keeper/config.go index 99555c1f9c7..d3035878ece 100644 --- a/core/services/ocr2/plugins/ocr2keeper/config.go +++ b/core/services/ocr2/plugins/ocr2keeper/config.go @@ -31,6 +31,10 @@ func (d Duration) Value() time.Duration { return time.Duration(d) } +// NOTE: This plugin config is shared among different versions of keepers +// Any changes to this config should keep in mind existing production +// deployments of all versions of keepers and should be backwards compatible +// with existing job specs. type PluginConfig struct { // CacheExpiration is the duration of time a cached key is available. Use // this value to balance memory usage and RPC calls. A new set of keys is @@ -52,6 +56,8 @@ type PluginConfig struct { // workers or slower RPC responses will cause this queue to build up. // Adding new items to the queue will block if the queue becomes full. ServiceQueueLength int `json:"serviceQueueLength"` + // ContractVersion is the contract version + ContractVersion string `json:"contractVersion"` } func ValidatePluginConfig(cfg PluginConfig) error { diff --git a/core/services/ocr2/plugins/ocr2keeper/evm20/abi.go b/core/services/ocr2/plugins/ocr2keeper/evm20/abi.go index 20f600972ec..4c0beee8fd6 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm20/abi.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm20/abi.go @@ -8,7 +8,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v2" ) type evmRegistryPackerV2_0 struct { diff --git a/core/services/ocr2/plugins/ocr2keeper/evm20/abi_test.go b/core/services/ocr2/plugins/ocr2keeper/evm20/abi_test.go index 37e887908ed..7efc3feb1f0 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm20/abi_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm20/abi_test.go @@ -8,7 +8,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common/hexutil" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v2" "github.com/stretchr/testify/assert" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper2_0" diff --git a/core/services/ocr2/plugins/ocr2keeper/evm20/encoder.go b/core/services/ocr2/plugins/ocr2keeper/evm20/encoder.go index bbb2b1c052a..3984cb7496b 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm20/encoder.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm20/encoder.go @@ -6,8 +6,8 @@ import ( "reflect" "github.com/ethereum/go-ethereum/accounts/abi" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" - "github.com/smartcontractkit/ocr2keepers/pkg/encoding" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v2" + "github.com/smartcontractkit/ocr2keepers/pkg/v2/encoding" ) type EVMAutomationEncoder20 struct { diff --git a/core/services/ocr2/plugins/ocr2keeper/evm20/encoder_test.go b/core/services/ocr2/plugins/ocr2keeper/evm20/encoder_test.go index 2e49c02f260..74be6b46ee5 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm20/encoder_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm20/encoder_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/pkg/errors" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v2" "github.com/stretchr/testify/assert" ) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm20/head.go b/core/services/ocr2/plugins/ocr2keeper/evm20/head.go index 152ca4f6ce9..1023bff5dd2 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm20/head.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm20/head.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v2" httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" diff --git a/core/services/ocr2/plugins/ocr2keeper/evm20/log_provider.go b/core/services/ocr2/plugins/ocr2keeper/evm20/log_provider.go index e5fa073fd27..69533e95869 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm20/log_provider.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm20/log_provider.go @@ -10,9 +10,9 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" gethtypes "github.com/ethereum/go-ethereum/core/types" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" - "github.com/smartcontractkit/ocr2keepers/pkg/encoding" pluginutils "github.com/smartcontractkit/ocr2keepers/pkg/util" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v2" + "github.com/smartcontractkit/ocr2keepers/pkg/v2/encoding" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" diff --git a/core/services/ocr2/plugins/ocr2keeper/evm20/registry.go b/core/services/ocr2/plugins/ocr2keeper/evm20/registry.go index f437f95480c..82cad9d4a5b 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm20/registry.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm20/registry.go @@ -15,7 +15,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/rpc" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v2" "go.uber.org/multierr" "github.com/smartcontractkit/chainlink/v2/core/chains/evm" diff --git a/core/services/ocr2/plugins/ocr2keeper/evm20/registry_test.go b/core/services/ocr2/plugins/ocr2keeper/evm20/registry_test.go index 1d84cd2b4b2..348b5a47c0f 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm20/registry_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm20/registry_test.go @@ -8,7 +8,7 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/abi.go b/core/services/ocr2/plugins/ocr2keeper/evm21/abi.go deleted file mode 100644 index dfac65daf97..00000000000 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/abi.go +++ /dev/null @@ -1,251 +0,0 @@ -package evm - -import ( - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common/hexutil" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" - - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1" - iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" -) - -// enum UpkeepFailureReason is defined by https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/dev/automation/2_1/interfaces/AutomationRegistryInterface2_1.sol#L97 -// make sure failure reasons are in sync between contract and offchain enum -const ( - UPKEEP_FAILURE_REASON_NONE = iota - UPKEEP_FAILURE_REASON_UPKEEP_CANCELLED - UPKEEP_FAILURE_REASON_UPKEEP_PAUSED - UPKEEP_FAILURE_REASON_TARGET_CHECK_REVERTED - UPKEEP_FAILURE_REASON_UPKEEP_NOT_NEEDED - UPKEEP_FAILURE_REASON_PERFORM_DATA_EXCEEDS_LIMIT - UPKEEP_FAILURE_REASON_INSUFFICIENT_BALANCE - UPKEEP_FAILURE_REASON_MERCURY_CALLBACK_REVERTED - UPKEEP_FAILURE_REASON_REVERT_DATA_EXCEEDS_LIMIT - UPKEEP_FAILURE_REASON_REGISTRY_PAUSED - - // Start of offchain failure types. All onchain failure reasons from - // contract should be put above - UPKEEP_FAILURE_REASON_MERCURY_ACCESS_NOT_ALLOWED -) - -var utilsABI = types.MustGetABI(automation_utils_2_1.AutomationUtilsABI) - -type UpkeepInfo = iregistry21.KeeperRegistryBase21UpkeepInfo - -// triggerWrapper is a wrapper for the different trigger types (log and condition triggers). -// NOTE: we use log trigger because it extends condition trigger, -type triggerWrapper = automation_utils_2_1.KeeperRegistryBase21LogTrigger - -type evmRegistryPackerV2_1 struct { - abi abi.ABI - utilsAbi abi.ABI -} - -func NewEvmRegistryPackerV2_1(abi abi.ABI, utilsAbi abi.ABI) *evmRegistryPackerV2_1 { - return &evmRegistryPackerV2_1{abi: abi, utilsAbi: utilsAbi} -} - -func (rp *evmRegistryPackerV2_1) UnpackCheckResult(key ocr2keepers.UpkeepPayload, raw string) (ocr2keepers.CheckResult, error) { - var result ocr2keepers.CheckResult - - b, err := hexutil.Decode(raw) - if err != nil { - return result, err - } - - out, err := rp.abi.Methods["checkUpkeep"].Outputs.UnpackValues(b) - if err != nil { - return result, fmt.Errorf("%w: unpack checkUpkeep return: %s", err, raw) - } - - result = ocr2keepers.CheckResult{ - Eligible: *abi.ConvertType(out[0], new(bool)).(*bool), - Retryable: false, - GasAllocated: uint64((*abi.ConvertType(out[4], new(*big.Int)).(**big.Int)).Int64()), - Payload: key, - } - ext := EVMAutomationResultExtension21{ - FastGasWei: *abi.ConvertType(out[5], new(*big.Int)).(**big.Int), - LinkNative: *abi.ConvertType(out[6], new(*big.Int)).(**big.Int), - FailureReason: *abi.ConvertType(out[2], new(uint8)).(*uint8), - } - result.Extension = ext - rawPerformData := *abi.ConvertType(out[1], new([]byte)).(*[]byte) - - // if NONE we expect the perform data. if TARGET_CHECK_REVERTED we will have the error data in the perform data used for off chain lookup - if ext.FailureReason == UPKEEP_FAILURE_REASON_NONE || (ext.FailureReason == UPKEEP_FAILURE_REASON_TARGET_CHECK_REVERTED && len(rawPerformData) > 0) { - result.PerformData = rawPerformData - } - - return result, nil -} - -func (rp *evmRegistryPackerV2_1) UnpackCheckCallbackResult(callbackResp []byte) (bool, []byte, uint8, *big.Int, error) { - out, err := rp.abi.Methods["checkCallback"].Outputs.UnpackValues(callbackResp) - if err != nil { - return false, nil, 0, nil, fmt.Errorf("%w: unpack checkUpkeep return: %s", err, hexutil.Encode(callbackResp)) - } - - upkeepNeeded := *abi.ConvertType(out[0], new(bool)).(*bool) - rawPerformData := *abi.ConvertType(out[1], new([]byte)).(*[]byte) - failureReason := *abi.ConvertType(out[2], new(uint8)).(*uint8) - gasUsed := *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) - return upkeepNeeded, rawPerformData, failureReason, gasUsed, nil -} - -func (rp *evmRegistryPackerV2_1) UnpackPerformResult(raw string) (bool, error) { - b, err := hexutil.Decode(raw) - if err != nil { - return false, err - } - - out, err := rp.abi.Methods["simulatePerformUpkeep"].Outputs.UnpackValues(b) - if err != nil { - return false, fmt.Errorf("%w: unpack simulatePerformUpkeep return: %s", err, raw) - } - - return *abi.ConvertType(out[0], new(bool)).(*bool), nil -} - -func (rp *evmRegistryPackerV2_1) UnpackUpkeepInfo(id *big.Int, raw string) (UpkeepInfo, error) { - b, err := hexutil.Decode(raw) - if err != nil { - return UpkeepInfo{}, err - } - - out, err := rp.abi.Methods["getUpkeep"].Outputs.UnpackValues(b) - if err != nil { - return UpkeepInfo{}, fmt.Errorf("%w: unpack getUpkeep return: %s", err, raw) - } - - info := *abi.ConvertType(out[0], new(UpkeepInfo)).(*UpkeepInfo) - - return info, nil -} - -// UnpackLogTriggerConfig unpacks the log trigger config from the given raw data -func (rp *evmRegistryPackerV2_1) UnpackLogTriggerConfig(raw []byte) (automation_utils_2_1.LogTriggerConfig, error) { - var cfg automation_utils_2_1.LogTriggerConfig - - out, err := utilsABI.Methods["_logTriggerConfig"].Inputs.UnpackValues(raw) - if err != nil { - return cfg, fmt.Errorf("%w: unpack _logTriggerConfig return: %s", err, raw) - } - - converted, ok := abi.ConvertType(out[0], new(automation_utils_2_1.LogTriggerConfig)).(*automation_utils_2_1.LogTriggerConfig) - if !ok { - return cfg, fmt.Errorf("failed to convert type") - } - return *converted, nil -} - -// PackTrigger packs the trigger into the format expected by the contract, -// according to the upkeep type of the given id. -func (rp *evmRegistryPackerV2_1) PackTrigger(id *big.Int, trig triggerWrapper) ([]byte, error) { - var trigger []byte - var err error - upkeepType := getUpkeepType(id.Bytes()) - switch upkeepType { - case conditionTrigger: - trig := automation_utils_2_1.KeeperRegistryBase21ConditionalTrigger{ - BlockNum: trig.BlockNum, - BlockHash: trig.BlockHash, - } - trigger, err = rp.utilsAbi.Pack("_conditionalTrigger", &trig) - case logTrigger: - logTrig := automation_utils_2_1.KeeperRegistryBase21LogTrigger{ - BlockNum: trig.BlockNum, - BlockHash: trig.BlockHash, - LogIndex: trig.LogIndex, - TxHash: trig.TxHash, - } - trigger, err = rp.utilsAbi.Pack("_logTrigger", &logTrig) - default: - err = fmt.Errorf("unknown trigger type: %d", upkeepType) - } - if err != nil { - return nil, err - } - return trigger[4:], nil -} - -// UnpackTrigger unpacks the trigger from the given raw data, according to the upkeep type of the given id. -func (rp *evmRegistryPackerV2_1) UnpackTrigger(id *big.Int, raw []byte) (triggerWrapper, error) { - upkeepType := getUpkeepType(id.Bytes()) - switch upkeepType { - case conditionTrigger: - unpacked, err := rp.utilsAbi.Methods["_conditionalTrigger"].Inputs.Unpack(raw) - if err != nil { - return triggerWrapper{}, fmt.Errorf("%w: failed to unpack conditional trigger", err) - } - converted, ok := abi.ConvertType(unpacked[0], new(automation_utils_2_1.KeeperRegistryBase21ConditionalTrigger)).(*automation_utils_2_1.KeeperRegistryBase21ConditionalTrigger) - if !ok { - return triggerWrapper{}, fmt.Errorf("failed to convert type") - } - triggerW := triggerWrapper{ - BlockNum: converted.BlockNum, - } - copy(triggerW.BlockHash[:], converted.BlockHash[:]) - return triggerW, nil - case logTrigger: - unpacked, err := rp.utilsAbi.Methods["_logTrigger"].Inputs.Unpack(raw) - if err != nil { - return triggerWrapper{}, fmt.Errorf("%w: failed to unpack log trigger", err) - } - converted, ok := abi.ConvertType(unpacked[0], new(automation_utils_2_1.KeeperRegistryBase21LogTrigger)).(*automation_utils_2_1.KeeperRegistryBase21LogTrigger) - if !ok { - return triggerWrapper{}, fmt.Errorf("failed to convert type") - } - triggerW := triggerWrapper{ - BlockNum: converted.BlockNum, - LogIndex: converted.LogIndex, - } - copy(triggerW.BlockHash[:], converted.BlockHash[:]) - copy(triggerW.TxHash[:], converted.TxHash[:]) - return triggerW, nil - default: - return triggerWrapper{}, fmt.Errorf("unknown trigger type: %d", upkeepType) - } -} - -// PackReport packs the report with abi definitions from the contract. -func (rp *evmRegistryPackerV2_1) PackReport(report automation_utils_2_1.KeeperRegistryBase21Report) ([]byte, error) { - bts, err := rp.utilsAbi.Pack("_report", &report) - if err != nil { - return nil, fmt.Errorf("%w: failed to pack report", err) - } - - return bts[4:], nil -} - -// UnpackReport unpacks the report from the given raw data. -func (rp *evmRegistryPackerV2_1) UnpackReport(raw []byte) (automation_utils_2_1.KeeperRegistryBase21Report, error) { - unpacked, err := rp.utilsAbi.Methods["_report"].Inputs.Unpack(raw) - if err != nil { - return automation_utils_2_1.KeeperRegistryBase21Report{}, fmt.Errorf("%w: failed to unpack report", err) - } - converted, ok := abi.ConvertType(unpacked[0], new(automation_utils_2_1.KeeperRegistryBase21Report)).(*automation_utils_2_1.KeeperRegistryBase21Report) - if !ok { - return automation_utils_2_1.KeeperRegistryBase21Report{}, fmt.Errorf("failed to convert type") - } - report := automation_utils_2_1.KeeperRegistryBase21Report{ - FastGasWei: converted.FastGasWei, - LinkNative: converted.LinkNative, - UpkeepIds: make([]*big.Int, len(converted.UpkeepIds)), - GasLimits: make([]*big.Int, len(converted.GasLimits)), - Triggers: make([][]byte, len(converted.Triggers)), - PerformDatas: make([][]byte, len(converted.PerformDatas)), - } - if len(report.UpkeepIds) > 0 { - copy(report.UpkeepIds, converted.UpkeepIds) - copy(report.GasLimits, converted.GasLimits) - copy(report.Triggers, converted.Triggers) - copy(report.PerformDatas, converted.PerformDatas) - } - - return report, nil -} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/active_list.go b/core/services/ocr2/plugins/ocr2keeper/evm21/active_list.go new file mode 100644 index 00000000000..899dd398d03 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/active_list.go @@ -0,0 +1,121 @@ +package evm + +import ( + "math/big" + "sync" + + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" +) + +// ActiveUpkeepList is a list to manage active upkeep IDs +type ActiveUpkeepList interface { + // Reset resets the list to the given IDs + Reset(ids ...*big.Int) + // Add adds new entries to the list + Add(id ...*big.Int) int + // Remove removes entries from the list + Remove(id ...*big.Int) int + // View returns the list of IDs of the given type + View(...ocr2keepers.UpkeepType) []*big.Int + // IsActive returns true if the given ID is of an active upkeep + IsActive(id *big.Int) bool + Size() int +} + +type activeList struct { + items map[string]bool + lock sync.RWMutex +} + +var _ ActiveUpkeepList = &activeList{} + +// NewActiveList creates a new ActiveList +func NewActiveUpkeepList() ActiveUpkeepList { + return &activeList{ + items: make(map[string]bool), + } +} + +// Reset resets the list to the given IDs +func (al *activeList) Reset(ids ...*big.Int) { + al.lock.Lock() + defer al.lock.Unlock() + + al.items = make(map[string]bool) + for _, id := range ids { + al.items[id.String()] = true + } +} + +// Add adds new entries to the list +func (al *activeList) Add(ids ...*big.Int) int { + al.lock.Lock() + defer al.lock.Unlock() + + count := 0 + for _, id := range ids { + if key := id.String(); !al.items[key] { + count++ + al.items[key] = true + } + } + return count +} + +// Remove removes entries from the list +func (al *activeList) Remove(ids ...*big.Int) int { + al.lock.Lock() + defer al.lock.Unlock() + + count := 0 + for _, id := range ids { + key := id.String() + if al.items[key] { + count++ + delete(al.items, key) + } + } + return count +} + +// View returns the list of IDs of the given type +func (al *activeList) View(upkeepTypes ...ocr2keepers.UpkeepType) []*big.Int { + al.lock.RLock() + defer al.lock.RUnlock() + + var keys []*big.Int + for key := range al.items { + id := &ocr2keepers.UpkeepIdentifier{} + bint, ok := big.NewInt(0).SetString(key, 10) + if !ok { + continue + } + if !id.FromBigInt(bint) { + continue + } + currentType := core.GetUpkeepType(*id) + for _, t := range upkeepTypes { + if currentType == t { + keys = append(keys, bint) + break + } + } + } + return keys +} + +func (al *activeList) IsActive(id *big.Int) bool { + al.lock.RLock() + defer al.lock.RUnlock() + + return al.items[id.String()] +} + +func (al *activeList) Size() int { + al.lock.RLock() + defer al.lock.RUnlock() + + return len(al.items) +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/active_list_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/active_list_test.go new file mode 100644 index 00000000000..76ca6bfdf19 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/active_list_test.go @@ -0,0 +1,103 @@ +package evm + +import ( + "math/big" + "sort" + "testing" + + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" +) + +func TestActiveUpkeepList(t *testing.T) { + logIDs := []ocr2keepers.UpkeepIdentifier{ + core.GenUpkeepID(ocr2keepers.LogTrigger, "0"), + core.GenUpkeepID(ocr2keepers.LogTrigger, "1"), + core.GenUpkeepID(ocr2keepers.LogTrigger, "2"), + core.GenUpkeepID(ocr2keepers.LogTrigger, "3"), + core.GenUpkeepID(ocr2keepers.LogTrigger, "4"), + } + conditionalIDs := []ocr2keepers.UpkeepIdentifier{ + core.GenUpkeepID(ocr2keepers.ConditionTrigger, "0"), + core.GenUpkeepID(ocr2keepers.ConditionTrigger, "1"), + core.GenUpkeepID(ocr2keepers.ConditionTrigger, "2"), + core.GenUpkeepID(ocr2keepers.ConditionTrigger, "3"), + core.GenUpkeepID(ocr2keepers.ConditionTrigger, "4"), + } + + tests := []struct { + name string + initial []*big.Int + add []*big.Int + remove []*big.Int + expectedLogIds []*big.Int + expectedConditionalIds []*big.Int + }{ + { + name: "happy flow", + initial: []*big.Int{logIDs[0].BigInt(), logIDs[1].BigInt(), conditionalIDs[0].BigInt(), conditionalIDs[1].BigInt()}, + add: []*big.Int{logIDs[2].BigInt(), logIDs[3].BigInt(), conditionalIDs[2].BigInt(), conditionalIDs[3].BigInt()}, + remove: []*big.Int{logIDs[3].BigInt(), conditionalIDs[3].BigInt()}, + expectedLogIds: []*big.Int{logIDs[0].BigInt(), logIDs[1].BigInt(), logIDs[2].BigInt()}, + expectedConditionalIds: []*big.Int{conditionalIDs[0].BigInt(), conditionalIDs[1].BigInt(), conditionalIDs[2].BigInt()}, + }, + { + name: "empty", + initial: []*big.Int{}, + add: []*big.Int{}, + remove: []*big.Int{}, + expectedLogIds: []*big.Int{}, + expectedConditionalIds: []*big.Int{}, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + al := NewActiveUpkeepList() + al.Reset(tc.initial...) + require.Equal(t, len(tc.initial), al.Size()) + for _, id := range tc.initial { + require.True(t, al.IsActive(id)) + } + al.Add(tc.add...) + for _, id := range tc.add { + require.True(t, al.IsActive(id)) + } + al.Remove(tc.remove...) + for _, id := range tc.remove { + require.False(t, al.IsActive(id)) + } + logIds := al.View(ocr2keepers.LogTrigger) + require.Equal(t, len(tc.expectedLogIds), len(logIds)) + sort.Slice(logIds, func(i, j int) bool { + return logIds[i].Cmp(logIds[j]) < 0 + }) + for i := range logIds { + require.Equal(t, tc.expectedLogIds[i], logIds[i]) + } + conditionalIds := al.View(ocr2keepers.ConditionTrigger) + require.Equal(t, len(tc.expectedConditionalIds), len(conditionalIds)) + sort.Slice(conditionalIds, func(i, j int) bool { + return conditionalIds[i].Cmp(conditionalIds[j]) < 0 + }) + for i := range conditionalIds { + require.Equal(t, tc.expectedConditionalIds[i], conditionalIds[i]) + } + }) + } +} + +func TestActiveUpkeepList_error(t *testing.T) { + t.Run("if invalid or negative numbers are in the store, they are excluded from the view operation", func(t *testing.T) { + al := &activeList{} + al.items = make(map[string]bool) + al.items["not a number"] = true + al.items["-1"] = true + al.items["100"] = true + + keys := al.View(ocr2keepers.ConditionTrigger) + require.Equal(t, []*big.Int{big.NewInt(100)}, keys) + }) +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber.go b/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber.go index d8f7b3d5da4..ca74eb85e1a 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber.go @@ -4,10 +4,11 @@ import ( "context" "fmt" "sync" + "sync/atomic" "time" "github.com/ethereum/go-ethereum/common" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" @@ -18,263 +19,264 @@ import ( ) const ( - // PollLogInterval is the interval to query log poller - PollLogInterval = time.Second - // CleanUpInterval is the interval for cleaning up block maps - CleanUpInterval = 15 * time.Minute - // ChannelSize represents the channel size for head broadcaster - ChannelSize = 20 + // cleanUpInterval is the interval for cleaning up block maps + cleanUpInterval = 15 * time.Minute + // channelSize represents the channel size for head broadcaster + channelSize = 100 + // lookbackDepth decides valid trigger block lookback range + lookbackDepth = 1024 + // blockHistorySize decides the block history size sent to subscribers + blockHistorySize = int64(256) ) -type BlockKey struct { - block int64 - hash common.Hash -} - -func (bk *BlockKey) getBlockKey() ocr2keepers.BlockKey { - return ocr2keepers.BlockKey(fmt.Sprintf("%d%s%s", bk.block, BlockKeySeparator, bk.hash.Hex())) -} - type BlockSubscriber struct { - sync utils.StartStopOnce - mu sync.RWMutex - ctx context.Context - cancel context.CancelFunc - hb httypes.HeadBroadcaster - lp logpoller.LogPoller - headC chan BlockKey - unsubscribe func() - subscribers map[int]chan ocr2keepers.BlockHistory - blocksFromPoller map[int64]common.Hash - blocksFromBroadcaster map[int64]common.Hash - maxSubId int - lastClearedBlock int64 - lastSentBlock int64 - blockHistorySize int64 - lggr logger.Logger + sync utils.StartStopOnce + mu sync.RWMutex + ctx context.Context + cancel context.CancelFunc + hb httypes.HeadBroadcaster + lp logpoller.LogPoller + headC chan *evmtypes.Head + unsubscribe func() + subscribers map[int]chan ocr2keepers.BlockHistory + blocks map[int64]string + maxSubId int + lastClearedBlock int64 + lastSentBlock int64 + latestBlock atomic.Pointer[ocr2keepers.BlockKey] + blockHistorySize int64 + blockSize int64 + lggr logger.Logger } -func NewBlockSubscriber(hb httypes.HeadBroadcaster, lp logpoller.LogPoller, blockHistorySize int64, lggr logger.Logger) *BlockSubscriber { +var _ ocr2keepers.BlockSubscriber = &BlockSubscriber{} + +func NewBlockSubscriber(hb httypes.HeadBroadcaster, lp logpoller.LogPoller, lggr logger.Logger) *BlockSubscriber { return &BlockSubscriber{ - hb: hb, - lp: lp, - headC: make(chan BlockKey, ChannelSize), - subscribers: map[int]chan ocr2keepers.BlockHistory{}, - blocksFromPoller: map[int64]common.Hash{}, - blocksFromBroadcaster: map[int64]common.Hash{}, - blockHistorySize: blockHistorySize, - lggr: lggr.Named("BlockSubscriber"), + hb: hb, + lp: lp, + headC: make(chan *evmtypes.Head, channelSize), + subscribers: map[int]chan ocr2keepers.BlockHistory{}, + blocks: map[int64]string{}, + blockHistorySize: blockHistorySize, + blockSize: lookbackDepth, + latestBlock: atomic.Pointer[ocr2keepers.BlockKey]{}, + lggr: lggr.Named("BlockSubscriber"), } } -func (hw *BlockSubscriber) getBlockRange(ctx context.Context) ([]uint64, error) { - h, err := hw.lp.LatestBlock(pg.WithParentCtx(ctx)) +func (bs *BlockSubscriber) getBlockRange(ctx context.Context) ([]uint64, error) { + h, err := bs.lp.LatestBlock(pg.WithParentCtx(ctx)) if err != nil { return nil, err } - hw.lggr.Infof("latest block from log poller is %d", h) + bs.lggr.Infof("latest block from log poller is %d", h) var blocks []uint64 - for i := int64(0); i < hw.blockHistorySize; i++ { - blocks = append(blocks, uint64(h-i)) + for i := bs.blockSize - 1; i >= 0; i-- { + if h-i > 0 { + blocks = append(blocks, uint64(h-i)) + } } return blocks, nil } -func (hw *BlockSubscriber) getLogPollerBlocks(ctx context.Context, blocks []uint64) error { - // request the past LOOK_BACK blocksFromPoller from log poller - // returned blocksFromPoller are in ASC order - logpollerBlocks, err := hw.lp.GetBlocksRange(ctx, blocks, pg.WithParentCtx(ctx)) +func (bs *BlockSubscriber) initializeBlocks(blocks []uint64) error { + logpollerBlocks, err := bs.lp.GetBlocksRange(bs.ctx, blocks, pg.WithParentCtx(bs.ctx)) if err != nil { return err } - hw.mu.Lock() - for _, b := range logpollerBlocks { - hw.blocksFromPoller[b.BlockNumber] = b.BlockHash + for i, b := range logpollerBlocks { + if i == 0 { + bs.lastClearedBlock = b.BlockNumber - 1 + bs.lggr.Infof("lastClearedBlock is %d", bs.lastClearedBlock) + } + bs.blocks[b.BlockNumber] = b.BlockHash.Hex() } - hw.mu.Unlock() + bs.lggr.Infof("initialize with %d blocks", len(logpollerBlocks)) return nil } -func (hw *BlockSubscriber) buildHistory(block int64) ocr2keepers.BlockHistory { - var keys []BlockKey +func (bs *BlockSubscriber) buildHistory(block int64) ocr2keepers.BlockHistory { + var keys []ocr2keepers.BlockKey // populate keys slice in block DES order - for i := int64(0); i < hw.blockHistorySize; i++ { - if h1, ok1 := hw.blocksFromPoller[block-i]; ok1 { - // if a block exists in log poller, use block data from log poller - keys = append(keys, BlockKey{ - block: block - i, - hash: h1, - }) - } else if h2, ok2 := hw.blocksFromBroadcaster[block-i]; ok2 { - // if a block only exists in broadcaster, use data from broadcaster - keys = append(keys, BlockKey{ - block: block - i, - hash: h2, - }) - } else { - hw.lggr.Infof("block %d is missing", block-i) + for i := int64(0); i < bs.blockHistorySize; i++ { + if block-i > 0 { + if h, ok := bs.blocks[block-i]; ok { + keys = append(keys, ocr2keepers.BlockKey{ + Number: ocr2keepers.BlockNumber(block - i), + Hash: common.HexToHash(h), + }) + } else { + bs.lggr.Debugf("block %d is missing", block-i) + } } - // if a block does not exist in both log poller and broadcaster, skip } - return getBlockHistory(keys) + return keys } -func (hw *BlockSubscriber) cleanup() { - hw.mu.Lock() - defer hw.mu.Unlock() +func (bs *BlockSubscriber) cleanup() { + bs.mu.Lock() + defer bs.mu.Unlock() - hw.lggr.Infof("start clearing blocks from %d to %d", hw.lastClearedBlock+1, hw.lastSentBlock-hw.blockHistorySize) - for i := hw.lastClearedBlock + 1; i <= hw.lastSentBlock-hw.blockHistorySize; i++ { - delete(hw.blocksFromPoller, i) - delete(hw.blocksFromBroadcaster, i) + bs.lggr.Debugf("start clearing blocks from %d to %d", bs.lastClearedBlock+1, bs.lastSentBlock-bs.blockSize) + for i := bs.lastClearedBlock + 1; i <= bs.lastSentBlock-bs.blockSize; i++ { + delete(bs.blocks, i) } - hw.lastClearedBlock = hw.lastSentBlock - hw.blockHistorySize - hw.lggr.Infof("lastClearedBlock is set to %d", hw.lastClearedBlock) + bs.lastClearedBlock = bs.lastSentBlock - bs.blockSize + bs.lggr.Infof("lastClearedBlock is set to %d", bs.lastClearedBlock) } -func (hw *BlockSubscriber) Start(_ context.Context) error { - hw.lggr.Info("block subscriber started.") - return hw.sync.StartOnce("BlockSubscriber", func() error { - hw.mu.Lock() - defer hw.mu.Unlock() - _, hw.unsubscribe = hw.hb.Subscribe(&headWrapper{headC: hw.headC}) - hw.ctx, hw.cancel = context.WithCancel(context.Background()) - - // poll from head broadcaster channel and push to subscribers - { - go func(ctx context.Context) { - for { - select { - case bk := <-hw.headC: - hw.mu.Lock() - if hw.lastClearedBlock == 0 { - hw.lastClearedBlock = bk.block - 1 - hw.lggr.Infof("lastClearedBlock is %d", hw.lastClearedBlock) - } - hw.blocksFromBroadcaster[bk.block] = bk.hash - hw.lggr.Infof("blocksFromBroadcaster block %d hash is %s", bk.block, bk.hash.String()) - - history := hw.buildHistory(bk.block) - - hw.lastSentBlock = bk.block - hw.lggr.Infof("lastSentBlock is %d", hw.lastSentBlock) - // send history to all subscribers - for _, subC := range hw.subscribers { - subC <- history - } - hw.lggr.Infof("published block history with length %d to %d subscriber(s)", len(history), len(hw.subscribers)) - - hw.mu.Unlock() - case <-ctx.Done(): - return - } - } - }(hw.ctx) +func (bs *BlockSubscriber) Start(ctx context.Context) error { + bs.lggr.Info("block subscriber started.") + return bs.sync.StartOnce("BlockSubscriber", func() error { + bs.mu.Lock() + defer bs.mu.Unlock() + bs.ctx, bs.cancel = context.WithCancel(context.Background()) + // initialize the blocks map with the recent blockSize blocks + blocks, err := bs.getBlockRange(bs.ctx) + if err != nil { + bs.lggr.Errorf("failed to get block range", err) } + err = bs.initializeBlocks(blocks) + if err != nil { + bs.lggr.Errorf("failed to get log poller blocks", err) + } + + _, bs.unsubscribe = bs.hb.Subscribe(&headWrapper{headC: bs.headC, lggr: bs.lggr}) - // poll logs from log poller at an interval and update block map + // poll from head broadcaster channel and push to subscribers { go func(ctx context.Context) { - ticker := time.NewTicker(PollLogInterval) for { select { - case <-ticker.C: - blocks, err := hw.getBlockRange(ctx) - if err != nil { - hw.lggr.Infof("failed to get block range", err) - return - } - err = hw.getLogPollerBlocks(ctx, blocks) - if err != nil { - hw.lggr.Infof("failed to get log poller blocks", err) + case h := <-bs.headC: + if h != nil { + bs.processHead(h) } case <-ctx.Done(): - ticker.Stop() return } } - }(hw.ctx) + }(bs.ctx) } // clean up block maps { go func(ctx context.Context) { - ticker := time.NewTicker(CleanUpInterval) + ticker := time.NewTicker(cleanUpInterval) for { select { case <-ticker.C: - hw.cleanup() + bs.cleanup() case <-ctx.Done(): ticker.Stop() return } } - }(hw.ctx) + }(bs.ctx) } return nil }) } -func (hw *BlockSubscriber) Close() error { - hw.lggr.Info("stop block subscriber") - return hw.sync.StopOnce("BlockSubscriber", func() error { - hw.mu.Lock() - defer hw.mu.Unlock() +func (bs *BlockSubscriber) Close() error { + bs.lggr.Info("stop block subscriber") + return bs.sync.StopOnce("BlockSubscriber", func() error { + bs.mu.Lock() + defer bs.mu.Unlock() - close(hw.headC) - hw.cancel() - hw.unsubscribe() + bs.cancel() + bs.unsubscribe() return nil }) } -func (hw *BlockSubscriber) Subscribe() (int, chan ocr2keepers.BlockHistory, error) { - hw.mu.Lock() - defer hw.mu.Unlock() +func (bs *BlockSubscriber) Subscribe() (int, chan ocr2keepers.BlockHistory, error) { + bs.mu.Lock() + defer bs.mu.Unlock() - hw.maxSubId++ - subId := hw.maxSubId - newC := make(chan ocr2keepers.BlockHistory, ChannelSize) - hw.subscribers[subId] = newC - hw.lggr.Infof("new subscriber %d", subId) + bs.maxSubId++ + subId := bs.maxSubId + newC := make(chan ocr2keepers.BlockHistory, channelSize) + bs.subscribers[subId] = newC + bs.lggr.Infof("new subscriber %d", subId) return subId, newC, nil } -func (hw *BlockSubscriber) Unsubscribe(subId int) error { - hw.mu.Lock() - defer hw.mu.Unlock() +func (bs *BlockSubscriber) Unsubscribe(subId int) error { + bs.mu.Lock() + defer bs.mu.Unlock() - c, ok := hw.subscribers[subId] + c, ok := bs.subscribers[subId] if !ok { return fmt.Errorf("subscriber %d does not exist", subId) } close(c) - delete(hw.subscribers, subId) - hw.lggr.Infof("subscriber %d unsubscribed", subId) + delete(bs.subscribers, subId) + bs.lggr.Infof("subscriber %d unsubscribed", subId) return nil } +func (bs *BlockSubscriber) processHead(h *evmtypes.Head) { + bs.mu.Lock() + defer bs.mu.Unlock() + // head parent is a linked list with EVM finality depth + // when re-org happens, new heads will have pointers to the new blocks + i := int64(0) + for cp := h; cp != nil; cp = cp.Parent { + if cp != h && bs.blocks[cp.Number] != cp.Hash.Hex() { + bs.lggr.Warnf("overriding block %d old hash %s with new hash %s due to re-org", cp.Number, bs.blocks[cp.Number], cp.Hash.Hex()) + } + bs.blocks[cp.Number] = cp.Hash.Hex() + i++ + if i > bs.blockSize { + break + } + } + bs.lggr.Debugf("blocks block %d hash is %s", h.Number, h.Hash.Hex()) + + history := bs.buildHistory(h.Number) + block := &ocr2keepers.BlockKey{ + Number: ocr2keepers.BlockNumber(h.Number), + } + copy(block.Hash[:], h.Hash[:]) + bs.latestBlock.Store(block) + bs.lastSentBlock = h.Number + // send history to all subscribers + for _, subC := range bs.subscribers { + // wrapped in a select to not get blocked by certain subscribers + select { + case subC <- history: + default: + bs.lggr.Warnf("subscriber channel is full, dropping block history with length %d", len(history)) + } + } + + bs.lggr.Debugf("published block history with length %d and latestBlock %d to %d subscriber(s)", len(history), bs.latestBlock.Load(), len(bs.subscribers)) +} + +func (bs *BlockSubscriber) queryBlocksMap(bn int64) (string, bool) { + bs.mu.RLock() + defer bs.mu.RUnlock() + v, ok := bs.blocks[bn] + return v, ok +} + type headWrapper struct { - headC chan BlockKey + headC chan *evmtypes.Head + lggr logger.Logger } func (w *headWrapper) OnNewLongestChain(_ context.Context, head *evmtypes.Head) { if head != nil { - w.headC <- BlockKey{ - block: head.Number, - hash: head.BlockHash(), + select { + case w.headC <- head: + default: + w.lggr.Debugf("head channel is full, discarding head %+v", head) } } } - -func getBlockHistory(keys []BlockKey) ocr2keepers.BlockHistory { - var blockKeys []ocr2keepers.BlockKey - for _, k := range keys { - blockKeys = append(blockKeys, k.getBlockKey()) - } - return blockKeys -} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber_test.go index a34d7aac8d6..19dfa7d9281 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber_test.go @@ -7,7 +7,7 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -16,17 +16,21 @@ import ( "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" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" ) -const blockHistorySize = int64(4) +const historySize = 4 +const blockSize = int64(4) func TestBlockSubscriber_Subscribe(t *testing.T) { lggr := logger.TestLogger(t) var hb types.HeadBroadcaster var lp logpoller.LogPoller - bs := NewBlockSubscriber(hb, lp, blockHistorySize, lggr) + bs := NewBlockSubscriber(hb, lp, lggr) + bs.blockHistorySize = historySize + bs.blockSize = blockSize subId, _, err := bs.Subscribe() assert.Nil(t, err) assert.Equal(t, subId, 1) @@ -43,7 +47,9 @@ func TestBlockSubscriber_Unsubscribe(t *testing.T) { var hb types.HeadBroadcaster var lp logpoller.LogPoller - bs := NewBlockSubscriber(hb, lp, blockHistorySize, lggr) + bs := NewBlockSubscriber(hb, lp, lggr) + bs.blockHistorySize = historySize + bs.blockSize = blockSize subId, _, err := bs.Subscribe() assert.Nil(t, err) assert.Equal(t, subId, 1) @@ -59,7 +65,9 @@ func TestBlockSubscriber_Unsubscribe_Failure(t *testing.T) { var hb types.HeadBroadcaster var lp logpoller.LogPoller - bs := NewBlockSubscriber(hb, lp, blockHistorySize, lggr) + bs := NewBlockSubscriber(hb, lp, lggr) + bs.blockHistorySize = historySize + bs.blockSize = blockSize err := bs.Unsubscribe(2) assert.Equal(t, err.Error(), "subscriber 2 does not exist") } @@ -81,7 +89,7 @@ func TestBlockSubscriber_GetBlockRange(t *testing.T) { { Name: "get block range", LatestBlock: 100, - ExpectedBlocks: []uint64{100, 99, 98, 97}, + ExpectedBlocks: []uint64{97, 98, 99, 100}, }, } @@ -89,8 +97,10 @@ func TestBlockSubscriber_GetBlockRange(t *testing.T) { t.Run(tc.Name, func(t *testing.T) { lp := new(mocks.LogPoller) lp.On("LatestBlock", mock.Anything).Return(tc.LatestBlock, tc.LatestBlockErr) - bs := NewBlockSubscriber(hb, lp, blockHistorySize, lggr) - blocks, err := bs.getBlockRange(context.Background()) + bs := NewBlockSubscriber(hb, lp, lggr) + bs.blockHistorySize = historySize + bs.blockSize = blockSize + blocks, err := bs.getBlockRange(testutils.Context(t)) if tc.LatestBlockErr != nil { assert.Equal(t, tc.LatestBlockErr.Error(), err.Error()) @@ -101,15 +111,16 @@ func TestBlockSubscriber_GetBlockRange(t *testing.T) { } } -func TestBlockSubscriber_GetLogPollerBlocks(t *testing.T) { +func TestBlockSubscriber_InitializeBlocks(t *testing.T) { lggr := logger.TestLogger(t) var hb types.HeadBroadcaster tests := []struct { - Name string - Blocks []uint64 - PollerBlocks []logpoller.LogPollerBlock - Error error + Name string + Blocks []uint64 + PollerBlocks []logpoller.LogPollerBlock + LastClearedBlock int64 + Error error }{ { Name: "failed to get latest block", @@ -117,25 +128,26 @@ func TestBlockSubscriber_GetLogPollerBlocks(t *testing.T) { }, { Name: "get block range", - Blocks: []uint64{100, 99, 98, 97}, + Blocks: []uint64{97, 98, 99, 100}, PollerBlocks: []logpoller.LogPollerBlock{ { - BlockNumber: 100, + BlockNumber: 97, BlockHash: common.HexToHash("0x5e7fadfc14e1cfa9c05a91128c16a20c6cbc3be38b4723c3d482d44bf9c0e07b"), }, { - BlockNumber: 99, + BlockNumber: 98, BlockHash: common.HexToHash("0xaf3f8b36a27837e9f1ea3b4da7cdbf2ce0bdf7ef4e87d23add83b19438a2fcba"), }, { - BlockNumber: 98, + BlockNumber: 99, BlockHash: common.HexToHash("0xa7ac5bbc905b81f3a2ad9fb8ef1fe45f4a95768df456736952e4ec6c21296abe"), }, { - BlockNumber: 97, + BlockNumber: 100, BlockHash: common.HexToHash("0xa7ac5bbc905b81f3a2ad9fb8ef1fe45f4a95768df456736952e4ec6c21296abe"), }, }, + LastClearedBlock: 96, }, } @@ -143,17 +155,20 @@ func TestBlockSubscriber_GetLogPollerBlocks(t *testing.T) { t.Run(tc.Name, func(t *testing.T) { lp := new(mocks.LogPoller) lp.On("GetBlocksRange", mock.Anything, tc.Blocks, mock.Anything).Return(tc.PollerBlocks, tc.Error) - bs := NewBlockSubscriber(hb, lp, blockHistorySize, lggr) - err := bs.getLogPollerBlocks(context.Background(), tc.Blocks) + bs := NewBlockSubscriber(hb, lp, lggr) + bs.blockHistorySize = historySize + bs.blockSize = blockSize + err := bs.initializeBlocks(tc.Blocks) if tc.Error != nil { assert.Equal(t, tc.Error.Error(), err.Error()) } else { for _, b := range tc.PollerBlocks { - h, ok := bs.blocksFromPoller[b.BlockNumber] + h, ok := bs.blocks[b.BlockNumber] assert.True(t, ok) - assert.Equal(t, b.BlockHash, h) + assert.Equal(t, b.BlockHash.Hex(), h) } + assert.Equal(t, tc.LastClearedBlock, bs.lastClearedBlock) } }) } @@ -165,37 +180,43 @@ func TestBlockSubscriber_BuildHistory(t *testing.T) { lp := new(mocks.LogPoller) tests := []struct { - Name string - BlocksFromLogPoller map[int64]common.Hash - BlocksFromBroadcaster map[int64]common.Hash - Block int64 - ExpectedHistory ocr2keepers.BlockHistory + Name string + Blocks map[int64]string + Block int64 + ExpectedHistory ocr2keepers.BlockHistory }{ { Name: "build history", - BlocksFromLogPoller: map[int64]common.Hash{ - 100: common.HexToHash("0x5e7fadfc14e1cfa9c05a91128c16a20c6cbc3be38b4723c3d482d44bf9c0e07b"), - 97: common.HexToHash("0xa7ac5bbc905b81f3a2ad9fb8ef1fe45f4a95768df456736952e4ec6c21296abe"), - 96: common.HexToHash("0x44f23c588193695abd92697ddc1ba032376d0a784818eddd2d159eee4c41f03f"), - }, - BlocksFromBroadcaster: map[int64]common.Hash{ - 100: common.HexToHash("0xaf3f8b36a27837e9f1ea3b4da7cdbf2ce0bdf7ef4e87d23add83b19438a2fcba"), - 98: common.HexToHash("0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0"), + Blocks: map[int64]string{ + 100: "0xaf3f8b36a27837e9f1ea3b4da7cdbf2ce0bdf7ef4e87d23add83b19438a2fcba", + 98: "0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0", + 97: "0xa7ac5bbc905b81f3a2ad9fb8ef1fe45f4a95768df456736952e4ec6c21296abe", + 95: "0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0", }, Block: 100, ExpectedHistory: ocr2keepers.BlockHistory{ - "100|0x5e7fadfc14e1cfa9c05a91128c16a20c6cbc3be38b4723c3d482d44bf9c0e07b", - "98|0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0", - "97|0xa7ac5bbc905b81f3a2ad9fb8ef1fe45f4a95768df456736952e4ec6c21296abe", + ocr2keepers.BlockKey{ + Number: 100, + Hash: common.HexToHash("0xaf3f8b36a27837e9f1ea3b4da7cdbf2ce0bdf7ef4e87d23add83b19438a2fcba"), + }, + ocr2keepers.BlockKey{ + Number: 98, + Hash: common.HexToHash("0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0"), + }, + ocr2keepers.BlockKey{ + Number: 97, + Hash: common.HexToHash("0xa7ac5bbc905b81f3a2ad9fb8ef1fe45f4a95768df456736952e4ec6c21296abe"), + }, }, }, } for _, tc := range tests { t.Run(tc.Name, func(t *testing.T) { - bs := NewBlockSubscriber(hb, lp, blockHistorySize, lggr) - bs.blocksFromPoller = tc.BlocksFromLogPoller - bs.blocksFromBroadcaster = tc.BlocksFromBroadcaster + bs := NewBlockSubscriber(hb, lp, lggr) + bs.blockHistorySize = historySize + bs.blockSize = blockSize + bs.blocks = tc.Blocks history := bs.buildHistory(tc.Block) assert.Equal(t, history, tc.ExpectedHistory) @@ -209,57 +230,44 @@ func TestBlockSubscriber_Cleanup(t *testing.T) { lp := new(mocks.LogPoller) tests := []struct { - Name string - BlocksFromLogPoller map[int64]common.Hash - BlocksFromBroadcaster map[int64]common.Hash - LastClearedBlock int64 - LastSentBlock int64 - ExpectedLastClearedBlock int64 - ExpectedLogPollerBlocks map[int64]common.Hash - ExpectedBroadcasterBlocks map[int64]common.Hash + Name string + Blocks map[int64]string + LastClearedBlock int64 + LastSentBlock int64 + ExpectedLastClearedBlock int64 + ExpectedBlocks map[int64]string }{ { Name: "build history", - BlocksFromLogPoller: map[int64]common.Hash{ - 101: common.HexToHash("0x5e7fadfc14e1cfa9c05a91128c16a20c6cbc3be38b4723c3d482d44bf9c0e07b"), - 100: common.HexToHash("0x5e7fadfc14e1cfa9c05a91128c16a20c6cbc3be38b4723c3d482d44bf9c0e07b"), - 97: common.HexToHash("0xa7ac5bbc905b81f3a2ad9fb8ef1fe45f4a95768df456736952e4ec6c21296abe"), - 96: common.HexToHash("0x44f23c588193695abd92697ddc1ba032376d0a784818eddd2d159eee4c41f03f"), - 95: common.HexToHash("0x44f23c588193695abd92697ddc1ba032376d0a784818eddd2d159eee4c41f03f"), - }, - BlocksFromBroadcaster: map[int64]common.Hash{ - 102: common.HexToHash("0xaf3f8b36a27837e9f1ea3b4da7cdbf2ce0bdf7ef4e87d23add83b19438a2fcba"), - 100: common.HexToHash("0xaf3f8b36a27837e9f1ea3b4da7cdbf2ce0bdf7ef4e87d23add83b19438a2fcba"), - 98: common.HexToHash("0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0"), - 95: common.HexToHash("0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0"), + Blocks: map[int64]string{ + 102: "0xaf3f8b36a27837e9f1ea3b4da7cdbf2ce0bdf7ef4e87d23add83b19438a2fcba", + 100: "0xaf3f8b36a27837e9f1ea3b4da7cdbf2ce0bdf7ef4e87d23add83b19438a2fcba", + 98: "0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0", + 95: "0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0", }, LastClearedBlock: 94, LastSentBlock: 101, ExpectedLastClearedBlock: 97, - ExpectedLogPollerBlocks: map[int64]common.Hash{ - 101: common.HexToHash("0x5e7fadfc14e1cfa9c05a91128c16a20c6cbc3be38b4723c3d482d44bf9c0e07b"), - 100: common.HexToHash("0x5e7fadfc14e1cfa9c05a91128c16a20c6cbc3be38b4723c3d482d44bf9c0e07b"), - }, - ExpectedBroadcasterBlocks: map[int64]common.Hash{ - 102: common.HexToHash("0xaf3f8b36a27837e9f1ea3b4da7cdbf2ce0bdf7ef4e87d23add83b19438a2fcba"), - 100: common.HexToHash("0xaf3f8b36a27837e9f1ea3b4da7cdbf2ce0bdf7ef4e87d23add83b19438a2fcba"), - 98: common.HexToHash("0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0"), + ExpectedBlocks: map[int64]string{ + 102: "0xaf3f8b36a27837e9f1ea3b4da7cdbf2ce0bdf7ef4e87d23add83b19438a2fcba", + 100: "0xaf3f8b36a27837e9f1ea3b4da7cdbf2ce0bdf7ef4e87d23add83b19438a2fcba", + 98: "0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0", }, }, } for _, tc := range tests { t.Run(tc.Name, func(t *testing.T) { - bs := NewBlockSubscriber(hb, lp, blockHistorySize, lggr) - bs.blocksFromPoller = tc.BlocksFromLogPoller - bs.blocksFromBroadcaster = tc.BlocksFromBroadcaster + bs := NewBlockSubscriber(hb, lp, lggr) + bs.blockHistorySize = historySize + bs.blockSize = blockSize + bs.blocks = tc.Blocks bs.lastClearedBlock = tc.LastClearedBlock bs.lastSentBlock = tc.LastSentBlock bs.cleanup() assert.Equal(t, tc.ExpectedLastClearedBlock, bs.lastClearedBlock) - assert.Equal(t, tc.ExpectedBroadcasterBlocks, bs.blocksFromBroadcaster) - assert.Equal(t, tc.ExpectedLogPollerBlocks, bs.blocksFromPoller) + assert.Equal(t, tc.ExpectedBlocks, bs.blocks) }) } } @@ -269,60 +277,183 @@ func TestBlockSubscriber_Start(t *testing.T) { hb := commonmocks.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).Maybe().Return(int64(0), fmt.Errorf("error")) + lp.On("LatestBlock", mock.Anything).Return(int64(100), nil) + blocks := []uint64{97, 98, 99, 100} + pollerBlocks := []logpoller.LogPollerBlock{ + { + BlockNumber: 97, + BlockHash: common.HexToHash("0xda2f9d1359eadd7b93338703adc07d942021a78195564038321ef53f23f87333"), + }, + { + BlockNumber: 98, + BlockHash: common.HexToHash("0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0"), + }, + { + BlockNumber: 99, + BlockHash: common.HexToHash("0x9bc2b51e147f9cad05f1614b7f1d8181cb24c544cbcf841f3155e54e752a3b44"), + }, + { + BlockNumber: 100, + BlockHash: common.HexToHash("0x5e7fadfc14e1cfa9c05a91128c16a20c6cbc3be38b4723c3d482d44bf9c0e07b"), + }, + } + + lp.On("GetBlocksRange", mock.Anything, blocks, mock.Anything).Return(pollerBlocks, nil) - bs := NewBlockSubscriber(hb, lp, blockHistorySize, lggr) + bs := NewBlockSubscriber(hb, lp, lggr) + bs.blockHistorySize = historySize + bs.blockSize = blockSize err := bs.Start(context.Background()) assert.Nil(t, err) + h97 := evmtypes.Head{ + Number: 97, + Hash: common.HexToHash("0xda2f9d1359eadd7b93338703adc07d942021a78195564038321ef53f23f87333"), + Parent: nil, + } + h98 := evmtypes.Head{ + Number: 98, + Hash: common.HexToHash("0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0"), + Parent: &h97, + } + h99 := evmtypes.Head{ + Number: 99, + Hash: common.HexToHash("0x9bc2b51e147f9cad05f1614b7f1d8181cb24c544cbcf841f3155e54e752a3b44"), + Parent: &h98, + } + h100 := evmtypes.Head{ + Number: 100, + Hash: common.HexToHash("0x5e7fadfc14e1cfa9c05a91128c16a20c6cbc3be38b4723c3d482d44bf9c0e07b"), + Parent: &h99, + } + // no subscribers yet - bs.headC <- BlockKey{ - block: 100, - hash: common.HexToHash("0x5e7fadfc14e1cfa9c05a91128c16a20c6cbc3be38b4723c3d482d44bf9c0e07b"), + bs.headC <- &h100 + + expectedBlocks := map[int64]string{ + 97: "0xda2f9d1359eadd7b93338703adc07d942021a78195564038321ef53f23f87333", + 98: "0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0", + 99: "0x9bc2b51e147f9cad05f1614b7f1d8181cb24c544cbcf841f3155e54e752a3b44", + 100: "0x5e7fadfc14e1cfa9c05a91128c16a20c6cbc3be38b4723c3d482d44bf9c0e07b", } // sleep 100 milli to wait for the go routine to finish time.Sleep(100 * time.Millisecond) - assert.Equal(t, blockHistorySize, bs.blockHistorySize) - assert.Equal(t, int64(99), bs.lastClearedBlock) + assert.Equal(t, int64(historySize), bs.blockHistorySize) + assert.Equal(t, int64(96), bs.lastClearedBlock) assert.Equal(t, int64(100), bs.lastSentBlock) + assert.Equal(t, expectedBlocks, bs.blocks) // add 1 subscriber subId1, c1, err := bs.Subscribe() assert.Nil(t, err) assert.Equal(t, 1, subId1) - bs.headC <- BlockKey{ - block: 101, - hash: common.HexToHash("0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0"), + h101 := &evmtypes.Head{ + Number: 101, + Hash: common.HexToHash("0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0"), + Parent: &h100, } + bs.headC <- h101 time.Sleep(100 * time.Millisecond) bk1 := <-c1 - assert.Equal(t, ocr2keepers.BlockHistory{"101|0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0", "100|0x5e7fadfc14e1cfa9c05a91128c16a20c6cbc3be38b4723c3d482d44bf9c0e07b"}, bk1) + assert.Equal(t, ocr2keepers.BlockHistory{ + ocr2keepers.BlockKey{ + Number: 101, + Hash: common.HexToHash("0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0"), + }, + ocr2keepers.BlockKey{ + Number: 100, + Hash: common.HexToHash("0x5e7fadfc14e1cfa9c05a91128c16a20c6cbc3be38b4723c3d482d44bf9c0e07b"), + }, + ocr2keepers.BlockKey{ + Number: 99, + Hash: common.HexToHash("0x9bc2b51e147f9cad05f1614b7f1d8181cb24c544cbcf841f3155e54e752a3b44"), + }, + ocr2keepers.BlockKey{ + Number: 98, + Hash: common.HexToHash("0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0"), + }, + }, bk1) // add 2nd subscriber subId2, c2, err := bs.Subscribe() assert.Nil(t, err) assert.Equal(t, 2, subId2) - bs.headC <- BlockKey{ - block: 103, - hash: common.HexToHash("0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0"), + // re-org happens + new99 := &evmtypes.Head{ + Number: 99, + Hash: common.HexToHash("0x70c03acc4ddbfb253ba41a25dc13fb21b25da8b63bcd1aa7fb55713d33a36c71"), + Parent: &h98, + } + new100 := &evmtypes.Head{ + Number: 100, + Hash: common.HexToHash("0x8a876b62d252e63e16cf3487db3486c0a7c0a8e06bc3792a3b116c5ca480503f"), + Parent: new99, + } + new101 := &evmtypes.Head{ + Number: 101, + Hash: common.HexToHash("0x41b5842b8847dcf834e39556d2ac51cc7d960a7de9471ec504673d0038fd6c8e"), + Parent: new100, + } + + new102 := &evmtypes.Head{ + Number: 102, + Hash: common.HexToHash("0x9ac1ebc307554cf1bcfcc2a49462278e89d6878d613a33df38a64d0aeac971b5"), + Parent: new101, } + bs.headC <- new102 + time.Sleep(100 * time.Millisecond) bk1 = <-c1 assert.Equal(t, - ocr2keepers.BlockHistory{"103|0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0", "101|0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0", "100|0x5e7fadfc14e1cfa9c05a91128c16a20c6cbc3be38b4723c3d482d44bf9c0e07b"}, + ocr2keepers.BlockHistory{ + ocr2keepers.BlockKey{ + Number: 102, + Hash: common.HexToHash("0x9ac1ebc307554cf1bcfcc2a49462278e89d6878d613a33df38a64d0aeac971b5"), + }, + ocr2keepers.BlockKey{ + Number: 101, + Hash: common.HexToHash("0x41b5842b8847dcf834e39556d2ac51cc7d960a7de9471ec504673d0038fd6c8e"), + }, + ocr2keepers.BlockKey{ + Number: 100, + Hash: common.HexToHash("0x8a876b62d252e63e16cf3487db3486c0a7c0a8e06bc3792a3b116c5ca480503f"), + }, + ocr2keepers.BlockKey{ + Number: 99, + Hash: common.HexToHash("0x70c03acc4ddbfb253ba41a25dc13fb21b25da8b63bcd1aa7fb55713d33a36c71"), + }, + }, bk1, ) + bk2 := <-c2 assert.Equal(t, - ocr2keepers.BlockHistory{"103|0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0", "101|0xc20c7b47466c081a44a3b168994e89affe85cb894547845d938f923b67c633c0", "100|0x5e7fadfc14e1cfa9c05a91128c16a20c6cbc3be38b4723c3d482d44bf9c0e07b"}, + ocr2keepers.BlockHistory{ + ocr2keepers.BlockKey{ + Number: 102, + Hash: common.HexToHash("0x9ac1ebc307554cf1bcfcc2a49462278e89d6878d613a33df38a64d0aeac971b5"), + }, + ocr2keepers.BlockKey{ + Number: 101, + Hash: common.HexToHash("0x41b5842b8847dcf834e39556d2ac51cc7d960a7de9471ec504673d0038fd6c8e"), + }, + ocr2keepers.BlockKey{ + Number: 100, + Hash: common.HexToHash("0x8a876b62d252e63e16cf3487db3486c0a7c0a8e06bc3792a3b116c5ca480503f"), + }, + ocr2keepers.BlockKey{ + Number: 99, + Hash: common.HexToHash("0x70c03acc4ddbfb253ba41a25dc13fb21b25da8b63bcd1aa7fb55713d33a36c71"), + }, + }, bk2, ) - assert.Equal(t, int64(103), bs.lastSentBlock) - assert.Equal(t, int64(99), bs.lastClearedBlock) + assert.Equal(t, int64(102), bs.lastSentBlock) + assert.Equal(t, int64(96), bs.lastClearedBlock) } diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/core/interfaces.go b/core/services/ocr2/plugins/ocr2keeper/evm21/core/interfaces.go new file mode 100644 index 00000000000..e6d9bb3d8a7 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/core/interfaces.go @@ -0,0 +1,14 @@ +package core + +import ( + "context" + + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" +) + +// UpkeepStateReader is the interface for reading the current state of upkeeps. +// +//go:generate mockery --quiet --name UpkeepStateReader --output ./mocks/ --case=underscore +type UpkeepStateReader interface { + SelectByWorkIDsInRange(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/core/mocks/upkeep_state_reader.go b/core/services/ocr2/plugins/ocr2keeper/evm21/core/mocks/upkeep_state_reader.go new file mode 100644 index 00000000000..09a5f299463 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/core/mocks/upkeep_state_reader.go @@ -0,0 +1,64 @@ +// Code generated by mockery v2.28.1. DO NOT EDIT. + +package mocks + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" + + types "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" +) + +// UpkeepStateReader is an autogenerated mock type for the UpkeepStateReader type +type UpkeepStateReader struct { + mock.Mock +} + +// SelectByWorkIDsInRange provides a mock function with given fields: ctx, start, end, workIDs +func (_m *UpkeepStateReader) SelectByWorkIDsInRange(ctx context.Context, start int64, end int64, workIDs ...string) ([]types.UpkeepState, error) { + _va := make([]interface{}, len(workIDs)) + for _i := range workIDs { + _va[_i] = workIDs[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, start, end) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 []types.UpkeepState + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, int64, int64, ...string) ([]types.UpkeepState, error)); ok { + return rf(ctx, start, end, workIDs...) + } + if rf, ok := ret.Get(0).(func(context.Context, int64, int64, ...string) []types.UpkeepState); ok { + r0 = rf(ctx, start, end, workIDs...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]types.UpkeepState) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, int64, int64, ...string) error); ok { + r1 = rf(ctx, start, end, workIDs...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +type mockConstructorTestingTNewUpkeepStateReader interface { + mock.TestingT + Cleanup(func()) +} + +// NewUpkeepStateReader creates a new instance of UpkeepStateReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewUpkeepStateReader(t mockConstructorTestingTNewUpkeepStateReader) *UpkeepStateReader { + mock := &UpkeepStateReader{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/core/payload.go b/core/services/ocr2/plugins/ocr2keeper/evm21/core/payload.go new file mode 100644 index 00000000000..d7336737674 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/core/payload.go @@ -0,0 +1,39 @@ +package core + +import ( + "encoding/hex" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/crypto" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" +) + +var ( + ErrInvalidUpkeepID = fmt.Errorf("invalid upkeepID") +) + +func UpkeepWorkID(uid ocr2keepers.UpkeepIdentifier, trigger ocr2keepers.Trigger) string { + var triggerExtBytes []byte + if trigger.LogTriggerExtension != nil { + triggerExtBytes = trigger.LogTriggerExtension.LogIdentifier() + } + hash := crypto.Keccak256(append(uid[:], triggerExtBytes...)) + return hex.EncodeToString(hash[:]) +} + +func NewUpkeepPayload(id *big.Int, trigger ocr2keepers.Trigger, checkData []byte) (ocr2keepers.UpkeepPayload, error) { + uid := &ocr2keepers.UpkeepIdentifier{} + ok := uid.FromBigInt(id) + if !ok { + return ocr2keepers.UpkeepPayload{}, ErrInvalidUpkeepID + } + p := ocr2keepers.UpkeepPayload{ + UpkeepID: *uid, + Trigger: trigger, + CheckData: checkData, + } + // set work id based on upkeep id and trigger + p.WorkID = UpkeepWorkID(*uid, trigger) + return p, nil +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/core/payload_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/core/payload_test.go new file mode 100644 index 00000000000..f7b245ffce0 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/core/payload_test.go @@ -0,0 +1,147 @@ +package core + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + + "github.com/stretchr/testify/assert" +) + +func TestWorkID(t *testing.T) { + tests := []struct { + name string + upkeepID string + trigger ocr2keepers.Trigger + expected string + }{ + { + name: "happy flow no extension", + upkeepID: "12345", + trigger: ocr2keepers.Trigger{ + BlockNumber: 123, + BlockHash: common.HexToHash("0xabcdef"), + }, + expected: "e546b0a52c2879744f6def0fb483d581dc6d205de83af8440456804dd8b62380", + }, + { + name: "empty trigger", + upkeepID: "12345", + trigger: ocr2keepers.Trigger{}, + // same as with no extension + expected: "e546b0a52c2879744f6def0fb483d581dc6d205de83af8440456804dd8b62380", + }, + { + name: "happy flow with extension", + upkeepID: GenUpkeepID(ocr2keepers.LogTrigger, "12345").String(), + trigger: ocr2keepers.Trigger{ + BlockNumber: 123, + BlockHash: common.HexToHash("0xabcdef"), + LogTriggerExtension: &ocr2keepers.LogTriggerExtension{ + Index: 1, + TxHash: common.HexToHash("0x12345"), + }, + }, + expected: "db0e245ff4e7551d6c862d9a0eb5466624e1439ad1db262a7a3d6137d892d0a3", + }, + { + name: "happy path example from an actual tx", + upkeepID: "57755329819103678328139927896464733492677608573736038892412245689671711489918", + trigger: ocr2keepers.Trigger{ + BlockNumber: 39344455, + BlockHash: common.HexToHash("0xb41258d18cd44ebf7a0d70de011f2bc4a67c9b68e8b6dada864045d8543bb020"), + LogTriggerExtension: &ocr2keepers.LogTriggerExtension{ + Index: 41, + TxHash: common.HexToHash("0x44079b1b33aff337dbf17b9e12c5724ecab979c50c8201a9814a488ff3e22384"), + }, + }, + expected: "cdb4cfd9b4855b28d243d099c41b832da6b2d99dda3e7d09b900899afd09328f", + }, + { + name: "empty upkeepID", + upkeepID: "0", + trigger: ocr2keepers.Trigger{ + BlockNumber: 123, + BlockHash: common.HexToHash("0xabcdef"), + }, + expected: "290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563", + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + // Convert the string to a big.Int + var id big.Int + _, success := id.SetString(tc.upkeepID, 10) + if !success { + t.Fatal("Invalid big integer value") + } + uid := &ocr2keepers.UpkeepIdentifier{} + ok := uid.FromBigInt(&id) + if !ok { + t.Fatal("Invalid upkeep identifier") + } + + res := UpkeepWorkID(*uid, tc.trigger) + assert.Equal(t, tc.expected, res, "UpkeepWorkID mismatch") + }) + } +} + +func TestNewUpkeepPayload(t *testing.T) { + tests := []struct { + name string + upkeepID *big.Int + upkeepType ocr2keepers.UpkeepType + trigger ocr2keepers.Trigger + check []byte + errored bool + workID string + }{ + { + name: "happy flow no extension", + upkeepID: big.NewInt(111), + upkeepType: ocr2keepers.ConditionTrigger, + trigger: ocr2keepers.Trigger{ + BlockNumber: 11, + BlockHash: common.HexToHash("0x11111"), + }, + check: []byte("check-data-111"), + workID: "39f2babe526038520877fc7c33d81accf578af4a06c5fa6b0d038cae36e12711", + }, + { + name: "happy flow with extension", + upkeepID: big.NewInt(111), + upkeepType: ocr2keepers.LogTrigger, + trigger: ocr2keepers.Trigger{ + BlockNumber: 11, + BlockHash: common.HexToHash("0x11111"), + LogTriggerExtension: &ocr2keepers.LogTriggerExtension{ + Index: 1, + TxHash: common.HexToHash("0x11111"), + }, + }, + check: []byte("check-data-111"), + workID: "d2fc1c0d626b480a4180f30b89142ae727c85e0b4dc0a82645bcef8062ff932a", + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + payload, err := NewUpkeepPayload( + tc.upkeepID, + tc.trigger, + tc.check, + ) + if tc.errored { + assert.Error(t, err) + return + } + assert.NoError(t, err) + + assert.Equal(t, tc.workID, payload.WorkID) + }) + } +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/core/testutil.go b/core/services/ocr2/plugins/ocr2keeper/evm21/core/testutil.go new file mode 100644 index 00000000000..47935b56f68 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/core/testutil.go @@ -0,0 +1,29 @@ +package core + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" +) + +// GenUpkeepID generates an ocr2keepers.UpkeepIdentifier with a specific UpkeepType and some random string +func GenUpkeepID(uType ocr2keepers.UpkeepType, rand string) ocr2keepers.UpkeepIdentifier { + b := append([]byte{1}, common.LeftPadBytes([]byte{uint8(uType)}, 15)...) + b = append(b, []byte(rand)...) + b = common.RightPadBytes(b, 32-len(b)) + if len(b) > 32 { + b = b[:32] + } + var id [32]byte + copy(id[:], b) + return ocr2keepers.UpkeepIdentifier(id) +} + +// UpkeepIDFromInt converts an int string to ocr2keepers.UpkeepIdentifier +func UpkeepIDFromInt(id string) ocr2keepers.UpkeepIdentifier { + uid := &ocr2keepers.UpkeepIdentifier{} + idInt, _ := big.NewInt(0).SetString(id, 10) + uid.FromBigInt(idInt) + return *uid +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger.go b/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger.go new file mode 100644 index 00000000000..9999aefbd25 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger.go @@ -0,0 +1,105 @@ +package core + +import ( + "fmt" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1" +) + +type triggerWrapper = automation_utils_2_1.KeeperRegistryBase21LogTrigger + +var ErrABINotParsable = fmt.Errorf("error parsing abi") + +// according to the upkeep type of the given id. +func PackTrigger(id *big.Int, trig triggerWrapper) ([]byte, error) { + var trigger []byte + var err error + + // construct utils abi + utilsABI, err := abi.JSON(strings.NewReader(automation_utils_2_1.AutomationUtilsABI)) + if err != nil { + return nil, fmt.Errorf("%w: %s", ErrABINotParsable, err) + } + + // pack trigger based on upkeep type + upkeepType, ok := getUpkeepTypeFromBigInt(id) + if !ok { + return nil, ErrInvalidUpkeepID + } + switch upkeepType { + case ocr2keepers.ConditionTrigger: + trig := automation_utils_2_1.KeeperRegistryBase21ConditionalTrigger{ + BlockNum: trig.BlockNum, + BlockHash: trig.BlockHash, + } + trigger, err = utilsABI.Pack("_conditionalTrigger", &trig) + case ocr2keepers.LogTrigger: + logTrig := automation_utils_2_1.KeeperRegistryBase21LogTrigger{ + BlockNum: trig.BlockNum, + BlockHash: trig.BlockHash, + LogIndex: trig.LogIndex, + TxHash: trig.TxHash, + } + trigger, err = utilsABI.Pack("_logTrigger", &logTrig) + default: + err = fmt.Errorf("unknown trigger type: %d", upkeepType) + } + if err != nil { + return nil, err + } + return trigger[4:], nil +} + +// UnpackTrigger unpacks the trigger from the given raw data, according to the upkeep type of the given id. +func UnpackTrigger(id *big.Int, raw []byte) (triggerWrapper, error) { + // construct utils abi + utilsABI, err := abi.JSON(strings.NewReader(automation_utils_2_1.AutomationUtilsABI)) + if err != nil { + return triggerWrapper{}, fmt.Errorf("%w: %s", ErrABINotParsable, err) + } + + upkeepType, ok := getUpkeepTypeFromBigInt(id) + if !ok { + return triggerWrapper{}, ErrInvalidUpkeepID + } + switch upkeepType { + case ocr2keepers.ConditionTrigger: + unpacked, err := utilsABI.Methods["_conditionalTrigger"].Inputs.Unpack(raw) + if err != nil { + return triggerWrapper{}, fmt.Errorf("%w: failed to unpack conditional trigger", err) + } + converted, ok := abi.ConvertType(unpacked[0], new(automation_utils_2_1.KeeperRegistryBase21ConditionalTrigger)).(*automation_utils_2_1.KeeperRegistryBase21ConditionalTrigger) + if !ok { + return triggerWrapper{}, fmt.Errorf("failed to convert type") + } + triggerW := triggerWrapper{ + BlockNum: converted.BlockNum, + } + copy(triggerW.BlockHash[:], converted.BlockHash[:]) + return triggerW, nil + case ocr2keepers.LogTrigger: + unpacked, err := utilsABI.Methods["_logTrigger"].Inputs.Unpack(raw) + if err != nil { + return triggerWrapper{}, fmt.Errorf("%w: failed to unpack log trigger", err) + } + converted, ok := abi.ConvertType(unpacked[0], new(automation_utils_2_1.KeeperRegistryBase21LogTrigger)).(*automation_utils_2_1.KeeperRegistryBase21LogTrigger) + if !ok { + return triggerWrapper{}, fmt.Errorf("failed to convert type") + } + triggerW := triggerWrapper{ + BlockNum: converted.BlockNum, + LogIndex: converted.LogIndex, + } + copy(triggerW.BlockHash[:], converted.BlockHash[:]) + copy(triggerW.TxHash[:], converted.TxHash[:]) + return triggerW, nil + default: + return triggerWrapper{}, fmt.Errorf("unknown trigger type: %d", upkeepType) + } +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger_test.go new file mode 100644 index 00000000000..5fa5ae5c910 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger_test.go @@ -0,0 +1,95 @@ +package core + +import ( + "fmt" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + "github.com/stretchr/testify/assert" +) + +func TestPackUnpackTrigger(t *testing.T) { + tests := []struct { + name string + id []byte + trigger triggerWrapper + encoded []byte + err error + }{ + { + "happy flow log trigger", + append([]byte{1}, common.LeftPadBytes([]byte{1}, 15)...), + triggerWrapper{ + BlockNum: 1, + BlockHash: common.HexToHash("0x01111111"), + LogIndex: 1, + TxHash: common.HexToHash("0x01111111"), + }, + func() []byte { + b, _ := hexutil.Decode("0x0000000000000000000000000000000000000000000000000000000001111111000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001111111") + return b + }(), + nil, + }, + { + "happy flow conditional trigger", + append([]byte{1}, common.LeftPadBytes([]byte{0}, 15)...), + triggerWrapper{ + BlockNum: 1, + BlockHash: common.HexToHash("0x01111111"), + }, + func() []byte { + b, _ := hexutil.Decode("0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001111111") + return b + }(), + nil, + }, + { + "invalid type", + append([]byte{1}, common.LeftPadBytes([]byte{8}, 15)...), + triggerWrapper{ + BlockNum: 1, + BlockHash: common.HexToHash("0x01111111"), + }, + []byte{}, + fmt.Errorf("unknown trigger type: %d", 8), + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + var idBytes [32]byte + copy(idBytes[:], tc.id) + id := ocr2keepers.UpkeepIdentifier(idBytes) + + encoded, err := PackTrigger(id.BigInt(), tc.trigger) + if tc.err != nil { + assert.EqualError(t, err, tc.err.Error()) + } else { + assert.NoError(t, err) + assert.Equal(t, tc.encoded, encoded) + decoded, err := UnpackTrigger(id.BigInt(), encoded) + assert.NoError(t, err) + assert.Equal(t, tc.trigger.BlockNum, decoded.BlockNum) + } + }) + } + + t.Run("unpacking invalid trigger", func(t *testing.T) { + _, err := UnpackTrigger(big.NewInt(0), []byte{1, 2, 3}) + assert.Error(t, err) + }) + + t.Run("unpacking unknown type", func(t *testing.T) { + uid := append([]byte{1}, common.LeftPadBytes([]byte{8}, 15)...) + var idBytes [32]byte + copy(idBytes[:], uid) + id := ocr2keepers.UpkeepIdentifier(idBytes) + decoded, _ := hexutil.Decode("0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001111111") + _, err := UnpackTrigger(id.BigInt(), decoded) + assert.EqualError(t, err, "unknown trigger type: 8") + }) +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/core/type.go b/core/services/ocr2/plugins/ocr2keeper/evm21/core/type.go new file mode 100644 index 00000000000..aeb56a16f62 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/core/type.go @@ -0,0 +1,34 @@ +package core + +import ( + "math/big" + + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" +) + +const ( + // upkeepTypeStartIndex is the index where the upkeep type bytes start. + // for 2.1 we use 11 zeros (reserved bytes for future use) + // and 1 byte to represent the type, with index equal upkeepTypeByteIndex + upkeepTypeStartIndex = 4 + // upkeepTypeByteIndex is the index of the byte that holds the upkeep type. + upkeepTypeByteIndex = 15 +) + +// GetUpkeepType returns the upkeep type from the given ID. +// it follows the same logic as the contract, but performs it locally. +func GetUpkeepType(id ocr2keepers.UpkeepIdentifier) ocr2keepers.UpkeepType { + for i := upkeepTypeStartIndex; i < upkeepTypeByteIndex; i++ { + if id[i] != 0 { // old id + return ocr2keepers.ConditionTrigger + } + } + typeByte := id[upkeepTypeByteIndex] + return ocr2keepers.UpkeepType(typeByte) +} + +func getUpkeepTypeFromBigInt(id *big.Int) (ocr2keepers.UpkeepType, bool) { + uid := &ocr2keepers.UpkeepIdentifier{} + ok := uid.FromBigInt(id) + return GetUpkeepType(*uid), ok +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/core/type_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/core/type_test.go new file mode 100644 index 00000000000..8a2a51533e5 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/core/type_test.go @@ -0,0 +1,55 @@ +package core + +import ( + "math/big" + "testing" + + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + + "github.com/stretchr/testify/assert" +) + +func TestGetUpkeepType(t *testing.T) { + tests := []struct { + name string + upkeepID []byte + upkeepType ocr2keepers.UpkeepType + }{ + { + "zeroed id", + big.NewInt(0).Bytes(), + ocr2keepers.ConditionTrigger, + }, + { + "old id", + []byte("5820911532554020907796191562093071158274499580927271776163559390280294438608"), + ocr2keepers.ConditionTrigger, + }, + { + "condition trigger", + GenUpkeepID(ocr2keepers.ConditionTrigger, "").BigInt().Bytes(), + ocr2keepers.ConditionTrigger, + }, + { + "log trigger", + GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt().Bytes(), + ocr2keepers.LogTrigger, + }, + { + "log trigger id", + func() []byte { + id, _ := big.NewInt(0).SetString("32329108151019397958065800113404894502874153543356521479058624064899121404671", 10) + return id.Bytes() + }(), + ocr2keepers.LogTrigger, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + uid := ocr2keepers.UpkeepIdentifier{} + copy(uid[:], tc.upkeepID) + assert.Equal(t, tc.upkeepType, GetUpkeepType(uid)) + }) + } +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/encoder.go b/core/services/ocr2/plugins/ocr2keeper/evm21/encoder.go deleted file mode 100644 index cc60bbd4d07..00000000000 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/encoder.go +++ /dev/null @@ -1,157 +0,0 @@ -package evm - -import ( - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/common" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" - "github.com/smartcontractkit/ocr2keepers/pkg/encoding" - - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider" -) - -var ( - ErrEmptyResults = fmt.Errorf("empty results; cannot encode") -) - -type EVMAutomationEncoder21 struct { - encoding.BasicEncoder - packer *evmRegistryPackerV2_1 -} - -type EVMAutomationUpkeepResult21 struct { - // Block is the block number used to build an UpkeepKey for this result - Block uint32 - // ID is the unique identifier for the upkeep - ID *big.Int - Eligible bool - FailureReason uint8 - GasUsed *big.Int - PerformData []byte - FastGasWei *big.Int - LinkNative *big.Int - // CheckBlockNumber is the block number that the contract indicates the - // upkeep was checked on - CheckBlockNumber uint32 - CheckBlockHash [32]byte - ExecuteGas uint32 - Retryable bool -} - -type EVMAutomationResultExtension21 struct { - FastGasWei *big.Int - LinkNative *big.Int - FailureReason uint8 // this is not encoded, only pass along for the purpose of pipeline run -} - -func (enc EVMAutomationEncoder21) Encode(results ...ocr2keepers.CheckResult) ([]byte, error) { - if len(results) == 0 { - return nil, ErrEmptyResults - } - - report := automation_utils_2_1.KeeperRegistryBase21Report{ - UpkeepIds: make([]*big.Int, len(results)), - GasLimits: make([]*big.Int, len(results)), - Triggers: make([][]byte, len(results)), - PerformDatas: make([][]byte, len(results)), - } - - for i, result := range results { - ext, ok := result.Extension.(EVMAutomationResultExtension21) - if !ok { - return nil, fmt.Errorf("unexpected check result extension struct") - } - - // only take these values from the first result - // TODO: find a new way to get these values - if i == 0 { - report.FastGasWei = ext.FastGasWei - report.LinkNative = ext.LinkNative - } - - id, ok := big.NewInt(0).SetString(string(result.Payload.Upkeep.ID), 10) - if !ok { - return nil, fmt.Errorf("failed to parse big int from upkeep id: %s", string(result.Payload.Upkeep.ID)) - } - report.UpkeepIds[i] = id - report.GasLimits[i] = big.NewInt(0).SetUint64(result.GasAllocated) - - triggerW := triggerWrapper{ - BlockNum: uint32(result.Payload.Trigger.BlockNumber), - BlockHash: common.HexToHash(result.Payload.Trigger.BlockHash), - } - switch getUpkeepType(id.Bytes()) { - case logTrigger: - trExt, ok := result.Payload.Trigger.Extension.(logprovider.LogTriggerExtension) - if !ok { - return nil, fmt.Errorf("unrecognized trigger extension data") - } - hex, err := common.ParseHexOrString(trExt.TxHash) - if err != nil { - return nil, fmt.Errorf("tx hash parse error: %w", err) - } - triggerW.TxHash = common.BytesToHash(hex[:]) - triggerW.LogIndex = uint32(trExt.LogIndex) - default: - } - trigger, err := enc.packer.PackTrigger(id, triggerW) - if err != nil { - return nil, fmt.Errorf("%w: failed to pack trigger", err) - } - report.Triggers[i] = trigger - report.PerformDatas[i] = result.PerformData - } - - return enc.packer.PackReport(report) -} - -// Extract the plugin will call this function to accept/transmit reports -func (enc EVMAutomationEncoder21) Extract(raw []byte) ([]ocr2keepers.ReportedUpkeep, error) { - report, err := enc.packer.UnpackReport(raw) - if err != nil { - return nil, fmt.Errorf("%w: failed to unpack report", err) - } - reportedUpkeeps := make([]ocr2keepers.ReportedUpkeep, len(report.UpkeepIds)) - for i, upkeepId := range report.UpkeepIds { - triggerW, err := enc.packer.UnpackTrigger(upkeepId, report.Triggers[i]) - if err != nil { - // TODO: log error and continue instead? - return nil, fmt.Errorf("%w: failed to unpack trigger", err) - } - logExt := logprovider.LogTriggerExtension{} - - switch getUpkeepType(upkeepId.Bytes()) { - case logTrigger: - logExt.TxHash = common.BytesToHash(triggerW.TxHash[:]).Hex() - logExt.LogIndex = int64(triggerW.LogIndex) - default: - } - trigger := ocr2keepers.NewTrigger( - int64(triggerW.BlockNum), - common.BytesToHash(triggerW.BlockHash[:]).Hex(), - logExt, - ) - reportedUpkeeps[i] = ocr2keepers.ReportedUpkeep{ - UpkeepID: ocr2keepers.UpkeepIdentifier(upkeepId.String()), - Trigger: trigger, - PerformData: report.PerformDatas[i], - } - } - return reportedUpkeeps, nil -} - -type BlockKeyHelper[T uint32 | int64] struct { -} - -func (kh BlockKeyHelper[T]) MakeBlockKey(b T) ocr2keepers.BlockKey { - return ocr2keepers.BlockKey(fmt.Sprintf("%d", b)) -} - -type UpkeepKeyHelper[T uint32 | int64] struct { -} - -func (kh UpkeepKeyHelper[T]) MakeUpkeepKey(b T, id *big.Int) ocr2keepers.UpkeepKey { - return ocr2keepers.UpkeepKey(fmt.Sprintf("%d%s%s", b, separator, id)) -} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/encoder_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/encoder_test.go deleted file mode 100644 index 23d9ea8545f..00000000000 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/encoder_test.go +++ /dev/null @@ -1,207 +0,0 @@ -package evm - -import ( - "errors" - "fmt" - "math/big" - "strings" - "testing" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" - "github.com/stretchr/testify/assert" - - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1" - iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider" -) - -func TestEVMAutomationEncoder21_Encode(t *testing.T) { - keepersABI, err := abi.JSON(strings.NewReader(iregistry21.IKeeperRegistryMasterABI)) - assert.Nil(t, err) - utilsABI, err := abi.JSON(strings.NewReader(automation_utils_2_1.AutomationUtilsABI)) - assert.Nil(t, err) - encoder := EVMAutomationEncoder21{ - packer: NewEvmRegistryPackerV2_1(keepersABI, utilsABI), - } - - tests := []struct { - name string - results []ocr2keepers.CheckResult - reportSize int - expectedErr error - }{ - { - "happy flow single", - []ocr2keepers.CheckResult{ - newResult(1, ocr2keepers.UpkeepIdentifier(genUpkeepID(conditionTrigger, "10").String())), - }, - 640, - nil, - }, - { - "happy flow multiple", - []ocr2keepers.CheckResult{ - newResult(1, ocr2keepers.UpkeepIdentifier(genUpkeepID(conditionTrigger, "10").String())), - newResult(2, ocr2keepers.UpkeepIdentifier(genUpkeepID(logTrigger, "20").String())), - newResult(3, ocr2keepers.UpkeepIdentifier(genUpkeepID(conditionTrigger, "30").String())), - }, - 1280, - nil, - }, - { - "empty results", - []ocr2keepers.CheckResult{}, - 0, - ErrEmptyResults, - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - b, err := encoder.Encode(tc.results...) - if tc.expectedErr != nil { - assert.Equal(t, tc.expectedErr, err) - return - } - assert.Nil(t, err) - assert.Len(t, b, tc.reportSize) - - upkeeps, err := decode(encoder.packer, b) - assert.Nil(t, err) - assert.Len(t, upkeeps, len(tc.results)) - - for i, u := range upkeeps { - upkeep, ok := u.(EVMAutomationUpkeepResult21) - assert.True(t, ok) - - assert.Equal(t, upkeep.Block, uint32(tc.results[i].Payload.Trigger.BlockNumber)) - assert.Equal(t, ocr2keepers.UpkeepIdentifier(upkeep.ID.String()), tc.results[i].Payload.Upkeep.ID) - assert.Equal(t, upkeep.Eligible, tc.results[i].Eligible) - assert.Equal(t, upkeep.PerformData, tc.results[i].PerformData) - assert.Equal(t, upkeep.CheckBlockNumber, uint32(tc.results[i].Payload.Trigger.BlockNumber)) - assert.Equal(t, common.BytesToHash(upkeep.CheckBlockHash[:]), common.HexToHash(tc.results[i].Payload.Trigger.BlockHash)) - } - }) - } -} - -func TestEVMAutomationEncoder21_EncodeExtract(t *testing.T) { - keepersABI, err := abi.JSON(strings.NewReader(iregistry21.IKeeperRegistryMasterABI)) - assert.Nil(t, err) - utilsABI, err := abi.JSON(strings.NewReader(automation_utils_2_1.AutomationUtilsABI)) - assert.Nil(t, err) - encoder := EVMAutomationEncoder21{ - packer: NewEvmRegistryPackerV2_1(keepersABI, utilsABI), - } - - tests := []struct { - name string - results []ocr2keepers.CheckResult - expectedErr error - }{ - { - "happy flow single", - []ocr2keepers.CheckResult{ - newResult(1, ocr2keepers.UpkeepIdentifier(genUpkeepID(logTrigger, "10").String())), - }, - nil, - }, - { - "happy flow multiple", - []ocr2keepers.CheckResult{ - newResult(1, ocr2keepers.UpkeepIdentifier(genUpkeepID(logTrigger, "10").String())), - newResult(2, ocr2keepers.UpkeepIdentifier(genUpkeepID(conditionTrigger, "20").String())), - newResult(3, ocr2keepers.UpkeepIdentifier(genUpkeepID(logTrigger, "30").String())), - }, - nil, - }, - { - "empty results", - []ocr2keepers.CheckResult{}, - errors.New(""), - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - b, _ := encoder.Encode(tc.results...) - reportedUpkeeps, err := encoder.Extract(b) - if tc.expectedErr != nil { - assert.Error(t, err) - return - } - assert.Nil(t, err) - assert.Len(t, reportedUpkeeps, len(tc.results)) - - for i, upkeep := range reportedUpkeeps { - assert.Equal(t, tc.results[i].Payload.Upkeep.ID, upkeep.UpkeepID) - assert.Equal(t, tc.results[i].Payload.Trigger.BlockHash, upkeep.Trigger.BlockHash) - assert.Equal(t, tc.results[i].Payload.Trigger.BlockNumber, upkeep.Trigger.BlockNumber) - assert.Equal(t, tc.results[i].PerformData, upkeep.PerformData) - } - }) - } -} - -func newResult(block int64, id ocr2keepers.UpkeepIdentifier) ocr2keepers.CheckResult { - logExt := logprovider.LogTriggerExtension{} - tp := getUpkeepType(id) - if tp == logTrigger { - logExt.LogIndex = 1 - logExt.TxHash = "0x1234567890123456789012345678901234567890123456789012345678901234" - } - payload := ocr2keepers.UpkeepPayload{ - Upkeep: ocr2keepers.ConfiguredUpkeep{ - ID: id, - Type: int(tp), - }, - Trigger: ocr2keepers.Trigger{ - BlockNumber: block, - BlockHash: hexutil.Encode([]byte{1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8}), - Extension: logExt, - }, - } - payload.ID = payload.GenerateID() - return ocr2keepers.CheckResult{ - Payload: payload, - Eligible: true, - GasAllocated: 100, - PerformData: []byte("data0"), - Extension: EVMAutomationResultExtension21{ - FastGasWei: big.NewInt(100), - LinkNative: big.NewInt(100), - }, - } -} - -func decode(packer *evmRegistryPackerV2_1, raw []byte) ([]ocr2keepers.UpkeepResult, error) { - report, err := packer.UnpackReport(raw) - if err != nil { - return nil, err - } - - res := make([]ocr2keepers.UpkeepResult, len(report.UpkeepIds)) - - for i := 0; i < len(report.UpkeepIds); i++ { - trigger, err := packer.UnpackTrigger(report.UpkeepIds[i], report.Triggers[i]) - if err != nil { - return nil, fmt.Errorf("%w: failed to unpack trigger", err) - } - r := EVMAutomationUpkeepResult21{ - Block: trigger.BlockNum, - ID: report.UpkeepIds[i], - Eligible: true, - PerformData: report.PerformDatas[i], - FastGasWei: report.FastGasWei, - LinkNative: report.LinkNative, - CheckBlockNumber: trigger.BlockNum, - CheckBlockHash: trigger.BlockHash, - } - res[i] = ocr2keepers.UpkeepResult(r) - } - - return res, nil -} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder.go b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder.go new file mode 100644 index 00000000000..62a359a7231 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder.go @@ -0,0 +1,124 @@ +package encoding + +import ( + "fmt" + "math/big" + + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" +) + +var ( + ErrEmptyResults = fmt.Errorf("empty results; cannot encode") +) + +type reportEncoder struct { + packer Packer +} + +var _ ocr2keepers.Encoder = (*reportEncoder)(nil) + +func NewReportEncoder(p Packer) ocr2keepers.Encoder { + return &reportEncoder{ + packer: p, + } +} + +func (e reportEncoder) Encode(results ...ocr2keepers.CheckResult) ([]byte, error) { + if len(results) == 0 { + return nil, ErrEmptyResults + } + + report := automation_utils_2_1.KeeperRegistryBase21Report{ + FastGasWei: big.NewInt(0), + LinkNative: big.NewInt(0), + UpkeepIds: make([]*big.Int, len(results)), + GasLimits: make([]*big.Int, len(results)), + Triggers: make([][]byte, len(results)), + PerformDatas: make([][]byte, len(results)), + } + + encoded := 0 + highestCheckBlock := big.NewInt(0) + + for i, result := range results { + checkBlock := big.NewInt(int64(result.Trigger.BlockNumber)) + + if checkBlock.Cmp(highestCheckBlock) == 1 { + highestCheckBlock = checkBlock + if result.FastGasWei != nil { + report.FastGasWei = result.FastGasWei + } + if result.LinkNative != nil { + report.LinkNative = result.LinkNative + } + } + + id := result.UpkeepID.BigInt() + report.UpkeepIds[i] = id + report.GasLimits[i] = big.NewInt(0).SetUint64(result.GasAllocated) + + triggerW := triggerWrapper{ + BlockNum: uint32(result.Trigger.BlockNumber), + BlockHash: result.Trigger.BlockHash, + } + switch core.GetUpkeepType(result.UpkeepID) { + case ocr2keepers.LogTrigger: + triggerW.TxHash = result.Trigger.LogTriggerExtension.TxHash + triggerW.LogIndex = result.Trigger.LogTriggerExtension.Index + default: + // no special handling here for conditional triggers + } + + trigger, err := core.PackTrigger(id, triggerW) + if err != nil { + return nil, fmt.Errorf("%w: failed to pack trigger", err) + } + + report.Triggers[i] = trigger + report.PerformDatas[i] = result.PerformData + + encoded++ + } + + return e.packer.PackReport(report) +} + +// Extract the plugin will call this function to accept/transmit reports +func (e reportEncoder) Extract(raw []byte) ([]ocr2keepers.ReportedUpkeep, error) { + report, err := e.packer.UnpackReport(raw) + if err != nil { + return nil, fmt.Errorf("%w: failed to unpack report", err) + } + reportedUpkeeps := make([]ocr2keepers.ReportedUpkeep, len(report.UpkeepIds)) + for i, upkeepId := range report.UpkeepIds { + triggerW, err := core.UnpackTrigger(upkeepId, report.Triggers[i]) + if err != nil { + return nil, fmt.Errorf("%w: failed to unpack trigger", err) + } + id := &ocr2keepers.UpkeepIdentifier{} + id.FromBigInt(upkeepId) + + trigger := ocr2keepers.NewTrigger( + ocr2keepers.BlockNumber(triggerW.BlockNum), + triggerW.BlockHash, + ) + switch core.GetUpkeepType(*id) { + case ocr2keepers.LogTrigger: + trigger.LogTriggerExtension = &ocr2keepers.LogTriggerExtension{} + trigger.LogTriggerExtension.TxHash = triggerW.TxHash + trigger.LogTriggerExtension.Index = triggerW.LogIndex + default: + } + workID := core.UpkeepWorkID(*id, trigger) + reportedUpkeeps[i] = ocr2keepers.ReportedUpkeep{ + WorkID: workID, + UpkeepID: *id, + Trigger: trigger, + } + } + + return reportedUpkeeps, nil +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder_test.go new file mode 100644 index 00000000000..a7fe7f536b1 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder_test.go @@ -0,0 +1,134 @@ +package encoding + +import ( + "math/big" + "strings" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1" + iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" +) + +func TestReportEncoder_EncodeExtract(t *testing.T) { + keepersABI, err := abi.JSON(strings.NewReader(iregistry21.IKeeperRegistryMasterABI)) + assert.Nil(t, err) + utilsABI, err := abi.JSON(strings.NewReader(automation_utils_2_1.AutomationUtilsABI)) + assert.Nil(t, err) + encoder := reportEncoder{ + packer: NewAbiPacker(keepersABI, utilsABI), + } + + tests := []struct { + name string + results []ocr2keepers.CheckResult + reportSize int + expectedFastGasWei int64 + expectedLinkNative int64 + expectedErr error + }{ + { + "happy flow single", + []ocr2keepers.CheckResult{ + newResult(1, 1, core.GenUpkeepID(ocr2keepers.LogTrigger, "123"), 1, 1), + }, + 704, + 1, + 1, + nil, + }, + { + "happy flow multiple", + []ocr2keepers.CheckResult{ + newResult(1, 1, core.GenUpkeepID(ocr2keepers.LogTrigger, "10"), 1, 1), + newResult(1, 1, core.GenUpkeepID(ocr2keepers.ConditionTrigger, "20"), 1, 1), + newResult(1, 1, core.GenUpkeepID(ocr2keepers.ConditionTrigger, "30"), 1, 1), + }, + 1280, + 3, + 3, + nil, + }, + { + "happy flow highest block number first", + []ocr2keepers.CheckResult{ + newResult(1, 1, core.GenUpkeepID(ocr2keepers.ConditionTrigger, "30"), 1, 1), + newResult(1, 1, core.GenUpkeepID(ocr2keepers.ConditionTrigger, "20"), 1, 1), + newResult(1, 1, core.GenUpkeepID(ocr2keepers.LogTrigger, "10"), 1, 1), + }, + 1280, + 1000, + 2000, + nil, + }, + { + "empty results", + []ocr2keepers.CheckResult{}, + 0, + 0, + 0, + ErrEmptyResults, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + b, err := encoder.Encode(tc.results...) + if tc.expectedErr != nil { + assert.Equal(t, tc.expectedErr, err) + return + } + + assert.Nil(t, err) + assert.Len(t, b, tc.reportSize) + + results, err := encoder.Extract(b) + assert.Nil(t, err) + assert.Len(t, results, len(tc.results)) + + for i, r := range results { + assert.Equal(t, r.UpkeepID, tc.results[i].UpkeepID) + assert.Equal(t, r.WorkID, tc.results[i].WorkID) + assert.Equal(t, r.Trigger, tc.results[i].Trigger) + } + }) + } +} + +func newResult(block int64, checkBlock ocr2keepers.BlockNumber, id ocr2keepers.UpkeepIdentifier, fastGasWei, linkNative int64) ocr2keepers.CheckResult { + tp := core.GetUpkeepType(id) + + trig := ocr2keepers.Trigger{ + BlockNumber: ocr2keepers.BlockNumber(block), + BlockHash: [32]byte{1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8}, + } + + if tp == ocr2keepers.LogTrigger { + trig.LogTriggerExtension = &ocr2keepers.LogTriggerExtension{ + Index: 1, + TxHash: common.HexToHash("0x1234567890123456789012345678901234567890123456789012345678901234"), + } + } + + payload, _ := core.NewUpkeepPayload( + id.BigInt(), + trig, + []byte{}, + ) + + return ocr2keepers.CheckResult{ + UpkeepID: id, + Trigger: payload.Trigger, + WorkID: payload.WorkID, + Eligible: true, + GasAllocated: 100, + PerformData: []byte("data0"), + FastGasWei: big.NewInt(fastGasWei), + LinkNative: big.NewInt(linkNative), + } +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go new file mode 100644 index 00000000000..e896a144aa8 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go @@ -0,0 +1,55 @@ +package encoding + +import ( + "math/big" + + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1" + iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" +) + +type UpkeepFailureReason uint8 +type PipelineExecutionState uint8 + +const ( + // upkeep failure onchain reasons + UpkeepFailureReasonNone UpkeepFailureReason = 0 + UpkeepFailureReasonUpkeepCancelled UpkeepFailureReason = 1 + UpkeepFailureReasonUpkeepPaused UpkeepFailureReason = 2 + UpkeepFailureReasonTargetCheckReverted UpkeepFailureReason = 3 + UpkeepFailureReasonUpkeepNotNeeded UpkeepFailureReason = 4 + UpkeepFailureReasonPerformDataExceedsLimit UpkeepFailureReason = 5 + UpkeepFailureReasonInsufficientBalance UpkeepFailureReason = 6 + UpkeepFailureReasonMercuryCallbackReverted UpkeepFailureReason = 7 + UpkeepFailureReasonRevertDataExceedsLimit UpkeepFailureReason = 8 + UpkeepFailureReasonRegistryPaused UpkeepFailureReason = 9 + // leaving a gap here for more onchain failure reasons in the future + // upkeep failure offchain reasons + UpkeepFailureReasonMercuryAccessNotAllowed UpkeepFailureReason = 32 + UpkeepFailureReasonTxHashNoLongerExists UpkeepFailureReason = 33 + UpkeepFailureReasonInvalidRevertDataInput UpkeepFailureReason = 34 + + // pipeline execution error + NoPipelineError PipelineExecutionState = 0 + CheckBlockTooOld PipelineExecutionState = 1 + CheckBlockInvalid PipelineExecutionState = 2 + RpcFlakyFailure PipelineExecutionState = 3 + MercuryFlakyFailure PipelineExecutionState = 4 + PackUnpackDecodeFailed PipelineExecutionState = 5 + MercuryUnmarshalError PipelineExecutionState = 6 + InvalidMercuryRequest PipelineExecutionState = 7 + InvalidMercuryResponse PipelineExecutionState = 8 // this will only happen if Mercury server sends bad responses +) + +type UpkeepInfo = iregistry21.KeeperRegistryBase21UpkeepInfo + +type Packer interface { + UnpackCheckResult(payload ocr2keepers.UpkeepPayload, raw string) (ocr2keepers.CheckResult, error) + UnpackCheckCallbackResult(callbackResp []byte) (PipelineExecutionState, bool, []byte, uint8, *big.Int, error) + UnpackPerformResult(raw string) (PipelineExecutionState, bool, error) + UnpackUpkeepInfo(id *big.Int, raw string) (UpkeepInfo, error) + UnpackLogTriggerConfig(raw []byte) (automation_utils_2_1.LogTriggerConfig, error) + PackReport(report automation_utils_2_1.KeeperRegistryBase21Report) ([]byte, error) + UnpackReport(raw []byte) (automation_utils_2_1.KeeperRegistryBase21Report, error) +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/packer.go b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/packer.go new file mode 100644 index 00000000000..c710b31291f --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/packer.go @@ -0,0 +1,178 @@ +package encoding + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common/hexutil" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1" +) + +var utilsABI = types.MustGetABI(automation_utils_2_1.AutomationUtilsABI) + +// triggerWrapper is a wrapper for the different trigger types (log and condition triggers). +// NOTE: we use log trigger because it extends condition trigger, +type triggerWrapper = automation_utils_2_1.KeeperRegistryBase21LogTrigger + +type abiPacker struct { + abi abi.ABI + utilsAbi abi.ABI +} + +var _ Packer = (*abiPacker)(nil) + +func NewAbiPacker(abi abi.ABI, utilsAbi abi.ABI) *abiPacker { + return &abiPacker{abi: abi, utilsAbi: utilsAbi} +} + +func (p *abiPacker) UnpackCheckResult(payload ocr2keepers.UpkeepPayload, raw string) (ocr2keepers.CheckResult, error) { + b, err := hexutil.Decode(raw) + if err != nil { + // decode failed, not retryable + return GetIneligibleCheckResultWithoutPerformData(payload, UpkeepFailureReasonNone, PackUnpackDecodeFailed, false), + fmt.Errorf("upkeepId %s failed to decode checkUpkeep result %s: %s", payload.UpkeepID.String(), raw, err) + } + + out, err := p.abi.Methods["checkUpkeep"].Outputs.UnpackValues(b) + if err != nil { + // unpack failed, not retryable + return GetIneligibleCheckResultWithoutPerformData(payload, UpkeepFailureReasonNone, PackUnpackDecodeFailed, false), + fmt.Errorf("upkeepId %s failed to unpack checkUpkeep result %s: %s", payload.UpkeepID.String(), raw, err) + } + + result := ocr2keepers.CheckResult{ + Eligible: *abi.ConvertType(out[0], new(bool)).(*bool), + Retryable: false, + GasAllocated: uint64((*abi.ConvertType(out[4], new(*big.Int)).(**big.Int)).Int64()), + UpkeepID: payload.UpkeepID, + Trigger: payload.Trigger, + WorkID: payload.WorkID, + FastGasWei: *abi.ConvertType(out[5], new(*big.Int)).(**big.Int), + LinkNative: *abi.ConvertType(out[6], new(*big.Int)).(**big.Int), + IneligibilityReason: *abi.ConvertType(out[2], new(uint8)).(*uint8), + } + + rawPerformData := *abi.ConvertType(out[1], new([]byte)).(*[]byte) + + // if NONE we expect the perform data. if TARGET_CHECK_REVERTED we will have the error data in the perform data used for off chain lookup + if result.IneligibilityReason == uint8(UpkeepFailureReasonNone) || (result.IneligibilityReason == uint8(UpkeepFailureReasonTargetCheckReverted) && len(rawPerformData) > 0) { + result.PerformData = rawPerformData + } + + return result, nil +} + +func (p *abiPacker) UnpackCheckCallbackResult(callbackResp []byte) (PipelineExecutionState, bool, []byte, uint8, *big.Int, error) { + out, err := p.abi.Methods["checkCallback"].Outputs.UnpackValues(callbackResp) + if err != nil { + return PackUnpackDecodeFailed, false, nil, 0, nil, fmt.Errorf("%w: unpack checkUpkeep return: %s", err, hexutil.Encode(callbackResp)) + } + + upkeepNeeded := *abi.ConvertType(out[0], new(bool)).(*bool) + rawPerformData := *abi.ConvertType(out[1], new([]byte)).(*[]byte) + failureReason := *abi.ConvertType(out[2], new(uint8)).(*uint8) + gasUsed := *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + + return NoPipelineError, upkeepNeeded, rawPerformData, failureReason, gasUsed, nil +} + +func (p *abiPacker) UnpackPerformResult(raw string) (PipelineExecutionState, bool, error) { + b, err := hexutil.Decode(raw) + if err != nil { + return PackUnpackDecodeFailed, false, err + } + + out, err := p.abi.Methods["simulatePerformUpkeep"].Outputs.UnpackValues(b) + if err != nil { + return PackUnpackDecodeFailed, false, err + } + + return NoPipelineError, *abi.ConvertType(out[0], new(bool)).(*bool), nil +} + +func (p *abiPacker) UnpackUpkeepInfo(id *big.Int, raw string) (UpkeepInfo, error) { + b, err := hexutil.Decode(raw) + if err != nil { + return UpkeepInfo{}, err + } + + out, err := p.abi.Methods["getUpkeep"].Outputs.UnpackValues(b) + if err != nil { + return UpkeepInfo{}, fmt.Errorf("%w: unpack getUpkeep return: %s", err, raw) + } + + info := *abi.ConvertType(out[0], new(UpkeepInfo)).(*UpkeepInfo) + + return info, nil +} + +// UnpackLogTriggerConfig unpacks the log trigger config from the given raw data +func (p *abiPacker) UnpackLogTriggerConfig(raw []byte) (automation_utils_2_1.LogTriggerConfig, error) { + var cfg automation_utils_2_1.LogTriggerConfig + + out, err := utilsABI.Methods["_logTriggerConfig"].Inputs.UnpackValues(raw) + if err != nil { + return cfg, fmt.Errorf("%w: unpack _logTriggerConfig return: %s", err, raw) + } + + converted, ok := abi.ConvertType(out[0], new(automation_utils_2_1.LogTriggerConfig)).(*automation_utils_2_1.LogTriggerConfig) + if !ok { + return cfg, fmt.Errorf("failed to convert type during UnpackLogTriggerConfig") + } + return *converted, nil +} + +// PackReport packs the report with abi definitions from the contract. +func (p *abiPacker) PackReport(report automation_utils_2_1.KeeperRegistryBase21Report) ([]byte, error) { + bts, err := p.utilsAbi.Methods["_report"].Inputs.Pack(&report) + if err != nil { + return nil, fmt.Errorf("%w: failed to pack report", err) + } + return bts, nil +} + +// UnpackReport unpacks the report from the given raw data. +func (p *abiPacker) UnpackReport(raw []byte) (automation_utils_2_1.KeeperRegistryBase21Report, error) { + unpacked, err := p.utilsAbi.Methods["_report"].Inputs.Unpack(raw) + if err != nil { + return automation_utils_2_1.KeeperRegistryBase21Report{}, fmt.Errorf("%w: failed to unpack report", err) + } + converted, ok := abi.ConvertType(unpacked[0], new(automation_utils_2_1.KeeperRegistryBase21Report)).(*automation_utils_2_1.KeeperRegistryBase21Report) + if !ok { + return automation_utils_2_1.KeeperRegistryBase21Report{}, fmt.Errorf("failed to convert type") + } + report := automation_utils_2_1.KeeperRegistryBase21Report{ + FastGasWei: converted.FastGasWei, + LinkNative: converted.LinkNative, + UpkeepIds: make([]*big.Int, len(converted.UpkeepIds)), + GasLimits: make([]*big.Int, len(converted.GasLimits)), + Triggers: make([][]byte, len(converted.Triggers)), + PerformDatas: make([][]byte, len(converted.PerformDatas)), + } + if len(report.UpkeepIds) > 0 { + copy(report.UpkeepIds, converted.UpkeepIds) + copy(report.GasLimits, converted.GasLimits) + copy(report.Triggers, converted.Triggers) + copy(report.PerformDatas, converted.PerformDatas) + } + + return report, nil +} + +// GetIneligibleCheckResultWithoutPerformData returns an ineligible check result with ineligibility reason and pipeline execution state but without perform data +func GetIneligibleCheckResultWithoutPerformData(p ocr2keepers.UpkeepPayload, reason UpkeepFailureReason, state PipelineExecutionState, retryable bool) ocr2keepers.CheckResult { + return ocr2keepers.CheckResult{ + IneligibilityReason: uint8(reason), + PipelineExecutionState: uint8(state), + Retryable: retryable, + UpkeepID: p.UpkeepID, + Trigger: p.Trigger, + WorkID: p.WorkID, + FastGasWei: big.NewInt(0), + LinkNative: big.NewInt(0), + } +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/abi_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/packer_test.go similarity index 58% rename from core/services/ocr2/plugins/ocr2keeper/evm21/abi_test.go rename to core/services/ocr2/plugins/ocr2keeper/evm21/encoding/packer_test.go index f2a3fa32b72..ccc84765baa 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/abi_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/packer_test.go @@ -1,4 +1,4 @@ -package evm +package encoding import ( "fmt" @@ -9,57 +9,184 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1" automation21Utils "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1" iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" ) -func TestUnpackCheckResults(t *testing.T) { - upkeepId, _ := new(big.Int).SetString("1843548457736589226156809205796175506139185429616502850435279853710366065936", 10) +func TestPacker_PackReport(t *testing.T) { + for _, tc := range []struct { + name string + report automation21Utils.KeeperRegistryBase21Report + expectsErr bool + wantErr error + wantBytes int + }{ + { + name: "all non-nil values get encoded to a byte array of a specific length", + report: automation21Utils.KeeperRegistryBase21Report{ + FastGasWei: big.NewInt(0), + LinkNative: big.NewInt(0), + UpkeepIds: []*big.Int{big.NewInt(3)}, + GasLimits: []*big.Int{big.NewInt(4)}, + Triggers: [][]byte{ + {5}, + }, + PerformDatas: [][]byte{ + {6}, + }, + }, + wantBytes: 608, + }, + { + name: "if upkeep IDs are nil, the packed report is smaller", + report: automation21Utils.KeeperRegistryBase21Report{ + FastGasWei: big.NewInt(1), + LinkNative: big.NewInt(2), + UpkeepIds: nil, + GasLimits: []*big.Int{big.NewInt(4)}, + Triggers: [][]byte{ + {5}, + }, + PerformDatas: [][]byte{ + {6}, + }, + }, + wantBytes: 576, + }, + { + name: "if gas limits are nil, the packed report is smaller", + report: automation21Utils.KeeperRegistryBase21Report{ + FastGasWei: big.NewInt(1), + LinkNative: big.NewInt(2), + UpkeepIds: []*big.Int{big.NewInt(3)}, + GasLimits: nil, + Triggers: [][]byte{ + {5}, + }, + PerformDatas: [][]byte{ + {6}, + }, + }, + wantBytes: 576, + }, + { + name: "if perform datas are nil, the packed report is smaller", + report: automation21Utils.KeeperRegistryBase21Report{ + FastGasWei: big.NewInt(1), + LinkNative: big.NewInt(2), + UpkeepIds: []*big.Int{big.NewInt(3)}, + GasLimits: []*big.Int{big.NewInt(4)}, + Triggers: [][]byte{ + {5}, + }, + PerformDatas: nil, + }, + wantBytes: 512, + }, + { + name: "if triggers are nil, the packed report is smaller", + report: automation21Utils.KeeperRegistryBase21Report{ + FastGasWei: big.NewInt(1), + LinkNative: big.NewInt(2), + UpkeepIds: []*big.Int{big.NewInt(3)}, + GasLimits: []*big.Int{big.NewInt(4)}, + Triggers: nil, + PerformDatas: [][]byte{ + {6}, + }, + }, + wantBytes: 512, + }, + } { + t.Run(tc.name, func(t *testing.T) { + packer, err := newPacker() + assert.NoError(t, err) + bytes, err := packer.PackReport(tc.report) + if tc.expectsErr { + assert.Error(t, err) + assert.Equal(t, tc.wantErr.Error(), err.Error()) + } else { + assert.NoError(t, err) + assert.Equal(t, tc.wantBytes, len(bytes)) + } + }) + } +} + +func TestPacker_UnpackCheckResults(t *testing.T) { + uid, _ := new(big.Int).SetString("1843548457736589226156809205796175506139185429616502850435279853710366065936", 10) + upkeepId := ocr2keepers.UpkeepIdentifier{} + upkeepId.FromBigInt(uid) + p1, _ := core.NewUpkeepPayload(uid, ocr2keepers.NewTrigger(19447615, common.HexToHash("0x0")), []byte{}) + + p2, _ := core.NewUpkeepPayload(uid, ocr2keepers.NewTrigger(19448272, common.HexToHash("0x0")), []byte{}) tests := []struct { Name string Payload ocr2keepers.UpkeepPayload RawData string - ExpectedResult EVMAutomationUpkeepResult21 + ExpectedResult ocr2keepers.CheckResult + ExpectedError error }{ { Name: "upkeep not needed", - Payload: ocr2keepers.NewUpkeepPayload(upkeepId, 0, "19447615", ocr2keepers.NewTrigger(19447615, "0x0", struct{}{}), []byte{}), + Payload: p1, RawData: "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000421c000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000000000000000000000000000000c8caf37f3b3890000000000000000000000000000000000000000000000000000000000000000", - ExpectedResult: EVMAutomationUpkeepResult21{ - Block: 19447615, - ID: upkeepId, - Eligible: false, - FailureReason: UPKEEP_FAILURE_REASON_UPKEEP_NOT_NEEDED, - GasUsed: big.NewInt(16924), - PerformData: nil, - FastGasWei: big.NewInt(1000000000), - LinkNative: big.NewInt(3532383906411401), - CheckBlockNumber: 0, - CheckBlockHash: [32]byte{}, - ExecuteGas: 5000000, + ExpectedResult: ocr2keepers.CheckResult{ + UpkeepID: upkeepId, + Eligible: false, + IneligibilityReason: uint8(UpkeepFailureReasonUpkeepNotNeeded), + Trigger: ocr2keepers.NewLogTrigger(ocr2keepers.BlockNumber(19447615), [32]byte{}, nil), + WorkID: "e54c524132d9c8d87b7e43b76f6d769face19ffd2ff93fc24f123dd745d3ce1e", + PerformData: nil, + FastGasWei: big.NewInt(1000000000), + LinkNative: big.NewInt(3532383906411401), }, }, { Name: "target check reverted", - Payload: ocr2keepers.NewUpkeepPayload(upkeepId, 0, "19448272", ocr2keepers.NewTrigger(19448272, "0x0", struct{}{}), []byte{}), + Payload: p2, RawData: "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000007531000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000000000000000000000000000000c8caf37f3b3890000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000008914039bf676e20aad43a5642485e666575ed0d927a4b5679745e947e7d125ee2687c10000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000024462e8a50d00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000128c1d000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000009666565644944537472000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000184554482d5553442d415242495452554d2d544553544e4554000000000000000000000000000000000000000000000000000000000000000000000000000000184254432d5553442d415242495452554d2d544553544e45540000000000000000000000000000000000000000000000000000000000000000000000000000000b626c6f636b4e756d6265720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000000000000000000000", - ExpectedResult: EVMAutomationUpkeepResult21{ - Block: 19448272, - ID: upkeepId, - Eligible: false, - FailureReason: UPKEEP_FAILURE_REASON_TARGET_CHECK_REVERTED, - GasUsed: big.NewInt(30001), - PerformData: []byte{98, 232, 165, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 40, 193, 208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 102, 101, 101, 100, 73, 68, 83, 116, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 69, 84, 72, 45, 85, 83, 68, 45, 65, 82, 66, 73, 84, 82, 85, 77, 45, 84, 69, 83, 84, 78, 69, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 66, 84, 67, 45, 85, 83, 68, 45, 65, 82, 66, 73, 84, 82, 85, 77, 45, 84, 69, 83, 84, 78, 69, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 98, 108, 111, 99, 107, 78, 117, 109, 98, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - FastGasWei: big.NewInt(1000000000), - LinkNative: big.NewInt(3532383906411401), - CheckBlockNumber: 8983555, - CheckBlockHash: [32]byte{155, 246, 118, 226, 10, 173, 67, 165, 100, 36, 133, 230, 102, 87, 94, 208, 217, 39, 164, 181, 103, 151, 69, 233, 71, 231, 209, 37, 238, 38, 135, 193}, - ExecuteGas: 5000000, + ExpectedResult: ocr2keepers.CheckResult{ + UpkeepID: upkeepId, + Eligible: false, + IneligibilityReason: uint8(UpkeepFailureReasonTargetCheckReverted), + Trigger: ocr2keepers.NewLogTrigger(ocr2keepers.BlockNumber(19448272), [32]byte{}, nil), + WorkID: "e54c524132d9c8d87b7e43b76f6d769face19ffd2ff93fc24f123dd745d3ce1e", + PerformData: []byte{98, 232, 165, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 40, 193, 208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 102, 101, 101, 100, 73, 68, 83, 116, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 69, 84, 72, 45, 85, 83, 68, 45, 65, 82, 66, 73, 84, 82, 85, 77, 45, 84, 69, 83, 84, 78, 69, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 66, 84, 67, 45, 85, 83, 68, 45, 65, 82, 66, 73, 84, 82, 85, 77, 45, 84, 69, 83, 84, 78, 69, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 98, 108, 111, 99, 107, 78, 117, 109, 98, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + FastGasWei: big.NewInt(1000000000), + LinkNative: big.NewInt(3532383906411401), + }, + }, + { + Name: "decode failed", + Payload: p2, + RawData: "invalid_raw_data", + ExpectedResult: ocr2keepers.CheckResult{ + UpkeepID: upkeepId, + PipelineExecutionState: uint8(PackUnpackDecodeFailed), + Trigger: p2.Trigger, + WorkID: p2.WorkID, }, + ExpectedError: fmt.Errorf("upkeepId %s failed to decode checkUpkeep result invalid_raw_data: hex string without 0x prefix", p2.UpkeepID.String()), + }, + { + Name: "unpack failed", + Payload: p2, + RawData: "0x123123", + ExpectedResult: ocr2keepers.CheckResult{ + UpkeepID: upkeepId, + PipelineExecutionState: uint8(PackUnpackDecodeFailed), + Trigger: p2.Trigger, + WorkID: p2.WorkID, + }, + ExpectedError: fmt.Errorf("upkeepId %s failed to unpack checkUpkeep result 0x123123: abi: cannot marshal in to go type: length insufficient 3 require 32", p2.UpkeepID.String()), }, } for _, test := range tests { @@ -67,13 +194,17 @@ func TestUnpackCheckResults(t *testing.T) { packer, err := newPacker() assert.NoError(t, err) rs, err := packer.UnpackCheckResult(test.Payload, test.RawData) - assert.Nil(t, err) - assert.Equal(t, test.ExpectedResult.Block, uint32(rs.Payload.Trigger.BlockNumber)) - assert.Equal(t, ocr2keepers.UpkeepIdentifier(test.ExpectedResult.ID.Bytes()), rs.Payload.Upkeep.ID) + if test.ExpectedError != nil { + assert.Equal(t, test.ExpectedError.Error(), err.Error()) + } else { + assert.Nil(t, err) + } + assert.Equal(t, test.ExpectedResult.UpkeepID, rs.UpkeepID) assert.Equal(t, test.ExpectedResult.Eligible, rs.Eligible) - ext, ok := rs.Extension.(EVMAutomationResultExtension21) - assert.True(t, ok) - assert.Equal(t, test.ExpectedResult.FailureReason, ext.FailureReason) + assert.Equal(t, test.ExpectedResult.Trigger, rs.Trigger) + assert.Equal(t, test.ExpectedResult.WorkID, rs.WorkID) + assert.Equal(t, test.ExpectedResult.IneligibilityReason, rs.IneligibilityReason) + assert.Equal(t, test.ExpectedResult.PipelineExecutionState, rs.PipelineExecutionState) }) } } @@ -82,19 +213,22 @@ func TestPacker_UnpackPerformResult(t *testing.T) { tests := []struct { Name string RawData string + State PipelineExecutionState }{ { Name: "unpack success", RawData: "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000a52d", + State: NoPipelineError, }, } for _, test := range tests { t.Run(test.Name, func(t *testing.T) { packer, err := newPacker() assert.NoError(t, err) - rs, err := packer.UnpackPerformResult(test.RawData) + state, rs, err := packer.UnpackPerformResult(test.RawData) assert.Nil(t, err) assert.True(t, rs) + assert.Equal(t, test.State, state) }) } } @@ -108,13 +242,14 @@ func TestPacker_UnpackCheckCallbackResult(t *testing.T) { FailureReason uint8 GasUsed *big.Int ErrorString string + State PipelineExecutionState }{ { Name: "unpack upkeep needed", CallbackResp: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 10, 11, 21, 31, 41, 15, 16, 17, 18, 19, 13, 14, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 120, 111, 101, 122, 90, 54, 44, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, UpkeepNeeded: true, PerformData: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 10, 11, 21, 31, 41, 15, 16, 17, 18, 19, 13, 14, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 120, 111, 101, 122, 90, 54, 44, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - FailureReason: UPKEEP_FAILURE_REASON_NONE, + FailureReason: uint8(UpkeepFailureReasonNone), GasUsed: big.NewInt(11796), }, { @@ -122,7 +257,7 @@ func TestPacker_UnpackCheckCallbackResult(t *testing.T) { CallbackResp: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 10, 11, 21, 31, 41, 15, 16, 17, 18, 19, 13, 14, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 120, 111, 101, 122, 90, 54, 44, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, UpkeepNeeded: false, PerformData: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 10, 11, 21, 31, 41, 15, 16, 17, 18, 19, 13, 14, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 120, 111, 101, 122, 90, 54, 44, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - FailureReason: UPKEEP_FAILURE_REASON_UPKEEP_NOT_NEEDED, + FailureReason: uint8(UpkeepFailureReasonUpkeepNotNeeded), GasUsed: big.NewInt(13008), }, { @@ -131,6 +266,7 @@ func TestPacker_UnpackCheckCallbackResult(t *testing.T) { UpkeepNeeded: false, PerformData: nil, ErrorString: "abi: improperly encoded boolean value: unpack checkUpkeep return: ", + State: PackUnpackDecodeFailed, }, } for _, test := range tests { @@ -138,7 +274,7 @@ func TestPacker_UnpackCheckCallbackResult(t *testing.T) { packer, err := newPacker() assert.NoError(t, err) - needed, pd, failureReason, gasUsed, err := packer.UnpackCheckCallbackResult(test.CallbackResp) + state, needed, pd, failureReason, gasUsed, err := packer.UnpackCheckCallbackResult(test.CallbackResp) if test.ErrorString != "" { assert.EqualError(t, err, test.ErrorString+hexutil.Encode(test.CallbackResp)) @@ -149,6 +285,7 @@ func TestPacker_UnpackCheckCallbackResult(t *testing.T) { assert.Equal(t, test.PerformData, pd) assert.Equal(t, test.FailureReason, failureReason) assert.Equal(t, test.GasUsed, gasUsed) + assert.Equal(t, test.State, state) }) } } @@ -198,94 +335,27 @@ func TestPacker_UnpackLogTriggerConfig(t *testing.T) { } } -func TestPacker_PackingTrigger(t *testing.T) { - tests := []struct { - name string - id ocr2keepers.UpkeepIdentifier - trigger triggerWrapper - encoded []byte - err error - }{ - { - "happy flow log trigger", - append([]byte{1}, common.LeftPadBytes([]byte{1}, 15)...), - triggerWrapper{ - BlockNum: 1, - BlockHash: common.HexToHash("0x01111111"), - LogIndex: 1, - TxHash: common.HexToHash("0x01111111"), - }, - func() []byte { - b, _ := hexutil.Decode("0x0000000000000000000000000000000000000000000000000000000001111111000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001111111") - return b - }(), - nil, - }, - { - "happy flow conditional trigger", - append([]byte{1}, common.LeftPadBytes([]byte{0}, 15)...), - triggerWrapper{ - BlockNum: 1, - BlockHash: common.HexToHash("0x01111111"), - }, - func() []byte { - b, _ := hexutil.Decode("0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001111111") - return b - }(), - nil, - }, - { - "invalid type", - append([]byte{1}, common.LeftPadBytes([]byte{8}, 15)...), - triggerWrapper{ - BlockNum: 1, - BlockHash: common.HexToHash("0x01111111"), - }, - []byte{}, - fmt.Errorf("unknown trigger type: %d", 8), - }, +func TestPacker_PackReport_UnpackReport(t *testing.T) { + report := automation_utils_2_1.KeeperRegistryBase21Report{ + FastGasWei: big.NewInt(1), + LinkNative: big.NewInt(1), + UpkeepIds: []*big.Int{big.NewInt(1), big.NewInt(2)}, + GasLimits: []*big.Int{big.NewInt(100), big.NewInt(200)}, + Triggers: [][]byte{{1, 2, 3, 4}, {5, 6, 7, 8}}, + PerformDatas: [][]byte{{5, 6, 7, 8}, {1, 2, 3, 4}}, } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - packer, err := newPacker() - assert.NoError(t, err) - id, ok := big.NewInt(0).SetString(hexutil.Encode(tc.id)[2:], 16) - assert.True(t, ok) - - encoded, err := packer.PackTrigger(id, tc.trigger) - if tc.err != nil { - assert.EqualError(t, err, tc.err.Error()) - } else { - assert.NoError(t, err) - assert.Equal(t, tc.encoded, encoded) - decoded, err := packer.UnpackTrigger(id, encoded) - assert.NoError(t, err) - assert.Equal(t, tc.trigger.BlockNum, decoded.BlockNum) - } - }) - } - - t.Run("unpacking invalid trigger", func(t *testing.T) { - packer, err := newPacker() - assert.NoError(t, err) - _, err = packer.UnpackTrigger(big.NewInt(0), []byte{1, 2, 3}) - assert.Error(t, err) - }) - - t.Run("unpacking unknown type", func(t *testing.T) { - packer, err := newPacker() - assert.NoError(t, err) - uid := append([]byte{1}, common.LeftPadBytes([]byte{8}, 15)...) - id, ok := big.NewInt(0).SetString(hexutil.Encode(uid)[2:], 16) - assert.True(t, ok) - decoded, _ := hexutil.Decode("0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001111111") - _, err = packer.UnpackTrigger(id, decoded) - assert.EqualError(t, err, "unknown trigger type: 8") - }) + packer, err := newPacker() + require.NoError(t, err) + res, err := packer.PackReport(report) + require.NoError(t, err) + report2, err := packer.UnpackReport(res) + require.NoError(t, err) + assert.Equal(t, report, report2) + expected := "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000040102030400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000405060708000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000004050607080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040102030400000000000000000000000000000000000000000000000000000000" + assert.Equal(t, hexutil.Encode(res), expected) } -func newPacker() (*evmRegistryPackerV2_1, error) { +func newPacker() (*abiPacker, error) { keepersABI, err := abi.JSON(strings.NewReader(iregistry21.IKeeperRegistryMasterABI)) if err != nil { return nil, err @@ -294,5 +364,5 @@ func newPacker() (*evmRegistryPackerV2_1, error) { if err != nil { return nil, err } - return NewEvmRegistryPackerV2_1(keepersABI, utilsABI), nil + return NewAbiPacker(keepersABI, utilsABI), nil } diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/feed_lookup.go b/core/services/ocr2/plugins/ocr2keeper/evm21/feed_lookup.go index 49ea387c058..9bf0de6c1d1 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/feed_lookup.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/feed_lookup.go @@ -22,22 +22,27 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/patrickmn/go-cache" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/encoding" ) const ( - BlockNumber = "blockNumber" // valid for v0.2 - FeedId = "feedId" // valid for v0.3 - FeedIdHex = "feedIdHex" // valid for v0.2 - MercuryPathV2 = "/client?" - MercuryPathV3 = "/v1/reports?" - MercuryBatchPathV3 = "/v1/reports/bulk?" - RetryDelay = 500 * time.Millisecond - Timestamp = "timestamp" // valid for v0.3 - TotalAttempt = 3 - UserId = "userId" - MercuryV02 = MercuryVersion("v0.2") - MercuryV03 = MercuryVersion("v0.3") + applicationJson = "application/json" + blockNumber = "blockNumber" // valid for v0.2 + feedIDs = "feedIDs" // valid for v0.3 + feedIdHex = "feedIdHex" // valid for v0.2 + headerAuthorization = "Authorization" + headerContentType = "Content-Type" + headerTimestamp = "X-Authorization-Timestamp" + headerSignature = "X-Authorization-Signature-SHA256" + headerUpkeepId = "X-Authorization-Upkeep-Id" + mercuryPathV02 = "/client?" // only used to access mercury v0.2 server + mercuryBatchPathV03 = "/api/v1/reports/bulk?" // only used to access mercury v0.3 server + retryDelay = 500 * time.Millisecond + timestamp = "timestamp" // valid for v0.3 + totalAttempt = 3 ) type MercuryVersion string @@ -52,159 +57,182 @@ type FeedLookup struct { block uint64 } -// MercuryResponse is used in both single feed endpoint and bulk endpoint because bulk endpoint will return ONE -// chainlinkBlob which contains multiple reports instead of multiple blobs. -type MercuryResponse struct { +// MercuryV02Response represents a JSON structure used by Mercury v0.2 +type MercuryV02Response struct { ChainlinkBlob string `json:"chainlinkBlob"` } -type MercuryBytes struct { +// MercuryV03Response represents a JSON structure used by Mercury v0.3 +type MercuryV03Response struct { + Reports []MercuryV03Report `json:"reports"` +} + +type MercuryV03Report struct { + FeedID string `json:"feedID"` // feed id in hex + ValidFromTimestamp string `json:"validFromTimestamp"` + ObservationsTimestamp string `json:"observationsTimestamp"` + FullReport string `json:"fullReport"` // the actual mercury report of this feed, can be sent to verifier +} + +type MercuryData struct { Index int Error error Retryable bool - Bytes []byte + Bytes [][]byte + State encoding.PipelineExecutionState } -// AdminOffchainConfig represents the administrative offchain config for each upkeep. It can be set by s_upkeepManager +// UpkeepPrivilegeConfig represents the administrative offchain config for each upkeep. It can be set by s_upkeepManager // role on the registry. Upkeeps allowed to use Mercury server will have this set to true. -type AdminOffchainConfig struct { +type UpkeepPrivilegeConfig struct { MercuryEnabled bool `json:"mercuryEnabled"` } // feedLookup looks through check upkeep results looking for any that need off chain lookup -func (r *EvmRegistry) feedLookup(ctx context.Context, upkeepResults []ocr2keepers.CheckResult) ([]ocr2keepers.CheckResult, error) { +func (r *EvmRegistry) feedLookup(ctx context.Context, checkResults []ocr2keepers.CheckResult) []ocr2keepers.CheckResult { + lggr := r.lggr.With("where", "FeedLookup") lookups := map[int]*FeedLookup{} - for i, res := range upkeepResults { - ext := res.Extension.(EVMAutomationResultExtension21) - if ext.FailureReason != UPKEEP_FAILURE_REASON_TARGET_CHECK_REVERTED { + for i, res := range checkResults { + if res.IneligibilityReason != uint8(encoding.UpkeepFailureReasonTargetCheckReverted) { + // Feedlookup only works when upkeep target check reverts continue } - block, upkeepId := r.getBlockAndUpkeepId(res.Payload) + block := big.NewInt(int64(res.Trigger.BlockNumber)) + upkeepId := res.UpkeepID - opts, err := r.buildCallOpts(ctx, block) + // Try to decode the revert error into feed lookup format. User upkeeps can revert with any reason, see if they + // tried to call mercury + lggr.Infof("at block %d upkeep %s trying to decodeFeedLookup performData=%s", block, upkeepId, hexutil.Encode(checkResults[i].PerformData)) + l, err := r.decodeFeedLookup(res.PerformData) if err != nil { - r.lggr.Errorf("[FeedLookup] upkeep %s block %d buildCallOpts: %v", upkeepId, block, err) - return nil, err - } - - allowed, err := r.allowedToUseMercury(opts, upkeepId) - if err != nil { - r.lggr.Errorf("[FeedLookup] upkeep %s block %d failed to time mercury allow list: %v", upkeepId, block, err) + lggr.Warnf("upkeep %s block %d decodeFeedLookup failed: %v", upkeepId, block, err) + // Not feed lookup error, nothing to do here continue } - if !allowed { - ext.FailureReason = UPKEEP_FAILURE_REASON_MERCURY_ACCESS_NOT_ALLOWED - upkeepResults[i].Extension = ext - r.lggr.Errorf("[FeedLookup] upkeep %s block %d NOT allowed to time Mercury server", upkeepId, block) + if len(l.feeds) == 0 { + checkResults[i].IneligibilityReason = uint8(encoding.UpkeepFailureReasonInvalidRevertDataInput) + lggr.Warnf("at block %s upkeep %s has empty feeds array", block, upkeepId) continue } + // mercury permission checking for v0.3 is done by mercury server + if l.feedParamKey == feedIdHex && l.timeParamKey == blockNumber { + // check permission on the registry for mercury v0.2 + opts := r.buildCallOpts(ctx, block) + state, reason, retryable, allowed, err := r.allowedToUseMercury(opts, upkeepId.BigInt()) + if err != nil { + lggr.Warnf("at block %s upkeep %s failed to query mercury allow list: %s", block, upkeepId, err) + checkResults[i].PipelineExecutionState = uint8(state) + checkResults[i].IneligibilityReason = uint8(reason) + checkResults[i].Retryable = retryable + continue + } - r.lggr.Infof("[FeedLookup] upkeep %s block %d decodeFeedLookup performData=%s", upkeepId, block, hexutil.Encode(upkeepResults[i].PerformData)) - lookup, err := r.decodeFeedLookup(res.PerformData) - if err != nil { - r.lggr.Errorf("[FeedLookup] upkeep %s block %d decodeFeedLookup: %v", upkeepId, block, err) + if !allowed { + lggr.Warnf("at block %d upkeep %s NOT allowed to query Mercury server", block, upkeepId) + checkResults[i].IneligibilityReason = uint8(encoding.UpkeepFailureReasonMercuryAccessNotAllowed) + continue + } + } else if l.feedParamKey != feedIDs || l.timeParamKey != timestamp { + // if mercury version cannot be determined, set failure reason + lggr.Warnf("at block %d upkeep %s NOT allowed to query Mercury server", block, upkeepId) + checkResults[i].IneligibilityReason = uint8(encoding.UpkeepFailureReasonInvalidRevertDataInput) continue } - lookup.upkeepId = upkeepId + + l.upkeepId = upkeepId.BigInt() // the block here is exclusively used to call checkCallback at this block, not to be confused with the block number // in the revert for mercury v0.2, which is denoted by time in the struct bc starting from v0.3, only timestamp will be supported - lookup.block = uint64(block.Int64()) - r.lggr.Infof("[FeedLookup] upkeep %s block %d decodeFeedLookup feedKey=%s timeKey=%s feeds=%v time=%s extraData=%s", upkeepId, block, lookup.feedParamKey, lookup.timeParamKey, lookup.feeds, lookup.time, hexutil.Encode(lookup.extraData)) - lookups[i] = lookup + l.block = uint64(block.Int64()) + lggr.Infof("at block %d upkeep %s decodeFeedLookup feedKey=%s timeKey=%s feeds=%v time=%s extraData=%s", block, upkeepId, l.feedParamKey, l.timeParamKey, l.feeds, l.time, hexutil.Encode(l.extraData)) + lookups[i] = l } var wg sync.WaitGroup for i, lookup := range lookups { wg.Add(1) - go r.doLookup(ctx, &wg, lookup, i, upkeepResults) + go r.doLookup(ctx, &wg, lookup, i, checkResults, lggr) } wg.Wait() // don't surface error to plugin bc FeedLookup process should be self-contained. - return upkeepResults, nil + return checkResults } -func (r *EvmRegistry) doLookup(ctx context.Context, wg *sync.WaitGroup, lookup *FeedLookup, i int, upkeepResults []ocr2keepers.CheckResult) { +func (r *EvmRegistry) doLookup(ctx context.Context, wg *sync.WaitGroup, lookup *FeedLookup, i int, checkResults []ocr2keepers.CheckResult, lggr logger.Logger) { defer wg.Done() - values, retryable, err := r.doMercuryRequest(ctx, lookup) + state, reason, values, retryable, err := r.doMercuryRequest(ctx, lookup, lggr) if err != nil { - r.lggr.Errorf("[FeedLookup] upkeep %s retryable %v doMercuryRequest: %v", lookup.upkeepId, retryable, err) - upkeepResults[i].Retryable = retryable + lggr.Errorf("upkeep %s retryable %v doMercuryRequest: %v", lookup.upkeepId, retryable, err) + checkResults[i].Retryable = retryable + checkResults[i].PipelineExecutionState = uint8(state) + checkResults[i].IneligibilityReason = uint8(reason) return } for j, v := range values { - r.lggr.Infof("[FeedLookup] checkCallback values[%d]=%s", j, hexutil.Encode(v)) + lggr.Infof("checkCallback values[%d]=%s", j, hexutil.Encode(v)) } - mercuryBytes, err := r.checkCallback(ctx, values, lookup) + state, retryable, mercuryBytes, err := r.checkCallback(ctx, values, lookup) if err != nil { - r.lggr.Errorf("[FeedLookup] upkeep %s block %d checkCallback err: %v", lookup.upkeepId, lookup.block, err) + lggr.Errorf("at block %d upkeep %s checkCallback err: %v", lookup.block, lookup.upkeepId, err) + checkResults[i].Retryable = retryable + checkResults[i].PipelineExecutionState = uint8(state) return } - r.lggr.Infof("[FeedLookup] checkCallback mercuryBytes=%s", hexutil.Encode(mercuryBytes)) + lggr.Infof("checkCallback mercuryBytes=%s", hexutil.Encode(mercuryBytes)) - needed, performData, failureReason, _, err := r.packer.UnpackCheckCallbackResult(mercuryBytes) + state, needed, performData, failureReason, _, err := r.packer.UnpackCheckCallbackResult(mercuryBytes) if err != nil { - r.lggr.Errorf("[FeedLookup] upkeep %s block %d UnpackCheckCallbackResult err: %v", lookup.upkeepId, lookup.block, err) - return - } - - ext, ok := upkeepResults[i].Extension.(EVMAutomationResultExtension21) - if !ok { - r.lggr.Errorf("[FeedLookup] upkeep %s block %d unexpected check result extension struct", lookup.upkeepId, lookup.block) + lggr.Errorf("at block %d upkeep %s UnpackCheckCallbackResult err: %v", lookup.block, lookup.upkeepId, err) + checkResults[i].PipelineExecutionState = uint8(state) return } - if int(failureReason) == UPKEEP_FAILURE_REASON_MERCURY_CALLBACK_REVERTED { - ext.FailureReason = UPKEEP_FAILURE_REASON_MERCURY_CALLBACK_REVERTED - upkeepResults[i].Extension = ext - r.lggr.Debugf("[FeedLookup] upkeep %s block %d mercury callback reverts", lookup.upkeepId, lookup.block) + if failureReason == uint8(encoding.UpkeepFailureReasonMercuryCallbackReverted) { + checkResults[i].IneligibilityReason = uint8(encoding.UpkeepFailureReasonMercuryCallbackReverted) + lggr.Debugf("at block %d upkeep %s mercury callback reverts", lookup.block, lookup.upkeepId) return } if !needed { - ext.FailureReason = UPKEEP_FAILURE_REASON_UPKEEP_NOT_NEEDED - upkeepResults[i].Extension = ext - r.lggr.Debugf("[FeedLookup] upkeep %s block %d callback reports upkeep not needed", lookup.upkeepId, lookup.block) + checkResults[i].IneligibilityReason = uint8(encoding.UpkeepFailureReasonUpkeepNotNeeded) + lggr.Debugf("at block %d upkeep %s callback reports upkeep not needed", lookup.block, lookup.upkeepId) return } - ext.FailureReason = UPKEEP_FAILURE_REASON_NONE - upkeepResults[i].Extension = ext - upkeepResults[i].Eligible = true - upkeepResults[i].PerformData = performData - r.lggr.Infof("[FeedLookup] upkeep %s block %d successful with perform data: %s", lookup.upkeepId, lookup.block, hexutil.Encode(performData)) + checkResults[i].IneligibilityReason = uint8(encoding.UpkeepFailureReasonNone) + checkResults[i].Eligible = true + checkResults[i].PerformData = performData + lggr.Infof("at block %d upkeep %s successful with perform data: %s", lookup.block, lookup.upkeepId, hexutil.Encode(performData)) } // allowedToUseMercury retrieves upkeep's administrative offchain config and decode a mercuryEnabled bool to indicate if // this upkeep is allowed to use Mercury service. -func (r *EvmRegistry) allowedToUseMercury(opts *bind.CallOpts, upkeepId *big.Int) (bool, error) { - var au activeUpkeep - var ok bool - if au, ok = r.active[upkeepId.String()]; !ok { - return false, fmt.Errorf("upkeep %s is not active", upkeepId) - } - - allowed, ok := r.mercury.allowListCache.Get(au.Admin.Hex()) +func (r *EvmRegistry) allowedToUseMercury(opts *bind.CallOpts, upkeepId *big.Int) (state encoding.PipelineExecutionState, reason encoding.UpkeepFailureReason, retryable bool, allow bool, err error) { + allowed, ok := r.mercury.allowListCache.Get(upkeepId.String()) if ok { - return allowed.(bool), nil + return encoding.NoPipelineError, encoding.UpkeepFailureReasonNone, false, allowed.(bool), nil } - cfg, err := r.registry.GetAdminPrivilegeConfig(opts, au.Admin) + cfg, err := r.registry.GetUpkeepPrivilegeConfig(opts, upkeepId) if err != nil { - return false, fmt.Errorf("failed to get upkeep privilege config for upkeep ID %s: %v", upkeepId, err) + return encoding.RpcFlakyFailure, encoding.UpkeepFailureReasonNone, true, false, fmt.Errorf("failed to get upkeep privilege config: %v", err) + } + if len(cfg) == 0 { + r.mercury.allowListCache.Set(upkeepId.String(), false, cache.DefaultExpiration) + return encoding.NoPipelineError, encoding.UpkeepFailureReasonMercuryAccessNotAllowed, false, false, fmt.Errorf("upkeep privilege config is empty") } - var a AdminOffchainConfig + var a UpkeepPrivilegeConfig err = json.Unmarshal(cfg, &a) if err != nil { - return false, fmt.Errorf("failed to unmarshal privilege config for upkeep ID %s: %v", upkeepId, err) + return encoding.MercuryUnmarshalError, encoding.UpkeepFailureReasonNone, false, false, fmt.Errorf("failed to unmarshal privilege config: %v", err) } - r.mercury.allowListCache.Set(au.Admin.Hex(), a.MercuryEnabled, cache.DefaultExpiration) - return a.MercuryEnabled, nil + r.mercury.allowListCache.Set(upkeepId.String(), a.MercuryEnabled, cache.DefaultExpiration) + return encoding.NoPipelineError, encoding.UpkeepFailureReasonNone, false, a.MercuryEnabled, nil } // decodeFeedLookup decodes the revert error FeedLookup(string feedParamKey, string[] feeds, string feedParamKey, uint256 time, byte[] extraData) @@ -225,10 +253,10 @@ func (r *EvmRegistry) decodeFeedLookup(data []byte) (*FeedLookup, error) { }, nil } -func (r *EvmRegistry) checkCallback(ctx context.Context, values [][]byte, lookup *FeedLookup) (hexutil.Bytes, error) { +func (r *EvmRegistry) checkCallback(ctx context.Context, values [][]byte, lookup *FeedLookup) (encoding.PipelineExecutionState, bool, hexutil.Bytes, error) { payload, err := r.abi.Pack("checkCallback", lookup.upkeepId, values, lookup.extraData) if err != nil { - return nil, err + return encoding.PackUnpackDecodeFailed, false, nil, err } var b hexutil.Bytes @@ -240,116 +268,146 @@ func (r *EvmRegistry) checkCallback(ctx context.Context, values [][]byte, lookup // call checkCallback function at the block which OCR3 has agreed upon err = r.client.CallContext(ctx, &b, "eth_call", args, hexutil.EncodeUint64(lookup.block)) if err != nil { - return nil, err + return encoding.RpcFlakyFailure, true, nil, err } - return b, nil + return encoding.NoPipelineError, false, b, nil } -// doMercuryRequest sends requests to Mercury API to retrieve ChainlinkBlob. -func (r *EvmRegistry) doMercuryRequest(ctx context.Context, ml *FeedLookup) ([][]byte, bool, error) { - // TODO (AUTO-3253): if no feed labels are provided in v0.3, request for all feeds +// doMercuryRequest sends requests to Mercury API to retrieve mercury data. +func (r *EvmRegistry) doMercuryRequest(ctx context.Context, ml *FeedLookup, lggr logger.Logger) (encoding.PipelineExecutionState, encoding.UpkeepFailureReason, [][]byte, bool, error) { + var isMercuryV03 bool resultLen := len(ml.feeds) - ch := make(chan MercuryBytes, resultLen) - if ml.feedParamKey == FeedIdHex && ml.timeParamKey == BlockNumber { + ch := make(chan MercuryData, resultLen) + if len(ml.feeds) == 0 { + return encoding.NoPipelineError, encoding.UpkeepFailureReasonInvalidRevertDataInput, [][]byte{}, false, fmt.Errorf("invalid revert data input: feed param key %s, time param key %s, feeds %s", ml.feedParamKey, ml.timeParamKey, ml.feeds) + } + if ml.feedParamKey == feedIdHex && ml.timeParamKey == blockNumber { // only mercury v0.2 for i := range ml.feeds { - go r.singleFeedRequest(ctx, ch, i, ml, MercuryV02) + go r.singleFeedRequest(ctx, ch, i, ml, lggr) } - } else if ml.feedParamKey == FeedId && ml.timeParamKey == Timestamp { + } else if ml.feedParamKey == feedIDs && ml.timeParamKey == timestamp { // only mercury v0.3 - if resultLen == 1 { - go r.singleFeedRequest(ctx, ch, 0, ml, MercuryV03) - } else { - // create a new channel with buffer size 1 since the batch endpoint will only return 1 blob - resultLen = 1 - ch = make(chan MercuryBytes, resultLen) - go r.multiFeedsRequest(ctx, ch, ml) - } + resultLen = 1 + isMercuryV03 = true + ch = make(chan MercuryData, resultLen) + go r.multiFeedsRequest(ctx, ch, ml, lggr) } else { - return nil, false, fmt.Errorf("invalid label combination: feed param key %s and time param key %s", ml.feedParamKey, ml.timeParamKey) + return encoding.NoPipelineError, encoding.UpkeepFailureReasonInvalidRevertDataInput, [][]byte{}, false, fmt.Errorf("invalid revert data input: feed param key %s, time param key %s, feeds %s", ml.feedParamKey, ml.timeParamKey, ml.feeds) } var reqErr error results := make([][]byte, len(ml.feeds)) retryable := true allSuccess := true - for i := 0; i < len(results); i++ { + // in v0.2, use the last execution error as the state, if no execution errors, state will be no error + state := encoding.NoPipelineError + for i := 0; i < resultLen; i++ { m := <-ch if m.Error != nil { reqErr = errors.Join(reqErr, m.Error) retryable = retryable && m.Retryable allSuccess = false + if m.State != encoding.NoPipelineError { + state = m.State + } + continue + } + if isMercuryV03 { + results = m.Bytes + } else { + results[m.Index] = m.Bytes[0] } - results[m.Index] = m.Bytes } - r.lggr.Debugf("FeedLookup upkeep %s retryable %s reqErr %w", ml.upkeepId.String(), retryable && !allSuccess, reqErr) + lggr.Debugf("upkeep %s retryable %s reqErr %w", ml.upkeepId.String(), retryable && !allSuccess, reqErr) // only retry when not all successful AND none are not retryable - return results, retryable && !allSuccess, reqErr + return state, encoding.UpkeepFailureReasonNone, results, retryable && !allSuccess, reqErr } -// singleFeedRequest sends a Mercury request for a single feed report. -func (r *EvmRegistry) singleFeedRequest(ctx context.Context, ch chan<- MercuryBytes, index int, ml *FeedLookup, mv MercuryVersion) { +// singleFeedRequest sends a v0.2 Mercury request for a single feed report. +func (r *EvmRegistry) singleFeedRequest(ctx context.Context, ch chan<- MercuryData, index int, ml *FeedLookup, lggr logger.Logger) { q := url.Values{ ml.feedParamKey: {ml.feeds[index]}, ml.timeParamKey: {ml.time.String()}, - UserId: {ml.upkeepId.String()}, } mercuryURL := r.mercury.cred.URL - path := MercuryPathV2 - if mv == MercuryV03 { - path = MercuryPathV3 - } - reqUrl := fmt.Sprintf("%s%s%s", mercuryURL, path, q.Encode()) - r.lggr.Debugf("FeedLookup request URL: %s", reqUrl) + reqUrl := fmt.Sprintf("%s%s%s", mercuryURL, mercuryPathV02, q.Encode()) + lggr.Debugf("request URL: %s", reqUrl) req, err := http.NewRequestWithContext(ctx, http.MethodGet, reqUrl, nil) if err != nil { - ch <- MercuryBytes{Index: index, Error: err} + ch <- MercuryData{Index: index, Error: err, Retryable: false, State: encoding.InvalidMercuryRequest} return } ts := time.Now().UTC().UnixMilli() - signature := r.generateHMAC(http.MethodGet, path+q.Encode(), []byte{}, r.mercury.cred.Username, r.mercury.cred.Password, ts) - req.Header.Set("Content-Type", "application/json") - req.Header.Set("Authorization", r.mercury.cred.Username) - req.Header.Set("X-Authorization-Timestamp", strconv.FormatInt(ts, 10)) - req.Header.Set("X-Authorization-Signature-SHA256", signature) - + signature := r.generateHMAC(http.MethodGet, mercuryPathV02+q.Encode(), []byte{}, r.mercury.cred.Username, r.mercury.cred.Password, ts) + req.Header.Set(headerContentType, applicationJson) + req.Header.Set(headerAuthorization, r.mercury.cred.Username) + req.Header.Set(headerTimestamp, strconv.FormatInt(ts, 10)) + req.Header.Set(headerSignature, signature) + + // in the case of multiple retries here, use the last attempt's data + state := encoding.NoPipelineError retryable := false + sent := false retryErr := retry.Do( func() error { retryable = false resp, err1 := r.hc.Do(req) if err1 != nil { - r.lggr.Errorf("FeedLookup upkeep %s block %s GET request fails for feed %s: %v", ml.upkeepId.String(), ml.time.String(), ml.feeds[index], err1) + lggr.Warnf("at block %s upkeep %s GET request fails for feed %s: %v", ml.time.String(), ml.upkeepId.String(), ml.feeds[index], err1) + retryable = true + state = encoding.MercuryFlakyFailure return err1 } - defer resp.Body.Close() + defer func(Body io.ReadCloser) { + err = Body.Close() + if err != nil { + lggr.Warnf("failed to close mercury response Body: %s", err) + } + }(resp.Body) + body, err1 := io.ReadAll(resp.Body) if err1 != nil { + retryable = false + state = encoding.InvalidMercuryResponse return err1 } if resp.StatusCode == http.StatusNotFound || resp.StatusCode == http.StatusInternalServerError { - r.lggr.Errorf("FeedLookup upkeep %s block %s received status code %d for feed %s", ml.upkeepId.String(), ml.time.String(), resp.StatusCode, ml.feeds[index]) + lggr.Warnf("at block %s upkeep %s received status code %d for feed %s", ml.time.String(), ml.upkeepId.String(), resp.StatusCode, ml.feeds[index]) retryable = true + state = encoding.MercuryFlakyFailure return errors.New(strconv.FormatInt(int64(resp.StatusCode), 10)) } else if resp.StatusCode != http.StatusOK { - return fmt.Errorf("FeedLookup upkeep %s block %s received status code %d for feed %s", ml.upkeepId.String(), ml.time.String(), resp.StatusCode, ml.feeds[index]) + retryable = false + state = encoding.InvalidMercuryRequest + return fmt.Errorf("at block %s upkeep %s received status code %d for feed %s", ml.time.String(), ml.upkeepId.String(), resp.StatusCode, ml.feeds[index]) } - var m MercuryResponse + var m MercuryV02Response err1 = json.Unmarshal(body, &m) if err1 != nil { - r.lggr.Errorf("FeedLookup upkeep %s block %s failed to unmarshal body to MercuryResponse for feed %s: %v", ml.upkeepId.String(), ml.time.String(), ml.feeds[index], err1) + lggr.Warnf("at block %s upkeep %s failed to unmarshal body to MercuryV02Response for feed %s: %v", ml.time.String(), ml.upkeepId.String(), ml.feeds[index], err1) + retryable = false + state = encoding.MercuryUnmarshalError return err1 } blobBytes, err1 := hexutil.Decode(m.ChainlinkBlob) if err1 != nil { - r.lggr.Errorf("FeedLookup upkeep %s block %s failed to decode chainlinkBlob %s for feed %s: %v", ml.upkeepId.String(), ml.time.String(), m.ChainlinkBlob, ml.feeds[index], err1) + lggr.Warnf("at block %s upkeep %s failed to decode chainlinkBlob %s for feed %s: %v", ml.time.String(), ml.upkeepId.String(), m.ChainlinkBlob, ml.feeds[index], err1) + retryable = false + state = encoding.InvalidMercuryResponse return err1 } - ch <- MercuryBytes{Index: index, Bytes: blobBytes} + ch <- MercuryData{ + Index: index, + Bytes: [][]byte{blobBytes}, + Retryable: false, + State: encoding.NoPipelineError, + } + sent = true return nil }, // only retry when the error is 404 Not Found or 500 Internal Server Error @@ -357,82 +415,121 @@ func (r *EvmRegistry) singleFeedRequest(ctx context.Context, ch chan<- MercuryBy return err.Error() == fmt.Sprintf("%d", http.StatusNotFound) || err.Error() == fmt.Sprintf("%d", http.StatusInternalServerError) }), retry.Context(ctx), - retry.Delay(RetryDelay), - retry.Attempts(TotalAttempt)) + retry.Delay(retryDelay), + retry.Attempts(totalAttempt)) - // if all retries fail, return the error and ask the caller to handle cool down and heavyweight retry - if retryErr != nil { - mb := MercuryBytes{ + if !sent { + md := MercuryData{ Index: index, + Bytes: [][]byte{}, Retryable: retryable, Error: retryErr, + State: state, } - ch <- mb + ch <- md } } -// multiFeedsRequest sends a Mercury request for a multi-feed report -func (r *EvmRegistry) multiFeedsRequest(ctx context.Context, ch chan<- MercuryBytes, ml *FeedLookup) { +// multiFeedsRequest sends a Mercury v0.3 request for a multi-feed report +func (r *EvmRegistry) multiFeedsRequest(ctx context.Context, ch chan<- MercuryData, ml *FeedLookup, lggr logger.Logger) { q := url.Values{ - FeedId: {strings.Join(ml.feeds, ",")}, - Timestamp: {ml.time.String()}, - UserId: {ml.upkeepId.String()}, + feedIDs: {strings.Join(ml.feeds, ",")}, + timestamp: {ml.time.String()}, } - reqUrl := fmt.Sprintf("%s%s%s", r.mercury.cred.URL, MercuryBatchPathV3, q.Encode()) - r.lggr.Debugf("FeedLookup request URL: %s", reqUrl) + reqUrl := fmt.Sprintf("%s%s%s", r.mercury.cred.URL, mercuryBatchPathV03, q.Encode()) + lggr.Debugf("request URL: %s", reqUrl) req, err := http.NewRequestWithContext(ctx, http.MethodGet, reqUrl, nil) if err != nil { - ch <- MercuryBytes{Index: 0, Error: err} + ch <- MercuryData{Index: 0, Error: err, Retryable: false, State: encoding.InvalidMercuryRequest} return } ts := time.Now().UTC().UnixMilli() - signature := r.generateHMAC(http.MethodGet, MercuryBatchPathV3+q.Encode(), []byte{}, r.mercury.cred.Username, r.mercury.cred.Password, ts) - req.Header.Set("Content-Type", "application/json") - req.Header.Set("Authorization", r.mercury.cred.Username) - req.Header.Set("X-Authorization-Timestamp", strconv.FormatInt(ts, 10)) - req.Header.Set("X-Authorization-Signature-SHA256", signature) - + signature := r.generateHMAC(http.MethodGet, mercuryBatchPathV03+q.Encode(), []byte{}, r.mercury.cred.Username, r.mercury.cred.Password, ts) + req.Header.Set(headerContentType, applicationJson) + // username here is often referred to as user id + req.Header.Set(headerAuthorization, r.mercury.cred.Username) + req.Header.Set(headerTimestamp, strconv.FormatInt(ts, 10)) + req.Header.Set(headerSignature, signature) + // mercury will inspect authorization headers above to make sure this user (in automation's context, this node) is eligible to access mercury + // and if it has an automation role. it will then look at this upkeep id to check if it has access to all the requested feeds. + req.Header.Set(headerUpkeepId, ml.upkeepId.String()) + + // in the case of multiple retries here, use the last attempt's data + state := encoding.NoPipelineError retryable := false + sent := false retryErr := retry.Do( func() error { retryable = false resp, err1 := r.hc.Do(req) if err1 != nil { - r.lggr.Errorf("FeedLookup upkeep %s block %s GET request fails for multi feed: %v", ml.upkeepId.String(), ml.time.String(), err1) + lggr.Warnf("at block %s upkeep %s GET request fails from mercury v0.3: %v", ml.time.String(), ml.upkeepId.String(), err1) + retryable = true + state = encoding.MercuryFlakyFailure return err1 } - defer resp.Body.Close() + defer func(Body io.ReadCloser) { + err = Body.Close() + if err != nil { + lggr.Warnf("failed to close mercury response Body: %s", err) + } + }(resp.Body) + body, err1 := io.ReadAll(resp.Body) if err1 != nil { + retryable = false + state = encoding.InvalidMercuryResponse return err1 } if resp.StatusCode == http.StatusNotFound || resp.StatusCode == http.StatusInternalServerError { - r.lggr.Errorf("FeedLookup upkeep %s block %s received status code %d for multi feed", ml.upkeepId.String(), ml.time.String(), resp.StatusCode) + lggr.Warnf("at block %s upkeep %s received status code %d from mercury v0.3", ml.time.String(), ml.upkeepId.String(), resp.StatusCode) retryable = true + state = encoding.MercuryFlakyFailure return errors.New(strconv.FormatInt(int64(resp.StatusCode), 10)) } else if resp.StatusCode != http.StatusOK { - return fmt.Errorf("FeedLookup upkeep %s block %s received status code %d for multi feed", ml.upkeepId.String(), ml.time.String(), resp.StatusCode) + retryable = false + state = encoding.InvalidMercuryRequest + return fmt.Errorf("at block %s upkeep %s received status code %d from mercury v0.3", ml.time.String(), ml.upkeepId.String(), resp.StatusCode) } - var m MercuryResponse - err1 = json.Unmarshal(body, &m) + var response MercuryV03Response + err1 = json.Unmarshal(body, &response) if err1 != nil { - r.lggr.Errorf("FeedLookup upkeep %s block %s failed to unmarshal body to MercuryResponse for multi feed: %v", ml.upkeepId.String(), ml.time.String(), err1) + lggr.Warnf("at block %s upkeep %s failed to unmarshal body to MercuryV03Response from mercury v0.3: %v", ml.time.String(), ml.upkeepId.String(), err1) + retryable = false + state = encoding.MercuryUnmarshalError return err1 } - blobBytes, err1 := hexutil.Decode(m.ChainlinkBlob) - if err1 != nil { - r.lggr.Errorf("FeedLookup upkeep %s block %s failed to decode chainlinkBlob %s for multi feed: %v", ml.upkeepId.String(), ml.time.String(), m.ChainlinkBlob, err1) - return err1 + if len(response.Reports) != len(ml.feeds) { + // this should never happen. if this upkeep does not have permission for any feeds it requests, or if certain feeds are + // missing in mercury server, the mercury server v0.3 should respond with 400s, rather than returning partial results + retryable = false + state = encoding.InvalidMercuryResponse + return fmt.Errorf("at block %s upkeep %s requested %d feeds but received %d reports from mercury v0.3", ml.time.String(), ml.upkeepId.String(), len(ml.feeds), len(response.Reports)) + } + var reportBytes [][]byte + var b []byte + for _, rsp := range response.Reports { + b, err1 = hexutil.Decode(rsp.FullReport) + if err1 != nil { + lggr.Warnf("upkeep %s block %s failed to decode fullReport %s from mercury v0.3: %v", ml.upkeepId.String(), ml.time.String(), rsp.FullReport, err1) + retryable = false + state = encoding.InvalidMercuryResponse + return err1 + } + reportBytes = append(reportBytes, b) } - ch <- MercuryBytes{ - Index: 0, - Bytes: blobBytes, + ch <- MercuryData{ + Index: 0, + Bytes: reportBytes, + Retryable: false, + State: encoding.NoPipelineError, } + sent = true return nil }, // only retry when the error is 404 Not Found or 500 Internal Server Error @@ -440,17 +537,18 @@ func (r *EvmRegistry) multiFeedsRequest(ctx context.Context, ch chan<- MercuryBy return err.Error() == fmt.Sprintf("%d", http.StatusNotFound) || err.Error() == fmt.Sprintf("%d", http.StatusInternalServerError) }), retry.Context(ctx), - retry.Delay(RetryDelay), - retry.Attempts(TotalAttempt)) + retry.Delay(retryDelay), + retry.Attempts(totalAttempt)) - // if all retries fail, return the error and ask the caller to handle cool down and heavyweight retry - if retryErr != nil { - mb := MercuryBytes{ + if !sent { + md := MercuryData{ Index: 0, + Bytes: [][]byte{}, Retryable: retryable, Error: retryErr, + State: state, } - ch <- mb + ch <- md } } diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/feed_lookup_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/feed_lookup_test.go index 6cb9381db69..a1d7d221b27 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/feed_lookup_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/feed_lookup_test.go @@ -11,17 +11,17 @@ import ( "strings" "testing" - "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/patrickmn/go-cache" "github.com/pkg/errors" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/encoding" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/mocks" evmClientMocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" @@ -49,17 +49,17 @@ func setupEVMRegistry(t *testing.T) *EvmRegistry { client := evmClientMocks.NewClient(t) r := &EvmRegistry{ - lggr: lggr, - poller: logPoller, - addr: addr, - client: client, - txHashes: make(map[string]bool), - registry: mockRegistry, - abi: keeperRegistryABI, - active: make(map[string]activeUpkeep), - packer: NewEvmRegistryPackerV2_1(keeperRegistryABI, utilsABI), - headFunc: func(ocr2keepers.BlockKey) {}, - chLog: make(chan logpoller.Log, 1000), + lggr: lggr, + poller: logPoller, + addr: addr, + client: client, + logProcessed: make(map[string]bool), + registry: mockRegistry, + abi: keeperRegistryABI, + active: NewActiveUpkeepList(), + packer: encoding.NewAbiPacker(keeperRegistryABI, utilsABI), + headFunc: func(ocr2keepers.BlockKey) {}, + chLog: make(chan logpoller.Log, 1000), mercury: &MercuryConfig{ cred: &models.MercuryCredentials{ URL: "https://google.com", @@ -67,7 +67,7 @@ func setupEVMRegistry(t *testing.T) *EvmRegistry { Password: "FakeClientKey", }, abi: feedLookupCompatibleABI, - allowListCache: cache.New(DefaultAllowListExpiration, CleanupInterval), + allowListCache: cache.New(defaultAllowListExpiration, allowListCleanupInterval), }, hc: mockHttpClient, } @@ -76,15 +76,15 @@ func setupEVMRegistry(t *testing.T) *EvmRegistry { func TestEvmRegistry_FeedLookup(t *testing.T) { upkeepId, ok := new(big.Int).SetString("71022726777042968814359024671382968091267501884371696415772139504780367423725", 10) + var upkeepIdentifier [32]byte + copy(upkeepIdentifier[:], upkeepId.Bytes()) assert.True(t, ok, t.Name()) - admin := common.HexToAddress("0x6cA639822c6C241Fa9A7A6b5032F6F7F1C513CAD") tests := []struct { name string input []ocr2keepers.CheckResult blob string callbackResp []byte expectedResults []ocr2keepers.CheckResult - wantErr error callbackNeeded bool extraData []byte checkCallbackResp []byte @@ -98,19 +98,11 @@ func TestEvmRegistry_FeedLookup(t *testing.T) { input: []ocr2keepers.CheckResult{ { PerformData: []byte{125, 221, 147, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 141, 110, 193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 102, 101, 101, 100, 73, 100, 72, 101, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 48, 120, 52, 53, 53, 52, 52, 56, 50, 100, 53, 53, 53, 51, 52, 52, 50, 100, 52, 49, 53, 50, 52, 50, 52, 57, 53, 52, 53, 50, 53, 53, 52, 100, 50, 100, 53, 52, 52, 53, 53, 51, 53, 52, 52, 101, 52, 53, 53, 52, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 98, 108, 111, 99, 107, 78, 117, 109, 98, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - Payload: ocr2keepers.UpkeepPayload{ - Upkeep: ocr2keepers.ConfiguredUpkeep{ - ID: upkeepId.Bytes(), - Type: 0, - Config: nil, - }, - CheckBlock: "26046145", - CheckData: nil, - Trigger: ocr2keepers.Trigger{ - BlockNumber: 26046145, - }, + UpkeepID: upkeepIdentifier, + Trigger: ocr2keepers.Trigger{ + BlockNumber: 26046145, }, - Extension: EVMAutomationResultExtension21{FailureReason: UPKEEP_FAILURE_REASON_TARGET_CHECK_REVERTED}, + IneligibilityReason: uint8(encoding.UpkeepFailureReasonTargetCheckReverted), }, }, blob: "0x00066dfcd1ed2d95b18c948dbc5bd64c687afe93e4ca7d663ddec14c20090ad80000000000000000000000000000000000000000000000000000000000159761000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000280000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001204554482d5553442d415242495452554d2d544553544e4554000000000000000000000000000000000000000000000000000000000000000000000000648a1fbb000000000000000000000000000000000000000000000000000000274421041500000000000000000000000000000000000000000000000000000027437c6ecd0000000000000000000000000000000000000000000000000000002744c5995d00000000000000000000000000000000000000000000000000000000018d6ec108936dfe39c48715572a51ac868129958f937fb95ef5abdf73a239cf86a4fee700000000000000000000000000000000000000000000000000000000018d6ec100000000000000000000000000000000000000000000000000000000648a1fbb00000000000000000000000000000000000000000000000000000000000000028a26e557ee2feb91ccb116f3ab4eb1469afe5c3b012538cb151dbe3fbceaf6f117b24ac2a82cff25b286ae0a9b903dc6badaa16f6e67bf0983461b008574e30a00000000000000000000000000000000000000000000000000000000000000020db5c5924481061b98df59caefd9c4c1e72657c4976bf7c7568730fbdaf828080bff6b1edea2c8fed5e8bbac5574aa94cf809d898f5055cb1db14a16f1493726", @@ -123,19 +115,11 @@ func TestEvmRegistry_FeedLookup(t *testing.T) { { Eligible: true, PerformData: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 224, 0, 6, 109, 252, 209, 237, 45, 149, 177, 140, 148, 141, 188, 91, 214, 76, 104, 122, 254, 147, 228, 202, 125, 102, 61, 222, 193, 76, 32, 9, 10, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 151, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 128, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 32, 69, 84, 72, 45, 85, 83, 68, 45, 65, 82, 66, 73, 84, 82, 85, 77, 45, 84, 69, 83, 84, 78, 69, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 138, 31, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 68, 33, 4, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 67, 124, 110, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 68, 197, 153, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 141, 110, 193, 8, 147, 109, 254, 57, 196, 135, 21, 87, 42, 81, 172, 134, 129, 41, 149, 143, 147, 127, 185, 94, 245, 171, 223, 115, 162, 57, 207, 134, 164, 254, 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 141, 110, 193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 138, 31, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 138, 38, 229, 87, 238, 47, 235, 145, 204, 177, 22, 243, 171, 78, 177, 70, 154, 254, 92, 59, 1, 37, 56, 203, 21, 29, 190, 63, 188, 234, 246, 241, 23, 178, 74, 194, 168, 44, 255, 37, 178, 134, 174, 10, 155, 144, 61, 198, 186, 218, 161, 111, 110, 103, 191, 9, 131, 70, 27, 0, 133, 116, 227, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 13, 181, 197, 146, 68, 129, 6, 27, 152, 223, 89, 202, 239, 217, 196, 193, 231, 38, 87, 196, 151, 107, 247, 199, 86, 135, 48, 251, 218, 248, 40, 8, 11, 255, 107, 30, 222, 162, 200, 254, 213, 232, 187, 172, 85, 116, 170, 148, 207, 128, 157, 137, 143, 80, 85, 203, 29, 177, 74, 22, 241, 73, 55, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 120, 111, 101, 122, 90, 54, 44, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - Payload: ocr2keepers.UpkeepPayload{ - Upkeep: ocr2keepers.ConfiguredUpkeep{ - ID: upkeepId.Bytes(), - Type: 0, - Config: nil, - }, - CheckBlock: "26046145", - CheckData: nil, - Trigger: ocr2keepers.Trigger{ - BlockNumber: 26046145, - }, + UpkeepID: upkeepIdentifier, + Trigger: ocr2keepers.Trigger{ + BlockNumber: 26046145, }, - Extension: EVMAutomationResultExtension21{FailureReason: UPKEEP_FAILURE_REASON_NONE}, + IneligibilityReason: uint8(encoding.UpkeepFailureReasonNone), }, }, hasError: false, @@ -146,105 +130,69 @@ func TestEvmRegistry_FeedLookup(t *testing.T) { input: []ocr2keepers.CheckResult{ { PerformData: []byte{}, - Payload: ocr2keepers.UpkeepPayload{ - Upkeep: ocr2keepers.ConfiguredUpkeep{ - ID: upkeepId.Bytes(), - Type: 0, - Config: nil, - }, - CheckBlock: "26046145", - CheckData: nil, - Trigger: ocr2keepers.Trigger{ - BlockNumber: 26046145, - }, + UpkeepID: upkeepIdentifier, + Trigger: ocr2keepers.Trigger{ + BlockNumber: 26046145, }, - Extension: EVMAutomationResultExtension21{FailureReason: UPKEEP_FAILURE_REASON_INSUFFICIENT_BALANCE}, + IneligibilityReason: uint8(encoding.UpkeepFailureReasonInsufficientBalance), }, }, expectedResults: []ocr2keepers.CheckResult{ { Eligible: false, PerformData: []byte{}, - Payload: ocr2keepers.UpkeepPayload{ - Upkeep: ocr2keepers.ConfiguredUpkeep{ - ID: upkeepId.Bytes(), - Type: 0, - Config: nil, - }, - CheckBlock: "26046145", - CheckData: nil, - Trigger: ocr2keepers.Trigger{ - BlockNumber: 26046145, - }, + UpkeepID: upkeepIdentifier, + Trigger: ocr2keepers.Trigger{ + BlockNumber: 26046145, }, - Extension: EVMAutomationResultExtension21{FailureReason: UPKEEP_FAILURE_REASON_INSUFFICIENT_BALANCE}, + IneligibilityReason: uint8(encoding.UpkeepFailureReasonInsufficientBalance), }, }, hasError: true, }, { - name: "skip - no mercury permission", + name: "skip - invalid revert data", input: []ocr2keepers.CheckResult{ { PerformData: []byte{}, - Payload: ocr2keepers.UpkeepPayload{ - Upkeep: ocr2keepers.ConfiguredUpkeep{ - ID: upkeepId.Bytes(), - Type: 0, - Config: nil, - }, - CheckBlock: "26046145", - CheckData: nil, - Trigger: ocr2keepers.Trigger{ - BlockNumber: 26046145, - }, + UpkeepID: upkeepIdentifier, + Trigger: ocr2keepers.Trigger{ + BlockNumber: 26046145, }, - Extension: EVMAutomationResultExtension21{FailureReason: UPKEEP_FAILURE_REASON_TARGET_CHECK_REVERTED}, + IneligibilityReason: uint8(encoding.UpkeepFailureReasonTargetCheckReverted), }, }, expectedResults: []ocr2keepers.CheckResult{ { Eligible: false, PerformData: []byte{}, - Payload: ocr2keepers.UpkeepPayload{ - Upkeep: ocr2keepers.ConfiguredUpkeep{ - ID: upkeepId.Bytes(), - Type: 0, - Config: nil, - }, - CheckBlock: "26046145", - CheckData: nil, - Trigger: ocr2keepers.Trigger{ - BlockNumber: 26046145, - }, + UpkeepID: upkeepIdentifier, + Trigger: ocr2keepers.Trigger{ + BlockNumber: 26046145, }, - Extension: EVMAutomationResultExtension21{FailureReason: UPKEEP_FAILURE_REASON_MERCURY_ACCESS_NOT_ALLOWED}, + IneligibilityReason: uint8(encoding.UpkeepFailureReasonTargetCheckReverted), }, }, - hasError: false, + hasError: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { r := setupEVMRegistry(t) - r.active[upkeepId.String()] = activeUpkeep{ - ID: upkeepId, - Admin: admin, - } if !tt.cachedAdminCfg && !tt.hasError { mockRegistry := mocks.NewRegistry(t) - cfg := AdminOffchainConfig{MercuryEnabled: tt.hasPermission} + cfg := UpkeepPrivilegeConfig{MercuryEnabled: tt.hasPermission} b, err := json.Marshal(cfg) assert.Nil(t, err) - mockRegistry.On("GetAdminPrivilegeConfig", mock.Anything, admin).Return(b, nil) + mockRegistry.On("GetUpkeepPrivilegeConfig", mock.Anything, upkeepId).Return(b, nil) r.registry = mockRegistry } if tt.blob != "" { hc := mocks.NewHttpClient(t) - mr := MercuryResponse{ChainlinkBlob: tt.blob} + mr := MercuryV02Response{ChainlinkBlob: tt.blob} b, err := json.Marshal(mr) assert.Nil(t, err) resp := &http.Response{ @@ -271,13 +219,8 @@ func TestEvmRegistry_FeedLookup(t *testing.T) { r.client = client } - got, err := r.feedLookup(context.Background(), tt.input) - if tt.wantErr != nil { - assert.Equal(t, tt.wantErr.Error(), err.Error(), tt.name) - assert.NotNil(t, err, tt.name) - } else { - assert.Equal(t, tt.expectedResults, got, tt.name) - } + got := r.feedLookup(context.Background(), tt.input) + assert.Equal(t, tt.expectedResults, got, tt.name) }) } } @@ -287,15 +230,16 @@ func TestEvmRegistry_DecodeFeedLookup(t *testing.T) { name string data []byte expected *FeedLookup + state encoding.PipelineExecutionState err error }{ { name: "success - decode to feed lookup", data: []byte{125, 221, 147, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 138, 215, 253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 102, 101, 101, 100, 73, 100, 72, 101, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 48, 120, 52, 53, 53, 52, 52, 56, 50, 100, 53, 53, 53, 51, 52, 52, 50, 100, 52, 49, 53, 50, 52, 50, 52, 57, 53, 52, 53, 50, 53, 53, 52, 100, 50, 100, 53, 52, 52, 53, 53, 51, 53, 52, 52, 101, 52, 53, 53, 52, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 48, 120, 52, 50, 53, 52, 52, 51, 50, 100, 53, 53, 53, 51, 52, 52, 50, 100, 52, 49, 53, 50, 52, 50, 52, 57, 53, 52, 53, 50, 53, 53, 52, 100, 50, 100, 53, 52, 52, 53, 53, 51, 53, 52, 52, 101, 52, 53, 53, 52, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 98, 108, 111, 99, 107, 78, 117, 109, 98, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, expected: &FeedLookup{ - feedParamKey: FeedIdHex, + feedParamKey: feedIdHex, feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"}, - timeParamKey: BlockNumber, + timeParamKey: blockNumber, time: big.NewInt(25876477), extraData: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100}, }, @@ -322,12 +266,16 @@ func TestEvmRegistry_DecodeFeedLookup(t *testing.T) { func TestEvmRegistry_AllowedToUseMercury(t *testing.T) { upkeepId, ok := new(big.Int).SetString("71022726777042968814359024671382968091267501884371696415772139504780367423725", 10) assert.True(t, ok, t.Name()) - admin := common.HexToAddress("0x6cA639822c6C241Fa9A7A6b5032F6F7F1C513CAD") tests := []struct { - name string - cached bool - allowed bool - errorMessage string + name string + cached bool + allowed bool + ethCallErr error + err error + state encoding.PipelineExecutionState + reason encoding.UpkeepFailureReason + retryable bool + config []byte }{ { name: "success - allowed via cache", @@ -336,7 +284,6 @@ func TestEvmRegistry_AllowedToUseMercury(t *testing.T) { }, { name: "success - allowed via fetching privilege config", - cached: false, allowed: true, }, { @@ -346,49 +293,56 @@ func TestEvmRegistry_AllowedToUseMercury(t *testing.T) { }, { name: "success - not allowed via fetching privilege config", - cached: false, allowed: false, }, { - name: "failure - cannot unmarshal privilege config", - cached: false, - errorMessage: "failed to unmarshal privilege config for upkeep ID 71022726777042968814359024671382968091267501884371696415772139504780367423725: invalid character '\\x00' looking for beginning of value", + name: "failure - cannot unmarshal privilege config", + err: fmt.Errorf("failed to unmarshal privilege config: invalid character '\\x00' looking for beginning of value"), + state: encoding.MercuryUnmarshalError, + config: []byte{0, 1}, + }, + { + name: "failure - flaky RPC", + retryable: true, + err: fmt.Errorf("failed to get upkeep privilege config: flaky RPC"), + state: encoding.RpcFlakyFailure, + ethCallErr: fmt.Errorf("flaky RPC"), + }, + { + name: "failure - empty upkeep privilege config", + err: fmt.Errorf("upkeep privilege config is empty"), + reason: encoding.UpkeepFailureReasonMercuryAccessNotAllowed, + config: []byte{}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { r := setupEVMRegistry(t) - r.active[upkeepId.String()] = activeUpkeep{ - ID: upkeepId, - Admin: admin, - } - if tt.errorMessage != "" { - mockRegistry := mocks.NewRegistry(t) - mockRegistry.On("GetAdminPrivilegeConfig", mock.Anything, admin).Return([]byte{0, 1}, nil) - r.registry = mockRegistry + if tt.cached { + r.mercury.allowListCache.Set(upkeepId.String(), tt.allowed, cache.DefaultExpiration) } else { - if tt.cached { - r.mercury.allowListCache.Set(admin.Hex(), tt.allowed, cache.DefaultExpiration) + if tt.err != nil { + mockRegistry := mocks.NewRegistry(t) + mockRegistry.On("GetUpkeepPrivilegeConfig", mock.Anything, upkeepId).Return(tt.config, tt.ethCallErr) + r.registry = mockRegistry } else { mockRegistry := mocks.NewRegistry(t) - cfg := AdminOffchainConfig{MercuryEnabled: tt.allowed} + cfg := UpkeepPrivilegeConfig{MercuryEnabled: tt.allowed} b, err := json.Marshal(cfg) assert.Nil(t, err) - mockRegistry.On("GetAdminPrivilegeConfig", mock.Anything, admin).Return(b, nil) + mockRegistry.On("GetUpkeepPrivilegeConfig", mock.Anything, upkeepId).Return(b, nil) r.registry = mockRegistry } } - allowed, err := r.allowedToUseMercury(nil, upkeepId) - if tt.errorMessage != "" { - assert.NotNil(t, err) - assert.Equal(t, tt.errorMessage, err.Error()) - } else { - assert.Nil(t, err) - assert.Equal(t, tt.allowed, allowed) - } + state, reason, retryable, allowed, err := r.allowedToUseMercury(nil, upkeepId) + assert.Equal(t, tt.err, err) + assert.Equal(t, tt.allowed, allowed) + assert.Equal(t, tt.state, state) + assert.Equal(t, tt.reason, reason) + assert.Equal(t, tt.retryable, retryable) }) } } @@ -405,13 +359,15 @@ func TestEvmRegistry_DoMercuryRequest(t *testing.T) { expectedValues [][]byte expectedRetryable bool expectedError error + state encoding.PipelineExecutionState + reason encoding.UpkeepFailureReason }{ { name: "success", lookup: &FeedLookup{ - feedParamKey: FeedIdHex, + feedParamKey: feedIdHex, feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"}, - timeParamKey: BlockNumber, + timeParamKey: blockNumber, time: big.NewInt(25880526), extraData: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100}, upkeepId: upkeepId, @@ -425,9 +381,9 @@ func TestEvmRegistry_DoMercuryRequest(t *testing.T) { { name: "failure - retryable", lookup: &FeedLookup{ - feedParamKey: FeedIdHex, + feedParamKey: feedIdHex, feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"}, - timeParamKey: BlockNumber, + timeParamKey: blockNumber, time: big.NewInt(25880526), extraData: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100}, upkeepId: upkeepId, @@ -437,13 +393,14 @@ func TestEvmRegistry_DoMercuryRequest(t *testing.T) { expectedValues: [][]byte{nil}, expectedRetryable: true, expectedError: errors.New("All attempts fail:\n#1: 500\n#2: 500\n#3: 500"), + state: encoding.MercuryFlakyFailure, }, { name: "failure - not retryable", lookup: &FeedLookup{ - feedParamKey: FeedIdHex, + feedParamKey: feedIdHex, feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"}, - timeParamKey: BlockNumber, + timeParamKey: blockNumber, time: big.NewInt(25880526), extraData: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100}, upkeepId: upkeepId, @@ -452,7 +409,34 @@ func TestEvmRegistry_DoMercuryRequest(t *testing.T) { mockChainlinkBlobs: []string{"0x00066dfcd1ed2d95b18c948dbc5bd64c687afe93e4ca7d663ddec14c20090ad80000000000000000000000000000000000000000000000000000000000081401000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000280000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001204554482d5553442d415242495452554d2d544553544e455400000000000000000000000000000000000000000000000000000000000000000000000064891c98000000000000000000000000000000000000000000000000000000289ad8d367000000000000000000000000000000000000000000000000000000289acf0b38000000000000000000000000000000000000000000000000000000289b3da40000000000000000000000000000000000000000000000000000000000018ae7ce74d9fa252a8983976eab600dc7590c778d04813430841bc6e765c34cd81a168d00000000000000000000000000000000000000000000000000000000018ae7cb0000000000000000000000000000000000000000000000000000000064891c98000000000000000000000000000000000000000000000000000000000000000260412b94e525ca6cedc9f544fd86f77606d52fe731a5d069dbe836a8bfc0fb8c911963b0ae7a14971f3b4621bffb802ef0605392b9a6c89c7fab1df8633a5ade00000000000000000000000000000000000000000000000000000000000000024500c2f521f83fba5efc2bf3effaaedde43d0a4adff785c1213b712a3aed0d8157642a84324db0cf9695ebd27708d4608eb0337e0dd87b0e43f0fa70c700d911"}, expectedValues: [][]byte{nil}, expectedRetryable: false, - expectedError: errors.New("All attempts fail:\n#1: FeedLookup upkeep 88786950015966611018675766524283132478093844178961698330929478019253453382042 block 25880526 received status code 502 for feed 0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"), + expectedError: errors.New("All attempts fail:\n#1: at block 25880526 upkeep 88786950015966611018675766524283132478093844178961698330929478019253453382042 received status code 502 for feed 0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"), + state: encoding.InvalidMercuryRequest, + }, + { + name: "failure - no feeds", + lookup: &FeedLookup{ + feedParamKey: feedIdHex, + feeds: []string{}, + timeParamKey: blockNumber, + time: big.NewInt(25880526), + extraData: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100}, + upkeepId: upkeepId, + }, + expectedValues: [][]byte{}, + reason: encoding.UpkeepFailureReasonInvalidRevertDataInput, + }, + { + name: "failure - invalid revert data", + lookup: &FeedLookup{ + feedParamKey: feedIDs, + feeds: []string{}, + timeParamKey: blockNumber, + time: big.NewInt(25880526), + extraData: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100}, + upkeepId: upkeepId, + }, + expectedValues: [][]byte{}, + reason: encoding.UpkeepFailureReasonInvalidRevertDataInput, }, } @@ -462,7 +446,7 @@ func TestEvmRegistry_DoMercuryRequest(t *testing.T) { hc := mocks.NewHttpClient(t) for _, blob := range tt.mockChainlinkBlobs { - mr := MercuryResponse{ChainlinkBlob: blob} + mr := MercuryV02Response{ChainlinkBlob: blob} b, err := json.Marshal(mr) assert.Nil(t, err) @@ -471,16 +455,18 @@ func TestEvmRegistry_DoMercuryRequest(t *testing.T) { Body: io.NopCloser(bytes.NewReader(b)), } if tt.expectedError != nil && tt.expectedRetryable { - hc.On("Do", mock.Anything).Return(resp, nil).Times(TotalAttempt) + hc.On("Do", mock.Anything).Return(resp, nil).Times(totalAttempt) } else { hc.On("Do", mock.Anything).Return(resp, nil).Once() } } r.hc = hc - values, retryable, reqErr := r.doMercuryRequest(context.Background(), tt.lookup) + state, reason, values, retryable, reqErr := r.doMercuryRequest(context.Background(), tt.lookup, r.lggr) assert.Equal(t, tt.expectedValues, values) assert.Equal(t, tt.expectedRetryable, retryable) + assert.Equal(t, tt.state, state) + assert.Equal(t, tt.reason, reason) if tt.expectedError != nil { assert.Equal(t, tt.expectedError.Error(), reqErr.Error()) } @@ -494,7 +480,6 @@ func TestEvmRegistry_SingleFeedRequest(t *testing.T) { name string index int lookup *FeedLookup - mv MercuryVersion blob string statusCode int lastStatusCode int @@ -506,26 +491,24 @@ func TestEvmRegistry_SingleFeedRequest(t *testing.T) { name: "success - mercury responds in the first try", index: 0, lookup: &FeedLookup{ - feedParamKey: FeedIdHex, + feedParamKey: feedIdHex, feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"}, - timeParamKey: BlockNumber, + timeParamKey: blockNumber, time: big.NewInt(123456), upkeepId: upkeepId, }, - mv: MercuryV02, blob: "0xab2123dc00000012", }, { name: "success - retry for 404", index: 0, lookup: &FeedLookup{ - feedParamKey: FeedIdHex, + feedParamKey: feedIdHex, feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"}, - timeParamKey: BlockNumber, + timeParamKey: blockNumber, time: big.NewInt(123456), upkeepId: upkeepId, }, - mv: MercuryV02, blob: "0xab2123dcbabbad", retryNumber: 1, statusCode: http.StatusNotFound, @@ -535,13 +518,12 @@ func TestEvmRegistry_SingleFeedRequest(t *testing.T) { name: "success - retry for 500", index: 0, lookup: &FeedLookup{ - feedParamKey: FeedIdHex, + feedParamKey: feedIdHex, feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"}, - timeParamKey: BlockNumber, + timeParamKey: blockNumber, time: big.NewInt(123456), upkeepId: upkeepId, }, - mv: MercuryV02, blob: "0xab2123dcbbabad", retryNumber: 2, statusCode: http.StatusInternalServerError, @@ -551,15 +533,14 @@ func TestEvmRegistry_SingleFeedRequest(t *testing.T) { name: "failure - returns retryable", index: 0, lookup: &FeedLookup{ - feedParamKey: FeedIdHex, + feedParamKey: feedIdHex, feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"}, - timeParamKey: BlockNumber, + timeParamKey: blockNumber, time: big.NewInt(123456), upkeepId: upkeepId, }, - mv: MercuryV02, blob: "0xab2123dc", - retryNumber: TotalAttempt, + retryNumber: totalAttempt, statusCode: http.StatusNotFound, retryable: true, errorMessage: "All attempts fail:\n#1: 404\n#2: 404\n#3: 404", @@ -568,33 +549,31 @@ func TestEvmRegistry_SingleFeedRequest(t *testing.T) { name: "failure - returns retryable and then non-retryable", index: 0, lookup: &FeedLookup{ - feedParamKey: FeedIdHex, + feedParamKey: feedIdHex, feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"}, - timeParamKey: BlockNumber, + timeParamKey: blockNumber, time: big.NewInt(123456), upkeepId: upkeepId, }, - mv: MercuryV02, blob: "0xab2123dc", retryNumber: 1, statusCode: http.StatusNotFound, lastStatusCode: http.StatusBadGateway, - errorMessage: "All attempts fail:\n#1: 404\n#2: FeedLookup upkeep 123456789 block 123456 received status code 502 for feed 0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", + errorMessage: "All attempts fail:\n#1: 404\n#2: at block 123456 upkeep 123456789 received status code 502 for feed 0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", }, { name: "failure - returns not retryable", index: 0, lookup: &FeedLookup{ - feedParamKey: FeedIdHex, + feedParamKey: feedIdHex, feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"}, - timeParamKey: BlockNumber, + timeParamKey: blockNumber, time: big.NewInt(123456), upkeepId: upkeepId, }, - mv: MercuryV02, blob: "0xab2123dc", statusCode: http.StatusBadGateway, - errorMessage: "All attempts fail:\n#1: FeedLookup upkeep 123456789 block 123456 received status code 502 for feed 0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", + errorMessage: "All attempts fail:\n#1: at block 123456 upkeep 123456789 received status code 502 for feed 0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", }, } @@ -603,7 +582,7 @@ func TestEvmRegistry_SingleFeedRequest(t *testing.T) { r := setupEVMRegistry(t) hc := mocks.NewHttpClient(t) - mr := MercuryResponse{ChainlinkBlob: tt.blob} + mr := MercuryV02Response{ChainlinkBlob: tt.blob} b, err := json.Marshal(mr) assert.Nil(t, err) @@ -621,7 +600,7 @@ func TestEvmRegistry_SingleFeedRequest(t *testing.T) { } hc.On("Do", mock.Anything).Return(resp, nil).Once() } - } else if tt.retryNumber > 0 && tt.retryNumber < TotalAttempt { + } else if tt.retryNumber > 0 && tt.retryNumber < totalAttempt { retryResp := &http.Response{ StatusCode: tt.statusCode, Body: io.NopCloser(bytes.NewReader(b)), @@ -642,20 +621,20 @@ func TestEvmRegistry_SingleFeedRequest(t *testing.T) { } r.hc = hc - ch := make(chan MercuryBytes, 1) - r.singleFeedRequest(context.Background(), ch, tt.index, tt.lookup, tt.mv) + ch := make(chan MercuryData, 1) + r.singleFeedRequest(context.Background(), ch, tt.index, tt.lookup, r.lggr) m := <-ch assert.Equal(t, tt.index, m.Index) assert.Equal(t, tt.retryable, m.Retryable) - if tt.retryNumber >= TotalAttempt || tt.errorMessage != "" { + if tt.retryNumber >= totalAttempt || tt.errorMessage != "" { assert.Equal(t, tt.errorMessage, m.Error.Error()) - assert.Nil(t, m.Bytes) + assert.Equal(t, [][]byte{}, m.Bytes) } else { blobBytes, err := hexutil.Decode(tt.blob) assert.Nil(t, err) assert.Nil(t, m.Error) - assert.Equal(t, blobBytes, m.Bytes) + assert.Equal(t, [][]byte{blobBytes}, m.Bytes) } }) } @@ -666,63 +645,108 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) { tests := []struct { name string lookup *FeedLookup - blob string statusCode int lastStatusCode int retryNumber int retryable bool errorMessage string + response MercuryV03Response }{ { name: "success - mercury responds in the first try", lookup: &FeedLookup{ - feedParamKey: FeedId, + feedParamKey: feedIDs, feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"}, - timeParamKey: Timestamp, + timeParamKey: timestamp, time: big.NewInt(123456), upkeepId: upkeepId, }, - blob: "0xab2123dc00000012", + response: MercuryV03Response{ + Reports: []MercuryV03Report{ + { + FeedID: "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", + ValidFromTimestamp: "123456", + ObservationsTimestamp: "123456", + FullReport: "0xab2123dc00000012", + }, + { + FeedID: "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000", + ValidFromTimestamp: "123458", + ObservationsTimestamp: "123458", + FullReport: "0xab2123dc00000016", + }, + }, + }, + statusCode: http.StatusOK, }, { name: "success - retry for 404", lookup: &FeedLookup{ - feedParamKey: FeedId, + feedParamKey: feedIDs, feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"}, - timeParamKey: Timestamp, + timeParamKey: timestamp, time: big.NewInt(123456), upkeepId: upkeepId, }, - blob: "0xab2123dcbabbad", retryNumber: 1, statusCode: http.StatusNotFound, lastStatusCode: http.StatusOK, + response: MercuryV03Response{ + Reports: []MercuryV03Report{ + { + FeedID: "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", + ValidFromTimestamp: "123456", + ObservationsTimestamp: "123456", + FullReport: "0xab2123dc00000012", + }, + { + FeedID: "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000", + ValidFromTimestamp: "123458", + ObservationsTimestamp: "123458", + FullReport: "0xab2123dc00000012", + }, + }, + }, }, { name: "success - retry for 500", lookup: &FeedLookup{ - feedParamKey: FeedId, + feedParamKey: feedIDs, feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"}, - timeParamKey: Timestamp, + timeParamKey: timestamp, time: big.NewInt(123456), upkeepId: upkeepId, }, - blob: "0xab2123dcbbabad", retryNumber: 2, statusCode: http.StatusInternalServerError, lastStatusCode: http.StatusOK, + response: MercuryV03Response{ + Reports: []MercuryV03Report{ + { + FeedID: "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", + ValidFromTimestamp: "123456", + ObservationsTimestamp: "123456", + FullReport: "0xab2123dc00000012", + }, + { + FeedID: "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000", + ValidFromTimestamp: "123458", + ObservationsTimestamp: "123458", + FullReport: "0xab2123dc00000019", + }, + }, + }, }, { name: "failure - returns retryable", lookup: &FeedLookup{ - feedParamKey: FeedId, + feedParamKey: feedIDs, feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"}, - timeParamKey: Timestamp, + timeParamKey: timestamp, time: big.NewInt(123456), upkeepId: upkeepId, }, - blob: "0xab2123dc", - retryNumber: TotalAttempt, + retryNumber: totalAttempt, statusCode: http.StatusNotFound, retryable: true, errorMessage: "All attempts fail:\n#1: 404\n#2: 404\n#3: 404", @@ -730,30 +754,50 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) { { name: "failure - returns retryable and then non-retryable", lookup: &FeedLookup{ - feedParamKey: FeedId, + feedParamKey: feedIDs, feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"}, - timeParamKey: Timestamp, + timeParamKey: timestamp, time: big.NewInt(123456), upkeepId: upkeepId, }, - blob: "0xab2123dc", retryNumber: 1, statusCode: http.StatusNotFound, lastStatusCode: http.StatusBadGateway, - errorMessage: "All attempts fail:\n#1: 404\n#2: FeedLookup upkeep 123456789 block 123456 received status code 502 for multi feed", + errorMessage: "All attempts fail:\n#1: 404\n#2: at block 123456 upkeep 123456789 received status code 502 from mercury v0.3", }, { name: "failure - returns not retryable", lookup: &FeedLookup{ - feedParamKey: FeedId, + feedParamKey: feedIDs, feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"}, - timeParamKey: Timestamp, + timeParamKey: timestamp, time: big.NewInt(123456), upkeepId: upkeepId, }, - blob: "0xab2123dc", statusCode: http.StatusBadGateway, - errorMessage: "All attempts fail:\n#1: FeedLookup upkeep 123456789 block 123456 received status code 502 for multi feed", + errorMessage: "All attempts fail:\n#1: at block 123456 upkeep 123456789 received status code 502 from mercury v0.3", + }, + { + name: "failure - reports length does not match feeds length", + lookup: &FeedLookup{ + feedParamKey: feedIDs, + feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"}, + timeParamKey: timestamp, + time: big.NewInt(123456), + upkeepId: upkeepId, + }, + response: MercuryV03Response{ + Reports: []MercuryV03Report{ + { + FeedID: "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", + ValidFromTimestamp: "123456", + ObservationsTimestamp: "123456", + FullReport: "0xab2123dc00000012", + }, + }, + }, + statusCode: http.StatusOK, + errorMessage: "All attempts fail:\n#1: at block 123456 upkeep 123456789 requested 2 feeds but received 1 reports from mercury v0.3", }, } @@ -761,26 +805,16 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) { t.Run(tt.name, func(t *testing.T) { r := setupEVMRegistry(t) hc := mocks.NewHttpClient(t) - - mr := MercuryResponse{ChainlinkBlob: tt.blob} - b, err := json.Marshal(mr) + b, err := json.Marshal(tt.response) assert.Nil(t, err) if tt.retryNumber == 0 { - if tt.errorMessage != "" { - resp := &http.Response{ - StatusCode: tt.statusCode, - Body: io.NopCloser(bytes.NewReader(b)), - } - hc.On("Do", mock.Anything).Return(resp, nil).Once() - } else { - resp := &http.Response{ - StatusCode: http.StatusOK, - Body: io.NopCloser(bytes.NewReader(b)), - } - hc.On("Do", mock.Anything).Return(resp, nil).Once() + resp := &http.Response{ + StatusCode: tt.statusCode, + Body: io.NopCloser(bytes.NewReader(b)), } - } else if tt.retryNumber > 0 && tt.retryNumber < TotalAttempt { + hc.On("Do", mock.Anything).Return(resp, nil).Once() + } else if tt.retryNumber < totalAttempt { retryResp := &http.Response{ StatusCode: tt.statusCode, Body: io.NopCloser(bytes.NewReader(b)), @@ -801,20 +835,25 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) { } r.hc = hc - ch := make(chan MercuryBytes, 1) - r.multiFeedsRequest(context.Background(), ch, tt.lookup) + ch := make(chan MercuryData, 1) + r.multiFeedsRequest(context.Background(), ch, tt.lookup, r.lggr) m := <-ch assert.Equal(t, 0, m.Index) assert.Equal(t, tt.retryable, m.Retryable) - if tt.retryNumber >= TotalAttempt || tt.errorMessage != "" { + if tt.retryNumber >= totalAttempt || tt.errorMessage != "" { assert.Equal(t, tt.errorMessage, m.Error.Error()) - assert.Nil(t, m.Bytes) + assert.Equal(t, [][]byte{}, m.Bytes) } else { - blobBytes, err := hexutil.Decode(tt.blob) - assert.Nil(t, err) assert.Nil(t, m.Error) - assert.Equal(t, blobBytes, m.Bytes) + var reports [][]byte + var report []byte + for _, rsp := range tt.response.Reports { + report, err = hexutil.Decode(rsp.FullReport) + assert.Nil(t, err) + reports = append(reports, report) + } + assert.Equal(t, reports, m.Bytes) } }) } @@ -822,7 +861,7 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) { func TestEvmRegistry_CheckCallback(t *testing.T) { upkeepId := big.NewInt(123456789) - blockNumber := uint64(999) + bn := uint64(999) bs := []byte{183, 114, 215, 10, 0, 0, 0, 0, 0, 0} values := [][]byte{bs} tests := []struct { @@ -831,24 +870,26 @@ func TestEvmRegistry_CheckCallback(t *testing.T) { values [][]byte statusCode int - callbackMsg ethereum.CallMsg callbackResp []byte callbackErr error upkeepNeeded bool performData []byte wantErr assert.ErrorAssertionFunc + + state encoding.PipelineExecutionState + retryable bool }{ { name: "success - empty extra data", lookup: &FeedLookup{ - feedParamKey: FeedIdHex, + feedParamKey: feedIdHex, feeds: []string{"ETD-USD", "BTC-ETH"}, - timeParamKey: BlockNumber, + timeParamKey: blockNumber, time: big.NewInt(100), extraData: []byte{48, 120, 48, 48}, upkeepId: upkeepId, - block: blockNumber, + block: bn, }, values: values, statusCode: http.StatusOK, @@ -860,14 +901,14 @@ func TestEvmRegistry_CheckCallback(t *testing.T) { { name: "success - with extra data", lookup: &FeedLookup{ - feedParamKey: FeedIdHex, + feedParamKey: feedIdHex, feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"}, - timeParamKey: BlockNumber, + timeParamKey: blockNumber, time: big.NewInt(18952430), // this is the address of precompile contract ArbSys(0x0000000000000000000000000000000000000064) extraData: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100}, upkeepId: upkeepId, - block: blockNumber, + block: bn, }, values: values, statusCode: http.StatusOK, @@ -879,19 +920,21 @@ func TestEvmRegistry_CheckCallback(t *testing.T) { { name: "failure - bad response", lookup: &FeedLookup{ - feedParamKey: FeedIdHex, + feedParamKey: feedIdHex, feeds: []string{"ETD-USD", "BTC-ETH"}, - timeParamKey: BlockNumber, + timeParamKey: blockNumber, time: big.NewInt(100), extraData: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 48, 120, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, upkeepId: upkeepId, - block: blockNumber, + block: bn, }, values: values, statusCode: http.StatusOK, callbackResp: []byte{}, callbackErr: errors.New("bad response"), wantErr: assert.Error, + state: encoding.RpcFlakyFailure, + retryable: true, }, } @@ -912,8 +955,10 @@ func TestEvmRegistry_CheckCallback(t *testing.T) { }).Once() r.client = client - _, err = r.checkCallback(context.Background(), tt.values, tt.lookup) + state, retryable, _, err := r.checkCallback(context.Background(), tt.values, tt.lookup) tt.wantErr(t, err, fmt.Sprintf("Error asserion failed: %v", tt.name)) + assert.Equal(t, tt.state, state) + assert.Equal(t, tt.retryable, retryable) }) } } diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/keyring.go b/core/services/ocr2/plugins/ocr2keeper/evm21/keyring.go new file mode 100644 index 00000000000..df4e3a86502 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/keyring.go @@ -0,0 +1,49 @@ +package evm + +import ( + "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/ocr2keepers/pkg/v3/plugin" +) + +var _ ocr3types.OnchainKeyring[plugin.AutomationReportInfo] = &onchainKeyringV3Wrapper{} + +type onchainKeyringV3Wrapper struct { + core types.OnchainKeyring +} + +func NewOnchainKeyringV3Wrapper(keyring types.OnchainKeyring) *onchainKeyringV3Wrapper { + return &onchainKeyringV3Wrapper{ + core: keyring, + } +} + +func (w *onchainKeyringV3Wrapper) PublicKey() types.OnchainPublicKey { + return w.core.PublicKey() +} + +func (w *onchainKeyringV3Wrapper) MaxSignatureLength() int { + return w.core.MaxSignatureLength() +} + +func (w *onchainKeyringV3Wrapper) Sign(digest types.ConfigDigest, seqNr uint64, r ocr3types.ReportWithInfo[plugin.AutomationReportInfo]) (signature []byte, err error) { + rCtx := types.ReportContext{ + ReportTimestamp: types.ReportTimestamp{ + ConfigDigest: digest, + Epoch: uint32(seqNr), + }, + } + + return w.core.Sign(rCtx, r.Report) +} + +func (w *onchainKeyringV3Wrapper) Verify(key types.OnchainPublicKey, digest types.ConfigDigest, seqNr uint64, r ocr3types.ReportWithInfo[plugin.AutomationReportInfo], signature []byte) bool { + rCtx := types.ReportContext{ + ReportTimestamp: types.ReportTimestamp{ + ConfigDigest: digest, + Epoch: uint32(seqNr), + }, + } + + return w.core.Verify(key, rCtx, r.Report, signature) +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/keyring_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/keyring_test.go new file mode 100644 index 00000000000..14c42a810c1 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/keyring_test.go @@ -0,0 +1,108 @@ +package evm + +import ( + "testing" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/ocr2keepers/pkg/v3/plugin" + "github.com/stretchr/testify/assert" +) + +func TestNewOnchainKeyringV3Wrapper(t *testing.T) { + t.Run("the on chain keyring wrapper gets the public key and max signature length from the wrapped keyring", func(t *testing.T) { + onchainKeyring := &mockOnchainKeyring{ + MaxSignatureLengthFn: func() int { + return 123 + }, + PublicKeyFn: func() types.OnchainPublicKey { + return types.OnchainPublicKey([]byte("abcdef")) + }, + } + keyring := NewOnchainKeyringV3Wrapper(onchainKeyring) + assert.Equal(t, 123, keyring.MaxSignatureLength()) + assert.Equal(t, types.OnchainPublicKey([]byte("abcdef")), keyring.PublicKey()) + }) + + t.Run("a report context is created and the wrapped keyring signs the report", func(t *testing.T) { + onchainKeyring := &mockOnchainKeyring{ + SignFn: func(context types.ReportContext, report types.Report) (signature []byte, err error) { + assert.Equal(t, types.ReportContext{ + ReportTimestamp: types.ReportTimestamp{ + ConfigDigest: types.ConfigDigest([32]byte{1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4}), + Epoch: 101, + Round: 0, + }, + ExtraHash: [32]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + }, context) + assert.Equal(t, types.Report([]byte("a report to sign")), report) + return []byte("signature"), err + }, + } + keyring := NewOnchainKeyringV3Wrapper(onchainKeyring) + signed, err := keyring.Sign( + types.ConfigDigest([32]byte{1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4}), + 101, + ocr3types.ReportWithInfo[plugin.AutomationReportInfo]{ + Report: []byte("a report to sign"), + Info: plugin.AutomationReportInfo{}, + }, + ) + assert.NoError(t, err) + assert.Equal(t, []byte("signature"), signed) + }) + + t.Run("a report context is created and the wrapped keyring verifies the report", func(t *testing.T) { + onchainKeyring := &mockOnchainKeyring{ + VerifyFn: func(pk types.OnchainPublicKey, rc types.ReportContext, r types.Report, signature []byte) bool { + assert.Equal(t, types.OnchainPublicKey([]byte("key")), pk) + assert.Equal(t, types.ReportContext{ + ReportTimestamp: types.ReportTimestamp{ + ConfigDigest: types.ConfigDigest([32]byte{1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4}), + Epoch: 999, + Round: 0, + }, + ExtraHash: [32]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + }, rc) + assert.Equal(t, types.Report([]byte("a report to sign")), r) + assert.Equal(t, []byte("signature"), signature) + return true + }, + } + keyring := NewOnchainKeyringV3Wrapper(onchainKeyring) + valid := keyring.Verify( + types.OnchainPublicKey([]byte("key")), + types.ConfigDigest([32]byte{1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4}), + 999, + ocr3types.ReportWithInfo[plugin.AutomationReportInfo]{ + Report: []byte("a report to sign"), + Info: plugin.AutomationReportInfo{}, + }, + []byte("signature"), + ) + assert.True(t, valid) + }) +} + +type mockOnchainKeyring struct { + PublicKeyFn func() types.OnchainPublicKey + SignFn func(types.ReportContext, types.Report) (signature []byte, err error) + VerifyFn func(_ types.OnchainPublicKey, _ types.ReportContext, _ types.Report, signature []byte) bool + MaxSignatureLengthFn func() int +} + +func (k *mockOnchainKeyring) PublicKey() types.OnchainPublicKey { + return k.PublicKeyFn() +} + +func (k *mockOnchainKeyring) Sign(c types.ReportContext, r types.Report) (signature []byte, err error) { + return k.SignFn(c, r) +} + +func (k *mockOnchainKeyring) Verify(pk types.OnchainPublicKey, c types.ReportContext, r types.Report, signature []byte) bool { + return k.VerifyFn(pk, c, r, signature) +} + +func (k *mockOnchainKeyring) MaxSignatureLength() int { + return k.MaxSignatureLengthFn() +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time.go new file mode 100644 index 00000000000..1d8500bcc61 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time.go @@ -0,0 +1,72 @@ +package logprovider + +import ( + "context" + "fmt" + "sort" + "time" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" +) + +var ( + defaultSampleSize = int64(10) + defaultBlockTime = time.Second * 1 +) + +type blockTimeResolver struct { + poller logpoller.LogPoller +} + +func newBlockTimeResolver(poller logpoller.LogPoller) *blockTimeResolver { + return &blockTimeResolver{ + poller: poller, + } +} + +func (r *blockTimeResolver) BlockTime(ctx context.Context, blockSampleSize int64) (time.Duration, error) { + if blockSampleSize < 2 { // min 2 blocks range + blockSampleSize = defaultSampleSize + } + + latest, err := r.poller.LatestBlock(pg.WithParentCtx(ctx)) + if err != nil { + return 0, fmt.Errorf("failed to get latest block from poller: %w", err) + } + if latest < blockSampleSize { + return defaultBlockTime, nil + } + blockTimes, err := r.getSampleTimestamps(ctx, blockSampleSize, latest) + if err != nil { + return 0, err + } + + var sumDiff time.Duration + for i := range blockTimes { + if i != int(blockSampleSize-1) { + sumDiff += blockTimes[i].Sub(blockTimes[i+1]) + } + } + + return sumDiff / time.Duration(blockSampleSize-1), nil +} + +func (r *blockTimeResolver) getSampleTimestamps(ctx context.Context, blockSampleSize, latest int64) ([]time.Time, error) { + blockSample := make([]uint64, blockSampleSize) + for i := range blockSample { + blockSample[i] = uint64(latest - blockSampleSize + int64(i)) + } + blocks, err := r.poller.GetBlocksRange(ctx, blockSample) + if err != nil { + return nil, fmt.Errorf("failed to get block range from poller: %w", err) + } + sort.Slice(blocks, func(i, j int) bool { + return blocks[i].BlockNumber > blocks[j].BlockNumber + }) + blockTimes := make([]time.Time, blockSampleSize) + for i, b := range blocks { + blockTimes[i] = b.BlockTimestamp + } + return blockTimes, nil +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time_test.go new file mode 100644 index 00000000000..55437ff6721 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time_test.go @@ -0,0 +1,85 @@ +package logprovider + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" +) + +func TestBlockTimeResolver_BlockTime(t *testing.T) { + now := time.Now() + + tests := []struct { + name string + blockSampleSize int64 + latestBlock int64 + latestBlockErr error + blocksRange []logpoller.LogPollerBlock + blocksRangeErr error + blockTime time.Duration + blockTimeErr error + }{ + { + "latest block err", + 10, + 0, + fmt.Errorf("test err"), + nil, + nil, + 0, + fmt.Errorf("test err"), + }, + { + "block range err", + 10, + 20, + nil, + nil, + fmt.Errorf("test err"), + 0, + fmt.Errorf("test err"), + }, + { + "2 sec block time", + 4, + 20, + nil, + []logpoller.LogPollerBlock{ + {BlockTimestamp: now.Add(-time.Second * (2 * 4)), BlockNumber: 1}, + {BlockTimestamp: now.Add(-time.Second * (2 * 3)), BlockNumber: 2}, + {BlockTimestamp: now.Add(-time.Second * (2 * 2)), BlockNumber: 3}, + {BlockTimestamp: now.Add(-time.Second * 2), BlockNumber: 4}, + }, + nil, + 2 * time.Second, + nil, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + lp := new(lpmocks.LogPoller) + resolver := newBlockTimeResolver(lp) + + lp.On("LatestBlock", mock.Anything).Return(tc.latestBlock, tc.latestBlockErr) + lp.On("GetBlocksRange", mock.Anything, mock.Anything).Return(tc.blocksRange, tc.blocksRangeErr) + + blockTime, err := resolver.BlockTime(ctx, tc.blockSampleSize) + if tc.blockTimeErr != nil { + require.Error(t, err) + return + } + require.Equal(t, tc.blockTime, blockTime) + }) + } +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer.go index 8a2e760bbf4..1977795f6e8 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer.go @@ -10,10 +10,17 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" ) +var ( + // AllowedLogsPerBlock is the maximum number of logs allowed per upkeep in a block. + AllowedLogsPerBlock = 128 + // BufferMaxBlockSize is the maximum number of blocks in the buffer. + BufferMaxBlockSize = 1024 +) + // fetchedLog holds the log and the ID of the upkeep type fetchedLog struct { - id *big.Int - log logpoller.Log + upkeepID *big.Int + log logpoller.Log } // fetchedBlock holds the logs fetched for a block @@ -26,23 +33,13 @@ type fetchedBlock struct { visited []fetchedLog } -// Reset resets the block to the given block number, if the block is newer than the current block. -func (b fetchedBlock) Reset(block int64) (fetchedBlock, int64) { - if b.blockNumber < block { - return fetchedBlock{ - blockNumber: block, - }, b.blockNumber - } - return b, b.blockNumber -} - // Has returns true if the block has the log, // and the number of logs for that upkeep in the block. func (b fetchedBlock) Has(id *big.Int, log logpoller.Log) (bool, int) { allLogs := append(b.logs, b.visited...) upkeepLogs := 0 for _, l := range allLogs { - if l.id.Cmp(id) != 0 { + if l.upkeepID.Cmp(id) != 0 { continue } upkeepLogs++ @@ -62,7 +59,7 @@ type logEventBuffer struct { // size is the number of blocks supported by the buffer size int32 - maxBlockLogs, maxUpkeepLogsPerBlock int32 + maxBlockLogs, maxUpkeepLogsPerBlock int // blocks is the circular buffer of fetched blocks blocks []fetchedBlock // latestBlock is the latest block number seen @@ -74,8 +71,8 @@ func newLogEventBuffer(lggr logger.Logger, size, maxBlockLogs, maxUpkeepLogsPerB lggr: lggr.Named("KeepersRegistry.LogEventBuffer"), size: int32(size), blocks: make([]fetchedBlock, size), - maxBlockLogs: int32(maxBlockLogs), - maxUpkeepLogsPerBlock: int32(maxUpkeepLogsPerBlock), + maxBlockLogs: maxBlockLogs, + maxUpkeepLogsPerBlock: maxUpkeepLogsPerBlock, } } @@ -105,32 +102,33 @@ func (b *logEventBuffer) enqueue(id *big.Int, logs ...logpoller.Log) int { continue } i := b.blockNumberIndex(log.BlockNumber) - block, prevBlock := b.blocks[i].Reset(log.BlockNumber) - if prevBlock > 0 { - if prevBlock > log.BlockNumber { - lggr.Debugw("Skipping old log", "currentBlock", block.blockNumber, "newBlock", log.BlockNumber) - continue - } else if prevBlock < log.BlockNumber { - lggr.Debugw("Overriding block", "prevBlock", prevBlock, "newBlock", log.BlockNumber) - } + currentBlock := b.blocks[i] + if currentBlock.blockNumber < log.BlockNumber { + lggr.Debugw("Got log on a new block", "prevBlock", currentBlock.blockNumber, "newBlock", log.BlockNumber) + currentBlock.blockNumber = log.BlockNumber + currentBlock.logs = nil + currentBlock.visited = nil + } else if currentBlock.blockNumber > log.BlockNumber { + // not expected to happen + lggr.Debugw("Skipping log from old block", "currentBlock", currentBlock.blockNumber, "newBlock", log.BlockNumber) + continue } - if len(block.logs)+1 > maxBlockLogs { + if len(currentBlock.logs)+1 > maxBlockLogs { lggr.Debugw("Reached max logs number per block, dropping log", "blockNumber", log.BlockNumber, "blockHash", log.BlockHash, "txHash", log.TxHash, "logIndex", log.LogIndex) continue } - if has, upkeepLogs := block.Has(id, log); has { - // lggr.Debugw("Skipping existing log", "blockNumber", log.BlockNumber, - // "blockHash", log.BlockHash, "txHash", log.TxHash, "logIndex", log.LogIndex) + if has, upkeepLogs := currentBlock.Has(id, log); has { + // Skipping existing log continue } else if upkeepLogs+1 > maxUpkeepLogs { lggr.Debugw("Reached max logs number per upkeep, dropping log", "blockNumber", log.BlockNumber, "blockHash", log.BlockHash, "txHash", log.TxHash, "logIndex", log.LogIndex) continue } - // lggr.Debugw("Adding log", "i", i, "blockBlock", block.blockNumber, "logBlock", log.BlockNumber, "id", id) - block.logs = append(block.logs, fetchedLog{id: id, log: log}) - b.blocks[i] = block + // lggr.Debugw("Adding log", "i", i, "blockBlock", currentBlock.blockNumber, "logBlock", log.BlockNumber, "id", id) + currentBlock.logs = append(currentBlock.logs, fetchedLog{upkeepID: id, log: log}) + b.blocks[i] = currentBlock added++ if log.BlockNumber > latestBlock { latestBlock = log.BlockNumber @@ -185,42 +183,45 @@ func (b *logEventBuffer) peekRange(start, end int64) []fetchedLog { return results } -// peek returns the logs in range [latestBlock-blocks, latestBlock] -func (b *logEventBuffer) dequeue(blocks int) []fetchedLog { - latestBlock := b.latestBlockSeen() - if latestBlock == 0 { - return nil - } - if blocks > int(latestBlock) { - blocks = int(latestBlock) - 1 - } - return b.dequeueRange(latestBlock-int64(blocks), latestBlock) -} - // dequeueRange returns the logs between start and end inclusive. -func (b *logEventBuffer) dequeueRange(start, end int64) []fetchedLog { +func (b *logEventBuffer) dequeueRange(start, end int64, upkeepLimit int) []fetchedLog { b.lock.Lock() defer b.lock.Unlock() blocksInRange := b.getBlocksInRange(int(start), int(end)) + logsCount := map[string]int{} var results []fetchedLog - for i, block := range blocksInRange { + for _, block := range blocksInRange { // double checking that we don't have any gaps in the range if block.blockNumber < start || block.blockNumber > end { continue } - results = append(results, block.logs...) - block.visited = append(block.visited, block.logs...) - block.logs = nil - b.blocks[i] = block + var remainingLogs, blockResults []fetchedLog + for _, log := range block.logs { + if logsCount[log.upkeepID.String()] >= upkeepLimit { + remainingLogs = append(remainingLogs, log) + continue + } + logsCount[log.upkeepID.String()]++ + blockResults = append(blockResults, log) + } + if len(blockResults) == 0 { + continue + } + block.visited = append(block.visited, blockResults...) + results = append(results, blockResults...) + block.logs = remainingLogs + b.blocks[b.blockNumberIndex(block.blockNumber)] = block } sort.SliceStable(results, func(i, j int) bool { return results[i].log.BlockNumber < results[j].log.BlockNumber }) - b.lggr.Debugw("Dequeued logs", "results", len(results), "start", start, "end", end) + if len(results) > 0 { + b.lggr.Debugw("Dequeued logs", "results", len(results), "start", start, "end", end) + } return results } @@ -229,47 +230,42 @@ func (b *logEventBuffer) dequeueRange(start, end int64) []fetchedLog { // NOTE: this function should be called with the lock held func (b *logEventBuffer) getBlocksInRange(start, end int) []fetchedBlock { var blocksInRange []fetchedBlock - start, end = b.normalRange(start, end) + start, end = b.blockRangeToIndices(start, end) if start == -1 || end == -1 { // invalid range return blocksInRange } - if start < end { - return b.blocks[start:end] + if start <= end { + // Normal range, need to return indices from start to end(inclusive) + return b.blocks[start : end+1] } // in case we get circular range such as [0, 1, end, ... , start, ..., size-1] - // we need to return the blocks in two ranges: [start, size-1] and [0, end] + // we need to return the blocks in two ranges: [0, end](inclusive) and [start, size-1] blocksInRange = append(blocksInRange, b.blocks[start:]...) - blocksInRange = append(blocksInRange, b.blocks[:end]...) + blocksInRange = append(blocksInRange, b.blocks[:end+1]...) return blocksInRange } -// normalRange returns the normalized range of start and end, -// aligned with buffer sizes. -func (b *logEventBuffer) normalRange(start, end int) (int, int) { - if end < start || end == 0 { +// blockRangeToIndices returns the normalized range of start to end block range, +// to indices aligned with buffer size. Note ranges inclusive of start, end indices. +func (b *logEventBuffer) blockRangeToIndices(start, end int) (int, int) { + latest := b.latestBlockSeen() + if end > int(latest) { + // Limit end of range to latest block seen + end = int(latest) + } + if end < start || start == 0 || end == 0 { // invalid range return -1, -1 } size := b.bufferSize() - if start == 0 { - // we reduce start by 1 to make it easier to calculate the index, - // but we need to ensure we don't go below 0. - start++ - } - if start == end { - // ensure we have at least one block in range - end++ - } - if end-start > size { - // ensure we don't have more than the buffer size + if end-start >= size { + // If range requires more than buffer size blocks, only to return + // last size blocks as that's the max the buffer stores. start = (end - size) + 1 } - start = (start - 1) % size - end = end % size - - return start, end + return b.blockNumberIndex(int64(start)), b.blockNumberIndex(int64(end)) } // blockNumberIndex returns the index of the block in the buffer diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer_test.go index f3abd04fd17..de68dd31e22 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer_test.go @@ -14,11 +14,10 @@ import ( func TestLogEventBuffer_GetBlocksInRange(t *testing.T) { size := 3 + maxSeenBlock := int64(4) buf := newLogEventBuffer(logger.TestLogger(t), size, 10, 10) buf.enqueue(big.NewInt(1), - logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 0}, - logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 1}, logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x2"), LogIndex: 0}, logpoller.Log{BlockNumber: 3, TxHash: common.HexToHash("0x3"), LogIndex: 0}, ) @@ -26,6 +25,8 @@ func TestLogEventBuffer_GetBlocksInRange(t *testing.T) { buf.enqueue(big.NewInt(2), logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x2"), LogIndex: 2}, logpoller.Log{BlockNumber: 3, TxHash: common.HexToHash("0x3"), LogIndex: 2}, + logpoller.Log{BlockNumber: 4, TxHash: common.HexToHash("0x1"), LogIndex: 0}, + logpoller.Log{BlockNumber: 4, TxHash: common.HexToHash("0x1"), LogIndex: 1}, ) tests := []struct { @@ -36,27 +37,26 @@ func TestLogEventBuffer_GetBlocksInRange(t *testing.T) { }{ { name: "all", - from: 1, - to: 3, + from: 2, + to: 4, want: 3, }, { name: "partial", - from: 1, - to: 2, + from: 2, + to: 3, want: 2, }, { name: "circular", - from: 2, + from: 3, to: 4, - want: 3, + want: 2, }, { name: "zero start", from: 0, to: 2, - want: 2, }, { name: "invalid zero end", @@ -68,6 +68,17 @@ func TestLogEventBuffer_GetBlocksInRange(t *testing.T) { from: 4, to: 2, }, + { + name: "outside max last seen", + from: 5, + to: 10, + }, + { + name: "limited by max last seen", + from: 2, + to: 5, + want: 3, + }, } for _, tc := range tests { @@ -76,15 +87,10 @@ func TestLogEventBuffer_GetBlocksInRange(t *testing.T) { require.Equal(t, tc.want, len(blocks)) if tc.want > 0 { from := tc.from - if from == 0 { - from++ - } require.Equal(t, from, blocks[0].blockNumber) to := tc.to - if to == 0 { - to++ - } else if to > int64(size) { - to = to % int64(size) + if to >= maxSeenBlock { + to = maxSeenBlock } require.Equal(t, to, blocks[len(blocks)-1].blockNumber) } @@ -175,7 +181,7 @@ func TestLogEventBuffer_EnqueueDequeue(t *testing.T) { }) t.Run("enqueue logs overflow", func(t *testing.T) { - buf := newLogEventBuffer(logger.TestLogger(t), 3, 2, 10) + buf := newLogEventBuffer(logger.TestLogger(t), 2, 2, 10) require.Equal(t, 2, buf.enqueue(big.NewInt(1), logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 0}, @@ -230,14 +236,14 @@ func TestLogEventBuffer_EnqueueDequeue(t *testing.T) { results := buf.peekRange(int64(1), int64(2)) require.Equal(t, 2, len(results)) verifyBlockNumbers(t, results, 1, 2) - removed := buf.dequeueRange(int64(1), int64(2)) + removed := buf.dequeueRange(int64(1), int64(2), 2) require.Equal(t, 2, len(removed)) results = buf.peekRange(int64(1), int64(2)) require.Equal(t, 0, len(results)) }) t.Run("enqueue peek and dequeue", func(t *testing.T) { - buf := newLogEventBuffer(logger.TestLogger(t), 3, 10, 10) + buf := newLogEventBuffer(logger.TestLogger(t), 4, 10, 10) require.Equal(t, buf.enqueue(big.NewInt(10), logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 10}, @@ -250,10 +256,11 @@ func TestLogEventBuffer_EnqueueDequeue(t *testing.T) { results := buf.peek(8) require.Equal(t, 4, len(results)) verifyBlockNumbers(t, results, 1, 2, 3, 3) - removed := buf.dequeue(8) + removed := buf.dequeueRange(1, 3, 5) require.Equal(t, 4, len(removed)) buf.lock.Lock() require.Equal(t, 0, len(buf.blocks[0].logs)) + require.Equal(t, int64(2), buf.blocks[1].blockNumber) require.Equal(t, 1, len(buf.blocks[1].visited)) buf.lock.Unlock() }) @@ -291,10 +298,40 @@ func TestLogEventBuffer_EnqueueDequeue(t *testing.T) { logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x2"), LogIndex: 0}, logpoller.Log{BlockNumber: 3, TxHash: common.HexToHash("0x3"), LogIndex: 0}, ), 2) - results := buf.peekRange(int64(0), int64(5)) + results := buf.peekRange(int64(1), int64(5)) fmt.Println(results) verifyBlockNumbers(t, results, 2, 3, 4, 4) }) + + t.Run("dequeue with limits", func(t *testing.T) { + buf := newLogEventBuffer(logger.TestLogger(t), 3, 5, 10) + require.Equal(t, buf.enqueue(big.NewInt(1), + logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 0}, + logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x2"), LogIndex: 0}, + logpoller.Log{BlockNumber: 3, TxHash: common.HexToHash("0x3"), LogIndex: 0}, + logpoller.Log{BlockNumber: 4, TxHash: common.HexToHash("0x4"), LogIndex: 0}, + logpoller.Log{BlockNumber: 5, TxHash: common.HexToHash("0x5"), LogIndex: 0}, + ), 5) + + logs := buf.dequeueRange(1, 5, 2) + require.Equal(t, 2, len(logs)) + }) + t.Run("dequeue doesn't return same logs again", func(t *testing.T) { + buf := newLogEventBuffer(logger.TestLogger(t), 3, 5, 10) + require.Equal(t, buf.enqueue(big.NewInt(1), + logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 0}, + logpoller.Log{BlockNumber: 2, TxHash: common.HexToHash("0x2"), LogIndex: 0}, + logpoller.Log{BlockNumber: 3, TxHash: common.HexToHash("0x3"), LogIndex: 0}, + ), 3) + + logs := buf.dequeueRange(3, 3, 2) + fmt.Println(logs) + require.Equal(t, 1, len(logs)) + + logs = buf.dequeueRange(3, 3, 2) + fmt.Println(logs) + require.Equal(t, 0, len(logs)) + }) } func verifyBlockNumbers(t *testing.T, logs []fetchedLog, bns ...int64) { diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/factory.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/factory.go new file mode 100644 index 00000000000..cbbb8db54dc --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/factory.go @@ -0,0 +1,19 @@ +package logprovider + +import ( + "github.com/ethereum/go-ethereum/accounts/abi" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" +) + +func New(lggr logger.Logger, poller logpoller.LogPoller, c client.Client, utilsABI abi.ABI, stateStore core.UpkeepStateReader) (LogEventProvider, LogRecoverer) { + filterStore := NewUpkeepFilterStore() + packer := NewLogEventsPacker(utilsABI) + provider := NewLogProvider(lggr, poller, packer, filterStore, nil) + recoverer := NewLogRecoverer(lggr, poller, c, stateStore, packer, filterStore, 0, provider.opts.LookbackBlocks) + + return provider, recoverer +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/filter_store.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/filter_store.go new file mode 100644 index 00000000000..38b1e4e26f3 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/filter_store.go @@ -0,0 +1,194 @@ +package logprovider + +import ( + "math/big" + "sync" + + "github.com/ethereum/go-ethereum/common" + "golang.org/x/time/rate" +) + +type UpkeepFilterStore interface { + GetIDs(selector func(upkeepFilter) bool) []*big.Int + UpdateFilters(updater func(upkeepFilter, upkeepFilter) upkeepFilter, filters ...upkeepFilter) + Has(id *big.Int) bool + Get(id *big.Int) *upkeepFilter + RangeFiltersByIDs(iterator func(int, upkeepFilter), ids ...*big.Int) + GetFilters(selector func(upkeepFilter) bool) []upkeepFilter + AddActiveUpkeeps(filters ...upkeepFilter) + RemoveActiveUpkeeps(filters ...upkeepFilter) + Size() int +} + +var _ UpkeepFilterStore = &upkeepFilterStore{} + +type upkeepFilter struct { + addr []byte + topics []common.Hash + upkeepID *big.Int + // configUpdateBlock is the block number the filter was last updated at + configUpdateBlock uint64 + // lastPollBlock is the last block number the logs were fetched for this upkeep + // used by log event provider. + lastPollBlock int64 + // blockLimiter is used to limit the number of blocks to fetch logs for an upkeep. + // used by log event provider. + blockLimiter *rate.Limiter + // lastRePollBlock is the last block number the logs were recovered for this upkeep + // used by log recoverer. + lastRePollBlock int64 +} + +func (f upkeepFilter) Clone() upkeepFilter { + topics := make([]common.Hash, len(f.topics)) + copy(topics, f.topics) + addr := make([]byte, len(f.addr)) + copy(addr, f.addr) + return upkeepFilter{ + upkeepID: f.upkeepID, + topics: topics, + addr: addr, + configUpdateBlock: f.configUpdateBlock, + lastPollBlock: f.lastPollBlock, + lastRePollBlock: f.lastRePollBlock, + blockLimiter: f.blockLimiter, + } +} + +type upkeepFilterStore struct { + lock *sync.RWMutex + // filters is a map of upkeepID to upkeepFilter + filters map[string]upkeepFilter +} + +func NewUpkeepFilterStore() *upkeepFilterStore { + return &upkeepFilterStore{ + lock: &sync.RWMutex{}, + filters: make(map[string]upkeepFilter), + } +} + +func (s *upkeepFilterStore) GetIDs(selector func(upkeepFilter) bool) []*big.Int { + s.lock.RLock() + defer s.lock.RUnlock() + + if selector == nil { + // noop selector returns true for all filters + selector = func(upkeepFilter) bool { return true } + } + + var ids []*big.Int + for _, f := range s.filters { + if selector(f) { + ids = append(ids, f.upkeepID) + } + } + + return ids +} + +func (s *upkeepFilterStore) UpdateFilters(resolveUpdated func(upkeepFilter, upkeepFilter) upkeepFilter, filters ...upkeepFilter) { + s.lock.Lock() + defer s.lock.Unlock() + + if resolveUpdated == nil { + // noop resolveUpdated will use the newer filter + resolveUpdated = func(_ upkeepFilter, f upkeepFilter) upkeepFilter { return f } + } + + for _, f := range filters { + uid := f.upkeepID.String() + orig, ok := s.filters[uid] + if !ok { + // not found, turned inactive probably + continue + } + updated := resolveUpdated(orig, f) + s.filters[uid] = updated + } +} + +func (s *upkeepFilterStore) Has(id *big.Int) bool { + s.lock.RLock() + defer s.lock.RUnlock() + + _, ok := s.filters[id.String()] + return ok +} + +func (s *upkeepFilterStore) Get(id *big.Int) *upkeepFilter { + s.lock.RLock() + defer s.lock.RUnlock() + + f, ok := s.filters[id.String()] + if !ok { + return nil + } + fp := f.Clone() + return &fp +} + +func (s *upkeepFilterStore) RangeFiltersByIDs(iterator func(int, upkeepFilter), ids ...*big.Int) { + s.lock.RLock() + defer s.lock.RUnlock() + + if iterator == nil { + // noop iterator does nothing + iterator = func(int, upkeepFilter) {} + } + + for i, id := range ids { + f, ok := s.filters[id.String()] + if !ok { + // in case the filter is not found, we still want to call the iterator + // with an empty filter, so + iterator(i, upkeepFilter{upkeepID: id}) + } else { + iterator(i, f) + } + } +} + +func (s *upkeepFilterStore) GetFilters(selector func(upkeepFilter) bool) []upkeepFilter { + s.lock.RLock() + defer s.lock.RUnlock() + + if selector == nil { + // noop selector returns true for all filters + selector = func(upkeepFilter) bool { return true } + } + + var filters []upkeepFilter + for _, f := range s.filters { + if selector(f) { + filters = append(filters, f.Clone()) + } + } + return filters +} + +func (s *upkeepFilterStore) AddActiveUpkeeps(filters ...upkeepFilter) { + s.lock.Lock() + defer s.lock.Unlock() + + for _, f := range filters { + s.filters[f.upkeepID.String()] = f + } +} + +func (s *upkeepFilterStore) RemoveActiveUpkeeps(filters ...upkeepFilter) { + s.lock.Lock() + defer s.lock.Unlock() + + for _, f := range filters { + uid := f.upkeepID.String() + delete(s.filters, uid) + } +} + +func (s *upkeepFilterStore) Size() int { + s.lock.RLock() + defer s.lock.RUnlock() + + return len(s.filters) +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/filter_store_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/filter_store_test.go new file mode 100644 index 00000000000..b2030a8dc96 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/filter_store_test.go @@ -0,0 +1,93 @@ +package logprovider + +import ( + "math/big" + "sort" + "sync" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestFilterStore_CRUD(t *testing.T) { + tests := []struct { + name string + initial []upkeepFilter + toAdd []upkeepFilter + expectedPostAdd []upkeepFilter + toRemove []upkeepFilter + expectedPostRemove []upkeepFilter + }{ + { + "empty", + []upkeepFilter{}, + []upkeepFilter{}, + []upkeepFilter{}, + []upkeepFilter{}, + []upkeepFilter{}, + }, + { + "add rm one", + []upkeepFilter{}, + []upkeepFilter{{upkeepID: big.NewInt(1)}}, + []upkeepFilter{{upkeepID: big.NewInt(1)}}, + []upkeepFilter{{upkeepID: big.NewInt(1)}}, + []upkeepFilter{}, + }, + { + "add rm multiple", + []upkeepFilter{}, + []upkeepFilter{{upkeepID: big.NewInt(1)}, {upkeepID: big.NewInt(2)}}, + []upkeepFilter{{upkeepID: big.NewInt(1)}, {upkeepID: big.NewInt(2)}}, + []upkeepFilter{{upkeepID: big.NewInt(1)}}, + []upkeepFilter{{upkeepID: big.NewInt(2)}}, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + s := NewUpkeepFilterStore() + s.AddActiveUpkeeps(tc.initial...) + require.Equal(t, len(tc.initial), len(s.GetIDs(nil))) + s.AddActiveUpkeeps(tc.toAdd...) + require.Equal(t, len(tc.expectedPostAdd), s.Size()) + filters := s.GetFilters(func(f upkeepFilter) bool { return true }) + require.Equal(t, len(tc.expectedPostAdd), len(filters)) + if len(filters) > 0 { + sort.Slice(filters, func(i, j int) bool { + return filters[i].upkeepID.Cmp(filters[j].upkeepID) < 0 + }) + for i, f := range filters { + require.Equal(t, tc.expectedPostAdd[i].upkeepID, f.upkeepID) + } + } + s.RemoveActiveUpkeeps(tc.toRemove...) + require.Equal(t, len(tc.expectedPostRemove), len(s.GetIDs(func(upkeepFilter) bool { return true }))) + }) + } +} + +func TestFilterStore_Concurrency(t *testing.T) { + s := NewUpkeepFilterStore() + var wg sync.WaitGroup + + wg.Add(1) + go func() { + defer wg.Done() + s.AddActiveUpkeeps(upkeepFilter{upkeepID: big.NewInt(1)}) + s.AddActiveUpkeeps(upkeepFilter{upkeepID: big.NewInt(2)}) + }() + wg.Add(1) + go func() { + defer wg.Done() + s.AddActiveUpkeeps(upkeepFilter{upkeepID: big.NewInt(2)}) + }() + + go func() { + _ = s.GetIDs(nil) + }() + + wg.Wait() + + require.Equal(t, 2, s.Size()) +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/integration_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/integration_test.go index 0ed221ad518..08d56c78c59 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/integration_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/integration_test.go @@ -2,11 +2,10 @@ package logprovider_test import ( "context" + "errors" "fmt" "math/big" "strings" - "sync" - "sync/atomic" "testing" "time" @@ -16,15 +15,17 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" "golang.org/x/time/rate" "github.com/smartcontractkit/sqlx" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" "github.com/smartcontractkit/chainlink/v2/core/assets" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1" @@ -35,7 +36,9 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + kevmcore "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) func TestIntegration_LogEventProvider(t *testing.T) { @@ -52,11 +55,14 @@ func TestIntegration_LogEventProvider(t *testing.T) { opts := &logprovider.LogEventProviderOptions{ ReadInterval: time.Second / 2, } - logProvider, lp, ethClient := setupLogProvider(t, db, backend, opts) + lp, ethClient, utilsABI := setupDependencies(t, db, backend) + filterStore := logprovider.NewUpkeepFilterStore() + provider, _ := setup(logger.TestLogger(t), lp, nil, utilsABI, nil, filterStore, opts) + logProvider := provider.(logprovider.LogEventProviderTest) n := 10 - ids, addrs, contracts := deployUpkeepCounter(t, n, backend, carrol, logProvider) + ids, addrs, contracts := deployUpkeepCounter(t, n, ethClient, backend, carrol, logProvider) lp.PollAndSaveLogs(ctx, int64(n)) go func() { @@ -68,57 +74,61 @@ func TestIntegration_LogEventProvider(t *testing.T) { defer logProvider.Close() logsRounds := 10 - pollerTimeout := time.Second * 5 poll := pollFn(ctx, t, lp, ethClient) triggerEvents(ctx, t, backend, carrol, logsRounds, poll, contracts...) poll(backend.Commit()) - // let it time to poll - <-time.After(pollerTimeout) - logs, _ := logProvider.GetLogs(ctx) - require.NoError(t, logProvider.Close()) + waitLogPoller(ctx, t, backend, lp, ethClient) + + waitLogProvider(ctx, t, logProvider, 3) + + allPayloads := collectPayloads(ctx, t, logProvider, n, 5) + require.GreaterOrEqual(t, len(allPayloads), n, + "failed to get logs after restart") - require.GreaterOrEqual(t, len(logs), n, "failed to get all logs") t.Run("Restart", func(t *testing.T) { + t.Log("restarting log provider") // assuming that our service was closed and restarted, // we should be able to backfill old logs and fetch new ones - require.NoError(t, logProvider.Close()) + logDataABI, err := abi.JSON(strings.NewReader(automation_utils_2_1.AutomationUtilsABI)) + require.NoError(t, err) + filterStore := logprovider.NewUpkeepFilterStore() + logProvider2 := logprovider.NewLogProvider(logger.TestLogger(t), lp, logprovider.NewLogEventsPacker(logDataABI), filterStore, opts) poll(backend.Commit()) - go func() { - if err := logProvider.Start(ctx); err != nil { - t.Logf("error starting log provider: %s", err) + if err2 := logProvider2.Start(ctx); err2 != nil { + t.Logf("error starting log provider: %s", err2) t.Fail() } }() - defer logProvider.Close() - - for i, addr := range addrs { - id := ids[i] - require.NoError(t, logProvider.RegisterFilter(id, newPlainLogTriggerConfig(addr))) + defer logProvider2.Close() + + // re-register filters + for i, id := range ids { + err = logProvider2.RegisterFilter(logprovider.FilterOptions{ + UpkeepID: id, + TriggerConfig: newPlainLogTriggerConfig(addrs[i]), + // using block number at which the upkeep was registered, + // before we emitted any logs + UpdateBlock: uint64(n), + }) + require.NoError(t, err) } - logsAfterRestart, _ := logProvider.GetLogs(ctx) - require.GreaterOrEqual(t, len(logsAfterRestart), 0, - "logs should have been marked visited") - - triggerEvents(ctx, t, backend, carrol, logsRounds, poll, contracts...) - // let it time to poll - poll(backend.Commit()) - <-time.After(pollerTimeout) + waitLogProvider(ctx, t, logProvider2, 2) - logsAfterRestart, _ = logProvider.GetLogs(ctx) - require.NoError(t, logProvider.Close()) + t.Log("getting logs after restart") + logsAfterRestart := collectPayloads(ctx, t, logProvider2, n, 5) require.GreaterOrEqual(t, len(logsAfterRestart), n, "failed to get logs after restart") }) } -func TestIntegration_LogEventProvider_RateLimit(t *testing.T) { +func TestIntegration_LogEventProvider_UpdateConfig(t *testing.T) { ctx, cancel := context.WithCancel(testutils.Context(t)) defer cancel() @@ -130,61 +140,318 @@ func TestIntegration_LogEventProvider_RateLimit(t *testing.T) { defer db.Close() opts := &logprovider.LogEventProviderOptions{ - BlockRateLimit: rate.Every(time.Minute), - BlockLimitBurst: 5, - ReadInterval: time.Second / 2, + ReadInterval: time.Second / 2, + } + lp, ethClient, utilsABI := setupDependencies(t, db, backend) + filterStore := logprovider.NewUpkeepFilterStore() + provider, _ := setup(logger.TestLogger(t), lp, nil, utilsABI, nil, filterStore, opts) + logProvider := provider.(logprovider.LogEventProviderTest) + + _, addrs, contracts := deployUpkeepCounter(t, 1, ethClient, backend, carrol, logProvider) + lp.PollAndSaveLogs(ctx, int64(5)) + require.Equal(t, 1, len(contracts)) + require.Equal(t, 1, len(addrs)) + + t.Run("update filter config", func(t *testing.T) { + upkeepID := kevmcore.GenUpkeepID(ocr2keepers.LogTrigger, "111") + id := upkeepID.BigInt() + cfg := newPlainLogTriggerConfig(addrs[0]) + b, err := ethClient.BlockByHash(ctx, backend.Commit()) + require.NoError(t, err) + bn := b.Number() + err = logProvider.RegisterFilter(logprovider.FilterOptions{ + UpkeepID: id, + TriggerConfig: cfg, + UpdateBlock: bn.Uint64(), + }) + require.NoError(t, err) + // old block + err = logProvider.RegisterFilter(logprovider.FilterOptions{ + UpkeepID: id, + TriggerConfig: cfg, + UpdateBlock: bn.Uint64() - 1, + }) + require.Error(t, err) + // new block + b, err = ethClient.BlockByHash(ctx, backend.Commit()) + require.NoError(t, err) + bn = b.Number() + err = logProvider.RegisterFilter(logprovider.FilterOptions{ + UpkeepID: id, + TriggerConfig: cfg, + UpdateBlock: bn.Uint64(), + }) + require.NoError(t, err) + }) + + t.Run("register same log filter", func(t *testing.T) { + upkeepID := kevmcore.GenUpkeepID(ocr2keepers.LogTrigger, "222") + id := upkeepID.BigInt() + cfg := newPlainLogTriggerConfig(addrs[0]) + b, err := ethClient.BlockByHash(ctx, backend.Commit()) + require.NoError(t, err) + bn := b.Number() + err = logProvider.RegisterFilter(logprovider.FilterOptions{ + UpkeepID: id, + TriggerConfig: cfg, + UpdateBlock: bn.Uint64(), + }) + require.NoError(t, err) + }) +} + +func TestIntegration_LogEventProvider_Backfill(t *testing.T) { + ctx, cancel := context.WithTimeout(testutils.Context(t), time.Second*60) + defer cancel() + + backend, stopMining, accounts := setupBackend(t) + defer stopMining() + carrol := accounts[2] + + db := setupDB(t) + defer db.Close() + + opts := &logprovider.LogEventProviderOptions{ + ReadInterval: time.Second / 4, } - logProvider, lp, ethClient := setupLogProvider(t, db, backend, opts) + lp, ethClient, utilsABI := setupDependencies(t, db, backend) + filterStore := logprovider.NewUpkeepFilterStore() + provider, _ := setup(logger.TestLogger(t), lp, nil, utilsABI, nil, filterStore, opts) + logProvider := provider.(logprovider.LogEventProviderTest) n := 10 - ids, _, contracts := deployUpkeepCounter(t, n, backend, carrol, logProvider) - lp.PollAndSaveLogs(ctx, int64(n)) + _, _, contracts := deployUpkeepCounter(t, n, ethClient, backend, carrol, logProvider) + poll := pollFn(ctx, t, lp, ethClient) - rounds := 4 + rounds := 8 for i := 0; i < rounds; i++ { + poll(backend.Commit()) triggerEvents(ctx, t, backend, carrol, n, poll, contracts...) poll(backend.Commit()) - for dummyBlocks := 0; dummyBlocks < n; dummyBlocks++ { - _ = backend.Commit() + } + + waitLogPoller(ctx, t, backend, lp, ethClient) + + // starting the log provider should backfill logs + go func() { + if startErr := logProvider.Start(ctx); startErr != nil { + t.Logf("error starting log provider: %s", startErr) + t.Fail() + } + }() + defer logProvider.Close() + + waitLogProvider(ctx, t, logProvider, 3) + + allPayloads := collectPayloads(ctx, t, logProvider, n, 5) + require.GreaterOrEqual(t, len(allPayloads), len(contracts), "failed to backfill logs") +} + +func TestIntegration_LogEventProvider_RateLimit(t *testing.T) { + setupTest := func( + t *testing.T, + opts *logprovider.LogEventProviderOptions, + ) ( + context.Context, + *backends.SimulatedBackend, + func(blockHash common.Hash), + logprovider.LogEventProviderTest, + []*big.Int, + func(), + ) { + ctx, cancel := context.WithCancel(testutils.Context(t)) + backend, stopMining, accounts := setupBackend(t) + userContractAccount := accounts[2] + db := setupDB(t) + + deferFunc := func() { + cancel() + stopMining() + _ = db.Close() + } + lp, ethClient, utilsABI := setupDependencies(t, db, backend) + filterStore := logprovider.NewUpkeepFilterStore() + provider, _ := setup(logger.TestLogger(t), lp, nil, utilsABI, nil, filterStore, opts) + logProvider := provider.(logprovider.LogEventProviderTest) + + rounds := 5 + numberOfUserContracts := 10 + poll := pollFn(ctx, t, lp, ethClient) + + // deployUpkeepCounter creates 'n' blocks and 'n' contracts + ids, _, contracts := deployUpkeepCounter( + t, + numberOfUserContracts, + ethClient, + backend, + userContractAccount, + logProvider) + + // have log poller save logs for current blocks + lp.PollAndSaveLogs(ctx, int64(numberOfUserContracts)) + + for i := 0; i < rounds; i++ { + triggerEvents( + ctx, + t, + backend, + userContractAccount, + numberOfUserContracts, + poll, + contracts...) + + for dummyBlocks := 0; dummyBlocks < numberOfUserContracts; dummyBlocks++ { + _ = backend.Commit() + } + + poll(backend.Commit()) } + + { + // total block history at this point should be 566 + var minimumBlockCount int64 = 500 + latestBlock, _ := lp.LatestBlock() + + assert.GreaterOrEqual(t, latestBlock, minimumBlockCount, "to ensure the integrety of the test, the minimum block count before the test should be %d but got %d", minimumBlockCount, latestBlock) + } + + require.NoError(t, logProvider.ReadLogs(ctx, ids...)) + + return ctx, backend, poll, logProvider, ids, deferFunc } - require.NoError(t, logProvider.ReadLogs(ctx, true, ids...)) - - var wg sync.WaitGroup - workers := 20 - limitErrs := int32(0) - for i := 0; i < workers; i++ { - idsCp := make([]*big.Int, len(ids)) - copy(idsCp, ids) - wg.Add(1) - go func(i int, ids []*big.Int) { - defer wg.Done() - err := logProvider.ReadLogs(ctx, true, ids...) + + // polling for logs at approximately the same rate as a chain produces + // blocks should not encounter rate limits + t.Run("should allow constant polls within the rate and burst limit", func(t *testing.T) { + ctx, backend, poll, logProvider, ids, deferFunc := setupTest(t, &logprovider.LogEventProviderOptions{ + // BlockRateLimit is set low to ensure the test does not exceed the + // rate limit + BlockRateLimit: rate.Every(50 * time.Millisecond), + // BlockLimitBurst is just set to a non-zero value + BlockLimitBurst: 5, + }) + + defer deferFunc() + + // set the wait time between reads higher than the rate limit + readWait := 50 * time.Millisecond + timer := time.NewTimer(readWait) + + for i := 0; i < 4; i++ { + <-timer.C + + // advance 1 block for every read + poll(backend.Commit()) + + err := logProvider.ReadLogs(ctx, ids...) if err != nil { - require.True(t, strings.Contains(err.Error(), logprovider.BlockLimitExceeded)) - atomic.AddInt32(&limitErrs, 1) + assert.False(t, errors.Is(err, logprovider.ErrBlockLimitExceeded), "error should not contain block limit exceeded") } - }(i, idsCp) - } - poll(backend.Commit()) - wg.Wait() - // TODO: fix test (might be caused by timeouts) and uncomment - // require.GreaterOrEqual(t, atomic.LoadInt32(&limitErrs), int32(1), "didn't got rate limit errors") - t.Logf("got %d rate limit errors", atomic.LoadInt32(&limitErrs)) + timer.Reset(readWait) + } - _, err := logProvider.GetLogs(ctx) - require.NoError(t, err) - require.NoError(t, logProvider.Close()) + poll(backend.Commit()) + + _, err := logProvider.GetLatestPayloads(ctx) + + require.NoError(t, err) + }) - // TODO: fix test (might be caused by timeouts) and uncomment - // require.Equal(t, len(logs), n*rounds, "failed to read all logs") + t.Run("should produce a rate limit error for over burst limit", func(t *testing.T) { + ctx, backend, poll, logProvider, ids, deferFunc := setupTest(t, &logprovider.LogEventProviderOptions{ + // BlockRateLimit is set low to ensure the test does not exceed the + // rate limit + BlockRateLimit: rate.Every(50 * time.Millisecond), + // BlockLimitBurst is just set to a non-zero value + BlockLimitBurst: 5, + }) + + defer deferFunc() + + // set the wait time between reads higher than the rate limit + readWait := 50 * time.Millisecond + timer := time.NewTimer(readWait) + + for i := 0; i < 4; i++ { + <-timer.C + + // advance 4 blocks for every read + for x := 0; x < 4; x++ { + poll(backend.Commit()) + } + + err := logProvider.ReadLogs(ctx, ids...) + if err != nil { + assert.True(t, errors.Is(err, logprovider.ErrBlockLimitExceeded), "error should not contain block limit exceeded") + } + + timer.Reset(readWait) + } + + poll(backend.Commit()) + + _, err := logProvider.GetLatestPayloads(ctx) + + require.NoError(t, err) + }) + + t.Run("should allow polling after lookback number of blocks have passed", func(t *testing.T) { + ctx, backend, poll, logProvider, ids, deferFunc := setupTest(t, &logprovider.LogEventProviderOptions{ + // BlockRateLimit is set low to ensure the test does not exceed the + // rate limit + BlockRateLimit: rate.Every(50 * time.Millisecond), + // BlockLimitBurst is set low to ensure the test exceeds the burst limit + BlockLimitBurst: 5, + // LogBlocksLookback is set low to reduce the number of blocks required + // to reset the block limiter to maxBurst + LookbackBlocks: 50, + }) + + defer deferFunc() + + // simulate a burst in unpolled blocks + for i := 0; i < 20; i++ { + _ = backend.Commit() + } + + poll(backend.Commit()) + + // all entries should error at this point because there are too many + // blocks to processes + err := logProvider.ReadLogs(ctx, ids...) + if err != nil { + assert.True(t, errors.Is(err, logprovider.ErrBlockLimitExceeded), "error should not contain block limit exceeded") + } + + // progress the chain by the same number of blocks as the lookback limit + // to trigger the usage of maxBurst + for i := 0; i < 50; i++ { + _ = backend.Commit() + } + + poll(backend.Commit()) + + // all entries should reset to the maxBurst because they are beyond + // the log lookback + err = logProvider.ReadLogs(ctx, ids...) + if err != nil { + assert.True(t, errors.Is(err, logprovider.ErrBlockLimitExceeded), "error should not contain block limit exceeded") + } + + poll(backend.Commit()) + + _, err = logProvider.GetLatestPayloads(ctx) + + require.NoError(t, err) + }) } -func TestIntegration_LogEventProvider_Backfill(t *testing.T) { - ctx, cancel := context.WithCancel(testutils.Context(t)) +func TestIntegration_LogRecoverer_Backfill(t *testing.T) { + t.Skip() // TODO: remove skip after removing constant timeouts + ctx, cancel := context.WithTimeout(testutils.Context(t), time.Second*60) defer cancel() backend, stopMining, accounts := setupBackend(t) @@ -194,49 +461,109 @@ func TestIntegration_LogEventProvider_Backfill(t *testing.T) { db := setupDB(t) defer db.Close() - logProvider, lp, ethClient := setupLogProvider(t, db, backend, &logprovider.LogEventProviderOptions{ - ReadInterval: time.Second / 4, - }) + lookbackBlocks := int64(200) + opts := &logprovider.LogEventProviderOptions{ + ReadInterval: time.Second / 4, + LookbackBlocks: lookbackBlocks, + } + lp, ethClient, utilsABI := setupDependencies(t, db, backend) + filterStore := logprovider.NewUpkeepFilterStore() + origDefaultRecoveryInterval := logprovider.DefaultRecoveryInterval + logprovider.DefaultRecoveryInterval = time.Millisecond * 200 + defer func() { + logprovider.DefaultRecoveryInterval = origDefaultRecoveryInterval + }() + provider, recoverer := setup(logger.TestLogger(t), lp, nil, utilsABI, &mockUpkeepStateStore{}, filterStore, opts) + logProvider := provider.(logprovider.LogEventProviderTest) n := 10 - pollerTimeout := time.Second * 2 - _, _, contracts := deployUpkeepCounter(t, n, backend, carrol, logProvider) + _, _, contracts := deployUpkeepCounter(t, n, ethClient, backend, carrol, logProvider) poll := pollFn(ctx, t, lp, ethClient) rounds := 8 for i := 0; i < rounds; i++ { - poll(backend.Commit()) triggerEvents(ctx, t, backend, carrol, n, poll, contracts...) poll(backend.Commit()) } + poll(backend.Commit()) - <-time.After(pollerTimeout) // let the log poller work + waitLogPoller(ctx, t, backend, lp, ethClient) + // create dummy blocks + var blockNumber int64 + for blockNumber < lookbackBlocks*4 { + b, err := ethClient.BlockByHash(ctx, backend.Commit()) + require.NoError(t, err) + bn := b.Number() + blockNumber = bn.Int64() + } + // starting the log recoverer should backfill logs go func() { - if err := logProvider.Start(ctx); err != nil { - t.Logf("error starting log provider: %s", err) + if startErr := recoverer.Start(ctx); startErr != nil { + t.Logf("error starting log provider: %s", startErr) t.Fail() } }() - defer logProvider.Close() + defer recoverer.Close() - go func(dummyPolls int) { - for i := 0; i < dummyPolls; i++ { - poll(backend.Commit()) - time.Sleep(20 * time.Millisecond) + lctx, lcancel := context.WithTimeout(ctx, time.Second*15) + defer lcancel() + var allProposals []ocr2keepers.UpkeepPayload + for lctx.Err() == nil { + poll(backend.Commit()) + proposals, err := recoverer.GetRecoveryProposals(ctx) + require.NoError(t, err) + allProposals = append(allProposals, proposals...) + if len(allProposals) < n { + time.Sleep(100 * time.Millisecond) + continue } - }(n * rounds) + break + } + require.NoError(t, lctx.Err(), "could not recover logs before timeout") +} - <-time.After(pollerTimeout * 2) // let the provider work +func collectPayloads(ctx context.Context, t *testing.T, logProvider logprovider.LogEventProvider, n, rounds int) []ocr2keepers.UpkeepPayload { + allPayloads := make([]ocr2keepers.UpkeepPayload, 0) + for ctx.Err() == nil && len(allPayloads) < n && rounds > 0 { + logs, err := logProvider.GetLatestPayloads(ctx) + require.NoError(t, err) + require.LessOrEqual(t, len(logs), logprovider.AllowedLogsPerUpkeep, "failed to get all logs") + allPayloads = append(allPayloads, logs...) + rounds-- + } + return allPayloads +} - logs, err := logProvider.GetLogs(ctx) - require.NoError(t, err) - require.NoError(t, logProvider.Close()) +// waitLogProvider waits until the provider reaches the given partition +func waitLogProvider(ctx context.Context, t *testing.T, logProvider logprovider.LogEventProviderTest, partition int) { + t.Logf("waiting for log provider to reach partition %d", partition) + for ctx.Err() == nil { + currentPartition := logProvider.CurrentPartitionIdx() + if currentPartition > uint64(partition) { // make sure we went over all items + break + } + time.Sleep(100 * time.Millisecond) + } +} - expected := 0 // TODO: fix test (might be caused by timeouts) and change to n - require.GreaterOrEqual(t, len(logs), expected, "failed to backfill logs") +// waitLogPoller waits until the log poller is familiar with the given block +func waitLogPoller(ctx context.Context, t *testing.T, backend *backends.SimulatedBackend, lp logpoller.LogPollerTest, ethClient *evmclient.SimulatedBackendClient) { + t.Log("waiting for log poller to get updated") + // let the log poller work + b, err := ethClient.BlockByHash(ctx, backend.Commit()) + require.NoError(t, err) + latestBlock := b.Number().Int64() + for { + latestPolled, lberr := lp.LatestBlock(pg.WithParentCtx(ctx)) + require.NoError(t, lberr) + if latestPolled >= latestBlock { + break + } + lp.PollAndSaveLogs(ctx, latestBlock) + } } func pollFn(ctx context.Context, t *testing.T, lp logpoller.LogPollerTest, ethClient *evmclient.SimulatedBackendClient) func(blockHash common.Hash) { @@ -278,6 +605,7 @@ func triggerEvents( func deployUpkeepCounter( t *testing.T, n int, + ethClient *evmclient.SimulatedBackendClient, backend *backends.SimulatedBackend, account *bind.TransactOpts, logProvider logprovider.LogEventProvider, @@ -298,9 +626,16 @@ func deployUpkeepCounter( // creating some dummy upkeepID to register filter upkeepID := ocr2keepers.UpkeepIdentifier(append(common.LeftPadBytes([]byte{1}, 16), upkeepAddr[:16]...)) - id := big.NewInt(0).SetBytes(upkeepID) + id := upkeepID.BigInt() ids = append(ids, id) - err = logProvider.RegisterFilter(id, newPlainLogTriggerConfig(upkeepAddr)) + b, err := ethClient.BlockByHash(context.Background(), backend.Commit()) + require.NoError(t, err) + bn := b.Number() + err = logProvider.RegisterFilter(logprovider.FilterOptions{ + UpkeepID: id, + TriggerConfig: newPlainLogTriggerConfig(upkeepAddr), + UpdateBlock: bn.Uint64(), + }) require.NoError(t, err) } return ids, contractsAddrs, contracts @@ -314,19 +649,29 @@ func newPlainLogTriggerConfig(upkeepAddr common.Address) logprovider.LogTriggerC } } -func setupLogProvider(t *testing.T, db *sqlx.DB, backend *backends.SimulatedBackend, opts *logprovider.LogEventProviderOptions) (logprovider.LogEventProviderTest, logpoller.LogPollerTest, *evmclient.SimulatedBackendClient) { +func setupDependencies(t *testing.T, db *sqlx.DB, backend *backends.SimulatedBackend) (logpoller.LogPollerTest, *evmclient.SimulatedBackendClient, abi.ABI) { ethClient := evmclient.NewSimulatedBackendClient(t, backend, big.NewInt(1337)) pollerLggr := logger.TestLogger(t) pollerLggr.SetLogLevel(zapcore.WarnLevel) lorm := logpoller.NewORM(big.NewInt(1337), db, pollerLggr, pgtest.NewQConfig(false)) lp := logpoller.NewLogPoller(lorm, ethClient, pollerLggr, 100*time.Millisecond, 1, 2, 2, 1000) - lggr := logger.TestLogger(t) - logDataABI, err := abi.JSON(strings.NewReader(automation_utils_2_1.AutomationUtilsABI)) + utilsABI, err := abi.JSON(strings.NewReader(automation_utils_2_1.AutomationUtilsABI)) require.NoError(t, err) - logProvider := logprovider.New(lggr, lp, logprovider.NewLogEventsPacker(logDataABI), opts) - return logProvider, lp, ethClient + return lp, ethClient, utilsABI +} + +func setup(lggr logger.Logger, poller logpoller.LogPoller, c client.Client, utilsABI abi.ABI, stateStore kevmcore.UpkeepStateReader, filterStore logprovider.UpkeepFilterStore, opts *logprovider.LogEventProviderOptions) (logprovider.LogEventProvider, logprovider.LogRecoverer) { + packer := logprovider.NewLogEventsPacker(utilsABI) + if opts == nil { + opts = new(logprovider.LogEventProviderOptions) + opts.Defaults() + } + provider := logprovider.NewLogProvider(lggr, poller, packer, filterStore, opts) + recoverer := logprovider.NewLogRecoverer(lggr, poller, c, stateStore, packer, filterStore, 0, opts.LookbackBlocks) + + return provider, recoverer } func setupBackend(t *testing.T) (*backends.SimulatedBackend, func(), []*bind.TransactOpts) { @@ -357,3 +702,14 @@ func setupDB(t *testing.T) *sqlx.DB { }) return db } + +type mockUpkeepStateStore struct { +} + +func (m *mockUpkeepStateStore) SelectByWorkIDsInRange(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) { + states := make([]ocr2keepers.UpkeepState, len(workIDs)) + for i := range workIDs { + states[i] = ocr2keepers.UnknownState + } + return states, nil +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/abi.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/log_packer.go similarity index 90% rename from core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/abi.go rename to core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/log_packer.go index c5660e1be1e..c4e8d7e0da2 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/abi.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/log_packer.go @@ -9,11 +9,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1" ) -type LogTriggerExtension struct { - TxHash string - LogIndex int64 -} - type LogDataPacker interface { PackLogData(log logpoller.Log) ([]byte, error) } @@ -33,7 +28,7 @@ func (p *logEventsPacker) PackLogData(log logpoller.Log) ([]byte, error) { } b, err := p.abi.Pack("_log", &automation_utils_2_1.Log{ Index: big.NewInt(log.LogIndex), - TxIndex: big.NewInt(0), // TODO + TxIndex: big.NewInt(0), // TODO: Add this to the logpoller TxHash: log.TxHash, BlockNumber: big.NewInt(log.BlockNumber), BlockHash: log.BlockHash, diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go index 38725fc767f..377315a69eb 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go @@ -3,64 +3,72 @@ package logprovider import ( "context" "crypto/sha256" + "errors" "fmt" "hash" + "io" "math/big" "runtime" "sync" + "sync/atomic" "time" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" - "go.uber.org/multierr" - "golang.org/x/time/rate" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) -const ( - BlockLimitExceeded = "block limit exceeded" - logTriggerType = 1 -) - var ( - ErrHeadNotAvailable = fmt.Errorf("head not available") + ErrHeadNotAvailable = fmt.Errorf("head not available") + ErrBlockLimitExceeded = fmt.Errorf("block limit exceeded") + + // AllowedLogsPerUpkeep is the maximum number of logs allowed per upkeep every single call. + AllowedLogsPerUpkeep = 5 + + readJobQueueSize = 64 + readLogsTimeout = 10 * time.Second ) // LogTriggerConfig is an alias for log trigger config. type LogTriggerConfig automation_utils_2_1.LogTriggerConfig -// upkeepFilterEntry holds the upkeep filter, rate limiter and last polled block. -type upkeepFilterEntry struct { - id *big.Int - filter logpoller.Filter - cfg LogTriggerConfig - // lastPollBlock is the last block number the logs were fetched for this upkeep - lastPollBlock int64 - // blockLimiter is used to limit the number of blocks to fetch logs for an upkeep - blockLimiter *rate.Limiter +type FilterOptions struct { + UpkeepID *big.Int + TriggerConfig LogTriggerConfig + UpdateBlock uint64 } -type LogEventProvider interface { - // Start starts the log event provider. - Start(ctx context.Context) error - // Close closes the log event provider. - Close() error +type LogTriggersLifeCycle interface { // RegisterFilter registers the filter (if valid) for the given upkeepID. - RegisterFilter(upkeepID *big.Int, cfg LogTriggerConfig) error + RegisterFilter(opts FilterOptions) error // UnregisterFilter removes the filter for the given upkeepID. UnregisterFilter(upkeepID *big.Int) error - // GetLogs returns the logs in the given range. - GetLogs(context.Context) ([]ocr2keepers.UpkeepPayload, error) +} +type LogEventProvider interface { + ocr2keepers.LogEventProvider + LogTriggersLifeCycle + + RefreshActiveUpkeeps(ids ...*big.Int) ([]*big.Int, error) + + Start(context.Context) error + io.Closer } type LogEventProviderTest interface { LogEventProvider - ReadLogs(ctx context.Context, force bool, ids ...*big.Int) error + ReadLogs(ctx context.Context, ids ...*big.Int) error + CurrentPartitionIdx() uint64 } +var _ LogEventProvider = &logEventProvider{} +var _ LogEventProviderTest = &logEventProvider{} + // logEventProvider manages log filters for upkeeps and enables to read the log events. type logEventProvider struct { lggr logger.Logger @@ -71,90 +79,122 @@ type logEventProvider struct { packer LogDataPacker - lock sync.RWMutex - active map[string]upkeepFilterEntry + lock sync.RWMutex + registerLock sync.Mutex - buffer *logEventBuffer + filterStore UpkeepFilterStore + buffer *logEventBuffer opts *LogEventProviderOptions + + currentPartitionIdx uint64 } -func New(lggr logger.Logger, poller logpoller.LogPoller, packer LogDataPacker, opts *LogEventProviderOptions) *logEventProvider { +func NewLogProvider(lggr logger.Logger, poller logpoller.LogPoller, packer LogDataPacker, filterStore UpkeepFilterStore, opts *LogEventProviderOptions) *logEventProvider { if opts == nil { opts = new(LogEventProviderOptions) } opts.Defaults() return &logEventProvider{ - packer: packer, - lggr: lggr.Named("KeepersRegistry.LogEventProvider"), - buffer: newLogEventBuffer(lggr, opts.LogBufferSize, opts.BufferMaxBlockSize, opts.AllowedLogsPerBlock), - poller: poller, - lock: sync.RWMutex{}, - active: make(map[string]upkeepFilterEntry), - opts: opts, + packer: packer, + lggr: lggr.Named("KeepersRegistry.LogEventProvider"), + buffer: newLogEventBuffer(lggr, int(opts.LookbackBlocks), BufferMaxBlockSize, AllowedLogsPerBlock), + poller: poller, + opts: opts, + filterStore: filterStore, } } -func (p *logEventProvider) Start(pctx context.Context) error { - ctx, cancel := context.WithCancel(pctx) - defer cancel() +func (p *logEventProvider) Start(context.Context) error { + ctx, cancel := context.WithCancel(context.Background()) p.lock.Lock() + if p.cancel != nil { + p.lock.Unlock() + cancel() // Cancel the created context + return errors.New("already started") + } p.cancel = cancel p.lock.Unlock() - readQ := make(chan []*big.Int, 32) + readQ := make(chan []*big.Int, readJobQueueSize) + + p.lggr.Infow("starting log event provider", "readInterval", p.opts.ReadInterval, "readMaxBatchSize", p.opts.ReadBatchSize, "readers", p.opts.Readers) - for i := 0; i < p.opts.Readers; i++ { - go p.startReader(ctx, readQ) + { // start readers + go func(ctx context.Context) { + for i := 0; i < p.opts.Readers; i++ { + go p.startReader(ctx, readQ) + } + }(ctx) } - return p.scheduleReadJobs(ctx, func(ids []*big.Int) { - select { - case readQ <- ids: - case <-ctx.Done(): - default: - p.lggr.Warnw("readQ is full, dropping ids", "ids", ids) - } - }) + { // start scheduler + lggr := p.lggr.With("where", "scheduler") + go func(ctx context.Context) { + err := p.scheduleReadJobs(ctx, func(ids []*big.Int) { + select { + case readQ <- ids: + case <-ctx.Done(): + default: + lggr.Warnw("readQ is full, dropping ids", "ids", ids) + } + }) + if err != nil { + lggr.Warnw("stopped scheduling read jobs with error", "err", err) + } + lggr.Debug("stopped scheduling read jobs") + }(ctx) + } + + return nil } func (p *logEventProvider) Close() error { p.lock.Lock() defer p.lock.Unlock() - p.active = make(map[string]upkeepFilterEntry) - if p.cancel != nil { - p.cancel() + if cancel := p.cancel; cancel != nil { + p.cancel = nil + cancel() + } else { + return errors.New("already stopped") } return nil } -func (p *logEventProvider) GetLogs(context.Context) ([]ocr2keepers.UpkeepPayload, error) { - latest := p.buffer.latestBlockSeen() - diff := latest - p.opts.LogBlocksLookback - if diff < 0 { - diff = latest +func (p *logEventProvider) Name() string { + return p.lggr.Name() +} + +func (p *logEventProvider) GetLatestPayloads(ctx context.Context) ([]ocr2keepers.UpkeepPayload, error) { + latest, err := p.poller.LatestBlock(pg.WithParentCtx(ctx)) + if err != nil { + return nil, fmt.Errorf("%w: %s", ErrHeadNotAvailable, err) } - logs := p.buffer.dequeue(int(diff)) + start := latest - p.opts.LookbackBlocks + if start <= 0 { + start = 1 + } + logs := p.buffer.dequeueRange(start, latest, AllowedLogsPerUpkeep) + + // p.lggr.Debugw("got latest logs from buffer", "latest", latest, "diff", diff, "logs", len(logs)) var payloads []ocr2keepers.UpkeepPayload for _, l := range logs { log := l.log - trig := ocr2keepers.NewTrigger( - log.BlockNumber, - log.BlockHash.Hex(), - LogTriggerExtension{ - TxHash: log.TxHash.Hex(), - LogIndex: log.LogIndex, - }, - ) + trig := logToTrigger(log) checkData, err := p.packer.PackLogData(log) if err != nil { p.lggr.Warnw("failed to pack log data", "err", err, "log", log) continue } - payload := ocr2keepers.NewUpkeepPayload(l.id, logTriggerType, ocr2keepers.BlockKey(fmt.Sprintf("%d", log.BlockNumber)), trig, checkData) + payload, err := core.NewUpkeepPayload(l.upkeepID, trig, checkData) + if err != nil { + p.lggr.Warnw("failed to create upkeep payload", "err", err, "id", l.upkeepID, "trigger", trig, "checkData", checkData) + continue + } + payloads = append(payloads, payload) } @@ -162,15 +202,21 @@ func (p *logEventProvider) GetLogs(context.Context) ([]ocr2keepers.UpkeepPayload } // ReadLogs fetches the logs for the given upkeeps. -func (p *logEventProvider) ReadLogs(ctx context.Context, force bool, ids ...*big.Int) error { +func (p *logEventProvider) ReadLogs(pctx context.Context, ids ...*big.Int) error { + ctx, cancel := context.WithTimeout(pctx, readLogsTimeout) + defer cancel() + latest, err := p.poller.LatestBlock(pg.WithParentCtx(ctx)) if err != nil { return fmt.Errorf("%w: %s", ErrHeadNotAvailable, err) } - entries := p.getEntries(latest, force, ids...) + if latest == 0 { + return fmt.Errorf("%w: %s", ErrHeadNotAvailable, "latest block is 0") + } + filters := p.getFilters(latest, ids...) - err = p.readLogs(ctx, latest, entries...) - p.updateEntriesLastPoll(entries) + err = p.readLogs(ctx, latest, filters) + p.updateFiltersLastPoll(filters) // p.lggr.Debugw("read logs for entries", "latestBlock", latest, "entries", len(entries), "err", err) if err != nil { return fmt.Errorf("fetched logs with errors: %w", err) @@ -179,6 +225,10 @@ func (p *logEventProvider) ReadLogs(ctx context.Context, force bool, ids ...*big return nil } +func (p *logEventProvider) CurrentPartitionIdx() uint64 { + return atomic.LoadUint64(&p.currentPartitionIdx) +} + // scheduleReadJobs starts a scheduler that pushed ids to readQ for reading logs in the background. func (p *logEventProvider) scheduleReadJobs(pctx context.Context, execute func([]*big.Int)) error { ctx, cancel := context.WithCancel(pctx) @@ -188,14 +238,15 @@ func (p *logEventProvider) scheduleReadJobs(pctx context.Context, execute func([ defer ticker.Stop() h := sha256.New() - partitionIdx := 0 + + partitionIdx := p.CurrentPartitionIdx() for { select { case <-ticker.C: - ids := p.getPartitionIds(h, partitionIdx) + ids := p.getPartitionIds(h, int(partitionIdx)) if len(ids) > 0 { - maxBatchSize := p.opts.ReadMaxBatchSize + maxBatchSize := p.opts.ReadBatchSize for len(ids) > maxBatchSize { batch := ids[:maxBatchSize] execute(batch) @@ -205,8 +256,9 @@ func (p *logEventProvider) scheduleReadJobs(pctx context.Context, execute func([ execute(ids) } partitionIdx++ + atomic.StoreUint64(&p.currentPartitionIdx, partitionIdx) case <-ctx.Done(): - return nil + return ctx.Err() } } } @@ -221,7 +273,10 @@ func (p *logEventProvider) startReader(pctx context.Context, readQ <-chan []*big for { select { case batch := <-readQ: - if err := p.ReadLogs(ctx, true, batch...); err != nil { + if err := p.ReadLogs(ctx, batch...); err != nil { + if ctx.Err() != nil { + return + } lggr.Warnw("failed to read logs", "err", err) } case <-ctx.Done(): @@ -233,141 +288,122 @@ func (p *logEventProvider) startReader(pctx context.Context, readQ <-chan []*big // getPartitionIds returns the upkeepIDs for the given partition and the number of partitions. // Partitioning is done by hashing the upkeepID and taking the modulus of the number of partitions. func (p *logEventProvider) getPartitionIds(hashFn hash.Hash, partition int) []*big.Int { - p.lock.RLock() - defer p.lock.RUnlock() - - numOfPartitions := len(p.active) / p.opts.ReadMaxBatchSize + numOfPartitions := p.filterStore.Size() / p.opts.ReadBatchSize if numOfPartitions < 1 { numOfPartitions = 1 } partition = partition % numOfPartitions - var ids []*big.Int - for _, entry := range p.active { - if len(entry.filter.Addresses) == 0 { - continue + ids := p.filterStore.GetIDs(func(f upkeepFilter) bool { + if len(f.addr) == 0 { + return false } - n, err := hashFn.Write(entry.filter.Addresses[0].Bytes()) + n, err := hashFn.Write(f.addr) if err != nil || n == 0 { - p.lggr.Warnw("failed to hash upkeep address", "err", err, "addr", entry.filter.Addresses[0]) - continue + p.lggr.Warnw("failed to hash upkeep address", "err", err, "addr", hexutil.Encode(f.addr)) + return false } h := hashFn.Sum(nil) + defer hashFn.Reset() // taking only 6 bytes to avoid working with big numbers i := big.NewInt(0).SetBytes(h[len(h)-6:]) - if int(i.Int64())%numOfPartitions == partition { - ids = append(ids, entry.id) - } - hashFn.Reset() - } + return int(i.Int64())%numOfPartitions == partition + }) return ids } -func (p *logEventProvider) updateEntriesLastPoll(entries []*upkeepFilterEntry) { - p.lock.Lock() - defer p.lock.Unlock() - - for _, entry := range entries { - // for successful queries, the last poll block was updated - orig, ok := p.active[entry.id.String()] - if !ok { - continue // entry was removed - } - if entry.lastPollBlock == orig.lastPollBlock { - continue +func (p *logEventProvider) updateFiltersLastPoll(entries []upkeepFilter) { + p.filterStore.UpdateFilters(func(orig, f upkeepFilter) upkeepFilter { + if f.lastPollBlock > orig.lastPollBlock { + orig.lastPollBlock = f.lastPollBlock } - orig.lastPollBlock = entry.lastPollBlock - p.active[entry.id.String()] = orig - } + return orig + }, entries...) } -// getEntries returns the filters for the given upkeepIDs, +// getFilters returns the filters for the given upkeepIDs, // returns empty filter for inactive upkeeps. -func (p *logEventProvider) getEntries(latestBlock int64, force bool, ids ...*big.Int) []*upkeepFilterEntry { - p.lock.RLock() - defer p.lock.RUnlock() - - var filters []*upkeepFilterEntry - for _, id := range ids { - entry, ok := p.active[id.String()] - if !ok { // entry not found, could be inactive upkeep - p.lggr.Debugw("upkeep filter not found", "upkeep", id.String()) - filters = append(filters, &upkeepFilterEntry{id: id}) - continue +func (p *logEventProvider) getFilters(latestBlock int64, ids ...*big.Int) []upkeepFilter { + var filters []upkeepFilter + p.filterStore.RangeFiltersByIDs(func(i int, f upkeepFilter) { + if len(f.addr) == 0 { // not found + p.lggr.Debugw("upkeep filter not found", "upkeep", f.upkeepID.String()) + filters = append(filters, f) + return } - if !force && entry.lastPollBlock > latestBlock { - p.lggr.Debugw("already polled latest block", "entry.lastPollBlock", entry.lastPollBlock, "latestBlock", latestBlock, "upkeep", id.String()) - filters = append(filters, &upkeepFilterEntry{id: id, lastPollBlock: entry.lastPollBlock}) - continue + if f.configUpdateBlock > uint64(latestBlock) { + p.lggr.Debugw("upkeep config update block was created after latestBlock", "upkeep", f.upkeepID.String(), "configUpdateBlock", f.configUpdateBlock, "latestBlock", latestBlock) + filters = append(filters, upkeepFilter{upkeepID: f.upkeepID}) + return } - // recreating the struct to be thread safe - filters = append(filters, &upkeepFilterEntry{ - id: id, - filter: p.newLogFilter(id, entry.cfg), - lastPollBlock: entry.lastPollBlock, - blockLimiter: entry.blockLimiter, - }) - } + if f.lastPollBlock > latestBlock { + p.lggr.Debugw("already polled latest block", "entry.lastPollBlock", f.lastPollBlock, "latestBlock", latestBlock, "upkeep", f.upkeepID.String()) + filters = append(filters, upkeepFilter{upkeepID: f.upkeepID}) + return + } + filters = append(filters, f.Clone()) + }, ids...) return filters } // readLogs calls log poller to get the logs for the given upkeep entries. -// we use p.opts.LookbackBuffer to check for reorgs based logs. // -// TODO: batch entries by contract address and call log poller once per contract address -// NOTE: the entries are already grouped by contract address -func (p *logEventProvider) readLogs(ctx context.Context, latest int64, entries ...*upkeepFilterEntry) (merr error) { - // mainLggr := p.lggr.With("latestBlock", latest) - logBlocksLookback := p.opts.LogBlocksLookback - maxBurst := int(logBlocksLookback*2 + 1) - - for _, entry := range entries { - if len(entry.filter.Addresses) == 0 { +// Exploratory: batch filters by contract address and call log poller once per contract address +// NOTE: the filters are already grouped by contract address +func (p *logEventProvider) readLogs(ctx context.Context, latest int64, filters []upkeepFilter) (merr error) { + lookbackBlocks := p.opts.LookbackBlocks + if latest < lookbackBlocks { + // special case of a new blockchain (e.g. simulated chain) + lookbackBlocks = latest - 1 + } + // maxBurst will be used to increase the burst limit to allow a long range scan + maxBurst := int(lookbackBlocks + 1) + + for _, filter := range filters { + if len(filter.addr) == 0 { continue } - // lggr := mainLggr.With("upkeep", entry.id.String(), "addrs", entry.filter.Addresses, "sigs", entry.filter.EventSigs) - start := entry.lastPollBlock - if start == 0 || start < latest-logBlocksLookback { - // long range or first time polling, - // using a larger lookback and burst - start = latest - logBlocksLookback*2 - entry.blockLimiter.SetBurst(maxBurst) + start := filter.lastPollBlock + // range should not exceed [lookbackBlocks, latest] + if start < latest-lookbackBlocks { + start = latest - lookbackBlocks + filter.blockLimiter.SetBurst(maxBurst) } - resv := entry.blockLimiter.ReserveN(time.Now(), int(latest-start)) + + resv := filter.blockLimiter.ReserveN(time.Now(), int(latest-start)) if !resv.OK() { - merr = multierr.Append(merr, fmt.Errorf("%s: %s", BlockLimitExceeded, entry.id.String())) + merr = errors.Join(merr, fmt.Errorf("%w: %s", ErrBlockLimitExceeded, filter.upkeepID.String())) continue } - start = start - p.opts.LookbackBuffer // adding a buffer to check for reorgs - if start < 0 { - start = 0 + // adding a buffer to check for reorged logs. + start = start - p.opts.ReorgBuffer + // make sure start of the range is not before the config update block + if configUpdateBlock := int64(filter.configUpdateBlock); start < configUpdateBlock { + start = configUpdateBlock } - // lggr = lggr.With("startBlock", start) - logs, err := p.poller.LogsWithSigs(start, latest, entry.filter.EventSigs, entry.filter.Addresses[0], pg.WithParentCtx(ctx)) + logs, err := p.poller.LogsWithSigs(start, latest, filter.topics, common.BytesToAddress(filter.addr), pg.WithParentCtx(ctx)) if err != nil { - resv.Cancel() // cancels limit reservation as we failed to get logs + // cancel limit reservation as we failed to get logs + resv.Cancel() if ctx.Err() != nil { - return multierr.Append(merr, ctx.Err()) + // exit if the context was canceled + return merr } - merr = multierr.Append(merr, fmt.Errorf("failed to get logs for upkeep %s: %w", entry.id.String(), err)) + merr = errors.Join(merr, fmt.Errorf("failed to get logs for upkeep %s: %w", filter.upkeepID.String(), err)) continue } - // if this limiter's burst was set to the max, - // we need to reset it - if entry.blockLimiter.Burst() == maxBurst { - resv.Cancel() // cancel the reservation as we are resetting the burst - entry.blockLimiter.SetBurst(p.opts.BlockLimitBurst) - } - added := p.buffer.enqueue(entry.id, logs...) - // if we added logs or couldn't find, update the last poll block - if added > 0 || len(logs) == 0 { - entry.lastPollBlock = latest + // if this limiter's burst was set to the max -> + // reset it and cancel the reservation to allow further processing + if filter.blockLimiter.Burst() == maxBurst { + resv.Cancel() + filter.blockLimiter.SetBurst(p.opts.BlockLimitBurst) } - // if n := len(logs); n > 0 { - // lggr.Debugw("got logs for upkeep", "logs", n, "added", added) - // } + + p.buffer.enqueue(filter.upkeepID, logs...) + + filter.lastPollBlock = latest } return merr diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go index e8d65ee9e31..4ddc93e376b 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go @@ -2,62 +2,140 @@ package logprovider import ( "bytes" + "errors" + "fmt" "math/big" + "time" "github.com/ethereum/go-ethereum/common" - "github.com/pkg/errors" "golang.org/x/time/rate" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" ) -func (p *logEventProvider) RegisterFilter(upkeepID *big.Int, cfg LogTriggerConfig) error { +var ( + // LogRetention is the amount of time to retain logs for. + LogRetention = 24 * time.Hour +) + +func (p *logEventProvider) RefreshActiveUpkeeps(ids ...*big.Int) ([]*big.Int, error) { + if len(ids) == 0 { + return nil, nil + } + p.lggr.Debugw("Refreshing active upkeeps", "upkeeps", len(ids)) + visited := make(map[string]bool, len(ids)) + for _, id := range ids { + visited[id.String()] = false + } + inactiveIDs := p.filterStore.GetIDs(func(f upkeepFilter) bool { + uid := f.upkeepID.String() + _, ok := visited[uid] + visited[uid] = true + return !ok + }) + var merr error + if len(inactiveIDs) > 0 { + p.lggr.Debugw("Removing inactive upkeeps", "upkeeps", len(inactiveIDs)) + for _, id := range inactiveIDs { + if err := p.UnregisterFilter(id); err != nil { + merr = errors.Join(merr, fmt.Errorf("failed to unregister filter: %s", id.String())) + } + } + } + var newIDs []*big.Int + for id, ok := range visited { + if !ok { + uid, _ := new(big.Int).SetString(id, 10) + newIDs = append(newIDs, uid) + } + } + + return newIDs, merr +} + +func (p *logEventProvider) RegisterFilter(opts FilterOptions) error { + upkeepID, cfg := opts.UpkeepID, opts.TriggerConfig if err := p.validateLogTriggerConfig(cfg); err != nil { - return errors.Wrap(err, "invalid log trigger config") + return fmt.Errorf("invalid log trigger config: %w", err) } - filter := p.newLogFilter(upkeepID, cfg) + lpFilter := p.newLogFilter(upkeepID, cfg) - // TODO: optimize locking, currently we lock the whole map while registering the filter - p.lock.Lock() - defer p.lock.Unlock() + // using lock to facilitate multiple events causing filter registration + // at the same time. + // Exploratory: consider using a q to handle registration requests + p.registerLock.Lock() + defer p.registerLock.Unlock() - uid := upkeepID.String() - if _, ok := p.active[uid]; ok { - // TODO: check for updates - return errors.Errorf("filter for upkeep with id %s already registered", uid) + var filter upkeepFilter + currentFilter := p.filterStore.Get(upkeepID) + if currentFilter != nil { + if currentFilter.configUpdateBlock > opts.UpdateBlock { + // already registered with a config from a higher block number + return fmt.Errorf("filter for upkeep with id %s already registered with newer config", upkeepID.String()) + } else if currentFilter.configUpdateBlock == opts.UpdateBlock { + // already registered with the same config + p.lggr.Debugf("filter for upkeep with id %s already registered with the same config", upkeepID.String()) + return nil + } + // removing filter so we can recreate it with updated values + err := p.poller.UnregisterFilter(p.filterName(currentFilter.upkeepID)) + if err != nil { + return fmt.Errorf("failed to unregister upkeep filter %s for update: %w", upkeepID.String(), err) + } + filter = *currentFilter + } else { // new filter + filter = upkeepFilter{ + upkeepID: upkeepID, + blockLimiter: rate.NewLimiter(p.opts.BlockRateLimit, p.opts.BlockLimitBurst), + } } - if err := p.poller.RegisterFilter(filter); err != nil { - return errors.Wrap(err, "failed to register upkeep filter") + filter.lastPollBlock = 0 + filter.lastRePollBlock = 0 + filter.configUpdateBlock = opts.UpdateBlock + filter.addr = lpFilter.Addresses[0].Bytes() + filter.topics = make([]common.Hash, len(lpFilter.EventSigs)) + copy(filter.topics, lpFilter.EventSigs) + + if err := p.register(lpFilter, filter); err != nil { + return fmt.Errorf("failed to register upkeep filter %s: %w", filter.upkeepID.String(), err) } - p.active[uid] = upkeepFilterEntry{ - id: upkeepID, - filter: filter, - cfg: cfg, - blockLimiter: rate.NewLimiter(p.opts.BlockRateLimit, p.opts.BlockLimitBurst), + + return nil +} + +// register registers the upkeep filter with the log poller and adds it to the filter store. +func (p *logEventProvider) register(lpFilter logpoller.Filter, ufilter upkeepFilter) error { + if err := p.poller.RegisterFilter(lpFilter); err != nil { + return err } + p.filterStore.AddActiveUpkeeps(ufilter) + p.poller.ReplayAsync(int64(ufilter.configUpdateBlock)) return nil } func (p *logEventProvider) UnregisterFilter(upkeepID *big.Int) error { - err := p.poller.UnregisterFilter(p.filterName(upkeepID), nil) - if err == nil { - p.lock.Lock() - delete(p.active, upkeepID.String()) - p.lock.Unlock() + err := p.poller.UnregisterFilter(p.filterName(upkeepID)) + if err != nil { + // TODO: mark as removed in filter store, so we'll + // automatically retry on next refresh + return fmt.Errorf("failed to unregister upkeep filter %s: %w", upkeepID.String(), err) } - return errors.Wrap(err, "failed to unregister upkeep filter") + p.filterStore.RemoveActiveUpkeeps(upkeepFilter{ + upkeepID: upkeepID, + }) + return nil } // newLogFilter creates logpoller.Filter from the given upkeep config func (p *logEventProvider) newLogFilter(upkeepID *big.Int, cfg LogTriggerConfig) logpoller.Filter { - sigs := p.getFiltersBySelector(cfg.FilterSelector, cfg.Topic1[:], cfg.Topic2[:], cfg.Topic3[:]) - sigs = append([]common.Hash{common.BytesToHash(cfg.Topic0[:])}, sigs...) + topics := p.getFiltersBySelector(cfg.FilterSelector, cfg.Topic1[:], cfg.Topic2[:], cfg.Topic3[:]) + topics = append([]common.Hash{common.BytesToHash(cfg.Topic0[:])}, topics...) return logpoller.Filter{ Name: p.filterName(upkeepID), - EventSigs: sigs, + EventSigs: topics, Addresses: []common.Address{cfg.ContractAddress}, - Retention: p.opts.LogRetention, + Retention: LogRetention, } } diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle_test.go index 356df382e3b..3f9ddaa5af3 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle_test.go @@ -5,20 +5,24 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" ) func TestLogEventProvider_LifeCycle(t *testing.T) { tests := []struct { - name string - errored bool - upkeepID *big.Int - upkeepCfg LogTriggerConfig - mockPoller bool + name string + errored bool + upkeepID *big.Int + upkeepCfg LogTriggerConfig + cfgUpdateBlock uint64 + mockPoller bool + unregister bool }{ { "new upkeep", @@ -28,13 +32,17 @@ func TestLogEventProvider_LifeCycle(t *testing.T) { ContractAddress: common.BytesToAddress(common.LeftPadBytes([]byte{1, 2, 3, 4}, 20)), Topic0: common.BytesToHash(common.LeftPadBytes([]byte{1, 2, 3, 4}, 32)), }, + uint64(1), true, + false, }, { "empty config", true, big.NewInt(111), LogTriggerConfig{}, + uint64(0), + false, false, }, { @@ -45,29 +53,99 @@ func TestLogEventProvider_LifeCycle(t *testing.T) { ContractAddress: common.BytesToAddress(common.LeftPadBytes([]byte{}, 20)), Topic0: common.BytesToHash(common.LeftPadBytes([]byte{}, 32)), }, + uint64(2), + false, + false, + }, + { + "existing config", + true, + big.NewInt(111), + LogTriggerConfig{ + ContractAddress: common.BytesToAddress(common.LeftPadBytes([]byte{1, 2, 3, 4}, 20)), + Topic0: common.BytesToHash(common.LeftPadBytes([]byte{1, 2, 3, 4}, 32)), + }, + uint64(0), + true, + false, + }, + { + "existing config with newer block", false, + big.NewInt(111), + LogTriggerConfig{ + ContractAddress: common.BytesToAddress(common.LeftPadBytes([]byte{1, 2, 3, 4}, 20)), + Topic0: common.BytesToHash(common.LeftPadBytes([]byte{1, 2, 3, 4}, 32)), + }, + uint64(2), + true, + true, }, } + mp := new(mocks.LogPoller) + mp.On("RegisterFilter", mock.Anything).Return(nil) + mp.On("UnregisterFilter", mock.Anything).Return(nil) + mp.On("ReplayAsync", mock.Anything).Return(nil) + p := NewLogProvider(logger.TestLogger(t), mp, &mockedPacker{}, NewUpkeepFilterStore(), nil) + for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - mp := new(mocks.LogPoller) - if tc.mockPoller { - mp.On("RegisterFilter", mock.Anything).Return(nil) - mp.On("UnregisterFilter", mock.Anything, mock.Anything).Return(nil) - } - p := New(logger.TestLogger(t), mp, &mockedPacker{}, nil) - err := p.RegisterFilter(tc.upkeepID, tc.upkeepCfg) + err := p.RegisterFilter(FilterOptions{ + UpkeepID: tc.upkeepID, + TriggerConfig: tc.upkeepCfg, + UpdateBlock: tc.cfgUpdateBlock, + }) if tc.errored { require.Error(t, err) } else { require.NoError(t, err) - require.NoError(t, p.UnregisterFilter(tc.upkeepID)) + if tc.unregister { + require.NoError(t, p.UnregisterFilter(tc.upkeepID)) + } } }) } } +func TestEventLogProvider_RefreshActiveUpkeeps(t *testing.T) { + mp := new(mocks.LogPoller) + mp.On("RegisterFilter", mock.Anything).Return(nil) + mp.On("UnregisterFilter", mock.Anything).Return(nil) + mp.On("ReplayAsync", mock.Anything).Return(nil) + + p := NewLogProvider(logger.TestLogger(t), mp, &mockedPacker{}, NewUpkeepFilterStore(), nil) + + require.NoError(t, p.RegisterFilter(FilterOptions{ + UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1111").BigInt(), + TriggerConfig: LogTriggerConfig{ + ContractAddress: common.BytesToAddress(common.LeftPadBytes([]byte{1, 2, 3, 4}, 20)), + Topic0: common.BytesToHash(common.LeftPadBytes([]byte{1, 2, 3, 4}, 32)), + }, + UpdateBlock: uint64(0), + })) + require.NoError(t, p.RegisterFilter(FilterOptions{ + UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "2222").BigInt(), + TriggerConfig: LogTriggerConfig{ + ContractAddress: common.BytesToAddress(common.LeftPadBytes([]byte{1, 2, 3, 4}, 20)), + Topic0: common.BytesToHash(common.LeftPadBytes([]byte{1, 2, 3, 4}, 32)), + }, + UpdateBlock: uint64(0), + })) + require.Equal(t, 2, p.filterStore.Size()) + + newIds, err := p.RefreshActiveUpkeeps() + require.NoError(t, err) + require.Len(t, newIds, 0) + newIds, err = p.RefreshActiveUpkeeps( + core.GenUpkeepID(ocr2keepers.LogTrigger, "2222").BigInt(), + core.GenUpkeepID(ocr2keepers.LogTrigger, "1234").BigInt(), + core.GenUpkeepID(ocr2keepers.LogTrigger, "123").BigInt()) + require.NoError(t, err) + require.Len(t, newIds, 2) + require.Equal(t, 1, p.filterStore.Size()) +} + func TestLogEventProvider_GetFiltersBySelector(t *testing.T) { var zeroBytes [32]byte tests := []struct { @@ -183,7 +261,7 @@ func TestLogEventProvider_GetFiltersBySelector(t *testing.T) { }, } - p := New(logger.TestLogger(t), nil, &mockedPacker{}, nil) + p := NewLogProvider(logger.TestLogger(t), nil, &mockedPacker{}, NewUpkeepFilterStore(), nil) for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_opts.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_opts.go index 7907bc1f21b..1a09e99ec08 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_opts.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_opts.go @@ -8,63 +8,45 @@ import ( // LogEventProviderOptions holds the options for the log event provider. type LogEventProviderOptions struct { - // LogRetention is the amount of time to retain logs for. - LogRetention time.Duration - // AllowedLogsPerBlock is the maximum number of logs allowed per block in the buffer. - BufferMaxBlockSize int - // LogBufferSize is the number of blocks in the buffer. - LogBufferSize int - // AllowedLogsPerBlock is the maximum number of logs allowed per block & upkeep in the buffer. - AllowedLogsPerBlock int - // LogBlocksLookback is the number of blocks to look back for logs. - LogBlocksLookback int64 - // LookbackBuffer is the number of blocks to add as a buffer to the lookback. - LookbackBuffer int64 - // BlockRateLimit is the rate limit for fetching logs per block. + // LookbackBlocks is the number of blocks to look back for logs. + LookbackBlocks int64 + // ReorgBuffer is the number of blocks to add as a buffer to the lookback. + ReorgBuffer int64 + // BlockRateLimit is the rate limit on the range of blocks the we fetch logs for. BlockRateLimit rate.Limit - // BlockLimitBurst is the burst limit for fetching logs per block. + // BlockLimitBurst is the burst upper limit on the range of blocks the we fetch logs for. BlockLimitBurst int // ReadInterval is the interval to fetch logs in the background. ReadInterval time.Duration - // ReadMaxBatchSize is the max number of items in one read batch / partition. - ReadMaxBatchSize int + // ReadBatchSize is the max number of items in one read batch / partition. + ReadBatchSize int // Readers is the number of reader workers to spawn. Readers int } // Defaults sets the default values for the options. func (o *LogEventProviderOptions) Defaults() { - if o.LogRetention == 0 { - o.LogRetention = 24 * time.Hour + if o.LookbackBlocks == 0 { + // TODO: Ensure lookback blocks is at least as large as Finality Depth to + // ensure recoverer does not go beyond finality depth + o.LookbackBlocks = 200 } - if o.BufferMaxBlockSize == 0 { - o.BufferMaxBlockSize = 1024 - } - if o.AllowedLogsPerBlock == 0 { - o.AllowedLogsPerBlock = 128 - } - if o.LogBlocksLookback == 0 { - o.LogBlocksLookback = 512 - } - if o.LogBufferSize == 0 { - o.LogBufferSize = int(o.LogBlocksLookback * 3) - } - if o.LookbackBuffer == 0 { - o.LookbackBuffer = 32 + if o.ReorgBuffer == 0 { + o.ReorgBuffer = 32 } if o.BlockRateLimit == 0 { o.BlockRateLimit = rate.Every(time.Second) } if o.BlockLimitBurst == 0 { - o.BlockLimitBurst = int(o.LogBlocksLookback) + o.BlockLimitBurst = int(o.LookbackBlocks) } if o.ReadInterval == 0 { o.ReadInterval = time.Second } - if o.ReadMaxBatchSize == 0 { - o.ReadMaxBatchSize = 32 + if o.ReadBatchSize == 0 { + o.ReadBatchSize = 32 } if o.Readers == 0 { - o.Readers = 2 + o.Readers = 4 } } diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_test.go index 2e7c10caab1..7c1aa84ac4b 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_test.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "math/big" + "runtime" "testing" "time" @@ -11,7 +12,7 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" @@ -20,68 +21,66 @@ import ( "golang.org/x/time/rate" ) -func TestLogEventProvider_GetEntries(t *testing.T) { - p := New(logger.TestLogger(t), nil, &mockedPacker{}, nil) +func TestLogEventProvider_GetFilters(t *testing.T) { + p := NewLogProvider(logger.TestLogger(t), nil, &mockedPacker{}, NewUpkeepFilterStore(), nil) _, f := newEntry(p, 1) - p.lock.Lock() - p.active[f.id.String()] = f - p.lock.Unlock() + p.filterStore.AddActiveUpkeeps(f) - t.Run("no entries", func(t *testing.T) { - entries := p.getEntries(0, false, big.NewInt(0)) - require.Len(t, entries, 1) - require.Equal(t, len(entries[0].filter.Addresses), 0) + t.Run("no filters", func(t *testing.T) { + filters := p.getFilters(0, big.NewInt(0)) + require.Len(t, filters, 1) + require.Equal(t, len(filters[0].addr), 0) }) - t.Run("has entry with lower lastPollBlock", func(t *testing.T) { - entries := p.getEntries(0, false, f.id) - require.Len(t, entries, 1) - require.Greater(t, len(entries[0].filter.Addresses), 0) - entries = p.getEntries(10, false, f.id) - require.Len(t, entries, 1) - require.Greater(t, len(entries[0].filter.Addresses), 0) + t.Run("has filter with lower lastPollBlock", func(t *testing.T) { + filters := p.getFilters(0, f.upkeepID) + require.Len(t, filters, 1) + require.Greater(t, len(filters[0].addr), 0) + filters = p.getFilters(10, f.upkeepID) + require.Len(t, filters, 1) + require.Greater(t, len(filters[0].addr), 0) }) - t.Run("has entry with higher lastPollBlock", func(t *testing.T) { + t.Run("has filter with higher lastPollBlock", func(t *testing.T) { _, f := newEntry(p, 2) f.lastPollBlock = 3 - p.lock.Lock() - p.active[f.id.String()] = f - p.lock.Unlock() + p.filterStore.AddActiveUpkeeps(f) - entries := p.getEntries(1, false, f.id) - require.Len(t, entries, 1) - require.Equal(t, len(entries[0].filter.Addresses), 0) + filters := p.getFilters(1, f.upkeepID) + require.Len(t, filters, 1) + require.Equal(t, len(filters[0].addr), 0) + }) - entries = p.getEntries(1, true, f.id) - require.Len(t, entries, 1) - require.Greater(t, len(entries[0].filter.Addresses), 0) + t.Run("has filter with higher configUpdateBlock", func(t *testing.T) { + _, f := newEntry(p, 2) + f.configUpdateBlock = 3 + p.filterStore.AddActiveUpkeeps(f) + + filters := p.getFilters(1, f.upkeepID) + require.Len(t, filters, 1) + require.Equal(t, len(filters[0].addr), 0) }) } func TestLogEventProvider_UpdateEntriesLastPoll(t *testing.T) { - p := New(logger.TestLogger(t), nil, &mockedPacker{}, nil) + p := NewLogProvider(logger.TestLogger(t), nil, &mockedPacker{}, NewUpkeepFilterStore(), nil) n := 10 - entries := map[string]upkeepFilterEntry{} + // entries := map[string]upkeepFilter{} for i := 0; i < n; i++ { _, f := newEntry(p, i+1) - entries[f.id.String()] = f + p.filterStore.AddActiveUpkeeps(f) } - p.lock.Lock() - p.active = entries - p.lock.Unlock() t.Run("no entries", func(t *testing.T) { _, f := newEntry(p, n*2) f.lastPollBlock = 10 - p.updateEntriesLastPoll([]*upkeepFilterEntry{&f}) + p.updateFiltersLastPoll([]upkeepFilter{f}) - p.lock.RLock() - defer p.lock.RUnlock() - for _, f := range p.active { + filters := p.filterStore.GetFilters(nil) + for _, f := range filters { require.Equal(t, int64(0), f.lastPollBlock) } }) @@ -91,22 +90,20 @@ func TestLogEventProvider_UpdateEntriesLastPoll(t *testing.T) { f2.lastPollBlock = 10 _, f1 := newEntry(p, n-1) f1.lastPollBlock = 10 - p.updateEntriesLastPoll([]*upkeepFilterEntry{&f1, &f2}) - - p.lock.RLock() - e := p.active[f1.id.String()] - require.Equal(t, int64(10), e.lastPollBlock) - e = p.active[f2.id.String()] - require.Equal(t, int64(10), e.lastPollBlock) - p.lock.RUnlock() + p.updateFiltersLastPoll([]upkeepFilter{f1, f2}) + + p.filterStore.RangeFiltersByIDs(func(_ int, f upkeepFilter) { + require.Equal(t, int64(10), f.lastPollBlock) + }, f1.upkeepID, f2.upkeepID) + // update with same block - p.updateEntriesLastPoll([]*upkeepFilterEntry{&f1}) + p.updateFiltersLastPoll([]upkeepFilter{f1}) + // checking other entries are not updated _, f := newEntry(p, 1) - p.lock.RLock() - defer p.lock.RUnlock() - e = p.active[f.id.String()] - require.Equal(t, int64(0), e.lastPollBlock) + p.filterStore.RangeFiltersByIDs(func(_ int, f upkeepFilter) { + require.Equal(t, int64(0), f.lastPollBlock) + }, f.upkeepID) }) } @@ -180,20 +177,18 @@ func TestLogEventProvider_ScheduleReadJobs(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - tick := 10 * time.Millisecond - p := New(logger.TestLogger(t), mp, &mockedPacker{}, &LogEventProviderOptions{ - ReadMaxBatchSize: tc.maxBatchSize, - ReadInterval: tick, + readInterval := 10 * time.Millisecond + p := NewLogProvider(logger.TestLogger(t), mp, &mockedPacker{}, NewUpkeepFilterStore(), &LogEventProviderOptions{ + ReadBatchSize: tc.maxBatchSize, + ReadInterval: readInterval, }) var ids []*big.Int - p.lock.Lock() for i, id := range tc.ids { _, f := newEntry(p, id, tc.addrs[i]) - p.active[f.id.String()] = f - ids = append(ids, f.id) + p.filterStore.AddActiveUpkeeps(f) + ids = append(ids, f.upkeepID) } - p.lock.Unlock() reads := make(chan []*big.Int, 100) @@ -207,9 +202,9 @@ func TestLogEventProvider_ScheduleReadJobs(t *testing.T) { }) }(ctx) - timeout := tick*time.Duration((1+len(tc.ids)/tc.maxBatchSize))*4 + 1 - <-time.After(timeout) - timeoutTicker := time.NewTicker(timeout) + batches := (len(tc.ids) / tc.maxBatchSize) + 1 + + timeoutTicker := time.NewTicker(readInterval * time.Duration(batches*10)) defer timeoutTicker.Stop() got := map[string]int{} @@ -225,12 +220,19 @@ func TestLogEventProvider_ScheduleReadJobs(t *testing.T) { } case <-ctx.Done(): break readLoop + default: + if p.CurrentPartitionIdx() > uint64(batches+1) { + break readLoop + } } + runtime.Gosched() } - require.Len(t, got, len(ids)) + require.Equal(t, len(ids), len(got)) for _, id := range ids { - require.GreaterOrEqual(t, got[id.String()], 1, "id %s", id.String()) + _, ok := got[id.String()] + require.True(t, ok, "id not found %s", id.String()) + require.GreaterOrEqual(t, got[id.String()], 1, "id don't have schdueled job %s", id.String()) } }) } @@ -243,6 +245,7 @@ func TestLogEventProvider_ReadLogs(t *testing.T) { mp := new(mocks.LogPoller) mp.On("RegisterFilter", mock.Anything).Return(nil) + mp.On("ReplayAsync", mock.Anything).Return() mp.On("UnregisterFilter", mock.Anything, mock.Anything).Return(nil) mp.On("LatestBlock", mock.Anything).Return(int64(1), nil) mp.On("LogsWithSigs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]logpoller.Log{ @@ -252,23 +255,26 @@ func TestLogEventProvider_ReadLogs(t *testing.T) { }, }, nil) - p := New(logger.TestLogger(t), mp, &mockedPacker{}, nil) + p := NewLogProvider(logger.TestLogger(t), mp, &mockedPacker{}, NewUpkeepFilterStore(), nil) var ids []*big.Int for i := 0; i < 10; i++ { cfg, f := newEntry(p, i+1) - ids = append(ids, f.id) - require.NoError(t, p.RegisterFilter(f.id, cfg)) + ids = append(ids, f.upkeepID) + require.NoError(t, p.RegisterFilter(FilterOptions{ + UpkeepID: f.upkeepID, + TriggerConfig: cfg, + })) } t.Run("no entries", func(t *testing.T) { - require.NoError(t, p.ReadLogs(ctx, false, big.NewInt(999999))) + require.NoError(t, p.ReadLogs(ctx, big.NewInt(999999))) logs := p.buffer.peek(10) require.Len(t, logs, 0) }) t.Run("has entries", func(t *testing.T) { - require.NoError(t, p.ReadLogs(ctx, true, ids[:2]...)) + require.NoError(t, p.ReadLogs(ctx, ids[:2]...)) logs := p.buffer.peek(10) require.Len(t, logs, 2) }) @@ -277,9 +283,11 @@ func TestLogEventProvider_ReadLogs(t *testing.T) { } -func newEntry(p *logEventProvider, i int, args ...string) (LogTriggerConfig, upkeepFilterEntry) { - id := ocr2keepers.UpkeepIdentifier(append(common.LeftPadBytes([]byte{1}, 16), []byte(fmt.Sprintf("%d", i))...)) - uid := big.NewInt(0).SetBytes(id) +func newEntry(p *logEventProvider, i int, args ...string) (LogTriggerConfig, upkeepFilter) { + idBytes := append(common.LeftPadBytes([]byte{1}, 16), []byte(fmt.Sprintf("%d", i))...) + id := ocr2keepers.UpkeepIdentifier{} + copy(id[:], idBytes) + uid := id.BigInt() for len(args) < 2 { args = append(args, "0x3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d") } @@ -289,12 +297,14 @@ func newEntry(p *logEventProvider, i int, args ...string) (LogTriggerConfig, upk FilterSelector: 0, Topic0: common.HexToHash(topic0), } - f := upkeepFilterEntry{ - id: uid, - filter: p.newLogFilter(uid, cfg), - cfg: cfg, - blockLimiter: rate.NewLimiter(p.opts.BlockRateLimit, p.opts.BlockLimitBurst), - lastPollBlock: 0, + filter := p.newLogFilter(uid, cfg) + topics := make([]common.Hash, len(filter.EventSigs)) + copy(topics, filter.EventSigs) + f := upkeepFilter{ + upkeepID: uid, + addr: filter.Addresses[0].Bytes(), + topics: topics, + blockLimiter: rate.NewLimiter(p.opts.BlockRateLimit, p.opts.BlockLimitBurst), } return cfg, f } diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go new file mode 100644 index 00000000000..6dd5f8fe56a --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go @@ -0,0 +1,520 @@ +package logprovider + +import ( + "context" + "crypto/rand" + "errors" + "fmt" + "io" + "math/big" + "sort" + "sync" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/common" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" +) + +var ( + ErrNotFound = errors.New("not found") + DefaultRecoveryInterval = 5 * time.Second + // TODO: Reduce these intervals to allow sending same proposals again if they were not fulfilled + RecoveryCacheTTL = 24*time.Hour - time.Second + GCInterval = time.Hour + + recoveryBatchSize = 10 + recoveryLogsBuffer = int64(50) +) + +type LogRecoverer interface { + ocr2keepers.RecoverableProvider + GetProposalData(context.Context, ocr2keepers.CoordinatedBlockProposal) ([]byte, error) + + Start(context.Context) error + io.Closer +} + +// TODO: Ensure that the logs enqueued into pending reach a final state +type logRecoverer struct { + lggr logger.Logger + + cancel context.CancelFunc + + lookbackBlocks *atomic.Int64 + blockTime *atomic.Int64 + + interval time.Duration + lock sync.RWMutex + + pending []ocr2keepers.UpkeepPayload + visited map[string]time.Time + + filterStore UpkeepFilterStore + states core.UpkeepStateReader + packer LogDataPacker + poller logpoller.LogPoller + client client.Client +} + +var _ LogRecoverer = &logRecoverer{} + +func NewLogRecoverer(lggr logger.Logger, poller logpoller.LogPoller, client client.Client, stateStore core.UpkeepStateReader, packer LogDataPacker, filterStore UpkeepFilterStore, interval time.Duration, lookbackBlocks int64) *logRecoverer { + if interval == 0 { + interval = DefaultRecoveryInterval + } + + rec := &logRecoverer{ + lggr: lggr.Named("LogRecoverer"), + + blockTime: &atomic.Int64{}, + lookbackBlocks: &atomic.Int64{}, + interval: interval, + + pending: make([]ocr2keepers.UpkeepPayload, 0), + visited: make(map[string]time.Time), + poller: poller, + filterStore: filterStore, + states: stateStore, + packer: packer, + client: client, + } + + rec.lookbackBlocks.Store(lookbackBlocks) + rec.blockTime.Store(int64(defaultBlockTime)) + + return rec +} + +func (r *logRecoverer) Start(pctx context.Context) error { + ctx, cancel := context.WithCancel(context.Background()) + + r.lock.Lock() + if r.cancel != nil { + r.lock.Unlock() + cancel() // Cancel the created context + return errors.New("already started") + } + r.cancel = cancel + r.lock.Unlock() + + blockTimeResolver := newBlockTimeResolver(r.poller) + blockTime, err := blockTimeResolver.BlockTime(ctx, defaultSampleSize) + if err != nil { + // TODO: TBD exit or just log a warning + // return fmt.Errorf("failed to compute block time: %w", err) + r.lggr.Warnw("failed to compute block time", "err", err) + } + if blockTime > 0 { + r.blockTime.Store(int64(blockTime)) + } + + r.lggr.Infow("starting log recoverer", "blockTime", r.blockTime.Load(), "lookbackBlocks", r.lookbackBlocks.Load(), "interval", r.interval) + + { + go func(ctx context.Context, interval time.Duration) { + ticker := time.NewTicker(interval) + defer ticker.Stop() + + gcTicker := time.NewTicker(GCInterval) + defer gcTicker.Stop() + + for { + select { + case <-ticker.C: + if err := r.recover(ctx); err != nil { + r.lggr.Warnw("failed to recover logs", "err", err) + } + case <-gcTicker.C: + r.clean(ctx) + case <-ctx.Done(): + return + } + } + }(ctx, r.interval) + } + + return nil +} + +func (r *logRecoverer) Close() error { + r.lock.Lock() + defer r.lock.Unlock() + + if cancel := r.cancel; cancel != nil { + r.cancel = nil + cancel() + } else { + return errors.New("already stopped") + } + return nil +} + +func (r *logRecoverer) GetProposalData(ctx context.Context, proposal ocr2keepers.CoordinatedBlockProposal) ([]byte, error) { + switch core.GetUpkeepType(proposal.UpkeepID) { + case ocr2keepers.LogTrigger: + return r.getLogTriggerCheckData(ctx, proposal) + default: + return []byte{}, errors.New("not a log trigger upkeep ID") + } +} + +func (r *logRecoverer) getLogTriggerCheckData(ctx context.Context, proposal ocr2keepers.CoordinatedBlockProposal) ([]byte, error) { + if !r.filterStore.Has(proposal.UpkeepID.BigInt()) { + return nil, fmt.Errorf("filter not found for upkeep %v", proposal.UpkeepID) + } + latest, err := r.poller.LatestBlock(pg.WithParentCtx(ctx)) + if err != nil { + return nil, err + } + + // TODO: Ensure start block is above upkeep creation block + start, offsetBlock := r.getRecoveryWindow(latest) + if proposal.Trigger.LogTriggerExtension == nil { + return nil, errors.New("missing log trigger extension") + } + logBlock := int64(proposal.Trigger.LogTriggerExtension.BlockNumber) + if logBlock == 0 { + var number *big.Int + number, _, err = r.getTxBlock(proposal.Trigger.LogTriggerExtension.TxHash) + if err != nil { + return nil, err + } + if number == nil { + return nil, errors.New("failed to get tx block") + } + logBlock = number.Int64() + } + if isRecoverable := logBlock < offsetBlock && logBlock > start; !isRecoverable { + return nil, errors.New("log block is not recoverable") + } + upkeepStates, err := r.states.SelectByWorkIDsInRange(ctx, int64(logBlock)-1, offsetBlock, proposal.WorkID) + if err != nil { + return nil, err + } + + for _, upkeepState := range upkeepStates { + switch upkeepState { + case ocr2keepers.Performed, ocr2keepers.Ineligible: + return nil, errors.New("upkeep state is not recoverable") + default: + // we can proceed + } + } + + var filter upkeepFilter + r.filterStore.RangeFiltersByIDs(func(i int, f upkeepFilter) { + filter = f + }, proposal.UpkeepID.BigInt()) + + if len(filter.addr) == 0 { + return nil, fmt.Errorf("invalid filter found for upkeepID %s", proposal.UpkeepID.String()) + } + + logs, err := r.poller.LogsWithSigs(logBlock-1, logBlock+1, filter.topics, common.BytesToAddress(filter.addr), pg.WithParentCtx(ctx)) + if err != nil { + return nil, fmt.Errorf("could not read logs: %w", err) + } + + for _, log := range logs { + trigger := logToTrigger(log) + // use coordinated proposal block number as checkblock/hash + trigger.BlockHash = proposal.Trigger.BlockHash + trigger.BlockNumber = proposal.Trigger.BlockNumber + wid := core.UpkeepWorkID(proposal.UpkeepID, trigger) + if wid == proposal.WorkID { + r.lggr.Debugw("found log for proposal", "upkeepId", proposal.UpkeepID, "trigger.ext", trigger.LogTriggerExtension) + checkData, err := r.packer.PackLogData(log) + if err != nil { + return nil, fmt.Errorf("failed to pack log data: %w", err) + } + return checkData, nil + } + } + return nil, fmt.Errorf("no log found for upkeepID %v and trigger %+v", proposal.UpkeepID, proposal.Trigger) +} + +func (r *logRecoverer) getTxBlock(txHash common.Hash) (*big.Int, common.Hash, error) { + // TODO: do manual eth_getTransactionReceipt call to get block number and hash + txr, err := r.client.TransactionReceipt(context.Background(), txHash) + if err != nil { + return nil, common.Hash{}, err + } + + return txr.BlockNumber, txr.BlockHash, nil +} + +func (r *logRecoverer) GetRecoveryProposals(ctx context.Context) ([]ocr2keepers.UpkeepPayload, error) { + r.lock.Lock() + defer r.lock.Unlock() + + if len(r.pending) == 0 { + return nil, nil + } + + logsCount := map[string]int{} + + var results, pending []ocr2keepers.UpkeepPayload + for _, payload := range r.pending { + uid := payload.UpkeepID.String() + if logsCount[uid] >= AllowedLogsPerUpkeep { + pending = append(pending, payload) + continue + } + logsCount[uid]++ + results = append(results, payload) + } + r.pending = pending + + r.lggr.Debugf("found %d pending payloads", len(pending)) + + return results, nil +} + +func (r *logRecoverer) recover(ctx context.Context) error { + latest, err := r.poller.LatestBlock(pg.WithParentCtx(ctx)) + if err != nil { + return fmt.Errorf("%w: %s", ErrHeadNotAvailable, err) + } + + start, offsetBlock := r.getRecoveryWindow(latest) + if offsetBlock < 0 { + // too soon to recover, we don't have enough blocks + return nil + } + if start < 0 { + start = 0 + } + + filters := r.getFilterBatch(offsetBlock) + if len(filters) == 0 { + return nil + } + + r.lggr.Debugw("recovering logs", "filters", filters, "startBlock", start, "offsetBlock", offsetBlock, "latestBlock", latest) + + var wg sync.WaitGroup + for _, f := range filters { + wg.Add(1) + go func(f upkeepFilter) { + defer wg.Done() + if err := r.recoverFilter(ctx, f, start, offsetBlock); err != nil { + r.lggr.Debugw("error recovering filter", "err", err.Error()) + } + }(f) + } + wg.Wait() + + return nil +} + +// recoverFilter recovers logs for a single upkeep filter. +func (r *logRecoverer) recoverFilter(ctx context.Context, f upkeepFilter, startBlock, offsetBlock int64) error { + start := f.lastRePollBlock + // ensure we don't recover logs from before the filter was created + // NOTE: we expect that filter with configUpdateBlock > offsetBlock were already filtered out. + if configUpdateBlock := int64(f.configUpdateBlock); start < configUpdateBlock { + start = configUpdateBlock + } + if start < startBlock { + start = startBlock + } + end := start + recoveryLogsBuffer + if end > offsetBlock { + end = offsetBlock + } + // we expect start to be > offsetBlock in any case + logs, err := r.poller.LogsWithSigs(start, end, f.topics, common.BytesToAddress(f.addr), pg.WithParentCtx(ctx)) + if err != nil { + return fmt.Errorf("could not read logs: %w", err) + } + + workIDs := make([]string, 0) + for _, log := range logs { + trigger := logToTrigger(log) + upkeepId := &ocr2keepers.UpkeepIdentifier{} + ok := upkeepId.FromBigInt(f.upkeepID) + if !ok { + r.lggr.Warnw("failed to convert upkeepID to UpkeepIdentifier", "upkeepID", f.upkeepID) + continue + } + workIDs = append(workIDs, core.UpkeepWorkID(*upkeepId, trigger)) + } + + states, err := r.states.SelectByWorkIDsInRange(ctx, start, end, workIDs...) + if err != nil { + return fmt.Errorf("could not read states: %w", err) + } + if len(logs) != len(states) { + return fmt.Errorf("log and state count mismatch: %d != %d", len(logs), len(states)) + } + filteredLogs := r.filterFinalizedStates(f, logs, states) + + added, alreadyPending := r.populatePending(f, filteredLogs) + if added > 0 { + r.lggr.Debugw("found missed logs", "count", added, "upkeepID", f.upkeepID) + } else if alreadyPending == 0 { + r.filterStore.UpdateFilters(func(uf1, uf2 upkeepFilter) upkeepFilter { + uf1.lastRePollBlock = end + return uf1 + }, f) + } + + return nil +} + +// populatePending adds the logs to the pending list if they are not already pending. +// returns the number of logs added and the number of logs that were already pending. +func (r *logRecoverer) populatePending(f upkeepFilter, filteredLogs []logpoller.Log) (int, int) { + r.lock.Lock() + defer r.lock.Unlock() + + pendingSizeBefore := len(r.pending) + alreadyPending := 0 + for _, log := range filteredLogs { + trigger := logToTrigger(log) + // Set the checkBlock and Hash to zero so that the checkPipeline uses the latest block + trigger.BlockHash = [32]byte{} + trigger.BlockNumber = 0 + upkeepId := &ocr2keepers.UpkeepIdentifier{} + ok := upkeepId.FromBigInt(f.upkeepID) + if !ok { + r.lggr.Warnw("failed to convert upkeepID to UpkeepIdentifier", "upkeepID", f.upkeepID) + continue + } + wid := core.UpkeepWorkID(*upkeepId, trigger) + if _, ok := r.visited[wid]; ok { + alreadyPending++ + continue + } + checkData, err := r.packer.PackLogData(log) + if err != nil { + r.lggr.Warnw("failed to pack log data", "err", err, "log", log) + continue + } + payload, err := core.NewUpkeepPayload(f.upkeepID, trigger, checkData) + if err != nil { + r.lggr.Warnw("failed to create payload", "err", err, "log", log) + continue + } + // r.lggr.Debugw("adding a payload to pending", "payload", payload) + r.visited[wid] = time.Now() + r.pending = append(r.pending, payload) + } + return len(r.pending) - pendingSizeBefore, alreadyPending +} + +// filterFinalizedStates filters out the log upkeeps that have already been completed (performed or ineligible). +func (r *logRecoverer) filterFinalizedStates(f upkeepFilter, logs []logpoller.Log, states []ocr2keepers.UpkeepState) []logpoller.Log { + filtered := make([]logpoller.Log, 0) + + for i, log := range logs { + state := states[i] + if state != ocr2keepers.UnknownState { + continue + } + filtered = append(filtered, log) + } + + return filtered +} + +// getRecoveryWindow returns the block range of which the recoverer will try work on +func (r *logRecoverer) getRecoveryWindow(latest int64) (int64, int64) { + lookbackBlocks := r.lookbackBlocks.Load() + blockTime := r.blockTime.Load() + blocksInDay := int64(24*time.Hour) / blockTime + return latest - blocksInDay, latest - lookbackBlocks +} + +// getFilterBatch returns a batch of filters that are ready to be recovered. +func (r *logRecoverer) getFilterBatch(offsetBlock int64) []upkeepFilter { + filters := r.filterStore.GetFilters(func(f upkeepFilter) bool { + // ensure we work only on filters that are ready to be recovered + // no need to recover in case f.configUpdateBlock is after offsetBlock + return f.lastRePollBlock <= offsetBlock && int64(f.configUpdateBlock) <= offsetBlock + }) + + sort.Slice(filters, func(i, j int) bool { + return filters[i].lastRePollBlock < filters[j].lastRePollBlock + }) + + return r.selectFilterBatch(filters) +} + +// selectFilterBatch selects a batch of filters to be recovered. +// Half of the batch is selected randomly, the other half is selected +// in order of the oldest lastRePollBlock. +func (r *logRecoverer) selectFilterBatch(filters []upkeepFilter) []upkeepFilter { + batchSize := recoveryBatchSize + + if len(filters) < batchSize { + return filters + } + results := filters[:batchSize/2] + filters = filters[batchSize/2:] + + for len(results) < batchSize && len(filters) != 0 { + i, err := r.randIntn(len(filters)) + if err != nil { + r.lggr.Debugw("error generating random number", "error", err.Error()) + continue + } + results = append(results, filters[i]) + if i == 0 { + filters = filters[1:] + } else if i == len(filters)-1 { + filters = filters[:i] + } else { + filters = append(filters[:i], filters[i+1:]...) + } + } + + return results +} + +func (r *logRecoverer) randIntn(limit int) (int, error) { + n, err := rand.Int(rand.Reader, big.NewInt(int64(limit))) + if err != nil { + return 0, err + } + + return int(n.Int64()), nil +} + +func logToTrigger(log logpoller.Log) ocr2keepers.Trigger { + t := ocr2keepers.NewTrigger( + ocr2keepers.BlockNumber(log.BlockNumber), + log.BlockHash, + ) + t.LogTriggerExtension = &ocr2keepers.LogTriggerExtension{ + TxHash: log.TxHash, + Index: uint32(log.LogIndex), + BlockHash: log.BlockHash, + BlockNumber: ocr2keepers.BlockNumber(log.BlockNumber), + } + return t +} + +func (r *logRecoverer) clean(ctx context.Context) { + r.lock.Lock() + defer r.lock.Unlock() + + cleaned := 0 + for id, t := range r.visited { + if time.Since(t) > RecoveryCacheTTL { + delete(r.visited, id) + cleaned++ + } + } + + if cleaned > 0 { + r.lggr.Debugw("gc: cleaned visited upkeeps", "cleaned", cleaned) + } +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer_test.go new file mode 100644 index 00000000000..ed2ce1b0347 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer_test.go @@ -0,0 +1,854 @@ +package logprovider + +import ( + "context" + "fmt" + "math/big" + "sort" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/pkg/errors" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +func TestLogRecoverer_GetRecoverables(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + r := NewLogRecoverer(logger.TestLogger(t), nil, nil, nil, nil, nil, time.Millisecond*10, 0) + + tests := []struct { + name string + pending []ocr2keepers.UpkeepPayload + want []ocr2keepers.UpkeepPayload + wantErr bool + }{ + { + "empty", + []ocr2keepers.UpkeepPayload{}, + []ocr2keepers.UpkeepPayload{}, + false, + }, + { + "happy flow", + []ocr2keepers.UpkeepPayload{ + {WorkID: "1", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")}, + {WorkID: "2", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "2")}, + }, + []ocr2keepers.UpkeepPayload{ + {WorkID: "1", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")}, + {WorkID: "2", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "2")}, + }, + false, + }, + { + "rate limiting", + []ocr2keepers.UpkeepPayload{ + {WorkID: "1", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")}, + {WorkID: "2", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")}, + {WorkID: "3", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")}, + {WorkID: "4", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")}, + {WorkID: "5", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")}, + {WorkID: "6", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")}, + {WorkID: "2", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "2")}, + }, + []ocr2keepers.UpkeepPayload{ + {WorkID: "1", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")}, + {WorkID: "2", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")}, + {WorkID: "3", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")}, + {WorkID: "4", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")}, + {WorkID: "5", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")}, + {WorkID: "2", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "2")}, + }, + false, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + r.lock.Lock() + r.pending = tc.pending + r.lock.Unlock() + + got, err := r.GetRecoveryProposals(ctx) + if tc.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + require.Len(t, got, len(tc.want)) + }) + } +} + +func TestLogRecoverer_Recover(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + tests := []struct { + name string + lookbackBlocks int64 + latestBlock int64 + latestBlockErr error + active []upkeepFilter + states []ocr2keepers.UpkeepState + statesErr error + logs []logpoller.Log + logsErr error + recoverErr error + proposalsWorkIDs []string + }{ + { + "no filters", + 200, + 300, + nil, + []upkeepFilter{}, + []ocr2keepers.UpkeepState{}, + nil, + []logpoller.Log{}, + nil, + nil, + []string{}, + }, + { + "latest block error", + 200, + 0, + fmt.Errorf("test error"), + []upkeepFilter{}, + []ocr2keepers.UpkeepState{}, + nil, + []logpoller.Log{}, + nil, + fmt.Errorf("test error"), + []string{}, + }, + { + "states error", + 100, + 200, + nil, + []upkeepFilter{ + { + upkeepID: big.NewInt(1), + addr: common.HexToAddress("0x1").Bytes(), + topics: []common.Hash{ + common.HexToHash("0x1"), + }, + }, + }, + nil, + fmt.Errorf("test error"), + []logpoller.Log{ + { + BlockNumber: 2, + TxHash: common.HexToHash("0x111"), + LogIndex: 1, + BlockHash: common.HexToHash("0x2"), + }, + }, + nil, + nil, + []string{}, + }, + { + "get logs error", + 200, + 300, + nil, + []upkeepFilter{ + { + upkeepID: big.NewInt(1), + addr: common.HexToAddress("0x1").Bytes(), + topics: []common.Hash{ + common.HexToHash("0x1"), + }, + }, + }, + []ocr2keepers.UpkeepState{}, + nil, + []logpoller.Log{}, + fmt.Errorf("test error"), + nil, + []string{}, + }, + { + "happy flow", + 100, + 200, + nil, + []upkeepFilter{ + { + upkeepID: big.NewInt(1), + addr: common.HexToAddress("0x1").Bytes(), + topics: []common.Hash{ + common.HexToHash("0x1"), + }, + }, + { + upkeepID: big.NewInt(2), + addr: common.HexToAddress("0x2").Bytes(), + topics: []common.Hash{ + common.HexToHash("0x2"), + }, + configUpdateBlock: 150, // should be filtered out + }, + }, + []ocr2keepers.UpkeepState{ocr2keepers.UnknownState}, + nil, + []logpoller.Log{ + { + BlockNumber: 2, + TxHash: common.HexToHash("0x111"), + LogIndex: 1, + BlockHash: common.HexToHash("0x2"), + }, + }, + nil, + nil, + []string{"84c83c79c2be2c3eabd8d35986a2a798d9187564d7f4f8f96c5a0f40f50bed3f"}, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + lookbackBlocks := int64(100) + recoverer, filterStore, lp, statesReader := setupTestRecoverer(t, time.Millisecond*50, lookbackBlocks) + + filterStore.AddActiveUpkeeps(tc.active...) + lp.On("LatestBlock", mock.Anything).Return(tc.latestBlock, tc.latestBlockErr) + lp.On("LogsWithSigs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.logs, tc.logsErr) + statesReader.On("SelectByWorkIDsInRange", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.states, tc.statesErr) + + err := recoverer.recover(ctx) + if tc.recoverErr != nil { + require.Error(t, err) + return + } + require.NoError(t, err) + + proposals, err := recoverer.GetRecoveryProposals(ctx) + require.NoError(t, err) + require.Equal(t, len(tc.proposalsWorkIDs), len(proposals)) + if len(proposals) > 0 { + sort.Slice(proposals, func(i, j int) bool { + return proposals[i].WorkID < proposals[j].WorkID + }) + } + for i := range proposals { + require.Equal(t, tc.proposalsWorkIDs[i], proposals[i].WorkID) + } + }) + } +} + +func TestLogRecoverer_SelectFilterBatch(t *testing.T) { + n := (recoveryBatchSize*2 + 2) + filters := []upkeepFilter{} + for i := 0; i < n; i++ { + filters = append(filters, upkeepFilter{ + upkeepID: big.NewInt(int64(i)), + }) + } + recoverer, _, _, _ := setupTestRecoverer(t, time.Millisecond*50, int64(100)) + + batch := recoverer.selectFilterBatch(filters) + require.Equal(t, recoveryBatchSize, len(batch)) + + batch = recoverer.selectFilterBatch(filters[:recoveryBatchSize/2]) + require.Equal(t, recoveryBatchSize/2, len(batch)) +} + +func TestLogRecoverer_getFilterBatch(t *testing.T) { + tests := []struct { + name string + offsetBlock int64 + filters []upkeepFilter + want int + }{ + { + "empty", + 2, + []upkeepFilter{}, + 0, + }, + { + "filter out of range", + 100, + []upkeepFilter{ + { + upkeepID: big.NewInt(1), + addr: common.HexToAddress("0x1").Bytes(), + lastRePollBlock: 50, + }, + { + upkeepID: big.NewInt(2), + addr: common.HexToAddress("0x2").Bytes(), + lastRePollBlock: 50, + configUpdateBlock: 101, // out of range + }, + { + upkeepID: big.NewInt(3), + addr: common.HexToAddress("0x3").Bytes(), + configUpdateBlock: 99, + }, + }, + 2, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + recoverer, filterStore, _, _ := setupTestRecoverer(t, time.Millisecond*50, int64(100)) + filterStore.AddActiveUpkeeps(tc.filters...) + batch := recoverer.getFilterBatch(tc.offsetBlock) + require.Equal(t, tc.want, len(batch)) + }) + } +} + +func TestLogRecoverer_FilterFinalizedStates(t *testing.T) { + tests := []struct { + name string + logs []logpoller.Log + states []ocr2keepers.UpkeepState + want []logpoller.Log + }{ + { + "empty", + []logpoller.Log{}, + []ocr2keepers.UpkeepState{}, + []logpoller.Log{}, + }, + { + "happy flow", + []logpoller.Log{ + {LogIndex: 0}, {LogIndex: 2}, {LogIndex: 2}, + }, + []ocr2keepers.UpkeepState{ + ocr2keepers.UnknownState, + ocr2keepers.Performed, + ocr2keepers.Ineligible, + }, + []logpoller.Log{ + {LogIndex: 0}, + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + recoverer, _, _, _ := setupTestRecoverer(t, time.Millisecond*50, int64(100)) + state := recoverer.filterFinalizedStates(upkeepFilter{}, tc.logs, tc.states) + require.Equal(t, len(tc.want), len(state)) + for i := range state { + require.Equal(t, tc.want[i].LogIndex, state[i].LogIndex) + } + }) + } +} + +func TestLogRecoverer_GetProposalData(t *testing.T) { + for _, tc := range []struct { + name string + proposal ocr2keepers.CoordinatedBlockProposal + skipFilter bool + filterStore UpkeepFilterStore + logPoller logpoller.LogPoller + client client.Client + stateReader core.UpkeepStateReader + wantBytes []byte + expectErr bool + wantErr error + }{ + { + name: "passing an empty proposal with an empty upkeep ID returns an error", + proposal: ocr2keepers.CoordinatedBlockProposal{}, + expectErr: true, + wantErr: errors.New("not a log trigger upkeep ID"), + }, + { + name: "if a filter is not found for the upkeep ID, an error is returned", + proposal: ocr2keepers.CoordinatedBlockProposal{ + UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "123"), + }, + skipFilter: true, + expectErr: true, + wantErr: errors.New("filter not found for upkeep 452312848583266388373324160190187140457511065560374322131410487042692349952"), + }, + { + name: "if an error is encountered fetching the latest block, an error is returned", + proposal: ocr2keepers.CoordinatedBlockProposal{ + UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "123"), + Trigger: ocr2keepers.Trigger{ + LogTriggerExtension: &ocr2keepers.LogTriggerExtension{ + BlockNumber: 0, + }, + }, + }, + filterStore: &mockFilterStore{ + HasFn: func(id *big.Int) bool { + return true + }, + }, + logPoller: &mockLogPoller{ + LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + return 0, errors.New("latest block boom") + }, + }, + expectErr: true, + wantErr: errors.New("latest block boom"), + }, + { + name: "if an error is encountered fetching the tx receipt, an error is returned", + proposal: ocr2keepers.CoordinatedBlockProposal{ + UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "123"), + Trigger: ocr2keepers.Trigger{ + LogTriggerExtension: &ocr2keepers.LogTriggerExtension{ + BlockNumber: 0, + }, + }, + }, + filterStore: &mockFilterStore{ + HasFn: func(id *big.Int) bool { + return true + }, + }, + logPoller: &mockLogPoller{ + LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + return 100, nil + }, + }, + client: &mockClient{ + TransactionReceiptFn: func(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { + return nil, errors.New("tx receipt boom") + }, + }, + expectErr: true, + wantErr: errors.New("tx receipt boom"), + }, + { + name: "if the tx block is nil, an error is returned", + proposal: ocr2keepers.CoordinatedBlockProposal{ + UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "123"), + Trigger: ocr2keepers.Trigger{ + LogTriggerExtension: &ocr2keepers.LogTriggerExtension{ + BlockNumber: 0, + }, + }, + }, + filterStore: &mockFilterStore{ + HasFn: func(id *big.Int) bool { + return true + }, + }, + logPoller: &mockLogPoller{ + LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + return 100, nil + }, + }, + client: &mockClient{ + TransactionReceiptFn: func(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { + return &types.Receipt{}, nil + }, + }, + expectErr: true, + wantErr: errors.New("failed to get tx block"), + }, + { + name: "if a log trigger extension block number is 0, and the block number on the tx receipt is not recoverable, an error is returned", + proposal: ocr2keepers.CoordinatedBlockProposal{ + UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "123"), + Trigger: ocr2keepers.Trigger{ + LogTriggerExtension: &ocr2keepers.LogTriggerExtension{ + BlockNumber: 0, + }, + }, + }, + filterStore: &mockFilterStore{ + HasFn: func(id *big.Int) bool { + return true + }, + }, + logPoller: &mockLogPoller{ + LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + return 100, nil + }, + }, + client: &mockClient{ + TransactionReceiptFn: func(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { + return &types.Receipt{ + BlockNumber: big.NewInt(200), + }, nil + }, + }, + expectErr: true, + wantErr: errors.New("log block is not recoverable"), + }, + { + name: "if a log block is not recoverable, an error is returned", + proposal: ocr2keepers.CoordinatedBlockProposal{ + UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "123"), + Trigger: ocr2keepers.Trigger{ + LogTriggerExtension: &ocr2keepers.LogTriggerExtension{ + BlockNumber: 200, + }, + }, + }, + filterStore: &mockFilterStore{ + HasFn: func(id *big.Int) bool { + return true + }, + }, + logPoller: &mockLogPoller{ + LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + return 100, nil + }, + }, + expectErr: true, + wantErr: errors.New("log block is not recoverable"), + }, + { + name: "if a log block is recoverable, when the upkeep state reader errors, an error is returned", + proposal: ocr2keepers.CoordinatedBlockProposal{ + UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "123"), + Trigger: ocr2keepers.Trigger{ + LogTriggerExtension: &ocr2keepers.LogTriggerExtension{ + BlockNumber: 80, + }, + }, + }, + filterStore: &mockFilterStore{ + HasFn: func(id *big.Int) bool { + return true + }, + }, + logPoller: &mockLogPoller{ + LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + return 100, nil + }, + }, + stateReader: &mockStateReader{ + SelectByWorkIDsInRangeFn: func(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) { + return nil, errors.New("upkeep state boom") + }, + }, + expectErr: true, + wantErr: errors.New("upkeep state boom"), + }, + { + name: "if a log block is recoverable, when the upkeep state reader returns a non recoverable state, an error is returned", + proposal: ocr2keepers.CoordinatedBlockProposal{ + UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "123"), + Trigger: ocr2keepers.Trigger{ + LogTriggerExtension: &ocr2keepers.LogTriggerExtension{ + BlockNumber: 80, + }, + }, + }, + filterStore: &mockFilterStore{ + HasFn: func(id *big.Int) bool { + return true + }, + }, + logPoller: &mockLogPoller{ + LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + return 100, nil + }, + }, + stateReader: &mockStateReader{ + SelectByWorkIDsInRangeFn: func(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) { + return []ocr2keepers.UpkeepState{ + ocr2keepers.Ineligible, + }, nil + }, + }, + expectErr: true, + wantErr: errors.New("upkeep state is not recoverable"), + }, + { + name: "if a log block is recoverable, when the filter address is empty, an error is returned", + proposal: ocr2keepers.CoordinatedBlockProposal{ + UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "123"), + Trigger: ocr2keepers.Trigger{ + LogTriggerExtension: &ocr2keepers.LogTriggerExtension{ + BlockNumber: 80, + }, + }, + }, + filterStore: &mockFilterStore{ + HasFn: func(id *big.Int) bool { + return true + }, + RangeFiltersByIDsFn: func(iterator func(int, upkeepFilter), ids ...*big.Int) { + + }, + }, + logPoller: &mockLogPoller{ + LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + return 100, nil + }, + }, + stateReader: &mockStateReader{ + SelectByWorkIDsInRangeFn: func(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) { + return []ocr2keepers.UpkeepState{ + ocr2keepers.UnknownState, + }, nil + }, + }, + expectErr: true, + wantErr: errors.New("invalid filter found for upkeepID 452312848583266388373324160190187140457511065560374322131410487042692349952"), + }, + { + name: "if a log block is recoverable, when the log poller returns an error fetching logs, an error is returned", + proposal: ocr2keepers.CoordinatedBlockProposal{ + UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "123"), + Trigger: ocr2keepers.Trigger{ + LogTriggerExtension: &ocr2keepers.LogTriggerExtension{ + BlockNumber: 80, + }, + }, + }, + logPoller: &mockLogPoller{ + LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + return 100, nil + }, + LogsWithSigsFn: func(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) { + return nil, errors.New("logs with sigs boom") + }, + }, + stateReader: &mockStateReader{ + SelectByWorkIDsInRangeFn: func(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) { + return []ocr2keepers.UpkeepState{ + ocr2keepers.UnknownState, + }, nil + }, + }, + expectErr: true, + wantErr: errors.New("could not read logs: logs with sigs boom"), + }, + { + name: "if a log block is recoverable, when logs cannot be found for an upkeep ID, an error is returned", + proposal: ocr2keepers.CoordinatedBlockProposal{ + UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "123"), + Trigger: ocr2keepers.Trigger{ + LogTriggerExtension: &ocr2keepers.LogTriggerExtension{ + BlockNumber: 80, + }, + }, + }, + logPoller: &mockLogPoller{ + LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + return 100, nil + }, + LogsWithSigsFn: func(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) { + return []logpoller.Log{ + { + BlockNumber: 80, + }, + }, nil + }, + }, + stateReader: &mockStateReader{ + SelectByWorkIDsInRangeFn: func(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) { + return []ocr2keepers.UpkeepState{ + ocr2keepers.UnknownState, + }, nil + }, + }, + expectErr: true, + wantErr: errors.New(`no log found for upkeepID 452312848583266388373324160190187140457511065560374322131410487042692349952 and trigger {"BlockNumber":0,"BlockHash":"0000000000000000000000000000000000000000000000000000000000000000","LogTriggerExtension":{"BlockHash":"0000000000000000000000000000000000000000000000000000000000000000","BlockNumber":80,"Index":0,"TxHash":"0000000000000000000000000000000000000000000000000000000000000000"}}`), + }, + { + name: "happy path with empty check data", + proposal: ocr2keepers.CoordinatedBlockProposal{ + UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "123"), + Trigger: func() ocr2keepers.Trigger { + t := ocr2keepers.NewTrigger( + ocr2keepers.BlockNumber(80), + [32]byte{1}, + ) + t.LogTriggerExtension = &ocr2keepers.LogTriggerExtension{ + TxHash: [32]byte{2}, + Index: uint32(3), + BlockHash: [32]byte{1}, + BlockNumber: ocr2keepers.BlockNumber(80), + } + return t + }(), + WorkID: "d91c6f090b8477f434cf775182e4ff12c90618ba4da5b8ec06aa719768b7743a", + }, + logPoller: &mockLogPoller{ + LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + return 100, nil + }, + LogsWithSigsFn: func(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) { + return []logpoller.Log{ + { + BlockNumber: 80, + BlockHash: [32]byte{1}, + TxHash: [32]byte{2}, + LogIndex: 3, + }, + }, nil + }, + }, + stateReader: &mockStateReader{ + SelectByWorkIDsInRangeFn: func(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) { + return []ocr2keepers.UpkeepState{ + ocr2keepers.UnknownState, + }, nil + }, + }, + wantBytes: []byte(nil), + }, + { + name: "happy path with check data", + proposal: ocr2keepers.CoordinatedBlockProposal{ + UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "123"), + Trigger: func() ocr2keepers.Trigger { + t := ocr2keepers.NewTrigger( + ocr2keepers.BlockNumber(80), + [32]byte{1}, + ) + t.LogTriggerExtension = &ocr2keepers.LogTriggerExtension{ + TxHash: [32]byte{2}, + Index: uint32(3), + BlockHash: [32]byte{1}, + BlockNumber: ocr2keepers.BlockNumber(80), + } + return t + }(), + WorkID: "d91c6f090b8477f434cf775182e4ff12c90618ba4da5b8ec06aa719768b7743a", + }, + logPoller: &mockLogPoller{ + LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + return 100, nil + }, + LogsWithSigsFn: func(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) { + return []logpoller.Log{ + { + EvmChainId: utils.NewBig(big.NewInt(1)), + LogIndex: 3, + BlockHash: [32]byte{1}, + BlockNumber: 80, + BlockTimestamp: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC), + EventSig: common.HexToHash("abc"), + TxHash: [32]byte{2}, + Data: []byte{1, 2, 3}, + CreatedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC), + }, + }, nil + }, + }, + stateReader: &mockStateReader{ + SelectByWorkIDsInRangeFn: func(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) { + return []ocr2keepers.UpkeepState{ + ocr2keepers.UnknownState, + }, nil + }, + }, + wantBytes: []byte{1, 2, 3}, + }, + } { + t.Run(tc.name, func(t *testing.T) { + recoverer, filterStore, _, _ := setupTestRecoverer(t, time.Second, 10) + + if !tc.skipFilter { + filterStore.AddActiveUpkeeps(upkeepFilter{ + addr: []byte("test"), + upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "123").BigInt(), + }) + } + + if tc.filterStore != nil { + recoverer.filterStore = tc.filterStore + } + if tc.logPoller != nil { + recoverer.poller = tc.logPoller + } + if tc.client != nil { + recoverer.client = tc.client + } + if tc.stateReader != nil { + recoverer.states = tc.stateReader + } + + b, err := recoverer.GetProposalData(context.Background(), tc.proposal) + if tc.expectErr { + assert.Error(t, err) + assert.Equal(t, tc.wantErr.Error(), err.Error()) + } else { + assert.NoError(t, err) + assert.Equal(t, tc.wantBytes, b) + } + }) + } +} + +type mockFilterStore struct { + UpkeepFilterStore + HasFn func(id *big.Int) bool + RangeFiltersByIDsFn func(iterator func(int, upkeepFilter), ids ...*big.Int) +} + +func (s *mockFilterStore) RangeFiltersByIDs(iterator func(int, upkeepFilter), ids ...*big.Int) { + s.RangeFiltersByIDsFn(iterator, ids...) +} + +func (s *mockFilterStore) Has(id *big.Int) bool { + return s.HasFn(id) +} + +type mockLogPoller struct { + logpoller.LogPoller + LatestBlockFn func(qopts ...pg.QOpt) (int64, error) + LogsWithSigsFn func(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) +} + +func (p *mockLogPoller) LogsWithSigs(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) { + return p.LogsWithSigsFn(start, end, eventSigs, address, qopts...) +} +func (p *mockLogPoller) LatestBlock(qopts ...pg.QOpt) (int64, error) { + return p.LatestBlockFn(qopts...) +} + +type mockClient struct { + client.Client + TransactionReceiptFn func(ctx context.Context, txHash common.Hash) (*types.Receipt, error) +} + +func (c *mockClient) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { + return c.TransactionReceiptFn(ctx, txHash) +} + +type mockStateReader struct { + SelectByWorkIDsInRangeFn func(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) +} + +func (r *mockStateReader) SelectByWorkIDsInRange(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) { + return r.SelectByWorkIDsInRangeFn(ctx, start, end, workIDs...) +} + +func setupTestRecoverer(t *testing.T, interval time.Duration, lookbackBlocks int64) (*logRecoverer, UpkeepFilterStore, *lpmocks.LogPoller, *mocks.UpkeepStateReader) { + lp := new(lpmocks.LogPoller) + statesReader := new(mocks.UpkeepStateReader) + filterStore := NewUpkeepFilterStore() + recoverer := NewLogRecoverer(logger.TestLogger(t), lp, nil, statesReader, &mockedPacker{}, filterStore, interval, lookbackBlocks) + return recoverer, filterStore, lp, statesReader +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/mocks/registry.go b/core/services/ocr2/plugins/ocr2keeper/evm21/mocks/registry.go index 7e6f9fb5827..1827d4cb57f 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/mocks/registry.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/mocks/registry.go @@ -6,7 +6,6 @@ import ( big "math/big" bind "github.com/ethereum/go-ethereum/accounts/abi/bind" - common "github.com/ethereum/go-ethereum/common" generated "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" @@ -74,32 +73,6 @@ func (_m *Registry) GetActiveUpkeepIDs(opts *bind.CallOpts, startIndex *big.Int, return r0, r1 } -// GetAdminPrivilegeConfig provides a mock function with given fields: opts, admin -func (_m *Registry) GetAdminPrivilegeConfig(opts *bind.CallOpts, admin common.Address) ([]byte, error) { - ret := _m.Called(opts, admin) - - var r0 []byte - var r1 error - if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) ([]byte, error)); ok { - return rf(opts, admin) - } - if rf, ok := ret.Get(0).(func(*bind.CallOpts, common.Address) []byte); ok { - r0 = rf(opts, admin) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]byte) - } - } - - if rf, ok := ret.Get(1).(func(*bind.CallOpts, common.Address) error); ok { - r1 = rf(opts, admin) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - // GetState provides a mock function with given fields: opts func (_m *Registry) GetState(opts *bind.CallOpts) (i_keeper_registry_master_wrapper_2_1.GetState, error) { ret := _m.Called(opts) @@ -148,6 +121,32 @@ func (_m *Registry) GetUpkeep(opts *bind.CallOpts, id *big.Int) (i_keeper_regist return r0, r1 } +// GetUpkeepPrivilegeConfig provides a mock function with given fields: opts, upkeepId +func (_m *Registry) GetUpkeepPrivilegeConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) { + ret := _m.Called(opts, upkeepId) + + var r0 []byte + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, *big.Int) ([]byte, error)); ok { + return rf(opts, upkeepId) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, *big.Int) []byte); ok { + r0 = rf(opts, upkeepId) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, *big.Int) error); ok { + r1 = rf(opts, upkeepId) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // GetUpkeepTriggerConfig provides a mock function with given fields: opts, upkeepId func (_m *Registry) GetUpkeepTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) { ret := _m.Called(opts, upkeepId) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder.go b/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder.go new file mode 100644 index 00000000000..9351aa71d65 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder.go @@ -0,0 +1,62 @@ +package evm + +import ( + "context" + + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider" +) + +type payloadBuilder struct { + upkeepList ActiveUpkeepList + lggr logger.Logger + recoverer logprovider.LogRecoverer +} + +var _ ocr2keepers.PayloadBuilder = &payloadBuilder{} + +func NewPayloadBuilder(activeUpkeepList ActiveUpkeepList, recoverer logprovider.LogRecoverer, lggr logger.Logger) *payloadBuilder { + return &payloadBuilder{ + upkeepList: activeUpkeepList, + lggr: lggr, + recoverer: recoverer, + } +} + +func (b *payloadBuilder) BuildPayloads(ctx context.Context, proposals ...ocr2keepers.CoordinatedBlockProposal) ([]ocr2keepers.UpkeepPayload, error) { + payloads := make([]ocr2keepers.UpkeepPayload, len(proposals)) + + for i, proposal := range proposals { + var payload ocr2keepers.UpkeepPayload + if b.upkeepList.IsActive(proposal.UpkeepID.BigInt()) { + b.lggr.Debugf("building payload for coordinated block proposal %+v", proposal) + checkData := []byte{} + var err error + switch core.GetUpkeepType(proposal.UpkeepID) { + case ocr2keepers.LogTrigger: + checkData, err = b.recoverer.GetProposalData(ctx, proposal) + if err != nil { + b.lggr.Warnw("failed to get log proposal data", "err", err, "upkeepID", proposal.UpkeepID, "trigger", proposal.Trigger) + continue + } + case ocr2keepers.ConditionTrigger: + // Empty checkData for conditionals + } + payload, err = core.NewUpkeepPayload(proposal.UpkeepID.BigInt(), proposal.Trigger, checkData) + if err != nil { + b.lggr.Warnw("error building upkeep payload", "err", err, "upkeepID", proposal.UpkeepID) + continue + } + } else { + b.lggr.Warnw("upkeep is not active, skipping", "upkeepID", proposal.UpkeepID) + continue + } + + payloads[i] = payload + } + + return payloads, nil +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder_test.go new file mode 100644 index 00000000000..6c0ef78bbc4 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder_test.go @@ -0,0 +1,209 @@ +package evm + +import ( + "context" + "math/big" + "testing" + + "github.com/pkg/errors" + "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider" +) + +func TestNewPayloadBuilder(t *testing.T) { + for _, tc := range []struct { + name string + activeList ActiveUpkeepList + recoverer logprovider.LogRecoverer + proposals []types.CoordinatedBlockProposal + wantPayloads []types.UpkeepPayload + }{ + { + name: "for log trigger upkeeps, new payloads are created", + activeList: &mockActiveUpkeepList{ + IsActiveFn: func(id *big.Int) bool { + return true + }, + }, + proposals: []types.CoordinatedBlockProposal{ + { + UpkeepID: core.GenUpkeepID(types.LogTrigger, "abc"), + WorkID: "workID1", + Trigger: types.Trigger{ + BlockNumber: 1, + BlockHash: [32]byte{1}, + }, + }, + { + UpkeepID: core.GenUpkeepID(types.LogTrigger, "def"), + WorkID: "workID2", + Trigger: types.Trigger{ + BlockNumber: 2, + BlockHash: [32]byte{2}, + }, + }, + }, + recoverer: &mockLogRecoverer{ + GetProposalDataFn: func(ctx context.Context, proposal types.CoordinatedBlockProposal) ([]byte, error) { + return []byte{1, 2, 3}, nil + }, + }, + wantPayloads: []types.UpkeepPayload{ + { + UpkeepID: core.GenUpkeepID(types.LogTrigger, "abc"), + WorkID: "714f83255c5b562823725748c4a75777c9b78ea8c5ba72ea819926a1fecd389e", + Trigger: types.Trigger{ + BlockNumber: 1, + BlockHash: [32]byte{1}, + }, + CheckData: []byte{1, 2, 3}, + }, + { + UpkeepID: core.GenUpkeepID(types.LogTrigger, "def"), + WorkID: "3956daa0378d6a761fe972ee00fe98338f17fb6b7865c1d49a8a416cd85977b8", + Trigger: types.Trigger{ + BlockNumber: 2, + BlockHash: [32]byte{2}, + }, + CheckData: []byte{1, 2, 3}, + }, + }, + }, + { + name: "for an inactive log trigger upkeep, an empty payload is added to the list of payloads", + activeList: &mockActiveUpkeepList{ + IsActiveFn: func(id *big.Int) bool { + return core.GenUpkeepID(types.LogTrigger, "ghi").BigInt().Cmp(id) != 0 + }, + }, + proposals: []types.CoordinatedBlockProposal{ + { + UpkeepID: core.GenUpkeepID(types.LogTrigger, "abc"), + WorkID: "workID1", + Trigger: types.Trigger{ + BlockNumber: 1, + BlockHash: [32]byte{1}, + }, + }, + { + UpkeepID: core.GenUpkeepID(types.LogTrigger, "def"), + WorkID: "workID2", + Trigger: types.Trigger{ + BlockNumber: 2, + BlockHash: [32]byte{2}, + }, + }, + { + UpkeepID: core.GenUpkeepID(types.LogTrigger, "ghi"), + WorkID: "workID3", + Trigger: types.Trigger{ + BlockNumber: 3, + BlockHash: [32]byte{3}, + }, + }, + }, + recoverer: &mockLogRecoverer{ + GetProposalDataFn: func(ctx context.Context, proposal types.CoordinatedBlockProposal) ([]byte, error) { + return []byte{1, 2, 3}, nil + }, + }, + wantPayloads: []types.UpkeepPayload{ + { + UpkeepID: core.GenUpkeepID(types.LogTrigger, "abc"), + WorkID: "714f83255c5b562823725748c4a75777c9b78ea8c5ba72ea819926a1fecd389e", + Trigger: types.Trigger{ + BlockNumber: 1, + BlockHash: [32]byte{1}, + }, + CheckData: []byte{1, 2, 3}, + }, + { + UpkeepID: core.GenUpkeepID(types.LogTrigger, "def"), + WorkID: "3956daa0378d6a761fe972ee00fe98338f17fb6b7865c1d49a8a416cd85977b8", + Trigger: types.Trigger{ + BlockNumber: 2, + BlockHash: [32]byte{2}, + }, + CheckData: []byte{1, 2, 3}, + }, + {}, + }, + }, + { + name: "when the recoverer errors, an empty payload is created but not added to the list of payloads", + activeList: &mockActiveUpkeepList{ + IsActiveFn: func(id *big.Int) bool { + return true + }, + }, + proposals: []types.CoordinatedBlockProposal{ + { + UpkeepID: core.GenUpkeepID(types.LogTrigger, "abc"), + WorkID: "workID1", + Trigger: types.Trigger{ + BlockNumber: 1, + BlockHash: [32]byte{1}, + }, + }, + }, + recoverer: &mockLogRecoverer{ + GetProposalDataFn: func(ctx context.Context, proposal types.CoordinatedBlockProposal) ([]byte, error) { + return nil, errors.New("recoverer boom") + }, + }, + wantPayloads: []types.UpkeepPayload{ + {}, + }, + }, + { + name: "for a conditional upkeep, a new payload with empty check data is added to the list of payloads", + activeList: &mockActiveUpkeepList{ + IsActiveFn: func(id *big.Int) bool { + return true + }, + }, + proposals: []types.CoordinatedBlockProposal{ + { + UpkeepID: core.GenUpkeepID(types.ConditionTrigger, "def"), + WorkID: "workID1", + Trigger: types.Trigger{ + BlockNumber: 1, + BlockHash: [32]byte{1}, + }, + }, + }, + wantPayloads: []types.UpkeepPayload{ + { + UpkeepID: core.GenUpkeepID(types.ConditionTrigger, "def"), + WorkID: "58f2f231792448679a75bac6efc2af4ba731901f0cb93a44a366525751cbabfb", + Trigger: types.Trigger{ + BlockNumber: 1, + BlockHash: [32]byte{1}, + }, + CheckData: make([]byte, 0), + }, + }, + }, + } { + t.Run(tc.name, func(t *testing.T) { + lggr, _ := logger.NewLogger() + builder := NewPayloadBuilder(tc.activeList, tc.recoverer, lggr) + payloads, err := builder.BuildPayloads(context.Background(), tc.proposals...) + assert.NoError(t, err) + assert.Equal(t, tc.wantPayloads, payloads) + }) + } +} + +type mockLogRecoverer struct { + logprovider.LogRecoverer + GetProposalDataFn func(context.Context, types.CoordinatedBlockProposal) ([]byte, error) +} + +func (r *mockLogRecoverer) GetProposalData(ctx context.Context, p types.CoordinatedBlockProposal) ([]byte, error) { + return r.GetProposalDataFn(ctx, p) +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go b/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go index 7c096cbbaa7..fabfcca8248 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go @@ -2,10 +2,10 @@ package evm import ( "context" + goerrors "errors" "fmt" "math/big" "net/http" - "strings" "sync" "time" @@ -15,56 +15,50 @@ import ( coreTypes "github.com/ethereum/go-ethereum/core/types" "github.com/pkg/errors" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/rpc" "github.com/patrickmn/go-cache" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" - "go.uber.org/multierr" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" - "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/gethwrappers/generated" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/feed_lookup_compatible_interface" iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/models" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/encoding" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider" "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/utils" ) const ( - // DefaultAllowListExpiration decides how long an upkeep's allow list info will be valid for. - DefaultAllowListExpiration = 20 * time.Minute - // CleanupInterval decides when the expired items in cache will be deleted. - CleanupInterval = 25 * time.Minute + // defaultAllowListExpiration decides how long an upkeep's allow list info will be valid for. + defaultAllowListExpiration = 20 * time.Minute + // allowListCleanupInterval decides when the expired items in allowList cache will be deleted. + allowListCleanupInterval = 5 * time.Minute ) var ( ErrLogReadFailure = fmt.Errorf("failure reading logs") ErrHeadNotAvailable = fmt.Errorf("head not available") - ErrRegistryCallFailure = fmt.Errorf("registry chain call failure") - ErrBlockKeyNotParsable = fmt.Errorf("block identifier not parsable") - ErrUpkeepKeyNotParsable = fmt.Errorf("upkeep key not parsable") ErrInitializationFailure = fmt.Errorf("failed to initialize registry") ErrContextCancelled = fmt.Errorf("context was cancelled") ErrABINotParsable = fmt.Errorf("error parsing abi") ActiveUpkeepIDBatchSize int64 = 1000 FetchUpkeepConfigBatchSize = 10 - separator = "|" - reInitializationDelay = 15 * time.Minute - logEventLookback int64 = 250 + // This is the interval at which active upkeep list is fully refreshed from chain + refreshInterval = 15 * time.Minute + // This is the lookback for polling upkeep state event logs from latest block + logEventLookback int64 = 250 ) //go:generate mockery --quiet --name Registry --output ./mocks/ --case=underscore type Registry interface { - GetUpkeep(opts *bind.CallOpts, id *big.Int) (UpkeepInfo, error) + GetUpkeep(opts *bind.CallOpts, id *big.Int) (encoding.UpkeepInfo, error) GetState(opts *bind.CallOpts) (iregistry21.GetState, error) GetActiveUpkeepIDs(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) - GetAdminPrivilegeConfig(opts *bind.CallOpts, admin common.Address) ([]byte, error) + GetUpkeepPrivilegeConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) GetUpkeepTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) CheckCallback(opts *bind.TransactOpts, id *big.Int, values [][]byte, extraData []byte) (*coreTypes.Transaction, error) ParseLog(log coreTypes.Log) (generated.AbigenLog, error) @@ -75,174 +69,85 @@ type HttpClient interface { Do(req *http.Request) (*http.Response, error) } -type LatestBlockGetter interface { - LatestBlock() int64 -} - -func NewEVMRegistryService(addr common.Address, client evm.Chain, mc *models.MercuryCredentials, lggr logger.Logger) (*EvmRegistry, error) { - feedLookupCompatibleABI, err := abi.JSON(strings.NewReader(feed_lookup_compatible_interface.FeedLookupCompatibleInterfaceABI)) - if err != nil { - return nil, fmt.Errorf("%w: %s", ErrABINotParsable, err) - } - keeperRegistryABI, err := abi.JSON(strings.NewReader(iregistry21.IKeeperRegistryMasterABI)) - if err != nil { - return nil, fmt.Errorf("%w: %s", ErrABINotParsable, err) - } - utilsABI, err := abi.JSON(strings.NewReader(automation_utils_2_1.AutomationUtilsABI)) - if err != nil { - return nil, fmt.Errorf("%w: %s", ErrABINotParsable, err) - } - packer := NewEvmRegistryPackerV2_1(keeperRegistryABI, utilsABI) - logPacker := logprovider.NewLogEventsPacker(utilsABI) - - registry, err := iregistry21.NewIKeeperRegistryMaster(addr, client.Client()) - if err != nil { - return nil, fmt.Errorf("%w: failed to create caller for address and backend", ErrInitializationFailure) - } - - r := &EvmRegistry{ - ht: client.HeadTracker(), - lggr: lggr.Named("EvmRegistry"), - poller: client.LogPoller(), - addr: addr, - client: client.Client(), - txHashes: make(map[string]bool), - registry: registry, - active: make(map[string]activeUpkeep), - abi: keeperRegistryABI, - packer: packer, - headFunc: func(ocr2keepers.BlockKey) {}, - chLog: make(chan logpoller.Log, 1000), +func NewEvmRegistry( + lggr logger.Logger, + addr common.Address, + client evm.Chain, + feedLookupCompatibleABI, keeperRegistryABI abi.ABI, + registry *iregistry21.IKeeperRegistryMaster, + mc *models.MercuryCredentials, + al ActiveUpkeepList, + logEventProvider logprovider.LogEventProvider, + packer encoding.Packer, + blockSub *BlockSubscriber, +) *EvmRegistry { + return &EvmRegistry{ + lggr: lggr.Named("EvmRegistry"), + poller: client.LogPoller(), + addr: addr, + client: client.Client(), + logProcessed: make(map[string]bool), + registry: registry, + abi: keeperRegistryABI, + active: al, + packer: packer, + headFunc: func(ocr2keepers.BlockKey) {}, + chLog: make(chan logpoller.Log, 1000), mercury: &MercuryConfig{ cred: mc, abi: feedLookupCompatibleABI, - allowListCache: cache.New(DefaultAllowListExpiration, CleanupInterval), + allowListCache: cache.New(defaultAllowListExpiration, allowListCleanupInterval), }, hc: http.DefaultClient, - enc: EVMAutomationEncoder21{}, - logEventProvider: logprovider.New(lggr, client.LogPoller(), logPacker, nil), // TODO: pass opts - } - - if err := r.registerEvents(client.ID().Uint64(), addr); err != nil { - return nil, fmt.Errorf("logPoller error while registering automation events: %w", err) + logEventProvider: logEventProvider, + bs: blockSub, } - - return r, nil } var upkeepStateEvents = []common.Hash{ iregistry21.IKeeperRegistryMasterUpkeepRegistered{}.Topic(), // adds new upkeep id to registry iregistry21.IKeeperRegistryMasterUpkeepReceived{}.Topic(), // adds new upkeep id to registry via migration - iregistry21.IKeeperRegistryMasterUpkeepGasLimitSet{}.Topic(), // unpauses an upkeep - iregistry21.IKeeperRegistryMasterUpkeepUnpaused{}.Topic(), // updates the gas limit for an upkeep + iregistry21.IKeeperRegistryMasterUpkeepUnpaused{}.Topic(), // unpauses an upkeep iregistry21.IKeeperRegistryMasterUpkeepPaused{}.Topic(), // pauses an upkeep + iregistry21.IKeeperRegistryMasterUpkeepMigrated{}.Topic(), // migrated an upkeep, equivalent to cancel from this registry's perspective iregistry21.IKeeperRegistryMasterUpkeepCanceled{}.Topic(), // cancels an upkeep iregistry21.IKeeperRegistryMasterUpkeepTriggerConfigSet{}.Topic(), // trigger config was changed } -var upkeepActiveEvents = []common.Hash{ - iregistry21.IKeeperRegistryMasterUpkeepPerformed{}.Topic(), - iregistry21.IKeeperRegistryMasterReorgedUpkeepReport{}.Topic(), - iregistry21.IKeeperRegistryMasterInsufficientFundsUpkeepReport{}.Topic(), - iregistry21.IKeeperRegistryMasterStaleUpkeepReport{}.Topic(), -} - -type checkResult struct { - cr []ocr2keepers.CheckResult - err error -} - -type activeUpkeep struct { - ID *big.Int - PerformGasLimit uint32 - CheckData []byte - Admin common.Address -} - type MercuryConfig struct { cred *models.MercuryCredentials abi abi.ABI - // allowListCache stores the admin address' privilege. in 2.1, this only includes a JSON bytes for allowed to use mercury + // allowListCache stores the upkeeps privileges. In 2.1, this only includes a JSON bytes for allowed to use mercury allowListCache *cache.Cache } type EvmRegistry struct { - ht types.HeadTracker - sync utils.StartStopOnce - lggr logger.Logger - poller logpoller.LogPoller - addr common.Address - client client.Client - registry Registry - abi abi.ABI - packer *evmRegistryPackerV2_1 - chLog chan logpoller.Log - reInit *time.Timer - mu sync.RWMutex - txHashes map[string]bool - lastPollBlock int64 - ctx context.Context - cancel context.CancelFunc - active map[string]activeUpkeep - headFunc func(ocr2keepers.BlockKey) - runState int - runError error - mercury *MercuryConfig - hc HttpClient - enc EVMAutomationEncoder21 - + sync utils.StartStopOnce + lggr logger.Logger + poller logpoller.LogPoller + addr common.Address + client client.Client + chainID uint64 + registry Registry + abi abi.ABI + packer encoding.Packer + chLog chan logpoller.Log + reInit *time.Timer + mu sync.RWMutex + logProcessed map[string]bool + active ActiveUpkeepList + lastPollBlock int64 + ctx context.Context + cancel context.CancelFunc + headFunc func(ocr2keepers.BlockKey) + runState int + runError error + mercury *MercuryConfig + hc HttpClient + bs *BlockSubscriber logEventProvider logprovider.LogEventProvider } -// GetActiveUpkeepIDs uses the latest head and map of all active upkeeps to build a -// slice of upkeep keys. -func (r *EvmRegistry) GetActiveUpkeepIDs(ctx context.Context) ([]ocr2keepers.UpkeepIdentifier, error) { - return r.GetActiveUpkeepIDsByType(ctx) -} - -// GetActiveUpkeepIDsByType returns all active upkeeps of the given trigger types. -func (r *EvmRegistry) GetActiveUpkeepIDsByType(ctx context.Context, triggers ...uint8) ([]ocr2keepers.UpkeepIdentifier, error) { - r.mu.RLock() - defer r.mu.RUnlock() - - keys := make([]ocr2keepers.UpkeepIdentifier, 0) - - for _, value := range r.active { - if len(triggers) == 0 { - keys = append(keys, ocr2keepers.UpkeepIdentifier(value.ID.String())) - continue - } - trigger := getUpkeepType(value.ID.Bytes()) - for _, t := range triggers { - if trigger == upkeepType(t) { - keys = append(keys, ocr2keepers.UpkeepIdentifier(value.ID.String())) - break - } - } - } - - return keys, nil -} - -func (r *EvmRegistry) CheckUpkeeps(ctx context.Context, keys ...ocr2keepers.UpkeepPayload) ([]ocr2keepers.CheckResult, error) { - chResult := make(chan checkResult, 1) - go r.doCheck(ctx, keys, chResult) - - select { - case rs := <-chResult: - result := make([]ocr2keepers.CheckResult, len(rs.cr)) - copy(result, rs.cr) - return result, rs.err - case <-ctx.Done(): - // safety on context done to provide an error on context cancellation - // contract calls through the geth wrappers are a bit of a black box - // so this safety net ensures contexts are fully respected and contract - // call functions have a more graceful closure outside the scope of - // CheckUpkeep needing to return immediately. - return nil, fmt.Errorf("%w: failed to check upkeep on registry", ErrContextCancelled) - } -} - func (r *EvmRegistry) Name() string { return r.lggr.Name() } @@ -252,9 +157,13 @@ func (r *EvmRegistry) Start(ctx context.Context) error { r.mu.Lock() defer r.mu.Unlock() r.ctx, r.cancel = context.WithCancel(context.Background()) - r.reInit = time.NewTimer(reInitializationDelay) + r.reInit = time.NewTimer(refreshInterval) - // initialize the upkeep keys; if the reInit timer returns, do it again + if err := r.registerEvents(r.chainID, r.addr); err != nil { + return fmt.Errorf("logPoller error while registering automation events: %w", err) + } + + // refresh the active upkeep keys; if the reInit timer returns, do it again { go func(cx context.Context, tmr *time.Timer, lggr logger.Logger, f func() error) { err := f() @@ -269,12 +178,12 @@ func (r *EvmRegistry) Start(ctx context.Context) error { if err != nil { lggr.Errorf("failed to re-initialize upkeeps", err) } - tmr.Reset(reInitializationDelay) + tmr.Reset(refreshInterval) case <-cx.Done(): return } } - }(r.ctx, r.reInit, r.lggr, r.initialize) + }(r.ctx, r.reInit, r.lggr, r.refreshActiveUpkeeps) } // start polling logs on an interval @@ -293,7 +202,7 @@ func (r *EvmRegistry) Start(ctx context.Context) error { return } } - }(r.ctx, r.lggr, r.pollLogs) + }(r.ctx, r.lggr, r.pollUpkeepStateLogs) } // run process to process logs from log channel @@ -313,20 +222,6 @@ func (r *EvmRegistry) Start(ctx context.Context) error { }(r.ctx, r.chLog, r.lggr, r.processUpkeepStateLog) } - // Start log event provider - { - go func(ctx context.Context, lggr logger.Logger, f func(context.Context) error, c func() error) { - for ctx.Err() == nil { - if err := f(ctx); err != nil { - lggr.Errorf("failed to start log event provider", err) - } - if err := c(); err != nil { - lggr.Errorf("failed to close log event provider", err) - } - } - }(r.ctx, r.lggr, r.logEventProvider.Start, r.logEventProvider.Close) - } - r.runState = 1 return nil }) @@ -363,61 +258,55 @@ func (r *EvmRegistry) HealthReport() map[string]error { return map[string]error{r.Name(): r.sync.Healthy()} } -func (r *EvmRegistry) LogEventProvider() logprovider.LogEventProvider { - return r.logEventProvider -} - -func (r *EvmRegistry) initialize() error { - startupCtx, cancel := context.WithTimeout(r.ctx, reInitializationDelay) +func (r *EvmRegistry) refreshActiveUpkeeps() error { + // Allow for max timeout of refreshInterval + ctx, cancel := context.WithTimeout(r.ctx, refreshInterval) defer cancel() - idMap := make(map[string]activeUpkeep) - - r.lggr.Debugf("Re-initializing active upkeeps list") + r.lggr.Debugf("Refreshing active upkeeps list") // get active upkeep ids from contract - ids, err := r.getLatestIDsFromContract(startupCtx) + ids, err := r.getLatestIDsFromContract(ctx) if err != nil { - return fmt.Errorf("failed to get ids from contract: %s", err) + return fmt.Errorf("failed to get active upkeep ids from contract during refresh: %s", err) } + r.active.Reset(ids...) - var offset int - for offset < len(ids) { - batch := FetchUpkeepConfigBatchSize - if len(ids)-offset < batch { - batch = len(ids) - offset - } + return r.refreshLogTriggerUpkeeps(ids) +} - actives, err := r.getUpkeepConfigs(startupCtx, ids[offset:offset+batch]) - if err != nil { - return fmt.Errorf("failed to get configs for id batch (length '%d'): %s", batch, err) +// refreshLogTriggerUpkeeps refreshes the active upkeep ids for log trigger upkeeps +// +// TODO: check for updated config for log trigger upkeeps and update it, currently we ignore them. +func (r *EvmRegistry) refreshLogTriggerUpkeeps(ids []*big.Int) error { + logTriggerIDs := make([]*big.Int, 0) + for _, id := range ids { + uid := &ocr2keepers.UpkeepIdentifier{} + if ok := uid.FromBigInt(id); !ok { + r.lggr.Warnf("failed to parse upkeep id %s", id.String()) } - - for _, active := range actives { - idMap[active.ID.String()] = active + switch core.GetUpkeepType(*uid) { + case ocr2keepers.LogTrigger: + logTriggerIDs = append(logTriggerIDs, id) + default: } - - offset += batch } - - r.mu.Lock() - r.active = idMap - r.mu.Unlock() - - // register upkeep ids for log triggers - for _, id := range ids { - switch getUpkeepType(id.Bytes()) { - case logTrigger: - if err := r.updateTriggerConfig(id, nil); err != nil { - r.lggr.Warnf("failed to update trigger config for upkeep ID %s: %s", id.String(), err) - } - default: + newUpkeeps, err := r.logEventProvider.RefreshActiveUpkeeps(logTriggerIDs...) + if err != nil { + return fmt.Errorf("failed to refresh active upkeep ids in log event provider: %w", err) + } + var merr error + for _, id := range newUpkeeps { + // TODO: find the ConfigSet/UpkeepUnpaused events for this upkeep and pass cfg and block number + // block number should be taken from UpkeepUnpaused if it's block is higher than ConfigSet + if err := r.updateTriggerConfig(id, nil, 0); err != nil { + merr = goerrors.Join(merr, fmt.Errorf("failed to update trigger config for upkeep id %s: %w", id.String(), err)) } } - return nil + return merr } -func (r *EvmRegistry) pollLogs() error { +func (r *EvmRegistry) pollUpkeepStateLogs() error { var latest int64 var end int64 var err error @@ -436,47 +325,34 @@ func (r *EvmRegistry) pollLogs() error { return nil } - { - var logs []logpoller.Log - - if logs, err = r.poller.LogsWithSigs( - end-logEventLookback, - end, - upkeepStateEvents, - r.addr, - pg.WithParentCtx(r.ctx), - ); err != nil { - return fmt.Errorf("%w: %s", ErrLogReadFailure, err) - } + var logs []logpoller.Log + if logs, err = r.poller.LogsWithSigs( + end-logEventLookback, + end, + upkeepStateEvents, + r.addr, + pg.WithParentCtx(r.ctx), + ); err != nil { + return fmt.Errorf("%w: %s", ErrLogReadFailure, err) + } - for _, log := range logs { - r.chLog <- log - } + for _, log := range logs { + r.chLog <- log } return nil } -func UpkeepFilterName(addr common.Address) string { - return logpoller.FilterName("KeeperRegistry Events", addr.String()) -} - -func (r *EvmRegistry) registerEvents(chainID uint64, addr common.Address) error { - // Add log filters for the log poller so that it can poll and find the logs that - // we need - return r.poller.RegisterFilter(logpoller.Filter{ - Name: UpkeepFilterName(addr), - EventSigs: append(upkeepStateEvents, upkeepActiveEvents...), - Addresses: []common.Address{addr}, - }) -} - func (r *EvmRegistry) processUpkeepStateLog(l logpoller.Log) error { - hash := l.TxHash.String() - if _, ok := r.txHashes[hash]; ok { + lid := fmt.Sprintf("%s%d", l.TxHash.String(), l.LogIndex) + r.mu.Lock() + if _, ok := r.logProcessed[lid]; ok { + r.mu.Unlock() return nil } - r.txHashes[hash] = true + r.logProcessed[lid] = true + r.mu.Unlock() + txHash := l.TxHash.String() rawLog := l.ToGethLog() abilog, err := r.registry.ParseLog(rawLog) @@ -486,52 +362,70 @@ func (r *EvmRegistry) processUpkeepStateLog(l logpoller.Log) error { switch l := abilog.(type) { case *iregistry21.IKeeperRegistryMasterUpkeepPaused: - r.lggr.Debugf("KeeperRegistryUpkeepPaused log detected for upkeep ID %s in transaction %s", l.Id.String(), hash) + r.lggr.Debugf("KeeperRegistryUpkeepPaused log detected for upkeep ID %s in transaction %s", l.Id.String(), txHash) r.removeFromActive(l.Id) case *iregistry21.IKeeperRegistryMasterUpkeepCanceled: - r.lggr.Debugf("KeeperRegistryUpkeepCanceled log detected for upkeep ID %s in transaction %s", l.Id.String(), hash) + r.lggr.Debugf("KeeperRegistryUpkeepCanceled log detected for upkeep ID %s in transaction %s", l.Id.String(), txHash) + r.removeFromActive(l.Id) + case *iregistry21.IKeeperRegistryMasterUpkeepMigrated: + r.lggr.Debugf("KeeperRegistryMasterUpkeepMigrated log detected for upkeep ID %s in transaction %s", l.Id.String(), txHash) r.removeFromActive(l.Id) case *iregistry21.IKeeperRegistryMasterUpkeepTriggerConfigSet: - r.lggr.Debugf("KeeperRegistryUpkeepTriggerConfigSet log detected for upkeep ID %s in transaction %s", l.Id.String(), hash) - // passing nil instead of l.TriggerConfig to protect against reorgs, - // as we'll fetch the latest config from the contract - if err := r.updateTriggerConfig(l.Id, nil); err != nil { - r.lggr.Warnf("failed to update trigger config for upkeep ID %s: %s", l.Id.String(), err) + r.lggr.Debugf("KeeperRegistryUpkeepTriggerConfigSet log detected for upkeep ID %s in transaction %s", l.Id.String(), txHash) + if err := r.updateTriggerConfig(l.Id, l.TriggerConfig, rawLog.BlockNumber); err != nil { + r.lggr.Warnf("failed to update trigger config upon KeeperRegistryMasterUpkeepTriggerConfigSet for upkeep ID %s: %s", l.Id.String(), err) } case *iregistry21.IKeeperRegistryMasterUpkeepRegistered: - trigger := getUpkeepType(l.Id.Bytes()) - r.lggr.Debugf("KeeperRegistryUpkeepRegistered log detected for upkeep ID %s (trigger=%d) in transaction %s", l.Id.String(), trigger, hash) - r.addToActive(l.Id, false) - if err := r.updateTriggerConfig(l.Id, nil); err != nil { - r.lggr.Warnf("failed to update trigger config for upkeep ID %s: %s", err) + uid := &ocr2keepers.UpkeepIdentifier{} + uid.FromBigInt(l.Id) + trigger := core.GetUpkeepType(*uid) + r.lggr.Debugf("KeeperRegistryUpkeepRegistered log detected for upkeep ID %s (trigger=%d) in transaction %s", l.Id.String(), trigger, txHash) + r.active.Add(l.Id) + if err := r.updateTriggerConfig(l.Id, nil, rawLog.BlockNumber); err != nil { + r.lggr.Warnf("failed to update trigger config upon KeeperRegistryMasterUpkeepRegistered for upkeep ID %s: %s", err) } case *iregistry21.IKeeperRegistryMasterUpkeepReceived: - r.lggr.Debugf("KeeperRegistryUpkeepReceived log detected for upkeep ID %s in transaction %s", l.Id.String(), hash) - r.addToActive(l.Id, false) + r.lggr.Debugf("KeeperRegistryUpkeepReceived log detected for upkeep ID %s in transaction %s", l.Id.String(), txHash) + r.active.Add(l.Id) + if err := r.updateTriggerConfig(l.Id, nil, rawLog.BlockNumber); err != nil { + r.lggr.Warnf("failed to update trigger config upon KeeperRegistryMasterUpkeepReceived for upkeep ID %s: %s", err) + } case *iregistry21.IKeeperRegistryMasterUpkeepUnpaused: - r.lggr.Debugf("KeeperRegistryUpkeepUnpaused log detected for upkeep ID %s in transaction %s", l.Id.String(), hash) - r.addToActive(l.Id, false) - if err := r.updateTriggerConfig(l.Id, nil); err != nil { - r.lggr.Warnf("failed to update trigger config for upkeep ID %s: %s", err) + r.lggr.Debugf("KeeperRegistryUpkeepUnpaused log detected for upkeep ID %s in transaction %s", l.Id.String(), txHash) + r.active.Add(l.Id) + if err := r.updateTriggerConfig(l.Id, nil, rawLog.BlockNumber); err != nil { + r.lggr.Warnf("failed to update trigger config upon KeeperRegistryMasterUpkeepUnpaused for upkeep ID %s: %s", err) } - case *iregistry21.IKeeperRegistryMasterUpkeepGasLimitSet: - r.lggr.Debugf("KeeperRegistryUpkeepGasLimitSet log detected for upkeep ID %s in transaction %s", l.Id.String(), hash) - r.addToActive(l.Id, true) default: - r.lggr.Debugf("Unknown log detected for log %+v in transaction %s", l, hash) + r.lggr.Debugf("Unknown log detected for log %+v in transaction %s", l, txHash) } return nil } +func RegistryUpkeepFilterName(addr common.Address) string { + return logpoller.FilterName("KeeperRegistry Events", addr.String()) +} + +func (r *EvmRegistry) registerEvents(chainID uint64, addr common.Address) error { + // Add log filters for the log poller so that it can poll and find the logs that + // we need + return r.poller.RegisterFilter(logpoller.Filter{ + Name: RegistryUpkeepFilterName(addr), + EventSigs: upkeepStateEvents, + Addresses: []common.Address{addr}, + }) +} + +// Removes an upkeepID from active list and unregisters the log filter for log upkeeps func (r *EvmRegistry) removeFromActive(id *big.Int) { - r.mu.Lock() - delete(r.active, id.String()) - r.mu.Unlock() + r.active.Remove(id) - trigger := getUpkeepType(id.Bytes()) + uid := &ocr2keepers.UpkeepIdentifier{} + uid.FromBigInt(id) + trigger := core.GetUpkeepType(*uid) switch trigger { - case logTrigger: + case ocr2keepers.LogTrigger: if err := r.logEventProvider.UnregisterFilter(id); err != nil { r.lggr.Warnw("failed to unregister log filter", "upkeepID", id.String()) } @@ -540,52 +434,25 @@ func (r *EvmRegistry) removeFromActive(id *big.Int) { } } -func (r *EvmRegistry) addToActive(id *big.Int, force bool) { - r.mu.Lock() - defer r.mu.Unlock() - - if r.active == nil { - r.active = make(map[string]activeUpkeep) - } - - if _, ok := r.active[id.String()]; !ok || force { - actives, err := r.getUpkeepConfigs(r.ctx, []*big.Int{id}) - if err != nil { - r.lggr.Errorf("failed to get upkeep configs during adding active upkeep: %w", err) - return - } - - if len(actives) != 1 { - return - } - - r.active[id.String()] = actives[0] - } -} - -func (r *EvmRegistry) buildCallOpts(ctx context.Context, block *big.Int) (*bind.CallOpts, error) { +func (r *EvmRegistry) buildCallOpts(ctx context.Context, block *big.Int) *bind.CallOpts { opts := bind.CallOpts{ - Context: ctx, - BlockNumber: nil, + Context: ctx, } if block == nil || block.Int64() == 0 { - l := r.ht.LatestChain() - if l != nil && l.BlockNumber() != 0 { - opts.BlockNumber = big.NewInt(l.BlockNumber()) + l := r.bs.latestBlock.Load() + if l != nil && l.Number != 0 { + opts.BlockNumber = big.NewInt(int64(l.Number)) } } else { opts.BlockNumber = block } - return &opts, nil + return &opts } func (r *EvmRegistry) getLatestIDsFromContract(ctx context.Context) ([]*big.Int, error) { - opts, err := r.buildCallOpts(ctx, nil) - if err != nil { - return nil, err - } + opts := r.buildCallOpts(ctx, nil) state, err := r.registry.GetState(opts) if err != nil { @@ -621,257 +488,11 @@ func (r *EvmRegistry) getLatestIDsFromContract(ctx context.Context) ([]*big.Int, return ids, nil } -func (r *EvmRegistry) doCheck(ctx context.Context, keys []ocr2keepers.UpkeepPayload, chResult chan checkResult) { - upkeepResults, err := r.checkUpkeeps(ctx, keys) - if err != nil { - chResult <- checkResult{ - err: err, - } - return - } - - upkeepResults, err = r.feedLookup(ctx, upkeepResults) - if err != nil { - chResult <- checkResult{ - err: err, - } - return - } - - upkeepResults, err = r.simulatePerformUpkeeps(ctx, upkeepResults) - if err != nil { - chResult <- checkResult{ - err: err, - } - return - } - - chResult <- checkResult{ - cr: upkeepResults, - } -} - -func (r *EvmRegistry) getBlockAndUpkeepId(key ocr2keepers.UpkeepPayload) (*big.Int, *big.Int) { - block := new(big.Int).SetInt64(key.Trigger.BlockNumber) - upkeepId := new(big.Int).SetBytes(key.Upkeep.ID) - return block, upkeepId -} - -// TODO (AUTO-2013): Have better error handling to not return nil results in case of partial errors -func (r *EvmRegistry) checkUpkeeps(ctx context.Context, keys []ocr2keepers.UpkeepPayload) ([]ocr2keepers.CheckResult, error) { - var ( - checkReqs = make([]rpc.BatchElem, len(keys)) - checkResults = make([]*string, len(keys)) - blocks = make([]*big.Int, len(keys)) - upkeepIds = make([]*big.Int, len(keys)) - ) - - for i, key := range keys { - block, upkeepId := r.getBlockAndUpkeepId(key) - blocks[i] = block - upkeepIds[i] = upkeepId - - opts, err := r.buildCallOpts(ctx, block) - if err != nil { - return nil, err - } - var payload []byte - switch getUpkeepType(upkeepId.Bytes()) { - case logTrigger: - // check data will include the log trigger config - payload, err = r.abi.Pack("checkUpkeep", upkeepId, key.CheckData) - if err != nil { - return nil, err - } - default: - payload, err = r.abi.Pack("checkUpkeep", upkeepId) - if err != nil { - return nil, err - } - } - - var result string - checkReqs[i] = rpc.BatchElem{ - Method: "eth_call", - Args: []interface{}{ - map[string]interface{}{ - "to": r.addr.Hex(), - "data": hexutil.Bytes(payload), - }, - hexutil.EncodeBig(opts.BlockNumber), - }, - Result: &result, - } - - checkResults[i] = &result - } - - if err := r.client.BatchCallContext(ctx, checkReqs); err != nil { - return nil, err - } - - var ( - multiErr error - results = make([]ocr2keepers.CheckResult, len(keys)) - ) - - for i, req := range checkReqs { - if req.Error != nil { - r.lggr.Debugf("error encountered for key %s with message '%s' in check", keys[i], req.Error) - multierr.AppendInto(&multiErr, req.Error) - } else { - var err error - results[i], err = r.packer.UnpackCheckResult(keys[i], *checkResults[i]) - if err != nil { - return nil, errors.Wrap(err, "failed to unpack check result") - } - } - } - - return results, multiErr -} - -// TODO (AUTO-2013): Have better error handling to not return nil results in case of partial errors -func (r *EvmRegistry) simulatePerformUpkeeps(ctx context.Context, checkResults []ocr2keepers.CheckResult) ([]ocr2keepers.CheckResult, error) { - var ( - performReqs = make([]rpc.BatchElem, 0, len(checkResults)) - performResults = make([]*string, 0, len(checkResults)) - performToKeyIdx = make([]int, 0, len(checkResults)) - ) - - for i, cr := range checkResults { - if !cr.Eligible { - continue - } - - block, upkeepId := r.getBlockAndUpkeepId(cr.Payload) - - opts, err := r.buildCallOpts(ctx, block) - if err != nil { - return nil, err - } - - // Since checkUpkeep is true, simulate perform upkeep to ensure it doesn't revert - payload, err := r.abi.Pack("simulatePerformUpkeep", upkeepId, cr.PerformData) - if err != nil { - return nil, err - } - - var result string - performReqs = append(performReqs, rpc.BatchElem{ - Method: "eth_call", - Args: []interface{}{ - map[string]interface{}{ - "to": r.addr.Hex(), - "data": hexutil.Bytes(payload), - }, - hexutil.EncodeBig(opts.BlockNumber), - }, - Result: &result, - }) - - performResults = append(performResults, &result) - performToKeyIdx = append(performToKeyIdx, i) - } - - if len(performReqs) > 0 { - if err := r.client.BatchCallContext(ctx, performReqs); err != nil { - return nil, err - } - } - - var multiErr error - for i, req := range performReqs { - if req.Error != nil { - r.lggr.Debugf("error encountered for key %d|%s with message '%s' in simulate perform", checkResults[i].Payload.Trigger.BlockNumber, new(big.Int).SetBytes(checkResults[i].Payload.Upkeep.ID), req.Error) - multierr.AppendInto(&multiErr, req.Error) - } else { - simulatePerformSuccess, err := r.packer.UnpackPerformResult(*performResults[i]) - if err != nil { - return nil, err - } - - if !simulatePerformSuccess { - checkResults[performToKeyIdx[i]].Eligible = false - } - } - } - - return checkResults, multiErr -} - -// TODO (AUTO-2013): Have better error handling to not return nil results in case of partial errors -func (r *EvmRegistry) getUpkeepConfigs(ctx context.Context, ids []*big.Int) ([]activeUpkeep, error) { - if len(ids) == 0 { - return []activeUpkeep{}, nil - } - - var ( - uReqs = make([]rpc.BatchElem, len(ids)) - uResults = make([]*string, len(ids)) - ) - - for i, id := range ids { - opts, err := r.buildCallOpts(ctx, nil) - if err != nil { - return nil, fmt.Errorf("failed to get call opts: %s", err) - } - - payload, err := r.abi.Pack("getUpkeep", id) - if err != nil { - return nil, fmt.Errorf("failed to pack id with abi: %s", err) - } - - var result string - uReqs[i] = rpc.BatchElem{ - Method: "eth_call", - Args: []interface{}{ - map[string]interface{}{ - "to": r.addr.Hex(), - "data": hexutil.Bytes(payload), - }, - hexutil.EncodeBig(opts.BlockNumber), - }, - Result: &result, - } - - uResults[i] = &result - } - - if err := r.client.BatchCallContext(ctx, uReqs); err != nil { - return nil, fmt.Errorf("rpc error: %s", err) - } - - var ( - multiErr error - results = make([]activeUpkeep, len(ids)) - ) - - for i, req := range uReqs { - if req.Error != nil { - r.lggr.Debugf("error encountered for config id %s with message '%s' in get config", ids[i], req.Error) - multierr.AppendInto(&multiErr, req.Error) - } else { - info, err := r.packer.UnpackUpkeepInfo(ids[i], *uResults[i]) - if err != nil { - return nil, fmt.Errorf("failed to unpack result: %s", err) - } - results[i] = activeUpkeep{ // TODO - ID: ids[i], - PerformGasLimit: info.PerformGas, - CheckData: info.CheckData, - Admin: info.Admin, - } - } - } - - return results, multiErr -} - -func (r *EvmRegistry) updateTriggerConfig(id *big.Int, cfg []byte) error { - uid := id.String() - switch getUpkeepType(id.Bytes()) { - case logTrigger: +func (r *EvmRegistry) updateTriggerConfig(id *big.Int, cfg []byte, logBlock uint64) error { + uid := &ocr2keepers.UpkeepIdentifier{} + uid.FromBigInt(id) + switch core.GetUpkeepType(*uid) { + case ocr2keepers.LogTrigger: if len(cfg) == 0 { fetched, err := r.fetchTriggerConfig(id) if err != nil { @@ -883,10 +504,14 @@ func (r *EvmRegistry) updateTriggerConfig(id *big.Int, cfg []byte) error { if err != nil { return errors.Wrap(err, "failed to unpack log upkeep config") } - if err := r.logEventProvider.RegisterFilter(id, logprovider.LogTriggerConfig(parsed)); err != nil { + if err := r.logEventProvider.RegisterFilter(logprovider.FilterOptions{ + TriggerConfig: logprovider.LogTriggerConfig(parsed), + UpkeepID: id, + UpdateBlock: logBlock, + }); err != nil { return errors.Wrap(err, "failed to register log filter") } - r.lggr.Debugw("registered log filter", "upkeepID", uid, "cfg", parsed) + r.lggr.Debugw("registered log filter", "upkeepID", id.String(), "cfg", parsed) default: } return nil @@ -894,11 +519,7 @@ func (r *EvmRegistry) updateTriggerConfig(id *big.Int, cfg []byte) error { // updateTriggerConfig gets invoked upon changes in the trigger config of an upkeep. func (r *EvmRegistry) fetchTriggerConfig(id *big.Int) ([]byte, error) { - opts, err := r.buildCallOpts(r.ctx, nil) - if err != nil { - r.lggr.Warnw("failed to build opts for tx", "err", err) - return nil, err - } + opts := r.buildCallOpts(r.ctx, nil) cfg, err := r.registry.GetUpkeepTriggerConfig(opts, id) if err != nil { r.lggr.Warnw("failed to get trigger config", "err", err) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go new file mode 100644 index 00000000000..07462208113 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go @@ -0,0 +1,348 @@ +package evm + +import ( + "context" + "fmt" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/rpc" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/encoding" +) + +const ( + // validCheckBlockRange decides the max distance between the check block and the current block + // allowed in checkPipeline + validCheckBlockRange = 128 +) + +type checkResult struct { + cr []ocr2keepers.CheckResult + err error +} + +func (r *EvmRegistry) CheckUpkeeps(ctx context.Context, keys ...ocr2keepers.UpkeepPayload) ([]ocr2keepers.CheckResult, error) { + r.lggr.Debugw("Checking upkeeps", "upkeeps", keys) + for i := range keys { + if keys[i].Trigger.BlockNumber == 0 { // check block was not populated, use latest + latest := r.bs.latestBlock.Load() + copy(keys[i].Trigger.BlockHash[:], latest.Hash[:]) + keys[i].Trigger.BlockNumber = latest.Number + r.lggr.Debugf("Check upkeep key had no trigger block number, using latest block %v", keys[i].Trigger.BlockNumber) + } + } + + chResult := make(chan checkResult, 1) + go r.doCheck(ctx, keys, chResult) + + select { + case rs := <-chResult: + result := make([]ocr2keepers.CheckResult, len(rs.cr)) + copy(result, rs.cr) + return result, rs.err + case <-ctx.Done(): + // safety on context done to provide an error on context cancellation + // contract calls through the geth wrappers are a bit of a black box + // so this safety net ensures contexts are fully respected and contract + // call functions have a more graceful closure outside the scope of + // CheckUpkeep needing to return immediately. + return nil, fmt.Errorf("%w: failed to check upkeep on registry", ErrContextCancelled) + } +} + +func (r *EvmRegistry) doCheck(ctx context.Context, keys []ocr2keepers.UpkeepPayload, chResult chan checkResult) { + upkeepResults, err := r.checkUpkeeps(ctx, keys) + if err != nil { + chResult <- checkResult{ + err: err, + } + return + } + + upkeepResults = r.feedLookup(ctx, upkeepResults) + + upkeepResults, err = r.simulatePerformUpkeeps(ctx, upkeepResults) + if err != nil { + chResult <- checkResult{ + err: err, + } + return + } + + chResult <- checkResult{ + cr: upkeepResults, + } +} + +// getBlockAndUpkeepId retrieves check block number, block hash from trigger and upkeep id +func (r *EvmRegistry) getBlockAndUpkeepId(upkeepID ocr2keepers.UpkeepIdentifier, trigger ocr2keepers.Trigger) (*big.Int, common.Hash, *big.Int) { + block := new(big.Int).SetInt64(int64(trigger.BlockNumber)) + return block, common.BytesToHash(trigger.BlockHash[:]), upkeepID.BigInt() +} + +func (r *EvmRegistry) getBlockHash(blockNumber *big.Int) (common.Hash, error) { + blocks, err := r.poller.GetBlocksRange(r.ctx, []uint64{blockNumber.Uint64()}) + if err != nil { + return [32]byte{}, err + } + if len(blocks) == 0 { + return [32]byte{}, fmt.Errorf("could not find block %d in log poller", blockNumber.Uint64()) + } + + return blocks[0].BlockHash, nil +} + +func (r *EvmRegistry) getTxBlock(txHash common.Hash) (*big.Int, common.Hash, error) { + // TODO: do manual eth_getTransactionReceipt call to get block number and hash + txr, err := r.client.TransactionReceipt(r.ctx, txHash) + if err != nil { + return nil, common.Hash{}, err + } + + return txr.BlockNumber, txr.BlockHash, nil +} + +// verifyCheckBlock checks that the check block and hash are valid, returns the pipeline execution state and retryable +func (r *EvmRegistry) verifyCheckBlock(ctx context.Context, checkBlock, upkeepId *big.Int, checkHash common.Hash) (state encoding.PipelineExecutionState, retryable bool) { + // verify check block number is not too old + latestBlock := r.bs.latestBlock.Load() + if int64(latestBlock.Number)-checkBlock.Int64() > validCheckBlockRange { + r.lggr.Warnf("latest block is %d, check block number %s is too old for upkeepId %s", r.bs.latestBlock.Load(), checkBlock, upkeepId) + return encoding.CheckBlockTooOld, false + } + r.lggr.Warnf("latestBlock=%d checkBlock=%d", r.bs.latestBlock.Load(), checkBlock.Int64()) + + var h string + var ok bool + // verify check block number and hash are valid + h, ok = r.bs.queryBlocksMap(checkBlock.Int64()) + if !ok { + r.lggr.Warnf("check block %s does not exist in block subscriber for upkeepId %s, querying eth client", checkBlock, upkeepId) + b, err := r.getBlockHash(checkBlock) + if err != nil { + r.lggr.Warnf("failed to query block %s: %s", checkBlock, err.Error()) + return encoding.RpcFlakyFailure, true + } + h = b.Hex() + } + if checkHash.Hex() != h { + r.lggr.Warnf("check block %s hash do not match. %s from block subscriber vs %s from trigger for upkeepId %s", checkBlock, h, checkHash.Hex(), upkeepId) + return encoding.CheckBlockInvalid, false + } + return encoding.NoPipelineError, false +} + +// verifyLogExists checks that the log still exists on chain, returns failure reason, pipeline error, and retryable +func (r *EvmRegistry) verifyLogExists(upkeepId *big.Int, p ocr2keepers.UpkeepPayload) (encoding.UpkeepFailureReason, encoding.PipelineExecutionState, bool) { + logBlockNumber := int64(p.Trigger.LogTriggerExtension.BlockNumber) + logBlockHash := common.BytesToHash(p.Trigger.LogTriggerExtension.BlockHash[:]) + // if log block number is populated, check log block number and block hash + if logBlockNumber != 0 { + h, ok := r.bs.queryBlocksMap(logBlockNumber) + if ok && h == logBlockHash.Hex() { + r.lggr.Debugf("tx hash %s exists on chain at block number %d for upkeepId %s", hexutil.Encode(p.Trigger.LogTriggerExtension.TxHash[:]), logBlockNumber, upkeepId) + return encoding.UpkeepFailureReasonNone, encoding.NoPipelineError, false + } + r.lggr.Debugf("log block %d does not exist in block subscriber for upkeepId %s, querying eth client", logBlockNumber, upkeepId) + } else { + r.lggr.Debugf("log block not provided, querying eth client for tx hash %s for upkeepId %s", hexutil.Encode(p.Trigger.LogTriggerExtension.TxHash[:]), upkeepId) + } + // query eth client as a fallback + bn, _, err := r.getTxBlock(p.Trigger.LogTriggerExtension.TxHash) + if err != nil { + // primitive way of checking errors + if strings.Contains(err.Error(), "missing required field") || strings.Contains(err.Error(), "not found") { + return encoding.UpkeepFailureReasonTxHashNoLongerExists, encoding.NoPipelineError, false + } + r.lggr.Warnf("failed to query tx hash %s for upkeepId %s: %s", hexutil.Encode(p.Trigger.LogTriggerExtension.TxHash[:]), upkeepId, err.Error()) + return encoding.UpkeepFailureReasonNone, encoding.RpcFlakyFailure, true + } + if bn == nil { + r.lggr.Warnf("tx hash %s does not exist on chain for upkeepId %s.", hexutil.Encode(p.Trigger.LogTriggerExtension.TxHash[:]), upkeepId) + return encoding.UpkeepFailureReasonTxHashNoLongerExists, encoding.NoPipelineError, false + } + r.lggr.Debugf("tx hash %s exists on chain for upkeepId %s", hexutil.Encode(p.Trigger.LogTriggerExtension.TxHash[:]), upkeepId) + return encoding.UpkeepFailureReasonNone, encoding.NoPipelineError, false +} + +func (r *EvmRegistry) checkUpkeeps(ctx context.Context, payloads []ocr2keepers.UpkeepPayload) ([]ocr2keepers.CheckResult, error) { + var ( + checkReqs []rpc.BatchElem + checkResults []*string + results = make([]ocr2keepers.CheckResult, len(payloads)) + ) + indices := map[int]int{} + + for i, p := range payloads { + block, checkHash, upkeepId := r.getBlockAndUpkeepId(p.UpkeepID, p.Trigger) + state, retryable := r.verifyCheckBlock(ctx, block, upkeepId, checkHash) + if state != encoding.NoPipelineError { + results[i] = encoding.GetIneligibleCheckResultWithoutPerformData(p, encoding.UpkeepFailureReasonNone, state, retryable) + continue + } + + opts := r.buildCallOpts(ctx, block) + var payload []byte + var err error + uid := &ocr2keepers.UpkeepIdentifier{} + uid.FromBigInt(upkeepId) + switch core.GetUpkeepType(*uid) { + case ocr2keepers.LogTrigger: + reason, state, retryable := r.verifyLogExists(upkeepId, p) + if reason != encoding.UpkeepFailureReasonNone || state != encoding.NoPipelineError { + results[i] = encoding.GetIneligibleCheckResultWithoutPerformData(p, reason, state, retryable) + continue + } + + // check data will include the log trigger config + payload, err = r.abi.Pack("checkUpkeep", upkeepId, p.CheckData) + if err != nil { + // pack error, no retryable + r.lggr.Warnf("failed to pack log trigger checkUpkeep data for upkeepId %s with check data %s: %s", upkeepId, hexutil.Encode(p.CheckData), err) + results[i] = encoding.GetIneligibleCheckResultWithoutPerformData(p, encoding.UpkeepFailureReasonNone, encoding.PackUnpackDecodeFailed, false) + continue + } + default: + // checkUpkeep is overloaded on the contract for conditionals and log upkeeps + // Need to use the first function (checkUpkeep0) for conditionals + payload, err = r.abi.Pack("checkUpkeep0", upkeepId) + if err != nil { + // pack error, no retryable + r.lggr.Warnf("failed to pack conditional checkUpkeep data for upkeepId %s with check data %s: %s", upkeepId, hexutil.Encode(p.CheckData), err) + results[i] = encoding.GetIneligibleCheckResultWithoutPerformData(p, encoding.UpkeepFailureReasonNone, encoding.PackUnpackDecodeFailed, false) + continue + } + } + indices[len(checkReqs)] = i + results[i] = encoding.GetIneligibleCheckResultWithoutPerformData(p, encoding.UpkeepFailureReasonNone, encoding.NoPipelineError, false) + + var result string + checkReqs = append(checkReqs, rpc.BatchElem{ + Method: "eth_call", + Args: []interface{}{ + map[string]interface{}{ + "to": r.addr.Hex(), + "data": hexutil.Bytes(payload), + }, + hexutil.EncodeBig(opts.BlockNumber), + }, + Result: &result, + }) + + checkResults = append(checkResults, &result) + } + + if len(checkResults) > 0 { + // In contrast to CallContext, BatchCallContext only returns errors that have occurred + // while sending the request. Any error specific to a request is reported through the + // Error field of the corresponding BatchElem. + // hence, if BatchCallContext returns an error, it will be an error which will terminate the pipeline + if err := r.client.BatchCallContext(ctx, checkReqs); err != nil { + r.lggr.Errorf("failed to batch call for checkUpkeeps: %s", err) + return nil, err + } + } + + for i, req := range checkReqs { + index := indices[i] + if req.Error != nil { + // individual upkeep failed in a batch call, retryable + r.lggr.Warnf("error encountered in check result for upkeepId %s: %s", results[index].UpkeepID.String(), req.Error) + results[index].Retryable = true + results[index].PipelineExecutionState = uint8(encoding.RpcFlakyFailure) + } else { + var err error + results[index], err = r.packer.UnpackCheckResult(payloads[index], *checkResults[i]) + if err != nil { + r.lggr.Warnf("failed to unpack check result: %s", err) + } + } + } + + return results, nil +} + +func (r *EvmRegistry) simulatePerformUpkeeps(ctx context.Context, checkResults []ocr2keepers.CheckResult) ([]ocr2keepers.CheckResult, error) { + var ( + performReqs = make([]rpc.BatchElem, 0, len(checkResults)) + performResults = make([]*string, 0, len(checkResults)) + performToKeyIdx = make([]int, 0, len(checkResults)) + ) + + for i, cr := range checkResults { + if !cr.Eligible { + continue + } + + block, _, upkeepId := r.getBlockAndUpkeepId(cr.UpkeepID, cr.Trigger) + + opts := r.buildCallOpts(ctx, block) + + // Since checkUpkeep is true, simulate perform upkeep to ensure it doesn't revert + payload, err := r.abi.Pack("simulatePerformUpkeep", upkeepId, cr.PerformData) + if err != nil { + // pack failed, not retryable + r.lggr.Warnf("failed to pack perform data %s for %s: %s", hexutil.Encode(cr.PerformData), upkeepId, err) + checkResults[i].Eligible = false + checkResults[i].PipelineExecutionState = uint8(encoding.PackUnpackDecodeFailed) + continue + } + + var result string + performReqs = append(performReqs, rpc.BatchElem{ + Method: "eth_call", + Args: []interface{}{ + map[string]interface{}{ + "to": r.addr.Hex(), + "data": hexutil.Bytes(payload), + }, + hexutil.EncodeBig(opts.BlockNumber), + }, + Result: &result, + }) + + performResults = append(performResults, &result) + performToKeyIdx = append(performToKeyIdx, i) + } + + if len(performReqs) > 0 { + if err := r.client.BatchCallContext(ctx, performReqs); err != nil { + r.lggr.Errorf("failed to batch call for simulatePerformUpkeeps: %s", err) + return nil, err + } + } + + for i, req := range performReqs { + idx := performToKeyIdx[i] + if req.Error != nil { + // individual upkeep failed in a batch call, retryable + r.lggr.Warnf("failed to simulate upkeepId %s: %s", checkResults[idx].UpkeepID.String(), req.Error) + checkResults[idx].Retryable = true + checkResults[idx].Eligible = false + checkResults[idx].PipelineExecutionState = uint8(encoding.RpcFlakyFailure) + continue + } + + state, simulatePerformSuccess, err := r.packer.UnpackPerformResult(*performResults[i]) + if err != nil { + // unpack failed, not retryable + r.lggr.Warnf("failed to unpack simulate performUpkeep result for upkeepId %s for state %d: %s", checkResults[idx].UpkeepID.String(), state, req.Error) + checkResults[idx].Retryable = false + checkResults[idx].Eligible = false + checkResults[idx].PipelineExecutionState = uint8(state) + continue + } + + if !simulatePerformSuccess { + r.lggr.Warnf("upkeepId %s is not eligible after simulation of perform", checkResults[idx].UpkeepID.String()) + checkResults[performToKeyIdx[i]].Eligible = false + } + } + + return checkResults, nil +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline_test.go new file mode 100644 index 00000000000..88016f07f15 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline_test.go @@ -0,0 +1,603 @@ +package evm + +import ( + "context" + "fmt" + "math/big" + "sync/atomic" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rpc" + + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + evmClientMocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/encoding" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" +) + +func TestRegistry_GetBlockAndUpkeepId(t *testing.T) { + r := &EvmRegistry{} + tests := []struct { + name string + input ocr2keepers.UpkeepPayload + wantBlock *big.Int + wantUpkeep *big.Int + }{ + { + "happy flow", + ocr2keepers.UpkeepPayload{ + UpkeepID: core.UpkeepIDFromInt("10"), + Trigger: ocr2keepers.Trigger{ + BlockNumber: 1, + BlockHash: common.HexToHash("0x1"), + }, + }, + big.NewInt(1), + big.NewInt(10), + }, + { + "empty trigger", + ocr2keepers.UpkeepPayload{ + UpkeepID: core.UpkeepIDFromInt("10"), + }, + big.NewInt(0), + big.NewInt(10), + }, + { + "empty payload", + ocr2keepers.UpkeepPayload{}, + big.NewInt(0), + big.NewInt(0), + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + block, _, upkeep := r.getBlockAndUpkeepId(tc.input.UpkeepID, tc.input.Trigger) + assert.Equal(t, tc.wantBlock, block) + assert.Equal(t, tc.wantUpkeep.String(), upkeep.String()) + }) + } +} + +func TestRegistry_VerifyCheckBlock(t *testing.T) { + lggr := logger.TestLogger(t) + upkeepId := ocr2keepers.UpkeepIdentifier{} + upkeepId.FromBigInt(big.NewInt(12345)) + tests := []struct { + name string + checkBlock *big.Int + latestBlock ocr2keepers.BlockKey + upkeepId *big.Int + checkHash common.Hash + payload ocr2keepers.UpkeepPayload + blocks map[int64]string + poller logpoller.LogPoller + state encoding.PipelineExecutionState + retryable bool + makeEthCall bool + }{ + { + name: "check block number too told", + checkBlock: big.NewInt(500), + latestBlock: ocr2keepers.BlockKey{Number: 800}, + upkeepId: big.NewInt(12345), + checkHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), + payload: ocr2keepers.UpkeepPayload{ + UpkeepID: upkeepId, + Trigger: ocr2keepers.NewTrigger(500, common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83")), + WorkID: "work", + }, + state: encoding.CheckBlockTooOld, + }, + { + name: "for an invalid check block number, if hash does not match the check hash, return CheckBlockInvalid", + checkBlock: big.NewInt(500), + latestBlock: ocr2keepers.BlockKey{Number: 560}, + upkeepId: big.NewInt(12345), + checkHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), + payload: ocr2keepers.UpkeepPayload{ + UpkeepID: upkeepId, + Trigger: ocr2keepers.NewTrigger(500, common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83")), + WorkID: "work", + }, + poller: &mockLogPoller{ + GetBlocksRangeFn: func(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]logpoller.LogPollerBlock, error) { + return []logpoller.LogPollerBlock{ + { + BlockHash: common.HexToHash("abcdef"), + }, + }, nil + }, + }, + state: encoding.CheckBlockInvalid, + retryable: false, + makeEthCall: true, + }, + { + name: "for an invalid check block number, if hash does match the check hash, return NoPipelineError", + checkBlock: big.NewInt(500), + latestBlock: ocr2keepers.BlockKey{Number: 560}, + upkeepId: big.NewInt(12345), + checkHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), + payload: ocr2keepers.UpkeepPayload{ + UpkeepID: upkeepId, + Trigger: ocr2keepers.NewTrigger(500, common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83")), + WorkID: "work", + }, + poller: &mockLogPoller{ + GetBlocksRangeFn: func(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]logpoller.LogPollerBlock, error) { + return []logpoller.LogPollerBlock{ + { + BlockHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), + }, + }, nil + }, + }, + state: encoding.NoPipelineError, + retryable: false, + makeEthCall: true, + }, + { + name: "check block hash does not match", + checkBlock: big.NewInt(500), + latestBlock: ocr2keepers.BlockKey{Number: 560}, + upkeepId: big.NewInt(12345), + checkHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), + payload: ocr2keepers.UpkeepPayload{ + UpkeepID: upkeepId, + Trigger: ocr2keepers.NewTrigger(500, common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83")), + WorkID: "work", + }, + blocks: map[int64]string{ + 500: "0xa518faeadcc423338c62572da84dda35fe44b34f521ce88f6081b703b250cca4", + }, + state: encoding.CheckBlockInvalid, + }, + { + name: "check block is valid", + checkBlock: big.NewInt(500), + latestBlock: ocr2keepers.BlockKey{Number: 560}, + upkeepId: big.NewInt(12345), + checkHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), + payload: ocr2keepers.UpkeepPayload{ + UpkeepID: upkeepId, + Trigger: ocr2keepers.NewTrigger(500, common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83")), + WorkID: "work", + }, + blocks: map[int64]string{ + 500: "0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83", + }, + state: encoding.NoPipelineError, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + bs := &BlockSubscriber{ + latestBlock: atomic.Pointer[ocr2keepers.BlockKey]{}, + blocks: tc.blocks, + } + bs.latestBlock.Store(&tc.latestBlock) + e := &EvmRegistry{ + lggr: lggr, + bs: bs, + poller: tc.poller, + } + if tc.makeEthCall { + client := new(evmClientMocks.Client) + client.On("BlockByNumber", mock.Anything, tc.checkBlock).Return(nil, fmt.Errorf("error")) + e.client = client + } + + state, retryable := e.verifyCheckBlock(context.Background(), tc.checkBlock, tc.upkeepId, tc.checkHash) + assert.Equal(t, tc.state, state) + assert.Equal(t, tc.retryable, retryable) + }) + } +} + +type mockLogPoller struct { + logpoller.LogPoller + GetBlocksRangeFn func(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]logpoller.LogPollerBlock, error) +} + +func (p *mockLogPoller) GetBlocksRange(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]logpoller.LogPollerBlock, error) { + return p.GetBlocksRangeFn(ctx, numbers, qopts...) +} + +func TestRegistry_VerifyLogExists(t *testing.T) { + lggr := logger.TestLogger(t) + upkeepId := ocr2keepers.UpkeepIdentifier{} + upkeepId.FromBigInt(big.NewInt(12345)) + + extension := &ocr2keepers.LogTriggerExtension{ + TxHash: common.HexToHash("0xc8def8abdcf3a4eaaf6cc13bff3e4e2a7168d86ea41dbbf97451235aa76c3651"), + Index: 0, + BlockHash: common.HexToHash("0x3df0e926f3e21ec1195ffe007a2899214905eb02e768aa89ce0b94accd7f3d71"), + BlockNumber: 500, + } + extension1 := &ocr2keepers.LogTriggerExtension{ + TxHash: common.HexToHash("0xc8def8abdcf3a4eaaf6cc13bff3e4e2a7168d86ea41dbbf97451235aa76c3651"), + Index: 0, + BlockHash: common.HexToHash("0x3df0e926f3e21ec1195ffe007a2899214905eb02e768aa89ce0b94accd7f3d71"), + BlockNumber: 0, + } + + tests := []struct { + name string + upkeepId *big.Int + payload ocr2keepers.UpkeepPayload + blocks map[int64]string + makeEthCall bool + reason encoding.UpkeepFailureReason + state encoding.PipelineExecutionState + retryable bool + ethCallErr error + receipt *types.Receipt + }{ + { + name: "log block number invalid", + upkeepId: big.NewInt(12345), + payload: ocr2keepers.UpkeepPayload{ + UpkeepID: upkeepId, + Trigger: ocr2keepers.NewLogTrigger(550, common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), extension), + WorkID: "work", + }, + reason: encoding.UpkeepFailureReasonNone, + state: encoding.RpcFlakyFailure, + retryable: true, + makeEthCall: true, + ethCallErr: fmt.Errorf("error"), + }, + { + name: "log block no longer exists", + upkeepId: big.NewInt(12345), + payload: ocr2keepers.UpkeepPayload{ + UpkeepID: upkeepId, + Trigger: ocr2keepers.NewLogTrigger(550, common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), extension), + WorkID: "work", + }, + reason: encoding.UpkeepFailureReasonTxHashNoLongerExists, + retryable: false, + makeEthCall: true, + blocks: map[int64]string{ + 500: "0xb2173b4b75f23f56b7b2b6b2cc5fa9ed1079b9d1655b12b40fdb4dbf59006419", + }, + receipt: &types.Receipt{}, + }, + { + name: "eth client returns a matching block", + upkeepId: big.NewInt(12345), + payload: ocr2keepers.UpkeepPayload{ + UpkeepID: upkeepId, + Trigger: ocr2keepers.NewLogTrigger(550, common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), extension1), + WorkID: "work", + }, + reason: encoding.UpkeepFailureReasonNone, + retryable: false, + blocks: map[int64]string{ + 500: "0xa518faeadcc423338c62572da84dda35fe44b34f521ce88f6081b703b250cca4", + }, + makeEthCall: true, + receipt: &types.Receipt{ + BlockNumber: big.NewInt(550), + BlockHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), + }, + }, + { + name: "log block is valid", + upkeepId: big.NewInt(12345), + payload: ocr2keepers.UpkeepPayload{ + UpkeepID: upkeepId, + Trigger: ocr2keepers.NewLogTrigger(550, common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), extension), + WorkID: "work", + }, + reason: encoding.UpkeepFailureReasonNone, + retryable: false, + blocks: map[int64]string{ + 500: "0x3df0e926f3e21ec1195ffe007a2899214905eb02e768aa89ce0b94accd7f3d71", + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + bs := &BlockSubscriber{ + blocks: tc.blocks, + } + e := &EvmRegistry{ + lggr: lggr, + bs: bs, + ctx: context.Background(), + } + + if tc.makeEthCall { + client := new(evmClientMocks.Client) + client.On("TransactionReceipt", mock.Anything, common.HexToHash("0xc8def8abdcf3a4eaaf6cc13bff3e4e2a7168d86ea41dbbf97451235aa76c3651")). + Return(tc.receipt, tc.ethCallErr) + e.client = client + } + + reason, state, retryable := e.verifyLogExists(tc.upkeepId, tc.payload) + assert.Equal(t, tc.reason, reason) + assert.Equal(t, tc.state, state) + assert.Equal(t, tc.retryable, retryable) + }) + } +} + +func TestRegistry_CheckUpkeeps(t *testing.T) { + lggr := logger.TestLogger(t) + uid0 := core.GenUpkeepID(ocr2keepers.UpkeepType(0), "p0") + uid1 := core.GenUpkeepID(ocr2keepers.UpkeepType(1), "p1") + uid2 := core.GenUpkeepID(ocr2keepers.UpkeepType(1), "p2") + + extension1 := &ocr2keepers.LogTriggerExtension{ + TxHash: common.HexToHash("0xc8def8abdcf3a4eaaf6cc13bff3e4e2a7168d86ea41dbbf97451235aa76c3651"), + Index: 0, + BlockHash: common.HexToHash("0x0919c83363b439ea634ce2b576cf3e30db26b340fb7a12058c2fcc401bd04ba0"), + BlockNumber: 550, + } + extension2 := &ocr2keepers.LogTriggerExtension{ + TxHash: common.HexToHash("0xc8def8abdcf3a4eaaf6cc13bff3e4e2a7168d86ea41dbbf97451235aa76c3651"), + Index: 0, + BlockHash: common.HexToHash("0x9840e5b709bfccf6a1b44f34c884bc39403f57923f3f5ead6243cc090546b857"), + BlockNumber: 550, + } + + trigger0 := ocr2keepers.NewTrigger(150, common.HexToHash("0x1c77db0abe32327cf3ea9de2aadf79876f9e6b6dfcee9d4719a8a2dc8ca289d0")) + trigger1 := ocr2keepers.NewLogTrigger(560, common.HexToHash("0x9840e5b709bfccf6a1b44f34c884bc39403f57923f3f5ead6243cc090546b857"), extension1) + trigger2 := ocr2keepers.NewLogTrigger(570, common.HexToHash("0x1222d75217e2dd461cc77e4091c37abe76277430d97f1963a822b4e94ebb83fc"), extension2) + + tests := []struct { + name string + inputs []ocr2keepers.UpkeepPayload + blocks map[int64]string + latestBlock ocr2keepers.BlockKey + results []ocr2keepers.CheckResult + err error + ethCalls map[string]bool + receipts map[string]*types.Receipt + ethCallErrors map[string]error + }{ + { + name: "check upkeeps with different upkeep types", + inputs: []ocr2keepers.UpkeepPayload{ + { + UpkeepID: uid0, + Trigger: trigger0, + WorkID: "work0", + }, + { + UpkeepID: uid1, + Trigger: trigger1, + WorkID: "work1", + }, + { + UpkeepID: uid2, + Trigger: trigger2, + WorkID: "work2", + // check data byte slice length cannot be odd number, abi pack error + CheckData: []byte{0, 0, 0, 0, 1}, + }, + }, + blocks: map[int64]string{ + 550: "0x9840e5b709bfccf6a1b44f34c884bc39403f57923f3f5ead6243cc090546b857", + 560: "0x9840e5b709bfccf6a1b44f34c884bc39403f57923f3f5ead6243cc090546b857", + 570: "0x1222d75217e2dd461cc77e4091c37abe76277430d97f1963a822b4e94ebb83fc", + }, + latestBlock: ocr2keepers.BlockKey{Number: 580}, + results: []ocr2keepers.CheckResult{ + { + PipelineExecutionState: uint8(encoding.CheckBlockTooOld), + Retryable: false, + Eligible: false, + IneligibilityReason: 0, + UpkeepID: uid0, + Trigger: trigger0, + WorkID: "work0", + GasAllocated: 0, + PerformData: nil, + FastGasWei: big.NewInt(0), + LinkNative: big.NewInt(0), + }, + { + PipelineExecutionState: uint8(encoding.RpcFlakyFailure), + Retryable: true, + Eligible: false, + IneligibilityReason: 0, + UpkeepID: uid1, + Trigger: trigger1, + WorkID: "work1", + GasAllocated: 0, + PerformData: nil, + FastGasWei: big.NewInt(0), + LinkNative: big.NewInt(0), + }, + { + PipelineExecutionState: uint8(encoding.PackUnpackDecodeFailed), + Retryable: false, + Eligible: false, + IneligibilityReason: 0, + UpkeepID: uid2, + Trigger: trigger2, + WorkID: "work2", + GasAllocated: 0, + PerformData: nil, + FastGasWei: big.NewInt(0), + LinkNative: big.NewInt(0), + }, + }, + ethCalls: map[string]bool{ + uid1.String(): true, + }, + receipts: map[string]*types.Receipt{ + //uid1.String(): { + // BlockNumber: big.NewInt(550), + // BlockHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), + //}, + }, + ethCallErrors: map[string]error{ + uid1.String(): fmt.Errorf("error"), + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + bs := &BlockSubscriber{ + latestBlock: atomic.Pointer[ocr2keepers.BlockKey]{}, + blocks: tc.blocks, + } + bs.latestBlock.Store(&tc.latestBlock) + e := &EvmRegistry{ + lggr: lggr, + bs: bs, + } + client := new(evmClientMocks.Client) + for _, i := range tc.inputs { + uid := i.UpkeepID.String() + if tc.ethCalls[uid] { + client.On("TransactionReceipt", mock.Anything, common.HexToHash("0xc8def8abdcf3a4eaaf6cc13bff3e4e2a7168d86ea41dbbf97451235aa76c3651")). + Return(tc.receipts[uid], tc.ethCallErrors[uid]) + } + } + e.client = client + + results, err := e.checkUpkeeps(context.Background(), tc.inputs) + assert.Equal(t, tc.results, results) + assert.Equal(t, tc.err, err) + }) + } +} + +func TestRegistry_SimulatePerformUpkeeps(t *testing.T) { + uid0 := core.GenUpkeepID(ocr2keepers.UpkeepType(0), "p0") + uid1 := core.GenUpkeepID(ocr2keepers.UpkeepType(1), "p1") + uid2 := core.GenUpkeepID(ocr2keepers.UpkeepType(1), "p2") + + extension1 := &ocr2keepers.LogTriggerExtension{ + TxHash: common.HexToHash("0xc8def8abdcf3a4eaaf6cc13bff3e4e2a7168d86ea41dbbf97451235aa76c3651"), + Index: 0, + BlockHash: common.HexToHash("0x9840e5b709bfccf6a1b44f34c884bc39403f57923f3f5ead6243cc090546b857"), + BlockNumber: 550, + } + + trigger0 := ocr2keepers.NewTrigger(150, common.HexToHash("0x1c77db0abe32327cf3ea9de2aadf79876f9e6b6dfcee9d4719a8a2dc8ca289d0")) + trigger1 := ocr2keepers.NewLogTrigger(570, common.HexToHash("0x1222d75217e2dd461cc77e4091c37abe76277430d97f1963a822b4e94ebb83fc"), extension1) + trigger2 := ocr2keepers.NewLogTrigger(570, common.HexToHash("0x1222d75217e2dd461cc77e4091c37abe76277430d97f1963a822b4e94ebb83fc"), extension1) + + cr0 := ocr2keepers.CheckResult{ + PipelineExecutionState: uint8(encoding.CheckBlockTooOld), + Retryable: false, + Eligible: false, + IneligibilityReason: 0, + UpkeepID: uid0, + Trigger: trigger0, + WorkID: "work0", + GasAllocated: 0, + PerformData: nil, + FastGasWei: big.NewInt(0), + LinkNative: big.NewInt(0), + } + + tests := []struct { + name string + inputs []ocr2keepers.CheckResult + results []ocr2keepers.CheckResult + err error + }{ + { + name: "simulate multiple upkeeps", + inputs: []ocr2keepers.CheckResult{ + cr0, + { + PipelineExecutionState: 0, + Retryable: false, + Eligible: true, + IneligibilityReason: 0, + UpkeepID: uid1, + Trigger: trigger1, + WorkID: "work1", + GasAllocated: 20000, + PerformData: []byte{0, 0, 0, 1, 2, 3}, + FastGasWei: big.NewInt(20000), + LinkNative: big.NewInt(20000), + }, + { + PipelineExecutionState: 0, + Retryable: false, + Eligible: true, + IneligibilityReason: 0, + UpkeepID: uid2, + Trigger: trigger2, + WorkID: "work2", + GasAllocated: 20000, + PerformData: []byte{0, 0, 0, 1, 2, 3}, + FastGasWei: big.NewInt(20000), + LinkNative: big.NewInt(20000), + }, + }, + results: []ocr2keepers.CheckResult{ + cr0, + { + PipelineExecutionState: uint8(encoding.RpcFlakyFailure), + Retryable: true, + Eligible: false, + IneligibilityReason: 0, + UpkeepID: uid1, + Trigger: trigger1, + WorkID: "work1", + GasAllocated: 20000, + PerformData: []byte{0, 0, 0, 1, 2, 3}, + FastGasWei: big.NewInt(20000), + LinkNative: big.NewInt(20000), + }, + { + PipelineExecutionState: uint8(encoding.PackUnpackDecodeFailed), + Retryable: false, + Eligible: false, + IneligibilityReason: 0, + UpkeepID: uid2, + Trigger: trigger2, + WorkID: "work2", + GasAllocated: 20000, + PerformData: []byte{0, 0, 0, 1, 2, 3}, + FastGasWei: big.NewInt(20000), + LinkNative: big.NewInt(20000), + }, + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + e := setupEVMRegistry(t) + client := new(evmClientMocks.Client) + client.On("BatchCallContext", mock.Anything, mock.MatchedBy(func(b []rpc.BatchElem) bool { + return len(b) == 2 && b[0].Method == "eth_call" && b[1].Method == "eth_call" + })).Return(nil). + Run(func(args mock.Arguments) { + be := args.Get(1).([]rpc.BatchElem) + be[0].Error = fmt.Errorf("error") + res := "0x0001" + be[1].Result = res + }).Once() + e.client = client + + results, err := e.simulatePerformUpkeeps(context.Background(), tc.inputs) + assert.Equal(t, tc.results, results) + assert.Equal(t, tc.err, err) + }) + } + +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_test.go index ccd52e46ce3..e17145ff81e 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_test.go @@ -1,14 +1,13 @@ package evm import ( - "context" "fmt" "math/big" "testing" "time" "github.com/ethereum/go-ethereum/common" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -17,127 +16,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/utils" ) -func TestGetActiveUpkeepIDs(t *testing.T) { - tests := []struct { - Name string - LatestHead int64 - ActiveIDs []string - ExpectedErr error - ExpectedKeys []ocr2keepers.UpkeepIdentifier - }{ - {Name: "NoActiveIDs", LatestHead: 1, ActiveIDs: []string{}, ExpectedKeys: []ocr2keepers.UpkeepIdentifier{}}, - {Name: "AvailableActiveIDs", LatestHead: 1, ActiveIDs: []string{"8", "9", "3", "1"}, ExpectedKeys: []ocr2keepers.UpkeepIdentifier{ - ocr2keepers.UpkeepIdentifier("8"), - ocr2keepers.UpkeepIdentifier("9"), - ocr2keepers.UpkeepIdentifier("3"), - ocr2keepers.UpkeepIdentifier("1"), - }}, - } - - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - actives := make(map[string]activeUpkeep) - for _, id := range test.ActiveIDs { - idNum := big.NewInt(0) - idNum.SetString(id, 10) - actives[id] = activeUpkeep{ID: idNum} - } - - rg := &EvmRegistry{ - active: actives, - } - - keys, err := rg.GetActiveUpkeepIDs(context.Background()) - - if test.ExpectedErr != nil { - assert.ErrorIs(t, err, test.ExpectedErr) - } else { - assert.Nil(t, err) - } - - if len(test.ExpectedKeys) > 0 { - for _, key := range keys { - assert.Contains(t, test.ExpectedKeys, key) - } - } else { - assert.Equal(t, test.ExpectedKeys, keys) - } - }) - } -} - -func TestGetActiveUpkeepIDsByType(t *testing.T) { - tests := []struct { - Name string - LatestHead int64 - ActiveIDs []string - ExpectedErr error - ExpectedKeys []ocr2keepers.UpkeepIdentifier - Triggers []uint8 - }{ - {Name: "no active ids", LatestHead: 1, ActiveIDs: []string{}, ExpectedKeys: []ocr2keepers.UpkeepIdentifier{}}, - { - Name: "get log upkeeps", - LatestHead: 1, - ActiveIDs: []string{"8", "32329108151019397958065800113404894502874153543356521479058624064899121404671"}, - ExpectedKeys: []ocr2keepers.UpkeepIdentifier{ - ocr2keepers.UpkeepIdentifier("32329108151019397958065800113404894502874153543356521479058624064899121404671"), - }, - Triggers: []uint8{uint8(logTrigger)}, - }, - { - Name: "get conditional upkeeps", - LatestHead: 1, - ActiveIDs: []string{"8", "32329108151019397958065800113404894502874153543356521479058624064899121404671"}, - ExpectedKeys: []ocr2keepers.UpkeepIdentifier{ - ocr2keepers.UpkeepIdentifier("8"), - }, - Triggers: []uint8{uint8(conditionTrigger)}, - }, - { - Name: "get multiple types of upkeeps", - LatestHead: 1, - ActiveIDs: []string{"8", "32329108151019397958065800113404894502874153543356521479058624064899121404671"}, - ExpectedKeys: []ocr2keepers.UpkeepIdentifier{ - ocr2keepers.UpkeepIdentifier("8"), - ocr2keepers.UpkeepIdentifier("32329108151019397958065800113404894502874153543356521479058624064899121404671"), - }, - Triggers: []uint8{uint8(logTrigger), uint8(conditionTrigger)}, - }, - } - - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - actives := make(map[string]activeUpkeep) - for _, id := range test.ActiveIDs { - idNum := big.NewInt(0) - idNum.SetString(id, 10) - actives[id] = activeUpkeep{ID: idNum} - } - - rg := &EvmRegistry{ - active: actives, - } - - keys, err := rg.GetActiveUpkeepIDsByType(context.Background(), test.Triggers...) - - if test.ExpectedErr != nil { - assert.ErrorIs(t, err, test.ExpectedErr) - } else { - assert.Nil(t, err) - } - - if len(test.ExpectedKeys) > 0 { - for _, key := range keys { - assert.Contains(t, test.ExpectedKeys, key) - } - } else { - assert.Equal(t, test.ExpectedKeys, keys) - } - }) - } -} - func TestPollLogs(t *testing.T) { tests := []struct { Name string @@ -269,7 +147,7 @@ func TestPollLogs(t *testing.T) { chLog: make(chan logpoller.Log, 10), } - err := rg.pollLogs() + err := rg.pollUpkeepStateLogs() assert.Equal(t, test.ExpectedLastPoll, rg.lastPollBlock) if test.ExpectedErr != nil { @@ -304,52 +182,3 @@ func TestPollLogs(t *testing.T) { }) } } - -func TestRegistry_GetBlockAndUpkeepId(t *testing.T) { - r := &EvmRegistry{} - tests := []struct { - name string - input ocr2keepers.UpkeepPayload - wantBlock *big.Int - wantUpkeep *big.Int - }{ - { - "happy flow", - ocr2keepers.UpkeepPayload{ - Upkeep: ocr2keepers.ConfiguredUpkeep{ - ID: ocr2keepers.UpkeepIdentifier([]byte("10")), - }, - Trigger: ocr2keepers.Trigger{ - BlockNumber: 1, - BlockHash: common.Bytes2Hex([]byte{1, 2, 3, 4, 5, 6, 7, 8}), - }, - }, - big.NewInt(1), - big.NewInt(0).SetBytes([]byte("10")), - }, - { - "empty block number", - ocr2keepers.UpkeepPayload{ - Upkeep: ocr2keepers.ConfiguredUpkeep{ - ID: ocr2keepers.UpkeepIdentifier([]byte("10")), - }, - }, - big.NewInt(0), - big.NewInt(0).SetBytes([]byte("10")), - }, - { - "empty payload", - ocr2keepers.UpkeepPayload{}, - big.NewInt(0), - big.NewInt(0), - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - block, upkeep := r.getBlockAndUpkeepId(tc.input) - assert.Equal(t, tc.wantBlock, block) - assert.Equal(t, tc.wantUpkeep, upkeep) - }) - } -} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/services.go b/core/services/ocr2/plugins/ocr2keeper/evm21/services.go new file mode 100644 index 00000000000..639b2b6af79 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/services.go @@ -0,0 +1,144 @@ +package evm + +import ( + "fmt" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/ocr2keepers/pkg/v3/plugin" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/feed_lookup_compatible_interface" + iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/models" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/encoding" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate" +) + +type AutomationServices interface { + Registry() *EvmRegistry + Encoder() ocr2keepers.Encoder + TransmitEventProvider() *TransmitEventProvider + BlockSubscriber() *BlockSubscriber + PayloadBuilder() ocr2keepers.PayloadBuilder + UpkeepStateStore() upkeepstate.UpkeepStateStore + LogEventProvider() logprovider.LogEventProvider + LogRecoverer() logprovider.LogRecoverer + UpkeepProvider() ocr2keepers.ConditionalUpkeepProvider + Keyring() ocr3types.OnchainKeyring[plugin.AutomationReportInfo] +} + +func New(addr common.Address, client evm.Chain, mc *models.MercuryCredentials, keyring ocrtypes.OnchainKeyring, lggr logger.Logger) (AutomationServices, error) { + feedLookupCompatibleABI, err := abi.JSON(strings.NewReader(feed_lookup_compatible_interface.FeedLookupCompatibleInterfaceABI)) + if err != nil { + return nil, fmt.Errorf("%w: %s", ErrABINotParsable, err) + } + keeperRegistryABI, err := abi.JSON(strings.NewReader(iregistry21.IKeeperRegistryMasterABI)) + if err != nil { + return nil, fmt.Errorf("%w: %s", ErrABINotParsable, err) + } + utilsABI, err := abi.JSON(strings.NewReader(automation_utils_2_1.AutomationUtilsABI)) + if err != nil { + return nil, fmt.Errorf("%w: %s", ErrABINotParsable, err) + } + registryContract, err := iregistry21.NewIKeeperRegistryMaster(addr, client.Client()) + if err != nil { + return nil, fmt.Errorf("%w: failed to create caller for address and backend", ErrInitializationFailure) + } + // lookback blocks for transmit event is hard coded and should provide ample time for logs + // to be detected in most cases + var transmitLookbackBlocks int64 = 250 + transmitter, err := NewTransmitEventProvider(lggr, client.LogPoller(), addr, client.Client(), transmitLookbackBlocks) + if err != nil { + return nil, err + } + + services := new(automationServices) + services.transmitter = transmitter + + packer := encoding.NewAbiPacker(keeperRegistryABI, utilsABI) + services.encoder = encoding.NewReportEncoder(packer) + + scanner := upkeepstate.NewPerformedEventsScanner(lggr, client.LogPoller(), addr) + services.upkeepState = upkeepstate.NewUpkeepStateStore(lggr, scanner) + + logProvider, logRecoverer := logprovider.New(lggr, client.LogPoller(), client.Client(), utilsABI, services.upkeepState) + services.logProvider = logProvider + services.logRecoverer = logRecoverer + services.blockSub = NewBlockSubscriber(client.HeadBroadcaster(), client.LogPoller(), lggr) + + services.keyring = NewOnchainKeyringV3Wrapper(keyring) + + al := NewActiveUpkeepList() + services.payloadBuilder = NewPayloadBuilder(al, logRecoverer, lggr) + + services.reg = NewEvmRegistry(lggr, addr, client, feedLookupCompatibleABI, + keeperRegistryABI, registryContract, mc, al, services.logProvider, + packer, services.blockSub) + + services.upkeepProvider = NewUpkeepProvider(al, services.blockSub, client.LogPoller()) + + return services, nil +} + +type automationServices struct { + reg *EvmRegistry + encoder ocr2keepers.Encoder + transmitter *TransmitEventProvider + blockSub *BlockSubscriber + payloadBuilder ocr2keepers.PayloadBuilder + upkeepState upkeepstate.UpkeepStateStore + logProvider logprovider.LogEventProvider + logRecoverer logprovider.LogRecoverer + upkeepProvider *upkeepProvider + keyring *onchainKeyringV3Wrapper +} + +var _ AutomationServices = &automationServices{} + +func (f *automationServices) Registry() *EvmRegistry { + return f.reg +} + +func (f *automationServices) Encoder() ocr2keepers.Encoder { + return f.encoder +} + +func (f *automationServices) TransmitEventProvider() *TransmitEventProvider { + return f.transmitter +} + +func (f *automationServices) BlockSubscriber() *BlockSubscriber { + return f.blockSub +} + +func (f *automationServices) PayloadBuilder() ocr2keepers.PayloadBuilder { + return f.payloadBuilder +} + +func (f *automationServices) UpkeepStateStore() upkeepstate.UpkeepStateStore { + return f.upkeepState +} + +func (f *automationServices) LogEventProvider() logprovider.LogEventProvider { + return f.logProvider +} + +func (f *automationServices) LogRecoverer() logprovider.LogRecoverer { + return f.logRecoverer +} + +func (f *automationServices) UpkeepProvider() ocr2keepers.ConditionalUpkeepProvider { + return f.upkeepProvider +} + +func (f *automationServices) Keyring() ocr3types.OnchainKeyring[plugin.AutomationReportInfo] { + return f.keyring +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit_event_provider.go b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit_event_provider.go index 85ee1f3b089..3b87277ee54 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit_event_provider.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit_event_provider.go @@ -2,22 +2,24 @@ package evm import ( "context" - "encoding/hex" "fmt" "math/big" "sync" "github.com/ethereum/go-ethereum/common" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/utils" ) +var _ ocr2keepers.TransmitEventProvider = &TransmitEventProvider{} + type TransmitEventProvider struct { sync utils.StartStopOnce mu sync.RWMutex @@ -49,14 +51,15 @@ func NewTransmitEventProvider( if err != nil { return nil, err } - // Add log filters for the log poller so that it can poll and find the logs that - // we need. err = logPoller.RegisterFilter(logpoller.Filter{ Name: TransmitEventProviderFilterName(contract.Address()), EventSigs: []common.Hash{ - iregistry21.IKeeperRegistryMasterUpkeepPerformed{}.Topic(), - iregistry21.IKeeperRegistryMasterReorgedUpkeepReport{}.Topic(), - iregistry21.IKeeperRegistryMasterInsufficientFundsUpkeepReport{}.Topic(), + // These are the events that are emitted when a node transmits a report + iregistry21.IKeeperRegistryMasterUpkeepPerformed{}.Topic(), // Happy path: report performed the upkeep + iregistry21.IKeeperRegistryMasterReorgedUpkeepReport{}.Topic(), // Report checkBlockNumber was reorged + iregistry21.IKeeperRegistryMasterInsufficientFundsUpkeepReport{}.Topic(), // Upkeep didn't have sufficient funds when report reached chain, perform was aborted early + // Report was too old when it reached the chain. For conditionals upkeep was already performed on a higher block than checkBlockNum + // for logs upkeep was already performed for the particular log iregistry21.IKeeperRegistryMasterStaleUpkeepReport{}.Topic(), }, Addresses: []common.Address{registryAddress}, @@ -120,7 +123,7 @@ func (c *TransmitEventProvider) HealthReport() map[string]error { return map[string]error{c.Name(): c.sync.Healthy()} } -func (c *TransmitEventProvider) Events(ctx context.Context) ([]ocr2keepers.TransmitEvent, error) { +func (c *TransmitEventProvider) GetLatestEvents(ctx context.Context) ([]ocr2keepers.TransmitEvent, error) { end, err := c.logPoller.LatestBlock(pg.WithParentCtx(ctx)) if err != nil { return nil, fmt.Errorf("%w: failed to get latest block from log poller", err) @@ -134,9 +137,8 @@ func (c *TransmitEventProvider) Events(ctx context.Context) ([]ocr2keepers.Trans []common.Hash{ iregistry21.IKeeperRegistryMasterUpkeepPerformed{}.Topic(), iregistry21.IKeeperRegistryMasterStaleUpkeepReport{}.Topic(), - // TODO: enable once we have the corredponding types in ocr2keepers - // iregistry21.IKeeperRegistryMasterReorgedUpkeepReport{}.Topic(), - // iregistry21.IKeeperRegistryMasterInsufficientFundsUpkeepReport{}.Topic(), + iregistry21.IKeeperRegistryMasterReorgedUpkeepReport{}.Topic(), + iregistry21.IKeeperRegistryMasterInsufficientFundsUpkeepReport{}.Topic(), }, c.registryAddress, pg.WithParentCtx(ctx), @@ -209,15 +211,36 @@ func (c *TransmitEventProvider) convertToTransmitEvents(logs []transmitEventLog, vals := []ocr2keepers.TransmitEvent{} for _, l := range logs { - upkeepId := ocr2keepers.UpkeepIdentifier(l.Id().Bytes()) - triggerID := l.TriggerID() + id := l.Id() + upkeepId := &ocr2keepers.UpkeepIdentifier{} + ok := upkeepId.FromBigInt(id) + if !ok { + return nil, core.ErrInvalidUpkeepID + } + triggerW, err := core.UnpackTrigger(id, l.Trigger()) + if err != nil { + return nil, fmt.Errorf("%w: failed to unpack trigger", err) + } + trigger := ocr2keepers.NewTrigger( + ocr2keepers.BlockNumber(triggerW.BlockNum), + triggerW.BlockHash, + ) + switch core.GetUpkeepType(*upkeepId) { + case ocr2keepers.LogTrigger: + trigger.LogTriggerExtension = &ocr2keepers.LogTriggerExtension{} + trigger.LogTriggerExtension.TxHash = triggerW.TxHash + trigger.LogTriggerExtension.Index = triggerW.LogIndex + default: + } + workID := core.UpkeepWorkID(*upkeepId, trigger) vals = append(vals, ocr2keepers.TransmitEvent{ Type: l.TransmitEventType(), - TransmitBlock: BlockKeyHelper[int64]{}.MakeBlockKey(l.BlockNumber), + TransmitBlock: ocr2keepers.BlockNumber(l.BlockNumber), Confirmations: latestBlock - l.BlockNumber, - TransactionHash: l.TxHash.Hex(), - ID: hex.EncodeToString(triggerID[:]), - UpkeepID: upkeepId, + TransactionHash: l.TxHash, + WorkID: workID, + UpkeepID: *upkeepId, + CheckBlock: trigger.BlockNumber, }) } @@ -248,18 +271,18 @@ func (l transmitEventLog) Id() *big.Int { } } -func (l transmitEventLog) TriggerID() [32]byte { +func (l transmitEventLog) Trigger() []byte { switch { case l.Performed != nil: - return l.Performed.UpkeepTriggerID + return l.Performed.Trigger case l.Stale != nil: - return l.Stale.UpkeepTriggerID + return l.Stale.Trigger case l.Reorged != nil: - return l.Reorged.UpkeepTriggerID + return l.Reorged.Trigger case l.InsufficientFunds != nil: - return l.InsufficientFunds.UpkeepTriggerID + return l.InsufficientFunds.Trigger default: - return [32]byte{} + return []byte{} } } @@ -270,12 +293,10 @@ func (l transmitEventLog) TransmitEventType() ocr2keepers.TransmitEventType { case l.Stale != nil: return ocr2keepers.StaleReportEvent case l.Reorged != nil: - // TODO: use reorged event type - return ocr2keepers.TransmitEventType(2) + return ocr2keepers.ReorgReportEvent case l.InsufficientFunds != nil: - // TODO: use insufficient funds event type - return ocr2keepers.TransmitEventType(3) + return ocr2keepers.InsufficientFundsReportEvent default: - return ocr2keepers.TransmitEventType(0) + return ocr2keepers.UnknownEvent } } diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit_event_provider_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit_event_provider_test.go index 048e2612bdf..de619c24df1 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit_event_provider_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit_event_provider_test.go @@ -7,7 +7,8 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" + "github.com/ethereum/go-ethereum/common/hexutil" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -16,6 +17,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" ) func TestTransmitEventProvider(t *testing.T) { @@ -90,7 +92,7 @@ func TestTransmitEventProvider(t *testing.T) { mp.On("LatestBlock", mock.Anything).Return(tc.latestBlock, nil) mp.On("LogsWithSigs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.logs, nil) - res, err := provider.Events(ctx) + res, err := provider.GetLatestEvents(ctx) require.Equal(t, tc.errored, err != nil) require.Len(t, res, tc.resultsLen) }) @@ -99,7 +101,7 @@ func TestTransmitEventProvider(t *testing.T) { func TestTransmitEventProvider_ConvertToTransmitEvents(t *testing.T) { provider := &TransmitEventProvider{} - id := genUpkeepID(logTrigger, "111") + id := core.GenUpkeepID(ocr2keepers.LogTrigger, "1111111111111111") tests := []struct { name string performed []transmitEventLog @@ -116,7 +118,11 @@ func TestTransmitEventProvider_ConvertToTransmitEvents(t *testing.T) { BlockHash: common.HexToHash("0x0102030405060708010203040506070801020304050607080102030405060708"), }, Performed: &iregistry21.IKeeperRegistryMasterUpkeepPerformed{ - Id: id, + Id: id.BigInt(), + Trigger: func() []byte { + b, _ := hexutil.Decode("0x0000000000000000000000000000000000000000000000000000000001111111000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001111111") + return b + }(), }, }, }, @@ -124,8 +130,8 @@ func TestTransmitEventProvider_ConvertToTransmitEvents(t *testing.T) { []ocr2keepers.TransmitEvent{ { Type: ocr2keepers.PerformEvent, - UpkeepID: ocr2keepers.UpkeepIdentifier(id.Bytes()), - CheckBlock: ocr2keepers.BlockKey(""), // empty for log triggers + UpkeepID: id, + CheckBlock: ocr2keepers.BlockNumber(1), // empty for log triggers }, }, false, @@ -154,7 +160,7 @@ func TestTransmitEventProvider_ConvertToTransmitEvents(t *testing.T) { } func TestTransmitEventLog(t *testing.T) { - uid := genUpkeepID(conditionTrigger, "111") + uid := core.GenUpkeepID(ocr2keepers.ConditionTrigger, "111") tests := []struct { name string @@ -169,10 +175,8 @@ func TestTransmitEventLog(t *testing.T) { BlockHash: common.HexToHash("0x010203040"), }, Performed: &iregistry21.IKeeperRegistryMasterUpkeepPerformed{ - Id: uid, - UpkeepTriggerID: [32]byte{ - 1, 2, 3, 4, 5, 6, 7, 8, - }, + Id: uid.BigInt(), + Trigger: []byte{1, 2, 3, 4, 5, 6, 7, 8}, }, }, ocr2keepers.PerformEvent, @@ -185,10 +189,8 @@ func TestTransmitEventLog(t *testing.T) { BlockHash: common.HexToHash("0x010203040"), }, Stale: &iregistry21.IKeeperRegistryMasterStaleUpkeepReport{ - Id: uid, - UpkeepTriggerID: [32]byte{ - 1, 2, 3, 4, 5, 6, 7, 8, - }, + Id: uid.BigInt(), + Trigger: []byte{1, 2, 3, 4, 5, 6, 7, 8}, }, }, ocr2keepers.StaleReportEvent, @@ -201,13 +203,11 @@ func TestTransmitEventLog(t *testing.T) { BlockHash: common.HexToHash("0x010203040"), }, InsufficientFunds: &iregistry21.IKeeperRegistryMasterInsufficientFundsUpkeepReport{ - Id: uid, - UpkeepTriggerID: [32]byte{ - 1, 2, 3, 4, 5, 6, 7, 8, - }, + Id: uid.BigInt(), + Trigger: []byte{1, 2, 3, 4, 5, 6, 7, 8}, }, }, - ocr2keepers.TransmitEventType(3), + ocr2keepers.InsufficientFundsReportEvent, }, { "reorged", @@ -217,13 +217,11 @@ func TestTransmitEventLog(t *testing.T) { BlockHash: common.HexToHash("0x010203040"), }, Reorged: &iregistry21.IKeeperRegistryMasterReorgedUpkeepReport{ - Id: uid, - UpkeepTriggerID: [32]byte{ - 1, 2, 3, 4, 5, 6, 7, 8, - }, + Id: uid.BigInt(), + Trigger: []byte{1, 2, 3, 4, 5, 6, 7, 8}, }, }, - ocr2keepers.TransmitEventType(2), + ocr2keepers.ReorgReportEvent, }, { "empty", @@ -233,17 +231,15 @@ func TestTransmitEventLog(t *testing.T) { BlockHash: common.HexToHash("0x010203040"), }, }, - ocr2keepers.TransmitEventType(0), + ocr2keepers.UnknownEvent, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { if tc.log.Id() != nil { - require.Equal(t, uid.Int64(), tc.log.Id().Int64()) - require.Equal(t, [32]byte{ - 1, 2, 3, 4, 5, 6, 7, 8, - }, tc.log.TriggerID()) + require.Equal(t, uid.BigInt().Int64(), tc.log.Id().Int64()) + require.Equal(t, []byte{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}, tc.log.Trigger()) } require.Equal(t, tc.etype, tc.log.TransmitEventType()) }) diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_info.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_info.go deleted file mode 100644 index b90d5540f8e..00000000000 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_info.go +++ /dev/null @@ -1,61 +0,0 @@ -package evm - -import ( - "encoding/hex" - "math/big" - - "github.com/ethereum/go-ethereum/crypto" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" -) - -type upkeepType uint8 - -const ( - conditionTrigger upkeepType = iota - logTrigger - cronTrigger - readyTrigger -) - -const ( - // upkeepTypeStartIndex is the index where the upkeep type bytes start. - // for 2.1 we use 11 zeros (reserved bytes for future use) - // and 1 byte to represent the type, with index equal upkeepTypeByteIndex - upkeepTypeStartIndex = 4 - // upkeepTypeByteIndex is the index of the byte that holds the upkeep type. - upkeepTypeByteIndex = 15 -) - -// getUpkeepType returns the upkeep type from the given ID. -// it follows the same logic as the contract, but performs it locally. -// -// TODO: check endianness -func getUpkeepType(id ocr2keepers.UpkeepIdentifier) upkeepType { - if len(id) < upkeepTypeByteIndex+1 { - return conditionTrigger - } - idx, ok := big.NewInt(0).SetString(string(id), 10) - if ok { - id = ocr2keepers.UpkeepIdentifier(idx.Bytes()) - } - for i := upkeepTypeStartIndex; i < upkeepTypeByteIndex; i++ { - if id[i] != 0 { // old id - return conditionTrigger - } - } - typeByte := id[upkeepTypeByteIndex] - return upkeepType(typeByte) -} - -// UpkeepTriggerID returns the identifier using the given upkeepID and trigger. -// It follows the same logic as the contract, but performs it locally. -func UpkeepTriggerID(id *big.Int, trigger []byte) (string, error) { - idBytes := id.Bytes() - - combined := append(idBytes, trigger...) - - triggerIDBytes := crypto.Keccak256(combined) - triggerID := hex.EncodeToString(triggerIDBytes) - - return triggerID, nil -} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_info_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_info_test.go deleted file mode 100644 index 7e709f95da2..00000000000 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_info_test.go +++ /dev/null @@ -1,100 +0,0 @@ -package evm - -import ( - "encoding/hex" - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/assert" - - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" -) - -func TestTriggerID(t *testing.T) { - upkeepIDStr := "82566255084862886500628610724995377215109748679571001950554849251333329872882" - // Convert the string to a big.Int - var upkeepID big.Int - _, success := upkeepID.SetString(upkeepIDStr, 10) - if !success { - t.Fatal("Invalid big integer value") - } - - triggerStr := "deadbeef" - triggerBytes, err := hex.DecodeString(triggerStr) - if err != nil { - t.Fatalf("Error decoding hex string: %s", err) - } - - res, err := UpkeepTriggerID(&upkeepID, triggerBytes) - if err != nil { - t.Fatalf("Error calculating UpkeepTriggerID: %s", err) - } - - expectedResult := "fe466794c97e8b54ca25b696ff3ee448a7d03e4a82a2e45d9d84de62ef4cc260" - assert.Equal(t, res, expectedResult, "UpkeepTriggerID mismatch") -} - -func TestGetUpkeepType(t *testing.T) { - tests := []struct { - name string - upkeepID ocr2keepers.UpkeepIdentifier - upkeepType upkeepType - }{ - { - "zeroed id", - big.NewInt(0).Bytes(), - conditionTrigger, - }, - { - "old id", - []byte("5820911532554020907796191562093071158274499580927271776163559390280294438608"), - conditionTrigger, - }, - { - "condition trigger", - genUpkeepID(conditionTrigger, "").Bytes(), - conditionTrigger, - }, - { - "log trigger string", - []byte(genUpkeepID(logTrigger, "111").String()), - logTrigger, - }, - { - "log trigger", - genUpkeepID(logTrigger, "111").Bytes(), - logTrigger, - }, - { - "cron trigger", - genUpkeepID(cronTrigger, "222").Bytes(), - cronTrigger, - }, - { - "ready trigger", - genUpkeepID(readyTrigger, "333").Bytes(), - readyTrigger, - }, - { - "log trigger id", - func() ocr2keepers.UpkeepIdentifier { - id, _ := big.NewInt(0).SetString("32329108151019397958065800113404894502874153543356521479058624064899121404671", 10) - return id.Bytes() - }(), - logTrigger, - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - assert.Equal(t, tc.upkeepType, getUpkeepType(tc.upkeepID)) - }) - } -} - -func genUpkeepID(uType upkeepType, rand string) *big.Int { - b := append([]byte{1}, common.LeftPadBytes([]byte{uint8(uType)}, 15)...) - b = append(b, []byte(rand)...) - return big.NewInt(0).SetBytes(b) -} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_provider.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_provider.go new file mode 100644 index 00000000000..8e08008eca4 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_provider.go @@ -0,0 +1,50 @@ +package evm + +import ( + "context" + "fmt" + + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" +) + +var _ ocr2keepers.ConditionalUpkeepProvider = &upkeepProvider{} + +type upkeepProvider struct { + activeUpkeeps ActiveUpkeepList + bs *BlockSubscriber + lp logpoller.LogPoller +} + +func NewUpkeepProvider(activeUpkeeps ActiveUpkeepList, bs *BlockSubscriber, lp logpoller.LogPoller) *upkeepProvider { + return &upkeepProvider{ + activeUpkeeps: activeUpkeeps, + bs: bs, + lp: lp, + } +} + +func (p *upkeepProvider) GetActiveUpkeeps(ctx context.Context) ([]ocr2keepers.UpkeepPayload, error) { + latestBlock := p.bs.latestBlock.Load() + if latestBlock == nil { + return nil, fmt.Errorf("no latest block found when fetching active upkeeps") + } + var payloads []ocr2keepers.UpkeepPayload + for _, uid := range p.activeUpkeeps.View(ocr2keepers.ConditionTrigger) { + payload, err := core.NewUpkeepPayload( + uid, + ocr2keepers.NewTrigger(ocr2keepers.BlockNumber(latestBlock.Number), latestBlock.Hash), + nil, + ) + if err != nil { + // skip invalid payloads + continue + } + + payloads = append(payloads, payload) + } + + return payloads, nil +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_provider_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_provider_test.go new file mode 100644 index 00000000000..ac49675812e --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_provider_test.go @@ -0,0 +1,112 @@ +package evm + +import ( + "math/big" + "sync/atomic" + "testing" + + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" +) + +func TestUpkeepProvider_GetActiveUpkeeps(t *testing.T) { + ctx := testutils.Context(t) + + var lp logpoller.LogPoller + + tests := []struct { + name string + active ActiveUpkeepList + latestBlock *ocr2keepers.BlockKey + want []ocr2keepers.UpkeepPayload + wantErr bool + }{ + { + "empty", + &mockActiveUpkeepList{ + ViewFn: func(upkeepType ...ocr2keepers.UpkeepType) []*big.Int { + return []*big.Int{} + }, + }, + &ocr2keepers.BlockKey{Number: 1}, + nil, + false, + }, + { + "happy flow", + &mockActiveUpkeepList{ + ViewFn: func(upkeepType ...ocr2keepers.UpkeepType) []*big.Int { + return []*big.Int{ + big.NewInt(1), + big.NewInt(2), + } + }, + }, + &ocr2keepers.BlockKey{Number: 1}, + []ocr2keepers.UpkeepPayload{ + { + UpkeepID: core.UpkeepIDFromInt("1"), + Trigger: ocr2keepers.NewTrigger(ocr2keepers.BlockNumber(1), [32]byte{}), + WorkID: "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6", + }, + { + UpkeepID: core.UpkeepIDFromInt("2"), + Trigger: ocr2keepers.NewTrigger(ocr2keepers.BlockNumber(1), [32]byte{}), + WorkID: "405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace", + }, + }, + false, + }, + { + "latest block not found", + &mockActiveUpkeepList{ + ViewFn: func(upkeepType ...ocr2keepers.UpkeepType) []*big.Int { + return []*big.Int{ + big.NewInt(1), + big.NewInt(2), + } + }, + }, + nil, + []ocr2keepers.UpkeepPayload{}, + true, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + bs := &BlockSubscriber{ + latestBlock: atomic.Pointer[ocr2keepers.BlockKey]{}, + } + bs.latestBlock.Store(tc.latestBlock) + p := NewUpkeepProvider(tc.active, bs, lp) + + got, err := p.GetActiveUpkeeps(ctx) + if tc.wantErr { + require.Error(t, err) + return + } + require.NoError(t, err) + require.Len(t, got, len(tc.want)) + require.Equal(t, tc.want, got) + }) + } +} + +type mockActiveUpkeepList struct { + ActiveUpkeepList + ViewFn func(...ocr2keepers.UpkeepType) []*big.Int + IsActiveFn func(id *big.Int) bool +} + +func (l *mockActiveUpkeepList) View(u ...ocr2keepers.UpkeepType) []*big.Int { + return l.ViewFn(u...) +} + +func (l *mockActiveUpkeepList) IsActive(id *big.Int) bool { + return l.IsActiveFn(id) +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_state_store.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_state_store.go deleted file mode 100644 index f67a91759d7..00000000000 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_state_store.go +++ /dev/null @@ -1,115 +0,0 @@ -package evm - -import ( - "fmt" - "math/big" - "strconv" - "strings" - "sync" - - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" - - mapset "github.com/deckarep/golang-set/v2" - - "github.com/smartcontractkit/chainlink/v2/core/logger" -) - -const BlockKeySeparator = "|" - -type upkeepState struct { - payload *ocr2keepers.UpkeepPayload - state *UpkeepState - block int64 - upkeepId string -} - -// TODO: use the same type defined in keeper plugin after a new release is cut -type UpkeepState uint8 - -const ( - Performed UpkeepState = iota - Eligible -) - -type UpkeepStateReader interface { - // SelectByUpkeepIDsAndBlockRange retrieves upkeep states for provided upkeep ids and block range, the result is currently not in particular order - SelectByUpkeepIDsAndBlockRange(upkeepIds []*big.Int, start, end int64) ([]*ocr2keepers.UpkeepPayload, []*UpkeepState, error) -} - -type UpkeepStateUpdater interface { - SetUpkeepState(ocr2keepers.UpkeepPayload, UpkeepState) error -} - -type UpkeepStateStore struct { - mu sync.RWMutex - statesByID map[string]*upkeepState - states []*upkeepState - lggr logger.Logger -} - -// NewUpkeepStateStore creates a new state store. This is an initial version of this store. More improvements to come: -// TODO: AUTO-4027 -func NewUpkeepStateStore(lggr logger.Logger) *UpkeepStateStore { - return &UpkeepStateStore{ - statesByID: map[string]*upkeepState{}, - lggr: lggr.Named("UpkeepStateStore"), - } -} - -func (u *UpkeepStateStore) SelectByUpkeepIDsAndBlockRange(upkeepIds []*big.Int, start, end int64) ([]*ocr2keepers.UpkeepPayload, []*UpkeepState, error) { - u.mu.RLock() - defer u.mu.RUnlock() - var pl []*ocr2keepers.UpkeepPayload - var us []*UpkeepState - - uids := mapset.NewSet[string]() - for _, uid := range upkeepIds { - uids.Add(uid.String()) - } - - for _, s := range u.states { - if s.block < start || s.block >= end || !uids.Contains(s.upkeepId) { - continue - } - pl = append(pl, s.payload) - us = append(us, s.state) - } - return pl, us, nil -} - -func (u *UpkeepStateStore) SetUpkeepState(pl ocr2keepers.UpkeepPayload, us UpkeepState) error { - u.mu.Lock() - defer u.mu.Unlock() - - upkeepId := big.NewInt(0).SetBytes(pl.Upkeep.ID) - arrs := strings.Split(string(pl.CheckBlock), BlockKeySeparator) - if len(arrs) != 2 { - return fmt.Errorf("check block %s is invalid for upkeep %s", pl.CheckBlock, upkeepId) - } - block, err := strconv.ParseInt(arrs[0], 10, 64) - if err != nil { - return err - } - state := &upkeepState{ - payload: &pl, - state: &us, - block: block, - upkeepId: upkeepId.String(), - } - - s, ok := u.statesByID[pl.ID] - if ok { - s.payload = state.payload - s.state = state.state - s.block = state.block - s.upkeepId = state.upkeepId - u.statesByID[pl.ID] = s - u.lggr.Infof("upkeep %s is overridden, payload ID is %s, block is %d", s.upkeepId, s.payload.ID, s.block) - return nil - } - - u.statesByID[pl.ID] = state - u.states = append(u.states, state) - u.lggr.Infof("added new state with upkeep %s payload ID %s block %d", state.upkeepId, state.payload.ID, state.block) - return nil -} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_state_store_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_state_store_test.go deleted file mode 100644 index 5da7bf7d7e6..00000000000 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_state_store_test.go +++ /dev/null @@ -1,159 +0,0 @@ -package evm - -import ( - "fmt" - "math/big" - "testing" - - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink/v2/core/logger" -) - -var ( - upkeepId1 = big.NewInt(100) - upkeepId2 = big.NewInt(200) - trigger1 = ocr2keepers.Trigger{ - BlockNumber: 95, - BlockHash: "0x1231eqwe12eqwd", - } - trigger2 = ocr2keepers.Trigger{ - BlockNumber: 125, - BlockHash: "0x1231eqwe12eqwd", - } - payload2 = ocr2keepers.NewUpkeepPayload(upkeepId1, conditionalType, blockKey2, trigger1, []byte{}) - payload3 = ocr2keepers.NewUpkeepPayload(upkeepId2, logTriggerType, blockKey2, trigger1, []byte{}) - payload4 = ocr2keepers.NewUpkeepPayload(upkeepId1, logTriggerType, blockKey1, trigger2, []byte{}) - payload5 = ocr2keepers.NewUpkeepPayload(upkeepId1, logTriggerType, blockKey3, trigger1, []byte{}) -) - -const ( - conditionalType = 0 - logTriggerType = 1 - block1 = 111 - block3 = 113 - blockKey1 = "111|0x123123132132" - blockKey2 = "112|0x565456465465" - blockKey3 = "113|0x111423246546" - invalidBlockKey = "2220x565456465465" -) - -func TestUpkeepStateStore_InvalidBlockKey(t *testing.T) { - tests := []struct { - name string - payloads []ocr2keepers.UpkeepPayload - states []UpkeepState - expectedError error - }{ - { - name: "failed to split invalid block key", - payloads: []ocr2keepers.UpkeepPayload{ - ocr2keepers.NewUpkeepPayload(upkeepId2, logTriggerType, invalidBlockKey, trigger1, []byte{}), - }, - states: []UpkeepState{Performed}, - expectedError: fmt.Errorf("check block %s is invalid for upkeep %s", invalidBlockKey, upkeepId2), - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - store := NewUpkeepStateStore(logger.TestLogger(t)) - for i, p := range tc.payloads { - err := store.SetUpkeepState(p, tc.states[i]) - require.Equal(t, err, tc.expectedError) - } - }) - } -} - -func TestUpkeepStateStore_OverrideUpkeepStates(t *testing.T) { - p := Performed - e := Eligible - - tests := []struct { - name string - payloads []ocr2keepers.UpkeepPayload - states []UpkeepState - expectedError error - oldIds []string - oldIdResult []upkeepState - newIds []string - newIdResult []upkeepState - upkeepIds []*big.Int - endBlock int64 - startBlock int64 - result []upkeepState - }{ - { - name: "overrides existing upkeep states", - payloads: []ocr2keepers.UpkeepPayload{ - payload2, - payload3, - payload4, - payload5, // this overrides payload 2 bc they have the same payload ID - }, - states: []UpkeepState{Performed, Performed, Performed, Eligible}, - oldIds: []string{payload2.ID, payload3.ID, payload4.ID}, - oldIdResult: []upkeepState{ - { - payload: &payload3, - state: &p, - }, - { - payload: &payload4, - state: &p, - }, - }, - newIds: []string{payload3.ID, payload4.ID, payload5.ID}, - newIdResult: []upkeepState{ - { - payload: &payload3, - state: &p, - }, - { - payload: &payload4, - state: &p, - }, - { - payload: &payload5, - state: &e, - }, - }, - - upkeepIds: []*big.Int{upkeepId1}, - endBlock: block3 + 1, - startBlock: block1, - result: []upkeepState{ - { - payload: &payload5, - state: &e, - }, - { - payload: &payload4, - state: &p, - }, - }, - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - store := NewUpkeepStateStore(logger.TestLogger(t)) - for i, p := range tc.payloads { - err := store.SetUpkeepState(p, tc.states[i]) - require.Equal(t, err, tc.expectedError) - } - - pl, us, err := store.SelectByUpkeepIDsAndBlockRange(tc.upkeepIds, tc.startBlock, tc.endBlock) - require.Nil(t, err) - require.Equal(t, len(tc.result), len(pl)) - require.Equal(t, len(tc.result), len(us)) - for j, r := range tc.result { - require.Equal(t, r.payload, pl[j]) - require.Equal(t, r.state, us[j]) - } - - }) - } -} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner.go new file mode 100644 index 00000000000..9a0684850ec --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner.go @@ -0,0 +1,90 @@ +package upkeepstate + +import ( + "context" + "encoding/hex" + "fmt" + "io" + + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" +) + +type PerformedLogsScanner interface { + WorkIDsInRange(ctx context.Context, start, end int64) ([]string, error) + + Start(context.Context) error + io.Closer +} + +type performedEventsScanner struct { + lggr logger.Logger + poller logpoller.LogPoller + registryAddress common.Address +} + +func NewPerformedEventsScanner( + lggr logger.Logger, + poller logpoller.LogPoller, + registryAddress common.Address, +) *performedEventsScanner { + return &performedEventsScanner{ + lggr: lggr, + poller: poller, + registryAddress: registryAddress, + } +} + +func (s *performedEventsScanner) Start(_ context.Context) error { + return s.poller.RegisterFilter(logpoller.Filter{ + Name: dedupFilterName(s.registryAddress), + EventSigs: []common.Hash{ + // listening to dedup key added event + iregistry21.IKeeperRegistryMasterDedupKeyAdded{}.Topic(), + }, + Addresses: []common.Address{s.registryAddress}, + }) +} + +// implements io.Closer, does nothing upon close +func (s *performedEventsScanner) Close() error { + return nil +} + +func (s *performedEventsScanner) WorkIDsInRange(ctx context.Context, start, end int64) ([]string, error) { + logs, err := s.poller.LogsWithSigs( + start, + end, + []common.Hash{ + iregistry21.IKeeperRegistryMasterDedupKeyAdded{}.Topic(), + }, + s.registryAddress, + pg.WithParentCtx(ctx), + ) + if err != nil { + return nil, fmt.Errorf("error fetching logs: %w", err) + } + + return s.logsToWorkIDs(logs), nil +} + +func (s *performedEventsScanner) logsToWorkIDs(logs []logpoller.Log) []string { + workIDs := make([]string, 0) + for _, log := range logs { + topics := log.GetTopics() + if len(topics) < 2 { + s.lggr.Debugw("unexpected log topics", "topics", topics) + continue + } + workIDs = append(workIDs, hex.EncodeToString(topics[1].Bytes())) + } + return workIDs +} + +func dedupFilterName(addr common.Address) string { + return logpoller.FilterName("KeepersRegistry UpkeepStates Deduped", addr) +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner_test.go new file mode 100644 index 00000000000..f066fe0aa43 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner_test.go @@ -0,0 +1,129 @@ +package upkeepstate + +import ( + "fmt" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func TestPerformedEventsScanner(t *testing.T) { + ctx := testutils.Context(t) + registryAddr := common.HexToAddress("0x12345") + lggr := logger.TestLogger(t) + + tests := []struct { + name string + pollerResults []logpoller.Log + scannerResults []string + pollerErr error + errored bool + }{ + { + "no logs", + []logpoller.Log{}, + []string{}, + nil, + false, + }, + { + "log poller error", + []logpoller.Log{}, + []string{}, + fmt.Errorf("test-error"), + true, + }, + { + "one result", + []logpoller.Log{ + { + BlockNumber: 1, + Address: registryAddr, + Topics: convertTopics([]common.Hash{ + iregistry21.IKeeperRegistryMasterDedupKeyAdded{}.Topic(), + common.HexToHash("0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563"), + }), + }, + }, + []string{"290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563"}, + nil, + false, + }, + { + "missing workID", + []logpoller.Log{ + { + BlockNumber: 1, + Address: registryAddr, + Topics: convertTopics([]common.Hash{ + iregistry21.IKeeperRegistryMasterDedupKeyAdded{}.Topic(), + }), + }, + }, + []string{}, + nil, + false, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + mp := new(mocks.LogPoller) + mp.On("RegisterFilter", mock.Anything).Return(nil) + mp.On("UnregisterFilter", mock.Anything, mock.Anything).Return(nil) + scanner := NewPerformedEventsScanner(lggr, mp, registryAddr) + + go func() { + _ = scanner.Start(ctx) + }() + defer func() { + _ = scanner.Close() + }() + + mp.On("LogsWithSigs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.pollerResults, tc.pollerErr) + + results, err := scanner.WorkIDsInRange(ctx, 0, 100) + if tc.errored { + require.Error(t, err) + return + } + require.NoError(t, err) + require.Equal(t, len(tc.scannerResults), len(results)) + + for _, result := range results { + require.Contains(t, tc.scannerResults, result) + } + }) + } +} + +func TestPerformedEventsScanner_LogPollerErrors(t *testing.T) { + ctx := testutils.Context(t) + registryAddr := common.HexToAddress("0x12345") + lggr := logger.TestLogger(t) + + mp := new(mocks.LogPoller) + scanner := NewPerformedEventsScanner(lggr, mp, registryAddr) + + mp.On("LogsWithSigs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, fmt.Errorf("test error")) + + workIDs, err := scanner.WorkIDsInRange(ctx, 0, 100) + require.Error(t, err) + require.Nil(t, workIDs) +} + +func convertTopics(topics []common.Hash) [][]byte { + var topicsForDB [][]byte + for _, t := range topics { + topicsForDB = append(topicsForDB, t.Bytes()) + } + return topicsForDB +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store.go new file mode 100644 index 00000000000..13fb749d222 --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store.go @@ -0,0 +1,235 @@ +package upkeepstate + +import ( + "context" + "fmt" + "io" + "sync" + "time" + + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core" +) + +var ( + // CacheExpiration is the amount of time that we keep a record in the cache. + CacheExpiration = 24 * time.Hour + // GCInterval is the amount of time between cache cleanups. + GCInterval = 2 * time.Hour +) + +// UpkeepStateStore is the interface for managing upkeeps final state in a local store. +type UpkeepStateStore interface { + ocr2keepers.UpkeepStateUpdater + core.UpkeepStateReader + Start(context.Context) error + io.Closer +} + +var ( + _ UpkeepStateStore = &upkeepStateStore{} +) + +// upkeepStateRecord is a record that we save in a local cache. +type upkeepStateRecord struct { + workID string + state ocr2keepers.UpkeepState + + addedAt time.Time +} + +// upkeepStateStore implements UpkeepStateStore. +// It stores the state of ineligible upkeeps in a local, in-memory cache. +// In addition, performed events are fetched by the scanner on demand. +// TODO: Add DB persistence +type upkeepStateStore struct { + lggr logger.Logger + + cancel context.CancelFunc + + mu sync.RWMutex + cache map[string]*upkeepStateRecord + + scanner PerformedLogsScanner +} + +// NewUpkeepStateStore creates a new state store +func NewUpkeepStateStore(lggr logger.Logger, scanner PerformedLogsScanner) *upkeepStateStore { + return &upkeepStateStore{ + lggr: lggr.Named("upkeepStateStore"), + cache: map[string]*upkeepStateRecord{}, + scanner: scanner, + } +} + +// Start starts the upkeep state store. +// it does background cleanup of the cache. +func (u *upkeepStateStore) Start(context.Context) error { + u.mu.Lock() + if u.cancel != nil { + u.mu.Unlock() + return fmt.Errorf("already started") + } + ctx, cancel := context.WithCancel(context.Background()) + u.cancel = cancel + u.mu.Unlock() + + if err := u.scanner.Start(ctx); err != nil { + return fmt.Errorf("failed to start scanner") + } + + u.lggr.Debug("Starting upkeep state store") + + { + go func(ctx context.Context) { + ticker := time.NewTicker(GCInterval) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + u.cleanup() + case <-ctx.Done(): + + } + } + }(ctx) + } + + return nil +} + +func (u *upkeepStateStore) Close() error { + u.mu.Lock() + defer u.mu.Unlock() + + if cancel := u.cancel; cancel != nil { + u.cancel = nil + cancel() + } else { + return fmt.Errorf("already stopped") + } + if err := u.scanner.Close(); err != nil { + return fmt.Errorf("failed to start scanner") + } + + return nil +} + +// SelectByWorkIDs returns the current state of the upkeep for the provided ids. +// If an id is not found, the state is returned as StateUnknown. +// We first check the cache, and if any ids are missing, we fetch them from the scanner. +func (u *upkeepStateStore) SelectByWorkIDsInRange(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) { + states, ok := u.selectFromCache(workIDs...) + if ok { + // all ids were found in the cache + return states, nil + } + if err := u.fetchPerformed(ctx, start, end); err != nil { + return nil, err + } + states, _ = u.selectFromCache(workIDs...) + + return states, nil +} + +// SetUpkeepState updates the state of the upkeep. +// Currently we only store the state if the upkeep is ineligible. +// Performed events will be fetched on demand. +func (u *upkeepStateStore) SetUpkeepState(_ context.Context, result ocr2keepers.CheckResult, _ ocr2keepers.UpkeepState) error { + if result.Eligible { + return nil + } + + u.upsertStateRecord(result.WorkID, ocr2keepers.Ineligible) + + return nil +} + +// upsertStateRecord inserts or updates a record for the provided +// check result. If an item already exists in the data store, the state and +// block are updated. +func (u *upkeepStateStore) upsertStateRecord(workID string, s ocr2keepers.UpkeepState) { + u.mu.Lock() + defer u.mu.Unlock() + + record, ok := u.cache[workID] + if !ok { + record = &upkeepStateRecord{ + workID: workID, + addedAt: time.Now(), + } + } + record.state = s + + u.cache[workID] = record +} + +// fetchPerformed fetches all performed logs from the scanner to populate the cache. +func (u *upkeepStateStore) fetchPerformed(ctx context.Context, start, end int64, workIDs ...string) error { + performed, err := u.scanner.WorkIDsInRange(ctx, start, end) + if err != nil { + return err + } + + u.mu.Lock() + defer u.mu.Unlock() + + for _, workID := range performed { + if _, ok := u.cache[workID]; !ok { + s := &upkeepStateRecord{ + workID: workID, + state: ocr2keepers.Performed, + addedAt: time.Now(), + } + u.cache[workID] = s + } + } + + return nil +} + +// selectFromCache returns all saved state values for the provided ids, +// returning stateNotFound for any ids that are not found. +// the second return value is true if all ids were found in the cache. +func (u *upkeepStateStore) selectFromCache(workIDs ...string) ([]ocr2keepers.UpkeepState, bool) { + u.mu.RLock() + defer u.mu.RUnlock() + + var hasMisses bool + states := make([]ocr2keepers.UpkeepState, len(workIDs)) + for i, workID := range workIDs { + if state, ok := u.cache[workID]; ok { + states[i] = state.state + } else { + hasMisses = true + states[i] = ocr2keepers.UnknownState + } + } + + return states, !hasMisses +} + +// cleanup removes any records that are older than the TTL from both cache and DB. +func (u *upkeepStateStore) cleanup() { + u.cleanCache() + u.cleanDB() +} + +// cleanDB cleans up records in the DB that are older than the TTL. +func (u *upkeepStateStore) cleanDB() { +} + +// cleanupCache removes any records from the cache that are older than the TTL. +func (u *upkeepStateStore) cleanCache() { + u.mu.Lock() + defer u.mu.Unlock() + + for id, state := range u.cache { + if time.Since(state.addedAt) > CacheExpiration { + delete(u.cache, id) + } + } +} diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store_test.go new file mode 100644 index 00000000000..853b0c317ce --- /dev/null +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store_test.go @@ -0,0 +1,209 @@ +package upkeepstate + +import ( + "context" + "fmt" + "math/big" + "sync" + "testing" + "time" + + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + "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" +) + +func TestUpkeepStateStore(t *testing.T) { + tests := []struct { + name string + inserts []ocr2keepers.CheckResult + workIDsSelect []string + workIDsFromScanner []string + errScanner error + expected []ocr2keepers.UpkeepState + errored bool + }{ + { + name: "empty store", + }, + { + name: "save only ineligible states", + inserts: []ocr2keepers.CheckResult{ + { + UpkeepID: createUpkeepIDForTest(1), + WorkID: "0x1", + Eligible: false, + Trigger: ocr2keepers.Trigger{ + BlockNumber: ocr2keepers.BlockNumber(1), + }, + }, + { + UpkeepID: createUpkeepIDForTest(2), + WorkID: "ox2", + Eligible: true, + Trigger: ocr2keepers.Trigger{ + BlockNumber: ocr2keepers.BlockNumber(2), + }, + }, + }, + workIDsSelect: []string{"0x1", "0x2"}, + expected: []ocr2keepers.UpkeepState{ + ocr2keepers.Ineligible, + ocr2keepers.UnknownState, + }, + }, + { + name: "fetch results from scanner", + inserts: []ocr2keepers.CheckResult{ + { + UpkeepID: createUpkeepIDForTest(1), + WorkID: "0x1", + Eligible: false, + Trigger: ocr2keepers.Trigger{ + BlockNumber: ocr2keepers.BlockNumber(1), + }, + }, + }, + workIDsSelect: []string{"0x1", "0x2"}, + workIDsFromScanner: []string{"0x2", "0x222"}, + expected: []ocr2keepers.UpkeepState{ + ocr2keepers.Ineligible, + ocr2keepers.Performed, + }, + }, + { + name: "unknown states", + inserts: []ocr2keepers.CheckResult{ + { + UpkeepID: createUpkeepIDForTest(1), + WorkID: "0x1", + Eligible: false, + Trigger: ocr2keepers.Trigger{ + BlockNumber: ocr2keepers.BlockNumber(1), + }, + }, + }, + workIDsSelect: []string{"0x2"}, + workIDsFromScanner: []string{}, + expected: []ocr2keepers.UpkeepState{ + ocr2keepers.UnknownState, + }, + }, + { + name: "scanner error", + inserts: []ocr2keepers.CheckResult{ + { + UpkeepID: createUpkeepIDForTest(1), + WorkID: "0x1", + Eligible: false, + Trigger: ocr2keepers.Trigger{ + BlockNumber: ocr2keepers.BlockNumber(1), + }, + }, + }, + workIDsSelect: []string{"0x1", "0x2"}, + workIDsFromScanner: []string{"0x2", "0x222"}, + errScanner: fmt.Errorf("test error"), + errored: true, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + ctx := testutils.Context(t) + + scanner := &mockScanner{} + scanner.addWorkID(tc.workIDsFromScanner...) + scanner.setErr(tc.errScanner) + store := NewUpkeepStateStore(logger.TestLogger(t), scanner) + + for _, insert := range tc.inserts { + assert.NoError(t, store.SetUpkeepState(ctx, insert, ocr2keepers.Performed)) + } + + states, err := store.SelectByWorkIDsInRange(ctx, 1, 100, tc.workIDsSelect...) + if tc.errored { + assert.Error(t, err) + return + } + assert.NoError(t, err) + + assert.Equal(t, len(tc.expected), len(states)) + for i, state := range states { + assert.Equal(t, tc.expected[i], state) + } + }) + } +} + +func TestUpkeepStateStore_Upsert(t *testing.T) { + ctx := testutils.Context(t) + store := NewUpkeepStateStore(logger.TestLogger(t), &mockScanner{}) + + res := ocr2keepers.CheckResult{ + UpkeepID: createUpkeepIDForTest(1), + WorkID: "0x1", + Eligible: false, + Trigger: ocr2keepers.Trigger{ + BlockNumber: ocr2keepers.BlockNumber(1), + }, + } + require.NoError(t, store.SetUpkeepState(ctx, res, ocr2keepers.Performed)) + <-time.After(10 * time.Millisecond) + res.Trigger.BlockNumber = ocr2keepers.BlockNumber(2) + now := time.Now() + require.NoError(t, store.SetUpkeepState(ctx, res, ocr2keepers.Performed)) + + store.mu.Lock() + addedAt := store.cache["0x1"].addedAt + store.mu.Unlock() + + require.True(t, now.After(addedAt)) +} + +func createUpkeepIDForTest(v int64) ocr2keepers.UpkeepIdentifier { + uid := &ocr2keepers.UpkeepIdentifier{} + _ = uid.FromBigInt(big.NewInt(v)) + + return *uid +} + +type mockScanner struct { + lock sync.Mutex + workIDs []string + err error +} + +func (s *mockScanner) addWorkID(workIDs ...string) { + s.lock.Lock() + defer s.lock.Unlock() + + s.workIDs = append(s.workIDs, workIDs...) +} + +func (s *mockScanner) setErr(err error) { + s.lock.Lock() + defer s.lock.Unlock() + + s.err = err +} + +func (s *mockScanner) WorkIDsInRange(ctx context.Context, start, end int64) ([]string, error) { + s.lock.Lock() + defer s.lock.Unlock() + + res := s.workIDs[:] + s.workIDs = nil + return res, s.err +} + +func (s *mockScanner) Start(context.Context) error { + return nil +} + +func (s *mockScanner) Close() error { + return nil +} diff --git a/core/services/ocr2/plugins/ocr2keeper/integration_21_test.go b/core/services/ocr2/plugins/ocr2keeper/integration_21_test.go index f207f4e209a..91e422ce949 100644 --- a/core/services/ocr2/plugins/ocr2keeper/integration_21_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/integration_21_test.go @@ -1,18 +1,53 @@ package ocr2keeper_test import ( + "context" "crypto/rand" + "encoding/hex" + "encoding/json" + "fmt" + "math/big" + "strings" + "sync" "testing" + "time" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/onsi/gomega" + "github.com/smartcontractkit/libocr/commontypes" + "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + ocrTypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/ocr2keepers/pkg/v3/config" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/umbracle/ethgo/abi" + "github.com/smartcontractkit/chainlink/v2/core/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + automationForwarderLogic "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_forwarder_logic" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/basic_upkeep_contract" + iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" + registrylogica21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_logic_a_wrapper_2_1" + registrylogicb21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_logic_b_wrapper_2_1" + registry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper_2_1" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/log_upkeep_counter_wrapper" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_v3_aggregator_contract" + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" ) func TestFilterNamesFromSpec21(t *testing.T) { @@ -40,3 +75,530 @@ func TestFilterNamesFromSpec21(t *testing.T) { _, err = ocr2keeper.FilterNamesFromSpec21(spec) require.ErrorContains(t, err, "not a valid EIP55 formatted address") } + +func TestIntegration_KeeperPluginConditionalUpkeep(t *testing.T) { + g := gomega.NewWithT(t) + lggr := logger.TestLogger(t) + + // setup blockchain + sergey := testutils.MustNewSimTransactor(t) // owns all the link + steve := testutils.MustNewSimTransactor(t) // registry owner + carrol := testutils.MustNewSimTransactor(t) // upkeep owner + genesisData := core.GenesisAlloc{ + sergey.From: {Balance: assets.Ether(10000).ToInt()}, + steve.From: {Balance: assets.Ether(10000).ToInt()}, + carrol.From: {Balance: assets.Ether(10000).ToInt()}, + } + // Generate 5 keys for nodes (1 bootstrap + 4 ocr nodes) and fund them with ether + var nodeKeys [5]ethkey.KeyV2 + for i := int64(0); i < 5; i++ { + nodeKeys[i] = cltest.MustGenerateRandomKey(t) + genesisData[nodeKeys[i].Address] = core.GenesisAccount{Balance: assets.Ether(1000).ToInt()} + } + + backend := cltest.NewSimulatedBackend(t, genesisData, uint32(ethconfig.Defaults.Miner.GasCeil)) + stopMining := cltest.Mine(backend, 3*time.Second) // Should be greater than deltaRound since we cannot access old blocks on simulated blockchain + defer stopMining() + + // Deploy registry + linkAddr, _, linkToken, err := link_token_interface.DeployLinkToken(sergey, backend) + require.NoError(t, err) + gasFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(steve, backend, 18, big.NewInt(60000000000)) + require.NoError(t, err) + linkFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(steve, backend, 18, big.NewInt(2000000000000000000)) + require.NoError(t, err) + registry := deployKeeper21Registry(t, steve, backend, linkAddr, linkFeedAddr, gasFeedAddr) + + nodes := setupNodes(t, nodeKeys, registry, backend, steve) + + <-time.After(time.Second * 5) + + upkeeps := 1 + + _, err = linkToken.Transfer(sergey, carrol.From, big.NewInt(0).Mul(oneHunEth, big.NewInt(int64(upkeeps+1)))) + require.NoError(t, err) + + // Register new upkeep + upkeepAddr, _, upkeepContract, err := basic_upkeep_contract.DeployBasicUpkeepContract(carrol, backend) + require.NoError(t, err) + registrationTx, err := registry.RegisterUpkeep(steve, upkeepAddr, 2_500_000, carrol.From, 0, []byte{}, []byte{}, []byte{}) + require.NoError(t, err) + backend.Commit() + upkeepID := getUpkeepIdFromTx21(t, registry, registrationTx, backend) + + // Fund the upkeep + _, err = linkToken.Transfer(sergey, carrol.From, oneHunEth) + require.NoError(t, err) + _, err = linkToken.Approve(carrol, registry.Address(), oneHunEth) + require.NoError(t, err) + _, err = registry.AddFunds(carrol, upkeepID, oneHunEth) + require.NoError(t, err) + backend.Commit() + + // Set upkeep to be performed + _, err = upkeepContract.SetBytesToSend(carrol, payload1) + require.NoError(t, err) + _, err = upkeepContract.SetShouldPerformUpkeep(carrol, true) + require.NoError(t, err) + backend.Commit() + + lggr.Infow("Upkeep registered and funded", "upkeepID", upkeepID.String()) + + // keeper job is triggered and payload is received + receivedBytes := func() []byte { + received, err2 := upkeepContract.ReceivedBytes(nil) + require.NoError(t, err2) + return received + } + g.Eventually(receivedBytes, testutils.WaitTimeout(t), cltest.DBPollingInterval).Should(gomega.Equal(payload1)) + + checkPipelineRuns(t, nodes, 1) + + // change payload + _, err = upkeepContract.SetBytesToSend(carrol, payload2) + require.NoError(t, err) + _, err = upkeepContract.SetShouldPerformUpkeep(carrol, true) + require.NoError(t, err) + + // observe 2nd job run and received payload changes + g.Eventually(receivedBytes, testutils.WaitTimeout(t), cltest.DBPollingInterval).Should(gomega.Equal(payload2)) +} + +func TestIntegration_KeeperPluginLogUpkeep(t *testing.T) { + t.Skip() // TODO: fix test (fails in CI) + g := gomega.NewWithT(t) + + // setup blockchain + sergey := testutils.MustNewSimTransactor(t) // owns all the link + steve := testutils.MustNewSimTransactor(t) // registry owner + carrol := testutils.MustNewSimTransactor(t) // upkeep owner + genesisData := core.GenesisAlloc{ + sergey.From: {Balance: assets.Ether(10000).ToInt()}, + steve.From: {Balance: assets.Ether(10000).ToInt()}, + carrol.From: {Balance: assets.Ether(10000).ToInt()}, + } + // Generate 5 keys for nodes (1 bootstrap + 4 ocr nodes) and fund them with ether + var nodeKeys [5]ethkey.KeyV2 + for i := int64(0); i < 5; i++ { + nodeKeys[i] = cltest.MustGenerateRandomKey(t) + genesisData[nodeKeys[i].Address] = core.GenesisAccount{Balance: assets.Ether(1000).ToInt()} + } + + backend := cltest.NewSimulatedBackend(t, genesisData, uint32(ethconfig.Defaults.Miner.GasCeil)) + stopMining := cltest.Mine(backend, 3*time.Second) // Should be greater than deltaRound since we cannot access old blocks on simulated blockchain + defer stopMining() + + // Deploy registry + linkAddr, _, linkToken, err := link_token_interface.DeployLinkToken(sergey, backend) + require.NoError(t, err) + gasFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(steve, backend, 18, big.NewInt(60000000000)) + require.NoError(t, err) + linkFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(steve, backend, 18, big.NewInt(2000000000000000000)) + require.NoError(t, err) + registry := deployKeeper21Registry(t, steve, backend, linkAddr, linkFeedAddr, gasFeedAddr) + + nodes := setupNodes(t, nodeKeys, registry, backend, steve) + // wait for nodes to start + // TODO: find a better way to do this + <-time.After(time.Second * 10) + + upkeeps := 1 + + _, err = linkToken.Transfer(sergey, carrol.From, big.NewInt(0).Mul(oneHunEth, big.NewInt(int64(upkeeps+1)))) + require.NoError(t, err) + + backend.Commit() + + ids, addrs, contracts := deployUpkeeps(t, backend, carrol, steve, linkToken, registry, upkeeps) + require.Equal(t, upkeeps, len(ids)) + require.Equal(t, len(ids), len(contracts)) + require.Equal(t, len(ids), len(addrs)) + + backend.Commit() + + emits := 10 + go emitEvents(testutils.Context(t), t, emits, contracts, carrol, func() { + backend.Commit() + time.Sleep(3 * time.Second) + }) + + listener, done := listenPerformed(t, backend, registry, ids, int64(1)) + g.Eventually(listener, testutils.WaitTimeout(t), cltest.DBPollingInterval).Should(gomega.BeTrue()) + done() + + runs := checkPipelineRuns(t, nodes, 1*len(nodes)) // TODO: TBD + + t.Run("recover logs", func(t *testing.T) { + t.Skip() // TODO: fix test (fails in CI) + + addr, contract := addrs[0], contracts[0] + upkeepID := registerUpkeep(t, registry, addr, carrol, steve, backend) + backend.Commit() + t.Logf("Registered new upkeep %s for address %s", upkeepID.String(), addr.String()) + // blockBeforeEmits := backend.Blockchain().CurrentBlock().Number.Uint64() + // Emit 100 logs in a burst + emits := 100 + i := 0 + emitEvents(testutils.Context(t), t, 100, []*log_upkeep_counter_wrapper.LogUpkeepCounter{contract}, carrol, func() { + i++ + if i%(emits/4) == 0 { + backend.Commit() + time.Sleep(time.Millisecond * 250) // otherwise we get "invalid transaction nonce" errors + } + }) + // Mine enough blocks to ensre these logs don't fall into log provider range + dummyBlocks := 500 + for i := 0; i < dummyBlocks; i++ { + backend.Commit() + time.Sleep(time.Millisecond * 10) + } + t.Logf("Mined %d blocks", dummyBlocks) + + // listener, done := listenPerformed(t, backend, registry, []*big.Int{upkeepID}, int64(blockBeforeEmits)) + // defer done() + // g.Eventually(listener, testutils.WaitTimeout(t), cltest.DBPollingInterval).Should(gomega.BeTrue()) + + expectedPostRecover := runs + emits // TODO: TBD + waitPipelineRuns(t, nodes, expectedPostRecover, testutils.WaitTimeout(t), cltest.DBPollingInterval) + + }) +} + +func waitPipelineRuns(t *testing.T, nodes []Node, n int, timeout, interval time.Duration) { + ctx, cancel := context.WithTimeout(testutils.Context(t), timeout) + defer cancel() + var allRuns []pipeline.Run + for len(allRuns) < n && ctx.Err() == nil { + allRuns = []pipeline.Run{} + for _, node := range nodes { + runs, err := node.App.PipelineORM().GetAllRuns() + require.NoError(t, err) + allRuns = append(allRuns, runs...) + } + time.Sleep(interval) + } + runs := len(allRuns) + t.Logf("found %d pipeline runs", runs) + require.GreaterOrEqual(t, runs, n) +} + +func checkPipelineRuns(t *testing.T, nodes []Node, n int) int { + var allRuns []pipeline.Run + for _, node := range nodes { + runs, err2 := node.App.PipelineORM().GetAllRuns() + require.NoError(t, err2) + allRuns = append(allRuns, runs...) + } + runs := len(allRuns) + t.Logf("found %d pipeline runs", runs) + require.GreaterOrEqual(t, runs, n) + return runs +} + +func emitEvents(ctx context.Context, t *testing.T, n int, contracts []*log_upkeep_counter_wrapper.LogUpkeepCounter, carrol *bind.TransactOpts, afterEmit func()) { + for i := 0; i < n && ctx.Err() == nil; i++ { + for _, contract := range contracts { + // t.Logf("[automation-ocr3 | EvmRegistry] calling upkeep contracts to emit events. run: %d; contract addr: %s", i+1, contract.Address().Hex()) + _, err := contract.Start(carrol) + require.NoError(t, err) + } + afterEmit() + } +} + +func mapListener(m *sync.Map, n int) func() bool { + return func() bool { + count := 0 + m.Range(func(key, value interface{}) bool { + count++ + return true + }) + return count > n + } +} + +func listenPerformed(t *testing.T, backend *backends.SimulatedBackend, registry *iregistry21.IKeeperRegistryMaster, ids []*big.Int, startBlock int64) (func() bool, func()) { + cache := &sync.Map{} + ctx, cancel := context.WithCancel(testutils.Context(t)) + start := startBlock + go func() { + for ctx.Err() == nil { + bl := backend.Blockchain().CurrentBlock().Number.Uint64() + sc := make([]bool, len(ids)) + for i := range sc { + sc[i] = true + } + iter, err := registry.FilterUpkeepPerformed(&bind.FilterOpts{ + Start: uint64(start), + End: &bl, + Context: ctx, + }, ids, sc) + if ctx.Err() != nil { + return + } + require.NoError(t, err) + for iter.Next() { + if iter.Event != nil { + t.Logf("[automation-ocr3 | EvmRegistry] upkeep performed event emitted for id %s", iter.Event.Id.String()) + cache.Store(iter.Event.Id.String(), true) + } + } + require.NoError(t, iter.Close()) + time.Sleep(time.Second) + } + }() + + return mapListener(cache, 0), cancel +} + +func setupNodes(t *testing.T, nodeKeys [5]ethkey.KeyV2, registry *iregistry21.IKeeperRegistryMaster, backend *backends.SimulatedBackend, usr *bind.TransactOpts) []Node { + lggr := logger.TestLogger(t) + // Setup bootstrap + oracle nodes + bootstrapNodePort := int64(19599) + appBootstrap, bootstrapPeerID, bootstrapTransmitter, bootstrapKb := setupNode(t, bootstrapNodePort, "bootstrap_keeper_ocr", nodeKeys[0], backend, nil) + bootstrapNode := Node{ + appBootstrap, bootstrapTransmitter, bootstrapKb, + } + var ( + oracles []confighelper.OracleIdentityExtra + nodes []Node + ) + // Set up the minimum 4 oracles all funded + for i := int64(0); i < 4; i++ { + app, peerID, transmitter, kb := setupNode(t, bootstrapNodePort+i+1, fmt.Sprintf("oracle_keeper%d", i), nodeKeys[i+1], backend, []commontypes.BootstrapperLocator{ + // Supply the bootstrap IP and port as a V2 peer address + {PeerID: bootstrapPeerID, Addrs: []string{fmt.Sprintf("127.0.0.1:%d", bootstrapNodePort)}}, + }) + + nodes = append(nodes, Node{ + app, transmitter, kb, + }) + offchainPublicKey, _ := hex.DecodeString(strings.TrimPrefix(kb.OnChainPublicKey(), "0x")) + oracles = append(oracles, confighelper.OracleIdentityExtra{ + OracleIdentity: confighelper.OracleIdentity{ + OnchainPublicKey: offchainPublicKey, + TransmitAccount: ocrTypes.Account(transmitter.String()), + OffchainPublicKey: kb.OffchainPublicKey(), + PeerID: peerID, + }, + ConfigEncryptionPublicKey: kb.ConfigEncryptionPublicKey(), + }) + } + // Add the bootstrap job + bootstrapNode.AddBootstrapJob(t, fmt.Sprintf(` + type = "bootstrap" + relay = "evm" + schemaVersion = 1 + name = "boot" + contractID = "%s" + contractConfigTrackerPollInterval = "15s" + + [relayConfig] + chainID = 1337 + `, registry.Address())) + + // Add OCR jobs + for i, node := range nodes { + node.AddJob(t, fmt.Sprintf(` + type = "offchainreporting2" + pluginType = "ocr2automation" + relay = "evm" + name = "ocr2keepers-%d" + schemaVersion = 1 + contractID = "%s" + contractConfigTrackerPollInterval = "15s" + ocrKeyBundleID = "%s" + transmitterID = "%s" + p2pv2Bootstrappers = [ + "%s" + ] + + [relayConfig] + chainID = 1337 + + [pluginConfig] + maxServiceWorkers = 100 + cacheEvictionInterval = "1s" + mercuryCredentialName = "%s" + contractVersion = "v2.1" + `, i, registry.Address(), node.KeyBundle.ID(), node.Transmitter, fmt.Sprintf("%s@127.0.0.1:%d", bootstrapPeerID, bootstrapNodePort), MercuryCredName)) + } + + // Setup config on contract + configType := abi.MustNewType("tuple(uint32 paymentPremiumPPB,uint32 flatFeeMicroLink,uint32 checkGasLimit,uint24 stalenessSeconds,uint16 gasCeilingMultiplier,uint96 minUpkeepSpend,uint32 maxPerformGas,uint32 maxCheckDataSize,uint32 maxPerformDataSize,uint32 maxRevertDataSize, uint256 fallbackGasPrice,uint256 fallbackLinkPrice,address transcoder,address[] registrars, address upkeepPrivilegeManager)") + onchainConfig, err := abi.Encode(map[string]interface{}{ + "paymentPremiumPPB": uint32(0), + "flatFeeMicroLink": uint32(0), + "checkGasLimit": uint32(6500000), + "stalenessSeconds": uint32(90000), + "gasCeilingMultiplier": uint16(2), + "minUpkeepSpend": uint32(0), + "maxPerformGas": uint32(5000000), + "maxCheckDataSize": uint32(5000), + "maxPerformDataSize": uint32(5000), + "maxRevertDataSize": uint32(5000), + "fallbackGasPrice": big.NewInt(60000000000), + "fallbackLinkPrice": big.NewInt(2000000000000000000), + "transcoder": testutils.NewAddress(), + "registrars": []common.Address{testutils.NewAddress()}, + "upkeepPrivilegeManager": testutils.NewAddress(), + }, configType) + require.NoError(t, err) + rawCfg, err := json.Marshal(config.OffchainConfig{ + PerformLockoutWindow: 100 * 12 * 1000, // ~100 block lockout (on goerli) + MinConfirmations: 1, + }) + if err != nil { + t.Logf("error creating off-chain config: %s", err) + t.FailNow() + } + + signers, transmitters, threshold, onchainConfig, offchainConfigVersion, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsForTests( + 5*time.Second, // deltaProgress time.Duration, + 10*time.Second, // deltaResend time.Duration, + 100*time.Millisecond, // deltaInitial time.Duration, + 1000*time.Millisecond, // deltaRound time.Duration, + 40*time.Millisecond, // deltaGrace time.Duration, + 200*time.Millisecond, // deltaRequestCertifiedCommit time.Duration, + 30*time.Second, // deltaStage time.Duration, + uint64(50), // rMax uint8, + []int{1, 1, 1, 1}, // s []int, + oracles, // oracles []OracleIdentityExtra, + rawCfg, // reportingPluginConfig []byte, + 20*time.Millisecond, // maxDurationQuery time.Duration, + 1600*time.Millisecond, // maxDurationObservation time.Duration, + 20*time.Millisecond, // maxDurationShouldAcceptFinalizedReport time.Duration, + 20*time.Millisecond, // maxDurationShouldTransmitAcceptedReport time.Duration, + 1, // f int, + onchainConfig, // onchainConfig []byte, + ) + + require.NoError(t, err) + signerAddresses, err := evm.OnchainPublicKeyToAddress(signers) + require.NoError(t, err) + transmitterAddresses, err := accountsToAddress(transmitters) + require.NoError(t, err) + + lggr.Infow("Setting Config on Oracle Contract", + "signerAddresses", signerAddresses, + "transmitterAddresses", transmitterAddresses, + "threshold", threshold, + "onchainConfig", onchainConfig, + "encodedConfigVersion", offchainConfigVersion, + "offchainConfig", offchainConfig, + ) + _, err = registry.SetConfig( + usr, + signerAddresses, + transmitterAddresses, + threshold, + onchainConfig, + offchainConfigVersion, + offchainConfig, + ) + require.NoError(t, err) + backend.Commit() + + return nodes +} + +func deployUpkeeps(t *testing.T, backend *backends.SimulatedBackend, carrol, steve *bind.TransactOpts, linkToken *link_token_interface.LinkToken, registry *iregistry21.IKeeperRegistryMaster, n int) ([]*big.Int, []common.Address, []*log_upkeep_counter_wrapper.LogUpkeepCounter) { + ids := make([]*big.Int, n) + addrs := make([]common.Address, n) + contracts := make([]*log_upkeep_counter_wrapper.LogUpkeepCounter, n) + for i := 0; i < n; i++ { + backend.Commit() + time.Sleep(1 * time.Second) + upkeepAddr, _, upkeepContract, err := log_upkeep_counter_wrapper.DeployLogUpkeepCounter( + carrol, backend, + big.NewInt(100000), + ) + require.NoError(t, err) + + upkeepID := registerUpkeep(t, registry, upkeepAddr, carrol, steve, backend) + + // Fund the upkeep + _, err = linkToken.Approve(carrol, registry.Address(), oneHunEth) + require.NoError(t, err) + _, err = registry.AddFunds(carrol, upkeepID, oneHunEth) + require.NoError(t, err) + backend.Commit() + + ids[i] = upkeepID + contracts[i] = upkeepContract + addrs[i] = upkeepAddr + } + return ids, addrs, contracts +} + +func registerUpkeep(t *testing.T, registry *iregistry21.IKeeperRegistryMaster, upkeepAddr common.Address, carrol, steve *bind.TransactOpts, backend *backends.SimulatedBackend) *big.Int { + logTriggerConfigType := abi.MustNewType("tuple(address contractAddress, uint8 filterSelector, bytes32 topic0, bytes32 topic1, bytes32 topic2, bytes32 topic3)") + logTriggerConfig, err := abi.Encode(map[string]interface{}{ + "contractAddress": upkeepAddr, + "filterSelector": 0, // no indexed topics filtered + "topic0": "0x3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d", // event sig for Trigger() + "topic1": "0x", + "topic2": "0x", + "topic3": "0x", + }, logTriggerConfigType) + require.NoError(t, err) + + registrationTx, err := registry.RegisterUpkeep(steve, upkeepAddr, 2_500_000, carrol.From, 1, []byte{}, logTriggerConfig, []byte{}) + require.NoError(t, err) + backend.Commit() + upkeepID := getUpkeepIdFromTx21(t, registry, registrationTx, backend) + + return upkeepID +} + +func deployKeeper21Registry( + t *testing.T, + auth *bind.TransactOpts, + backend *backends.SimulatedBackend, + linkAddr, linkFeedAddr, + gasFeedAddr common.Address, +) *iregistry21.IKeeperRegistryMaster { + automationForwarderLogicAddr, _, _, err := automationForwarderLogic.DeployAutomationForwarderLogic(auth, backend) + require.NoError(t, err) + backend.Commit() + registryLogicBAddr, _, _, err := registrylogicb21.DeployKeeperRegistryLogicB( + auth, + backend, + 0, // Payment model + linkAddr, + linkFeedAddr, + gasFeedAddr, + automationForwarderLogicAddr, + ) + require.NoError(t, err) + backend.Commit() + + registryLogicAAddr, _, _, err := registrylogica21.DeployKeeperRegistryLogicA( + auth, + backend, + registryLogicBAddr, + ) + require.NoError(t, err) + backend.Commit() + + registryAddr, _, _, err := registry21.DeployKeeperRegistry( + auth, + backend, + registryLogicAAddr, + ) + require.NoError(t, err) + backend.Commit() + + registryMaster, err := iregistry21.NewIKeeperRegistryMaster(registryAddr, backend) + require.NoError(t, err) + + return registryMaster +} + +func getUpkeepIdFromTx21(t *testing.T, registry *iregistry21.IKeeperRegistryMaster, registrationTx *types.Transaction, backend *backends.SimulatedBackend) *big.Int { + receipt, err := backend.TransactionReceipt(testutils.Context(t), registrationTx.Hash()) + require.NoError(t, err) + parsedLog, err := registry.ParseUpkeepRegistered(*receipt.Logs[0]) + require.NoError(t, err) + return parsedLog.Id +} diff --git a/core/services/ocr2/plugins/ocr2keeper/integration_test.go b/core/services/ocr2/plugins/ocr2keeper/integration_test.go index 453aac147c5..8b7e92c40fe 100644 --- a/core/services/ocr2/plugins/ocr2keeper/integration_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/integration_test.go @@ -23,7 +23,7 @@ import ( "github.com/smartcontractkit/libocr/commontypes" "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" ocrTypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - "github.com/smartcontractkit/ocr2keepers/pkg/config" + "github.com/smartcontractkit/ocr2keepers/pkg/v2/config" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -447,7 +447,7 @@ func setupForwarderForNode( _, err = forwarderORM.CreateForwarder(faddr, chainID) require.NoError(t, err) - chain, err := app.GetChains().EVM.Get((*big.Int)(&chainID)) + chain, err := app.GetRelayers().LegacyEVMChains().Get((*big.Int)(&chainID).String()) require.NoError(t, err) fwdr, err := chain.TxManager().GetForwarderForEOA(recipient) require.NoError(t, err) diff --git a/core/services/ocr2/plugins/ocr2keeper/util.go b/core/services/ocr2/plugins/ocr2keeper/util.go index ed699cfaabe..5934ed45df2 100644 --- a/core/services/ocr2/plugins/ocr2keeper/util.go +++ b/core/services/ocr2/plugins/ocr2keeper/util.go @@ -2,17 +2,18 @@ package ocr2keeper import ( "fmt" - "math/big" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" - "github.com/smartcontractkit/ocr2keepers/pkg/coordinator" - "github.com/smartcontractkit/ocr2keepers/pkg/observer/polling" - "github.com/smartcontractkit/ocr2keepers/pkg/runner" - "github.com/smartcontractkit/ocr2keepers/pkg/v3/plugin" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + ocr2keepers20 "github.com/smartcontractkit/ocr2keepers/pkg/v2" + ocr2keepers20coordinator "github.com/smartcontractkit/ocr2keepers/pkg/v2/coordinator" + ocr2keepers20polling "github.com/smartcontractkit/ocr2keepers/pkg/v2/observer/polling" + ocr2keepers20runner "github.com/smartcontractkit/ocr2keepers/pkg/v2/runner" "github.com/smartcontractkit/sqlx" "github.com/smartcontractkit/chainlink-relay/pkg/types" + ocr2keepers21 "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" @@ -20,21 +21,20 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/models" kevm20 "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm20" kevm21 "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" ) -type Encoder interface { - ocr2keepers.Encoder - coordinator.Encoder - polling.Encoder - runner.Encoder - coordinator.Encoder +type Encoder20 interface { + ocr2keepers20.Encoder + ocr2keepers20coordinator.Encoder + ocr2keepers20polling.Encoder + ocr2keepers20runner.Encoder + ocr2keepers20coordinator.Encoder } type Encoder21 interface { - plugin.Encoder + ocr2keepers21.Encoder } var ( @@ -64,30 +64,24 @@ func EVMProvider(db *sqlx.DB, chain evm.Chain, lggr logger.Logger, spec job.Job, return keeperProvider, nil } -func EVMDependencies20(spec job.Job, db *sqlx.DB, lggr logger.Logger, set evm.ChainSet, pr pipeline.Runner) (evmrelay.OCR2KeeperProvider, *kevm20.EvmRegistry, Encoder, *kevm20.LogProvider, error) { +func EVMDependencies20( + spec job.Job, + db *sqlx.DB, + lggr logger.Logger, + chain evm.Chain, + pr pipeline.Runner, +) (evmrelay.OCR2KeeperProvider, *kevm20.EvmRegistry, Encoder20, *kevm20.LogProvider, error) { var err error - var chain evm.Chain + var keeperProvider evmrelay.OCR2KeeperProvider var registry *kevm20.EvmRegistry - oSpec := spec.OCR2OracleSpec - - // get the chain from the config - chainID, err2 := spec.OCR2OracleSpec.RelayConfig.EVMChainID() - if err2 != nil { - return nil, nil, nil, nil, err2 - } - chain, err2 = set.Get(big.NewInt(chainID)) - if err2 != nil { - return nil, nil, nil, nil, fmt.Errorf("%w: %s", ErrNoChainFromSpec, err2) - } - // the provider will be returned as a dependency if keeperProvider, err = EVMProvider(db, chain, lggr, spec, pr); err != nil { return nil, nil, nil, nil, err } - rAddr := ethkey.MustEIP55Address(oSpec.ContractID).Address() + rAddr := ethkey.MustEIP55Address(spec.OCR2OracleSpec.ContractID).Address() if registry, err = kevm20.NewEVMRegistryService(rAddr, chain, lggr); err != nil { return nil, nil, nil, nil, err } @@ -111,44 +105,31 @@ func FilterNamesFromSpec20(spec *job.OCR2OracleSpec) (names []string, err error) return []string{kevm20.LogProviderFilterName(addr.Address()), kevm20.UpkeepFilterName(addr.Address())}, err } -func EVMDependencies21(spec job.Job, db *sqlx.DB, lggr logger.Logger, set evm.ChainSet, pr pipeline.Runner, mc *models.MercuryCredentials) (evmrelay.OCR2KeeperProvider, *kevm21.EvmRegistry, Encoder21, *kevm21.TransmitEventProvider, logprovider.LogEventProvider, *kevm21.BlockSubscriber, error) { +func EVMDependencies21( + spec job.Job, + db *sqlx.DB, + lggr logger.Logger, + chain evm.Chain, + pr pipeline.Runner, + mc *models.MercuryCredentials, + keyring ocrtypes.OnchainKeyring, +) (evmrelay.OCR2KeeperProvider, kevm21.AutomationServices, error) { var err error - var chain evm.Chain var keeperProvider evmrelay.OCR2KeeperProvider - var registry *kevm21.EvmRegistry oSpec := spec.OCR2OracleSpec - - // get the chain from the config - chainID, err2 := spec.OCR2OracleSpec.RelayConfig.EVMChainID() - if err2 != nil { - return nil, nil, nil, nil, nil, nil, err2 - } - chain, err2 = set.Get(big.NewInt(chainID)) - if err2 != nil { - return nil, nil, nil, nil, nil, nil, fmt.Errorf("%w: %s", ErrNoChainFromSpec, err2) - } - // the provider will be returned as a dependency if keeperProvider, err = EVMProvider(db, chain, lggr, spec, pr); err != nil { - return nil, nil, nil, nil, nil, nil, err + return nil, nil, err } rAddr := ethkey.MustEIP55Address(oSpec.ContractID).Address() - if registry, err = kevm21.NewEVMRegistryService(rAddr, chain, mc, lggr); err != nil { - return nil, nil, nil, nil, nil, nil, err + services, err := kevm21.New(rAddr, chain, mc, keyring, lggr) + if err != nil { + return nil, nil, err } - encoder := kevm21.EVMAutomationEncoder21{} - - hp := kevm21.NewBlockSubscriber(chain.HeadBroadcaster(), chain.LogPoller(), 128, lggr) - - // lookback blocks is hard coded and should provide ample time for logs - // to be detected in most cases - var lookbackBlocks int64 = 250 - // TODO: accept a version of the registry contract and use the correct interfaces - logTransmitter, err := kevm21.NewTransmitEventProvider(lggr, chain.LogPoller(), rAddr, chain.Client(), lookbackBlocks) - return keeperProvider, registry, encoder, logTransmitter, registry.LogEventProvider(), hp, err + return keeperProvider, services, err } func FilterNamesFromSpec21(spec *job.OCR2OracleSpec) (names []string, err error) { @@ -156,5 +137,5 @@ func FilterNamesFromSpec21(spec *job.OCR2OracleSpec) (names []string, err error) if err != nil { return nil, err } - return []string{kevm21.TransmitEventProviderFilterName(addr.Address()), kevm21.UpkeepFilterName(addr.Address())}, err + return []string{kevm21.TransmitEventProviderFilterName(addr.Address()), kevm21.RegistryUpkeepFilterName(addr.Address())}, err } 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 db646b4e807..0ca6fb383c6 100644 --- a/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go +++ b/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go @@ -431,7 +431,7 @@ func runOCR2VRFTest(t *testing.T, useForwarders bool) { err = bootstrapNode.app.Start(testutils.Context(t)) require.NoError(t, err) - chainSet := bootstrapNode.app.GetChains().EVM + chainSet := bootstrapNode.app.GetRelayers().LegacyEVMChains() require.NotNil(t, chainSet) bootstrapJobSpec := fmt.Sprintf(` type = "bootstrap" diff --git a/core/services/ocr2/plugins/threshold/decryption_queue.go b/core/services/ocr2/plugins/threshold/decryption_queue.go index 415079a8cb8..b051e94dfe8 100644 --- a/core/services/ocr2/plugins/threshold/decryption_queue.go +++ b/core/services/ocr2/plugins/threshold/decryption_queue.go @@ -105,7 +105,7 @@ func (dq *decryptionQueue) getResult(ciphertextId decryptionPlugin.CiphertextId, req, ok := dq.completedRequests[string(ciphertextId)] if ok { - dq.lggr.Debugf("ciphertextId %s was already decrypted by the DON", string(ciphertextId)) + dq.lggr.Debugf("ciphertextId %s was already decrypted by the DON", ciphertextId) chPlaintext <- req.plaintext req.timer.Stop() delete(dq.completedRequests, string(ciphertextId)) @@ -126,7 +126,7 @@ func (dq *decryptionQueue) getResult(ciphertextId decryptionPlugin.CiphertextId, chPlaintext, ciphertext, } - dq.lggr.Debugf("ciphertextId %s added to pendingRequestQueue", string(ciphertextId)) + dq.lggr.Debugf("ciphertextId %s added to pendingRequestQueue", ciphertextId) return chPlaintext, nil } @@ -144,21 +144,21 @@ func (dq *decryptionQueue) GetRequests(requestCountLimit int, totalBytesLimit in break } - requestId := dq.pendingRequestQueue[i] - pendingRequest, exists := dq.pendingRequests[string(requestId)] + ciphertextId := dq.pendingRequestQueue[i] + pendingRequest, exists := dq.pendingRequests[string(ciphertextId)] if !exists { - dq.lggr.Debugf("pending decryption request for ciphertextId %s expired", string(requestId)) + dq.lggr.Debugf("pending decryption request for ciphertextId %s expired", ciphertextId) indicesToRemove[i] = struct{}{} continue } requestToAdd := decryptionPlugin.DecryptionRequest{ - CiphertextId: requestId, + CiphertextId: ciphertextId, Ciphertext: pendingRequest.ciphertext, } - requestTotalLen := len(requestId) + len(pendingRequest.ciphertext) + requestTotalLen := len(ciphertextId) + len(pendingRequest.ciphertext) if (totalBytes + requestTotalLen) > totalBytesLimit { dq.lggr.Debug("totalBytesLimit reached in GetRequests") @@ -171,7 +171,7 @@ func (dq *decryptionQueue) GetRequests(requestCountLimit int, totalBytesLimit in dq.pendingRequestQueue = removeMultipleIndices(dq.pendingRequestQueue, indicesToRemove) - dq.lggr.Debugf("returning first %d of %d total requests awaiting decryption", requestCountLimit, len(dq.pendingRequestQueue)) + dq.lggr.Debugf("returning first %d of %d total requests awaiting decryption", len(requests), len(dq.pendingRequestQueue)) return requests } @@ -194,32 +194,47 @@ func (dq *decryptionQueue) GetCiphertext(ciphertextId decryptionPlugin.Ciphertex req, ok := dq.pendingRequests[string(ciphertextId)] if !ok { - return nil, errors.New("ciphertext not found") + return nil, fmt.Errorf("ciphertextID %s not found", ciphertextId) } return req.ciphertext, nil } -func (dq *decryptionQueue) SetResult(ciphertextId decryptionPlugin.CiphertextId, plaintext []byte) { +func (dq *decryptionQueue) SetResult(ciphertextId decryptionPlugin.CiphertextId, plaintext []byte, err error) { dq.mu.Lock() defer dq.mu.Unlock() + if err == nil && plaintext == nil { + dq.lggr.Errorf("received nil error and nil plaintext for ciphertextId %s", ciphertextId) + return + } + req, ok := dq.pendingRequests[string(ciphertextId)] if ok { - dq.lggr.Debugf("responding with result for pending decryption request ciphertextId %s", string(ciphertextId)) - req.chPlaintext <- plaintext + if err != nil { + dq.lggr.Debugf("decryption error for ciphertextId %s", ciphertextId) + } else { + dq.lggr.Debugf("responding with result for pending decryption request ciphertextId %s", ciphertextId) + req.chPlaintext <- plaintext + } close(req.chPlaintext) delete(dq.pendingRequests, string(ciphertextId)) } else { + if err != nil { + // This is currently possible only for ErrAggregation, encountered during Report() phase. + dq.lggr.Debugf("received decryption error for ciphertextId %s which doesn't exist locally", ciphertextId) + return + } + // Cache plaintext result in completedRequests map for cacheTimeoutMs to account for delayed Decrypt() calls timer := time.AfterFunc(dq.completedRequestsCacheTimeout, func() { - dq.lggr.Debugf("expired decryption result for ciphertextId %s from completedRequests cache", string(ciphertextId)) + dq.lggr.Debugf("expired decryption result for ciphertextId %s from completedRequests cache", ciphertextId) dq.mu.Lock() delete(dq.completedRequests, string(ciphertextId)) dq.mu.Unlock() }) - dq.lggr.Debugf("adding decryption result for ciphertextId %s to completedRequests cache", string(ciphertextId)) + dq.lggr.Debugf("adding decryption result for ciphertextId %s to completedRequests cache", ciphertextId) dq.completedRequests[string(ciphertextId)] = completedRequest{ plaintext, timer, diff --git a/core/services/ocr2/plugins/threshold/decryption_queue_test.go b/core/services/ocr2/plugins/threshold/decryption_queue_test.go index a81b5a9b075..dbe6e779ea6 100644 --- a/core/services/ocr2/plugins/threshold/decryption_queue_test.go +++ b/core/services/ocr2/plugins/threshold/decryption_queue_test.go @@ -32,7 +32,7 @@ func Test_decryptionQueue_Decrypt_ReturnResultAfterCallingDecrypt(t *testing.T) go func() { waitForPendingRequestToBeAdded(t, dq, []byte("1")) - dq.SetResult([]byte("1"), []byte("decrypted")) + dq.SetResult([]byte("1"), []byte("decrypted"), nil) }() ctx, cancel := context.WithCancel(testutils.Context(t)) @@ -199,15 +199,15 @@ func Test_decryptionQueue_GetCiphertext_CiphertextNotFound(t *testing.T) { lggr := logger.TestLogger(t) dq := NewDecryptionQueue(3, 1000, 64, testutils.WaitTimeout(t), lggr) - _, err := dq.GetCiphertext([]byte("8")) - assert.Equal(t, err.Error(), "ciphertext not found") + _, err := dq.GetCiphertext([]byte{0xa5}) + assert.Equal(t, err.Error(), "ciphertextID 0xa5 not found") } func Test_decryptionQueue_Decrypt_DecryptCalledAfterReadyResult(t *testing.T) { lggr := logger.TestLogger(t) dq := NewDecryptionQueue(2, 1000, 64, testutils.WaitTimeout(t), lggr) - dq.SetResult([]byte("9"), []byte("decrypted")) + dq.SetResult([]byte("9"), []byte("decrypted"), nil) ctx, cancel := context.WithCancel(testutils.Context(t)) defer cancel() @@ -223,7 +223,7 @@ func Test_decryptionQueue_ReadyResult_ExpireRequest(t *testing.T) { lggr := logger.TestLogger(t) dq := NewDecryptionQueue(2, 1000, 64, 100, lggr) - dq.SetResult([]byte("9"), []byte("decrypted")) + dq.SetResult([]byte("9"), []byte("decrypted"), nil) waitForCompletedRequestToBeAdded(t, dq, []byte("9")) @@ -238,7 +238,7 @@ func Test_decryptionQueue_Decrypt_CleanupSuccessfulRequest(t *testing.T) { lggr := logger.TestLogger(t) dq := NewDecryptionQueue(2, 1000, 64, testutils.WaitTimeout(t), lggr) - dq.SetResult([]byte("10"), []byte("decrypted")) + dq.SetResult([]byte("10"), []byte("decrypted"), nil) ctx1, cancel1 := context.WithCancel(testutils.Context(t)) defer cancel1() @@ -253,20 +253,38 @@ func Test_decryptionQueue_Decrypt_CleanupSuccessfulRequest(t *testing.T) { assert.Equal(t, err2.Error(), "context provided by caller was cancelled") } +func Test_decryptionQueue_Decrypt_UserErrorDuringDecryption(t *testing.T) { + lggr := logger.TestLogger(t) + dq := NewDecryptionQueue(5, 1000, 64, testutils.WaitTimeout(t), lggr) + ciphertextId := []byte{0x12, 0x0f} + + go func() { + waitForPendingRequestToBeAdded(t, dq, ciphertextId) + dq.SetResult(ciphertextId, nil, decryptionPlugin.ErrAggregation) + }() + + ctx, cancel := context.WithCancel(testutils.Context(t)) + defer cancel() + + _, err := dq.Decrypt(ctx, ciphertextId, []byte("encrypted")) + assert.Equal(t, err.Error(), "pending decryption request for ciphertextId 0x120f was closed without a response") +} + func Test_decryptionQueue_Decrypt_HandleClosedChannelWithoutPlaintextResponse(t *testing.T) { lggr := logger.TestLogger(t) dq := NewDecryptionQueue(5, 1000, 64, testutils.WaitTimeout(t), lggr) + ciphertextId := []byte{0x00, 0xff} go func() { - waitForPendingRequestToBeAdded(t, dq, []byte("1")) - close(dq.pendingRequests[string([]byte("1"))].chPlaintext) + waitForPendingRequestToBeAdded(t, dq, ciphertextId) + close(dq.pendingRequests[string(ciphertextId)].chPlaintext) }() ctx, cancel := context.WithCancel(testutils.Context(t)) defer cancel() - _, err := dq.Decrypt(ctx, []byte("1"), []byte("encrypted")) - assert.Equal(t, err.Error(), "pending decryption request for ciphertextId 1 was closed without a response") + _, err := dq.Decrypt(ctx, ciphertextId, []byte("encrypted")) + assert.Equal(t, err.Error(), "pending decryption request for ciphertextId 0x00ff was closed without a response") } func Test_decryptionQueue_GetRequests_RequestsCountLimit(t *testing.T) { @@ -418,7 +436,7 @@ func Test_decryptionQueue_Close(t *testing.T) { lggr := logger.TestLogger(t) dq := NewDecryptionQueue(4, 1000, 64, testutils.WaitTimeout(t), lggr) - dq.SetResult([]byte("14"), []byte("decrypted")) + dq.SetResult([]byte("14"), []byte("decrypted"), nil) err := dq.Close() diff --git a/core/services/ocr2/plugins/threshold/mocks/decryptor.go b/core/services/ocr2/plugins/threshold/mocks/decryptor.go index 1b4520a63d1..7b899262904 100644 --- a/core/services/ocr2/plugins/threshold/mocks/decryptor.go +++ b/core/services/ocr2/plugins/threshold/mocks/decryptor.go @@ -5,6 +5,7 @@ package mocks import ( context "context" + decryptionplugin "github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin" mock "github.com/stretchr/testify/mock" ) @@ -14,15 +15,15 @@ type Decryptor struct { } // Decrypt provides a mock function with given fields: ctx, ciphertextId, ciphertext -func (_m *Decryptor) Decrypt(ctx context.Context, ciphertextId []byte, ciphertext []byte) ([]byte, error) { +func (_m *Decryptor) Decrypt(ctx context.Context, ciphertextId decryptionplugin.CiphertextId, ciphertext []byte) ([]byte, error) { ret := _m.Called(ctx, ciphertextId, ciphertext) var r0 []byte var r1 error - if rf, ok := ret.Get(0).(func(context.Context, []byte, []byte) ([]byte, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, decryptionplugin.CiphertextId, []byte) ([]byte, error)); ok { return rf(ctx, ciphertextId, ciphertext) } - if rf, ok := ret.Get(0).(func(context.Context, []byte, []byte) []byte); ok { + if rf, ok := ret.Get(0).(func(context.Context, decryptionplugin.CiphertextId, []byte) []byte); ok { r0 = rf(ctx, ciphertextId, ciphertext) } else { if ret.Get(0) != nil { @@ -30,7 +31,7 @@ func (_m *Decryptor) Decrypt(ctx context.Context, ciphertextId []byte, ciphertex } } - if rf, ok := ret.Get(1).(func(context.Context, []byte, []byte) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, decryptionplugin.CiphertextId, []byte) error); ok { r1 = rf(ctx, ciphertextId, ciphertext) } else { r1 = ret.Error(1) diff --git a/core/services/ocr2/validate/validate.go b/core/services/ocr2/validate/validate.go index 9c6e86ed9e4..ca1ab60deb9 100644 --- a/core/services/ocr2/validate/validate.go +++ b/core/services/ocr2/validate/validate.go @@ -112,7 +112,7 @@ func validateSpec(tree *toml.Tree, spec job.Job) error { // TODO validator for DR-OCR spec: https://app.shortcut.com/chainlinklabs/story/54054/ocr-plugin-for-directrequest-ocr return nil case job.Mercury: - return validateOCR2MercurySpec(spec.OCR2OracleSpec.PluginConfig) + return validateOCR2MercurySpec(spec.OCR2OracleSpec.PluginConfig, *spec.OCR2OracleSpec.FeedID) case "": return errors.New("no plugin specified") default: @@ -188,11 +188,11 @@ func validateOCR2KeeperSpec(jsonConfig job.JSONConfig) error { return nil } -func validateOCR2MercurySpec(jsonConfig job.JSONConfig) error { +func validateOCR2MercurySpec(jsonConfig job.JSONConfig, feedId [32]byte) error { var pluginConfig mercuryconfig.PluginConfig err := json.Unmarshal(jsonConfig.Bytes(), &pluginConfig) if err != nil { return pkgerrors.Wrap(err, "error while unmarshaling plugin config") } - return pkgerrors.Wrap(mercuryconfig.ValidatePluginConfig(pluginConfig), "Mercury PluginConfig is invalid") + return pkgerrors.Wrap(mercuryconfig.ValidatePluginConfig(pluginConfig, feedId), "Mercury PluginConfig is invalid") } diff --git a/core/services/ocrbootstrap/delegate.go b/core/services/ocrbootstrap/delegate.go index 22f432e1b77..b39f9eec6ec 100644 --- a/core/services/ocrbootstrap/delegate.go +++ b/core/services/ocrbootstrap/delegate.go @@ -2,6 +2,8 @@ package ocrbootstrap import ( "context" + "encoding/json" + "fmt" "github.com/pkg/errors" @@ -20,18 +22,29 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) +type RelayGetter interface { + Get(relay.ID) (loop.Relayer, error) +} + // Delegate creates Bootstrap jobs type Delegate struct { - db *sqlx.DB - jobORM job.ORM - peerWrapper *ocrcommon.SingletonPeerWrapper - ocr2Cfg validate.OCR2Config - insecureCfg validate.InsecureConfig - lggr logger.SugaredLogger - relayers map[relay.Network]loop.Relayer + db *sqlx.DB + jobORM job.ORM + peerWrapper *ocrcommon.SingletonPeerWrapper + ocr2Cfg validate.OCR2Config + insecureCfg validate.InsecureConfig + lggr logger.SugaredLogger + RelayGetter isNewlyCreatedJob bool } +// Extra fields to enable router proxy contract support. Must match field names of functions' PluginConfig. +type relayConfigRouterContractFields struct { + DONID string `json:"donID"` + ContractVersion uint32 `json:"contractVersion"` + ContractUpdateCheckFrequencySec uint32 `json:"contractUpdateCheckFrequencySec"` +} + // NewDelegateBootstrap creates a new Delegate func NewDelegateBootstrap( db *sqlx.DB, @@ -40,7 +53,7 @@ func NewDelegateBootstrap( lggr logger.Logger, ocr2Cfg validate.OCR2Config, insecureCfg validate.InsecureConfig, - relayers map[relay.Network]loop.Relayer, + relayers RelayGetter, ) *Delegate { return &Delegate{ db: db, @@ -49,7 +62,7 @@ func NewDelegateBootstrap( lggr: logger.Sugared(lggr), ocr2Cfg: ocr2Cfg, insecureCfg: insecureCfg, - relayers: relayers, + RelayGetter: relayers, } } @@ -63,7 +76,7 @@ func (d *Delegate) BeforeJobCreated(spec job.Job) { } // ServicesForSpec satisfies the job.Delegate interface. -func (d *Delegate) ServicesForSpec(jobSpec job.Job) (services []job.ServiceCtx, err error) { +func (d *Delegate) ServicesForSpec(jobSpec job.Job, qopts ...pg.QOpt) (services []job.ServiceCtx, err error) { spec := jobSpec.BootstrapSpec if spec == nil { return nil, errors.Errorf("Bootstrap.Delegate expects an *job.BootstrapSpec to be present, got %v", jobSpec) @@ -73,9 +86,15 @@ func (d *Delegate) ServicesForSpec(jobSpec job.Job) (services []job.ServiceCtx, } else if !d.peerWrapper.IsStarted() { return nil, errors.New("peerWrapper is not started. OCR2 jobs require a started and running p2p v2 peer") } - relayer, exists := d.relayers[spec.Relay] - if !exists { - return nil, errors.Errorf("%s relay does not exist is it enabled?", spec.Relay) + s := spec.AsOCR2Spec() + rid, err := s.RelayID() + if err != nil { + return nil, fmt.Errorf("ServicesForSpec: could not get relayer: %w", err) + } + + relayer, err := d.RelayGetter.Get(rid) + if err != nil { + return nil, fmt.Errorf("ServiceForSpec: failed to get relay %s is it enabled?: %w", rid.Name(), err) } if spec.FeedID != nil { spec.RelayConfig["feedID"] = *spec.FeedID @@ -89,13 +108,39 @@ func (d *Delegate) ServicesForSpec(jobSpec job.Job) (services []job.ServiceCtx, } ctx := ctxVals.ContextWithValues(context.Background()) - configProvider, err := relayer.NewConfigProvider(ctx, types.RelayArgs{ - ExternalJobID: jobSpec.ExternalJobID, - JobID: spec.ID, - ContractID: spec.ContractID, - New: d.isNewlyCreatedJob, - RelayConfig: spec.RelayConfig.Bytes(), - }) + var routerFields relayConfigRouterContractFields + if err = json.Unmarshal(spec.RelayConfig.Bytes(), &routerFields); err != nil { + return nil, err + } + + var configProvider types.ConfigProvider + if routerFields.DONID != "" { + if routerFields.ContractVersion != 1 || routerFields.ContractUpdateCheckFrequencySec == 0 { + return nil, errors.New("invalid router contract config") + } + configProvider, err = relayer.NewFunctionsProvider( + ctx, + types.RelayArgs{ + ExternalJobID: jobSpec.ExternalJobID, + JobID: spec.ID, + ContractID: spec.ContractID, + RelayConfig: spec.RelayConfig.Bytes(), + New: d.isNewlyCreatedJob, + }, + types.PluginArgs{ + PluginConfig: spec.RelayConfig.Bytes(), // contains all necessary fields for config provider + }, + ) + } else { + configProvider, err = relayer.NewConfigProvider(ctx, types.RelayArgs{ + ExternalJobID: jobSpec.ExternalJobID, + JobID: spec.ID, + ContractID: spec.ContractID, + New: d.isNewlyCreatedJob, + RelayConfig: spec.RelayConfig.Bytes(), + }) + } + if err != nil { return nil, errors.Wrap(err, "error calling 'relayer.NewConfigWatcher'") } diff --git a/core/services/ocrcommon/data_source.go b/core/services/ocrcommon/data_source.go index 03f5a33500b..4ea7cb7a9a9 100644 --- a/core/services/ocrcommon/data_source.go +++ b/core/services/ocrcommon/data_source.go @@ -15,6 +15,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + "github.com/smartcontractkit/chainlink/v2/core/utils" ) diff --git a/core/services/ocrcommon/telemetry.go b/core/services/ocrcommon/telemetry.go index 7a306249c38..636a18262e1 100644 --- a/core/services/ocrcommon/telemetry.go +++ b/core/services/ocrcommon/telemetry.go @@ -16,7 +16,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" "github.com/smartcontractkit/chainlink/v2/core/utils" - relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" + relaymercuryv1 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v1" ) type eaTelemetry struct { @@ -35,7 +35,7 @@ type EnhancedTelemetryData struct { type EnhancedTelemetryMercuryData struct { TaskRunResults pipeline.TaskRunResults - Observation relaymercury.Observation + Observation relaymercuryv1.Observation RepTimestamp ocrtypes.ReportTimestamp } @@ -262,7 +262,7 @@ func (e *EnhancedTelemetryService[T]) collectAndSend(trrs *pipeline.TaskRunResul // collectMercuryEnhancedTelemetry checks if enhanced telemetry should be collected, fetches the information needed and // sends the telemetry -func (e *EnhancedTelemetryService[T]) collectMercuryEnhancedTelemetry(obs relaymercury.Observation, trrs pipeline.TaskRunResults, repts ocrtypes.ReportTimestamp) { +func (e *EnhancedTelemetryService[T]) collectMercuryEnhancedTelemetry(obs relaymercuryv1.Observation, trrs pipeline.TaskRunResults, repts ocrtypes.ReportTimestamp) { if e.monitoringEndpoint == nil { return } @@ -395,7 +395,7 @@ func (e *EnhancedTelemetryService[T]) getPricesFromResults(startTask pipeline.Ta } // getFinalValues runs a parse on the pipeline.TaskRunResults and returns the values -func (e *EnhancedTelemetryService[T]) getFinalValues(obs relaymercury.Observation) (int64, int64, int64, int64, []byte, uint64) { +func (e *EnhancedTelemetryService[T]) getFinalValues(obs relaymercuryv1.Observation) (int64, int64, int64, int64, []byte, uint64) { var benchmarkPrice, bid, ask int64 if obs.BenchmarkPrice.Val != nil { diff --git a/core/services/ocrcommon/telemetry_test.go b/core/services/ocrcommon/telemetry_test.go index 0adf26b526f..e7c41c46761 100644 --- a/core/services/ocrcommon/telemetry_test.go +++ b/core/services/ocrcommon/telemetry_test.go @@ -14,6 +14,7 @@ import ( "google.golang.org/protobuf/proto" "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" + mercuryv1 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v1" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -422,7 +423,7 @@ var trrsMercury = pipeline.TaskRunResults{ func TestGetFinalValues(t *testing.T) { e := EnhancedTelemetryService[EnhancedTelemetryMercuryData]{} - o := mercury.Observation{ + o := mercuryv1.Observation{ BenchmarkPrice: mercury.ObsResult[*big.Int]{Val: big.NewInt(111111)}, Bid: mercury.ObsResult[*big.Int]{Val: big.NewInt(222222)}, Ask: mercury.ObsResult[*big.Int]{Val: big.NewInt(333333)}, @@ -439,7 +440,7 @@ func TestGetFinalValues(t *testing.T) { require.Equal(t, blockHash, common.HexToHash("0x123321").Bytes()) require.Equal(t, blockTimestamp, uint64(987654321)) - benchmarkPrice, bid, ask, blockNr, blockHash, blockTimestamp = e.getFinalValues(mercury.Observation{}) + benchmarkPrice, bid, ask, blockNr, blockHash, blockTimestamp = e.getFinalValues(mercuryv1.Observation{}) require.Equal(t, benchmarkPrice, int64(0)) require.Equal(t, bid, int64(0)) require.Equal(t, ask, int64(0)) @@ -581,7 +582,7 @@ func TestCollectMercuryEnhancedTelemetry(t *testing.T) { chTelem <- EnhancedTelemetryMercuryData{ TaskRunResults: trrsMercury, - Observation: mercury.Observation{ + Observation: mercuryv1.Observation{ BenchmarkPrice: mercury.ObsResult[*big.Int]{Val: big.NewInt(111111)}, Bid: mercury.ObsResult[*big.Int]{Val: big.NewInt(222222)}, Ask: mercury.ObsResult[*big.Int]{Val: big.NewInt(333333)}, @@ -633,7 +634,7 @@ func TestCollectMercuryEnhancedTelemetry(t *testing.T) { Value: nil, }}, }, - Observation: mercury.Observation{}, + Observation: mercuryv1.Observation{}, RepTimestamp: types.ReportTimestamp{ ConfigDigest: types.ConfigDigest{2}, Epoch: 11, @@ -644,7 +645,7 @@ func TestCollectMercuryEnhancedTelemetry(t *testing.T) { trrsMercury[0].Result.Value = "" chTelem <- EnhancedTelemetryMercuryData{ TaskRunResults: trrsMercury, - Observation: mercury.Observation{}, + Observation: mercuryv1.Observation{}, RepTimestamp: types.ReportTimestamp{ ConfigDigest: types.ConfigDigest{2}, Epoch: 11, diff --git a/core/services/pipeline/common.go b/core/services/pipeline/common.go index c2b19c30a9c..8cc54d540fb 100644 --- a/core/services/pipeline/common.go +++ b/core/services/pipeline/common.go @@ -20,7 +20,6 @@ import ( pkgerrors "github.com/pkg/errors" "gopkg.in/guregu/null.v4" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config" "github.com/smartcontractkit/chainlink/v2/core/logger" cnull "github.com/smartcontractkit/chainlink/v2/core/null" @@ -546,23 +545,13 @@ func CheckInputs(inputs []Result, minLen, maxLen, maxErrors int) ([]interface{}, return vals, nil } -func getChainByString(chainSet evm.ChainSet, str string) (evm.Chain, error) { - if str == "" { - return chainSet.Default() - } - id, ok := new(big.Int).SetString(str, 10) - if !ok { - return nil, pkgerrors.Errorf("invalid EVM chain ID: %s", str) - } - return chainSet.Get(id) -} +var ErrInvalidEVMChainID = errors.New("invalid EVM chain ID") -func SelectGasLimit(cfg config.ChainScopedConfig, jobType string, specGasLimit *uint32) uint32 { +func SelectGasLimit(ge config.GasEstimator, jobType string, specGasLimit *uint32) uint32 { if specGasLimit != nil { return *specGasLimit } - ge := cfg.EVM().GasEstimator() jt := ge.LimitJobType() var jobTypeGasLimit *uint32 switch jobType { diff --git a/core/services/pipeline/common_test.go b/core/services/pipeline/common_test.go index 558fe7bfe59..37cc60f27e9 100644 --- a/core/services/pipeline/common_test.go +++ b/core/services/pipeline/common_test.go @@ -338,42 +338,42 @@ func TestSelectGasLimit(t *testing.T) { t.Run("spec defined gas limit", func(t *testing.T) { var specGasLimit uint32 = 1 - gasLimit := pipeline.SelectGasLimit(cfg, pipeline.DirectRequestJobType, &specGasLimit) + gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.DirectRequestJobType, &specGasLimit) assert.Equal(t, uint32(1), gasLimit) }) t.Run("direct request specific gas limit", func(t *testing.T) { - gasLimit := pipeline.SelectGasLimit(cfg, pipeline.DirectRequestJobType, nil) + gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.DirectRequestJobType, nil) assert.Equal(t, uint32(100), gasLimit) }) t.Run("OCR specific gas limit", func(t *testing.T) { - gasLimit := pipeline.SelectGasLimit(cfg, pipeline.OffchainReportingJobType, nil) + gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.OffchainReportingJobType, nil) assert.Equal(t, uint32(103), gasLimit) }) t.Run("OCR2 specific gas limit", func(t *testing.T) { - gasLimit := pipeline.SelectGasLimit(cfg, pipeline.OffchainReporting2JobType, nil) + gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.OffchainReporting2JobType, nil) assert.Equal(t, uint32(105), gasLimit) }) t.Run("VRF specific gas limit", func(t *testing.T) { - gasLimit := pipeline.SelectGasLimit(cfg, pipeline.VRFJobType, nil) + gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.VRFJobType, nil) assert.Equal(t, uint32(101), gasLimit) }) t.Run("flux monitor specific gas limit", func(t *testing.T) { - gasLimit := pipeline.SelectGasLimit(cfg, pipeline.FluxMonitorJobType, nil) + gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.FluxMonitorJobType, nil) assert.Equal(t, uint32(102), gasLimit) }) t.Run("keeper specific gas limit", func(t *testing.T) { - gasLimit := pipeline.SelectGasLimit(cfg, pipeline.KeeperJobType, nil) + gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.KeeperJobType, nil) assert.Equal(t, uint32(104), gasLimit) }) t.Run("fallback to default gas limit", func(t *testing.T) { - gasLimit := pipeline.SelectGasLimit(cfg, pipeline.WebhookJobType, nil) + gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.WebhookJobType, nil) assert.Equal(t, uint32(999), gasLimit) }) } diff --git a/core/services/pipeline/helpers_test.go b/core/services/pipeline/helpers_test.go index 3a7d1fc8161..974ff29d11c 100644 --- a/core/services/pipeline/helpers_test.go +++ b/core/services/pipeline/helpers_test.go @@ -50,15 +50,15 @@ func (t *HTTPTask) HelperSetDependencies(config Config, restrictedHTTPClient, un t.unrestrictedHTTPClient = unrestrictedHTTPClient } -func (t *ETHCallTask) HelperSetDependencies(cc evm.ChainSet, config Config, specGasLimit *uint32, jobType string) { - t.chainSet = cc +func (t *ETHCallTask) HelperSetDependencies(legacyChains evm.LegacyChainContainer, config Config, specGasLimit *uint32, jobType string) { + t.legacyChains = legacyChains t.config = config t.specGasLimit = specGasLimit t.jobType = jobType } -func (t *ETHTxTask) HelperSetDependencies(cc evm.ChainSet, keyStore ETHKeyStore, specGasLimit *uint32, jobType string) { - t.chainSet = cc +func (t *ETHTxTask) HelperSetDependencies(legacyChains evm.LegacyChainContainer, keyStore ETHKeyStore, specGasLimit *uint32, jobType string) { + t.legacyChains = legacyChains t.keyStore = keyStore t.specGasLimit = specGasLimit t.jobType = jobType diff --git a/core/services/pipeline/orm_test.go b/core/services/pipeline/orm_test.go index 722524d6e56..0863226e647 100644 --- a/core/services/pipeline/orm_test.go +++ b/core/services/pipeline/orm_test.go @@ -23,6 +23,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/job" "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/store/models" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -520,8 +521,10 @@ func Test_GetUnfinishedRuns_Keepers(t *testing.T) { porm := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgeORM := bridges.NewORM(db, lggr, config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - jorm := job.NewORM(db, cc, porm, bridgeORM, keyStore, lggr, config.Database()) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + jorm := job.NewORM(db, legacyChains, porm, bridgeORM, keyStore, lggr, config.Database()) defer func() { assert.NoError(t, jorm.Close()) }() timestamp := time.Now() @@ -545,7 +548,7 @@ func Test_GetUnfinishedRuns_Keepers(t *testing.T) { MaxTaskDuration: models.Interval(1 * time.Minute), } - err := jorm.CreateJob(&keeperJob) + err = jorm.CreateJob(&keeperJob) require.NoError(t, err) require.Equal(t, job.Keeper, keeperJob.Type) @@ -621,8 +624,10 @@ func Test_GetUnfinishedRuns_DirectRequest(t *testing.T) { porm := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()) bridgeORM := bridges.NewORM(db, lggr, config.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) - jorm := job.NewORM(db, cc, porm, bridgeORM, keyStore, lggr, config.Database()) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + jorm := job.NewORM(db, legacyChains, porm, bridgeORM, keyStore, lggr, config.Database()) defer func() { assert.NoError(t, jorm.Close()) }() timestamp := time.Now() @@ -645,7 +650,7 @@ func Test_GetUnfinishedRuns_DirectRequest(t *testing.T) { MaxTaskDuration: models.Interval(1 * time.Minute), } - err := jorm.CreateJob(&drJob) + err = jorm.CreateJob(&drJob) require.NoError(t, err) require.Equal(t, job.DirectRequest, drJob.Type) diff --git a/core/services/pipeline/runner.go b/core/services/pipeline/runner.go index 05d6735dde9..7a755e8fe11 100644 --- a/core/services/pipeline/runner.go +++ b/core/services/pipeline/runner.go @@ -20,6 +20,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/recovery" "github.com/smartcontractkit/chainlink/v2/core/services" "github.com/smartcontractkit/chainlink/v2/core/services/pg" + "github.com/smartcontractkit/chainlink/v2/core/store/models" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -55,7 +56,7 @@ type runner struct { btORM bridges.ORM config Config bridgeConfig BridgeConfig - chainSet evm.ChainSet + legacyEVMChains evm.LegacyChainContainer ethKeyStore ETHKeyStore vrfKeyStore VRFKeyStore runReaperWorker utils.SleeperTask @@ -101,13 +102,13 @@ var ( ) ) -func NewRunner(orm ORM, btORM bridges.ORM, cfg Config, bridgeCfg BridgeConfig, chainSet evm.ChainSet, ethks ETHKeyStore, vrfks VRFKeyStore, lggr logger.Logger, httpClient, unrestrictedHTTPClient *http.Client) *runner { +func NewRunner(orm ORM, btORM bridges.ORM, cfg Config, bridgeCfg BridgeConfig, legacyChains evm.LegacyChainContainer, ethks ETHKeyStore, vrfks VRFKeyStore, lggr logger.Logger, httpClient, unrestrictedHTTPClient *http.Client) *runner { r := &runner{ orm: orm, btORM: btORM, config: cfg, bridgeConfig: bridgeCfg, - chainSet: chainSet, + legacyEVMChains: legacyChains, ethKeyStore: ethks, vrfKeyStore: vrfks, chStop: make(chan struct{}), @@ -260,7 +261,7 @@ func (r *runner) initializePipeline(run *Run) (*Pipeline, error) { // may run external adapters on their own hardware task.(*BridgeTask).httpClient = r.unrestrictedHTTPClient case TaskTypeETHCall: - task.(*ETHCallTask).chainSet = r.chainSet + task.(*ETHCallTask).legacyChains = r.legacyEVMChains task.(*ETHCallTask).config = r.config task.(*ETHCallTask).specGasLimit = run.PipelineSpec.GasLimit task.(*ETHCallTask).jobType = run.PipelineSpec.JobType @@ -271,12 +272,12 @@ func (r *runner) initializePipeline(run *Run) (*Pipeline, error) { case TaskTypeVRFV2Plus: task.(*VRFTaskV2Plus).keyStore = r.vrfKeyStore case TaskTypeEstimateGasLimit: - task.(*EstimateGasLimitTask).chainSet = r.chainSet + task.(*EstimateGasLimitTask).legacyChains = r.legacyEVMChains task.(*EstimateGasLimitTask).specGasLimit = run.PipelineSpec.GasLimit task.(*EstimateGasLimitTask).jobType = run.PipelineSpec.JobType case TaskTypeETHTx: task.(*ETHTxTask).keyStore = r.ethKeyStore - task.(*ETHTxTask).chainSet = r.chainSet + task.(*ETHTxTask).legacyChains = r.legacyEVMChains task.(*ETHTxTask).specGasLimit = run.PipelineSpec.GasLimit task.(*ETHTxTask).jobType = run.PipelineSpec.JobType task.(*ETHTxTask).forwardingAllowed = run.PipelineSpec.ForwardingAllowed diff --git a/core/services/pipeline/runner_test.go b/core/services/pipeline/runner_test.go index e2918cf8385..1b13289289e 100644 --- a/core/services/pipeline/runner_test.go +++ b/core/services/pipeline/runner_test.go @@ -20,6 +20,8 @@ import ( "github.com/stretchr/testify/require" "gopkg.in/guregu/null.v4" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + "github.com/smartcontractkit/chainlink/v2/core/bridges" bridgesMocks "github.com/smartcontractkit/chainlink/v2/core/bridges/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" @@ -41,13 +43,15 @@ import ( func newRunner(t testing.TB, db *sqlx.DB, bridgeORM bridges.ORM, cfg chainlink.GeneralConfig) (pipeline.Runner, *mocks.ORM) { lggr := logger.TestLogger(t) ethKeyStore := cltest.NewKeyStore(t, db, cfg.Database()).Eth() - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, KeyStore: ethKeyStore}) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, KeyStore: ethKeyStore}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) orm := mocks.NewORM(t) q := pg.NewQ(db, lggr, cfg.Database()) orm.On("GetQ").Return(q).Maybe() c := clhttptest.NewTestLocalOnlyHTTPClient() - r := pipeline.NewRunner(orm, bridgeORM, cfg.JobPipeline(), cfg.WebServer(), cc, ethKeyStore, nil, logger.TestLogger(t), c, c) + r := pipeline.NewRunner(orm, bridgeORM, cfg.JobPipeline(), cfg.WebServer(), legacyChains, ethKeyStore, nil, logger.TestLogger(t), c, c) return r, orm } @@ -477,9 +481,11 @@ func Test_PipelineRunner_HandleFaultsPersistRun(t *testing.T) { Return(nil) cfg := configtest.NewTestGeneralConfig(t) ethKeyStore := cltest.NewKeyStore(t, db, cfg.Database()).Eth() - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, KeyStore: ethKeyStore}) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, KeyStore: ethKeyStore}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) lggr := logger.TestLogger(t) - r := pipeline.NewRunner(orm, btORM, cfg.JobPipeline(), cfg.WebServer(), cc, ethKeyStore, nil, lggr, nil, nil) + r := pipeline.NewRunner(orm, btORM, cfg.JobPipeline(), cfg.WebServer(), legacyChains, ethKeyStore, nil, lggr, nil, nil) spec := pipeline.Spec{DotDagSource: ` fail_but_i_dont_care [type=fail] diff --git a/core/services/pipeline/task.estimategas.go b/core/services/pipeline/task.estimategas.go index 5bf82837cb8..967fb7ca034 100644 --- a/core/services/pipeline/task.estimategas.go +++ b/core/services/pipeline/task.estimategas.go @@ -2,6 +2,7 @@ package pipeline import ( "context" + "fmt" "math" "strconv" @@ -29,7 +30,7 @@ type EstimateGasLimitTask struct { EVMChainID string `json:"evmChainID" mapstructure:"evmChainID"` specGasLimit *uint32 - chainSet evm.ChainSet + legacyChains evm.LegacyChainContainer jobType string } @@ -64,11 +65,13 @@ func (t *EstimateGasLimitTask) Run(ctx context.Context, lggr logger.Logger, vars return Result{Error: err}, runInfo } - chain, err := getChainByString(t.chainSet, t.EVMChainID) + chain, err := t.legacyChains.Get(t.EVMChainID) if err != nil { - return Result{Error: err}, retryableRunInfo() + err = fmt.Errorf("%w: %s: %w", ErrInvalidEVMChainID, t.EVMChainID, err) + return Result{Error: err}, runInfo } - maximumGasLimit := SelectGasLimit(chain.Config(), t.jobType, t.specGasLimit) + + maximumGasLimit := SelectGasLimit(chain.Config().EVM().GasEstimator(), t.jobType, t.specGasLimit) to := common.Address(toAddr) gasLimit, err := chain.Client().EstimateGas(ctx, ethereum.CallMsg{ From: common.Address(fromAddr), diff --git a/core/services/pipeline/task.eth_call.go b/core/services/pipeline/task.eth_call.go index b93e3c45c66..f3c76d404d4 100644 --- a/core/services/pipeline/task.eth_call.go +++ b/core/services/pipeline/task.eth_call.go @@ -2,6 +2,7 @@ package pipeline import ( "context" + "fmt" "time" "github.com/ethereum/go-ethereum" @@ -34,7 +35,7 @@ type ETHCallTask struct { EVMChainID string `json:"evmChainID" mapstructure:"evmChainID"` specGasLimit *uint32 - chainSet evm.ChainSet + legacyChains evm.LegacyChainContainer config Config jobType string } @@ -88,10 +89,12 @@ func (t *ETHCallTask) Run(ctx context.Context, lggr logger.Logger, vars Vars, in return Result{Error: errors.Wrapf(ErrBadInput, "data param must not be empty")}, runInfo } - chain, err := getChainByString(t.chainSet, string(chainID)) + chain, err := t.legacyChains.Get(string(chainID)) if err != nil { + err = fmt.Errorf("%w: %s: %w", ErrInvalidEVMChainID, chainID, err) return Result{Error: err}, runInfo } + var selectedGas uint32 if gasUnlimited { if gas > 0 { @@ -101,7 +104,7 @@ func (t *ETHCallTask) Run(ctx context.Context, lggr logger.Logger, vars Vars, in if gas > 0 { selectedGas = uint32(gas) } else { - selectedGas = SelectGasLimit(chain.Config(), t.jobType, t.specGasLimit) + selectedGas = SelectGasLimit(chain.Config().EVM().GasEstimator(), t.jobType, t.specGasLimit) } } diff --git a/core/services/pipeline/task.eth_call_test.go b/core/services/pipeline/task.eth_call_test.go index 7686caa1e70..8d7f128a0d4 100644 --- a/core/services/pipeline/task.eth_call_test.go +++ b/core/services/pipeline/task.eth_call_test.go @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink/v2/core/chains" "github.com/smartcontractkit/chainlink/v2/core/chains/evm" evmclimocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" txmmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr/mocks" @@ -24,6 +25,7 @@ import ( keystoremocks "github.com/smartcontractkit/chainlink/v2/core/services/keystore/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" pipelinemocks "github.com/smartcontractkit/chainlink/v2/core/services/pipeline/mocks" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" ) func TestETHCallTask(t *testing.T) { @@ -225,7 +227,7 @@ func TestETHCallTask(t *testing.T) { On("CallContract", mock.Anything, ethereum.CallMsg{To: &contractAddr, Data: []byte("foo bar")}, (*big.Int)(nil)). Return([]byte("baz quux"), nil).Maybe() }, - nil, nil, "not found", + nil, nil, chains.ErrNoSuchChainID.Error(), }, } @@ -255,14 +257,17 @@ func TestETHCallTask(t *testing.T) { txManager := txmmocks.NewMockEvmTxManager(t) db := pgtest.NewSqlxDB(t) - var cc evm.ChainSet + var legacyChains evm.LegacyChainContainer + var err error if test.expectedErrorCause != nil || test.expectedErrorContains != "" { - cc = evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, TxManager: txManager, KeyStore: keyStore}) + exts := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, TxManager: txManager, KeyStore: keyStore}) + legacyChains, err = evmrelay.NewLegacyChainsFromRelayerExtenders(exts) + require.NoError(t, err) } else { - cc = cltest.NewChainSetMockWithOneChain(t, ethClient, evmtest.NewChainScopedConfig(t, cfg)) + legacyChains = cltest.NewLegacyChainsWithMockChain(t, ethClient, cfg) } - task.HelperSetDependencies(cc, cfg.JobPipeline(), test.specGasLimit, pipeline.DirectRequestJobType) + task.HelperSetDependencies(legacyChains, cfg.JobPipeline(), test.specGasLimit, pipeline.DirectRequestJobType) result, runInfo := task.Run(testutils.Context(t), lggr, test.vars, test.inputs) assert.False(t, runInfo.IsPending) diff --git a/core/services/pipeline/task.eth_tx.go b/core/services/pipeline/task.eth_tx.go index c0585b5448d..8761732e4f0 100644 --- a/core/services/pipeline/task.eth_tx.go +++ b/core/services/pipeline/task.eth_tx.go @@ -2,6 +2,7 @@ package pipeline import ( "context" + "fmt" "math/big" "reflect" "strconv" @@ -41,7 +42,7 @@ type ETHTxTask struct { forwardingAllowed bool specGasLimit *uint32 keyStore ETHKeyStore - chainSet evm.ChainSet + legacyChains evm.LegacyChainContainer jobType string } @@ -62,18 +63,20 @@ func (t *ETHTxTask) Run(_ context.Context, lggr logger.Logger, vars Vars, inputs return Result{Error: err}, runInfo } - chain, err := getChainByString(t.chainSet, string(chainID)) + chain, err := t.legacyChains.Get(string(chainID)) if err != nil { - return Result{Error: errors.Wrapf(err, "failed to get chain by id: %v", t.EVMChainID)}, retryableRunInfo() + err = fmt.Errorf("%w: %s: %w", ErrInvalidEVMChainID, chainID, err) + return Result{Error: err}, retryableRunInfo() } - cfg := chain.Config() + + cfg := chain.Config().EVM() txManager := chain.TxManager() _, err = CheckInputs(inputs, -1, -1, 0) if err != nil { return Result{Error: errors.Wrap(err, "task inputs")}, runInfo } - maximumGasLimit := SelectGasLimit(cfg, t.jobType, t.specGasLimit) + maximumGasLimit := SelectGasLimit(cfg.GasEstimator(), t.jobType, t.specGasLimit) var ( fromAddrs AddressSliceParam @@ -102,7 +105,7 @@ func (t *ETHTxTask) Run(_ context.Context, lggr logger.Logger, vars Vars, inputs if min, isSet := maybeMinConfirmations.Uint64(); isSet { minOutgoingConfirmations = min } else { - minOutgoingConfirmations = uint64(cfg.EVM().FinalityDepth()) + minOutgoingConfirmations = uint64(cfg.FinalityDepth()) } txMeta, err := decodeMeta(txMetaMap) diff --git a/core/services/pipeline/task.eth_tx_test.go b/core/services/pipeline/task.eth_tx_test.go index 0afd008d88e..83f855c9982 100644 --- a/core/services/pipeline/task.eth_tx_test.go +++ b/core/services/pipeline/task.eth_tx_test.go @@ -11,6 +11,7 @@ import ( "gopkg.in/guregu/null.v4" txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" + "github.com/smartcontractkit/chainlink/v2/core/chains" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" txmmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" @@ -22,6 +23,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" keystoremocks "github.com/smartcontractkit/chainlink/v2/core/services/keystore/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" ) func TestETHTxTask(t *testing.T) { @@ -541,7 +543,7 @@ func TestETHTxTask(t *testing.T) { nil, func(keyStore *keystoremocks.Eth, txManager *txmmocks.MockEvmTxManager) { }, - nil, nil, "not found", pipeline.RunInfo{IsRetryable: true}, + nil, nil, chains.ErrNoSuchChainID.Error(), pipeline.RunInfo{IsRetryable: true}, }, } @@ -571,11 +573,13 @@ func TestETHTxTask(t *testing.T) { }) lggr := logger.TestLogger(t) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, TxManager: txManager, KeyStore: keyStore}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) test.setupClientMocks(keyStore, txManager) - task.HelperSetDependencies(cc, keyStore, test.specGasLimit, pipeline.DirectRequestJobType) + task.HelperSetDependencies(legacyChains, keyStore, test.specGasLimit, pipeline.DirectRequestJobType) result, runInfo := task.Run(testutils.Context(t), lggr, test.vars, test.inputs) assert.Equal(t, test.expectedRunInfo, runInfo) diff --git a/core/services/relay/evm/contract_transmitter_test.go b/core/services/relay/evm/contract_transmitter_test.go index 73c9234a13e..e03c5508247 100644 --- a/core/services/relay/evm/contract_transmitter_test.go +++ b/core/services/relay/evm/contract_transmitter_test.go @@ -55,7 +55,7 @@ func TestContractTransmitter(t *testing.T) { // scanLogs = true digestAndEpochScanLogs, _ := hex.DecodeString( - "0000000000000000000000000000000000000000000000000000000000000001" + // false + "0000000000000000000000000000000000000000000000000000000000000001" + // true "000130da6b9315bd59af6b0a3f5463c0d0a39e92eaa34cbcbdbace7b3bfcc776" + // config digest "0000000000000000000000000000000000000000000000000000000000000002") // epoch c.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(digestAndEpochScanLogs, nil).Once() diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index 22d2cc1d362..86cb1cf433e 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -33,8 +33,11 @@ import ( "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/relay/evm/functions" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/reportcodec" + reportcodecv1 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v1/reportcodec" + reportcodecv2 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v2/reportcodec" + reportcodecv3 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/reportcodec" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -44,23 +47,28 @@ var _ relaytypes.Relayer = &Relayer{} type Relayer struct { db *sqlx.DB - chainSet evm.ChainSet + chain evm.Chain lggr logger.Logger - cfg pg.QConfig - ks keystore.Master + ks CSAETHKeystore mercuryPool wsrpc.Pool eventBroadcaster pg.EventBroadcaster + pgCfg pg.QConfig +} + +type CSAETHKeystore interface { + CSA() keystore.CSA + Eth() keystore.Eth } -func NewRelayer(db *sqlx.DB, chainSet evm.ChainSet, lggr logger.Logger, cfg pg.QConfig, ks keystore.Master, eventBroadcaster pg.EventBroadcaster) *Relayer { +func NewRelayer(db *sqlx.DB, chain evm.Chain, cfg pg.QConfig, lggr logger.Logger, ks CSAETHKeystore, eventBroadcaster pg.EventBroadcaster) *Relayer { return &Relayer{ db: db, - chainSet: chainSet, + chain: chain, lggr: lggr.Named("Relayer"), - cfg: cfg, ks: ks, mercuryPool: wsrpc.NewPool(lggr.Named("Mercury.WSRPCPool")), eventBroadcaster: eventBroadcaster, + pgCfg: cfg, } } @@ -84,15 +92,15 @@ func (r *Relayer) Ready() error { func (r *Relayer) HealthReport() (report map[string]error) { report = make(map[string]error) - maps.Copy(report, r.chainSet.HealthReport()) maps.Copy(report, r.mercuryPool.HealthReport()) return } func (r *Relayer) NewMercuryProvider(rargs relaytypes.RelayArgs, pargs relaytypes.PluginArgs) (relaytypes.MercuryProvider, error) { - var relayConfig types.RelayConfig - if err := json.Unmarshal(rargs.RelayConfig, &relayConfig); err != nil { - return nil, errors.WithStack(err) + relayOpts := types.NewRelayOpts(rargs) + relayConfig, err := relayOpts.RelayConfig() + if err != nil { + return nil, fmt.Errorf("failed to get relay config: %w", err) } var mercuryConfig mercuryconfig.PluginConfig @@ -104,12 +112,20 @@ func (r *Relayer) NewMercuryProvider(rargs relaytypes.RelayArgs, pargs relaytype return nil, errors.New("FeedID must be specified") } - configWatcher, err := newConfigProvider(r.lggr, r.chainSet, rargs, r.eventBroadcaster) + if relayConfig.ChainID.String() != r.chain.ID().String() { + return nil, fmt.Errorf("internal error: chain id in spec does not match this relayer's chain: have %s expected %s", relayConfig.ChainID.String(), r.chain.ID().String()) + } + configWatcher, err := newConfigProvider(r.lggr, r.chain, relayOpts, r.eventBroadcaster) if err != nil { return nil, errors.WithStack(err) } - reportCodec := reportcodec.NewEVMReportCodec(*relayConfig.FeedID, r.lggr.Named("ReportCodec")) + // FIXME: We actually know the version here since it's in the feed ID, can + // we use generics to avoid passing three of this? + // https://smartcontract-it.atlassian.net/browse/MERC-1414 + reportCodecV1 := reportcodecv1.NewReportCodec(*relayConfig.FeedID, r.lggr.Named("ReportCodecV1")) + reportCodecV2 := reportcodecv2.NewReportCodec(*relayConfig.FeedID, r.lggr.Named("ReportCodecV2")) + reportCodecV3 := reportcodecv3.NewReportCodec(*relayConfig.FeedID, r.lggr.Named("ReportCodecV3")) if !relayConfig.EffectiveTransmitterID.Valid { return nil, errors.New("EffectiveTransmitterID must be specified") @@ -123,13 +139,28 @@ func (r *Relayer) NewMercuryProvider(rargs relaytypes.RelayArgs, pargs relaytype if err != nil { return nil, err } - transmitter := mercury.NewTransmitter(r.lggr, configWatcher.ContractConfigTracker(), client, privKey.PublicKey, *relayConfig.FeedID, r.db, r.cfg) + transmitter := mercury.NewTransmitter(r.lggr, configWatcher.ContractConfigTracker(), client, privKey.PublicKey, *relayConfig.FeedID, r.db, r.pgCfg) + + return NewMercuryProvider(configWatcher, transmitter, reportCodecV1, reportCodecV2, reportCodecV3, r.lggr), nil +} - return NewMercuryProvider(configWatcher, transmitter, reportCodec, r.lggr), nil +func (r *Relayer) NewFunctionsProvider(rargs relaytypes.RelayArgs, pargs relaytypes.PluginArgs) (relaytypes.FunctionsProvider, error) { + // TODO(FUN-668): Not ready yet (doesn't implement FunctionsEvents() properly) + return NewFunctionsProvider(r.chain, rargs, pargs, r.lggr, r.ks.Eth(), functions.FunctionsPlugin) } func (r *Relayer) NewConfigProvider(args relaytypes.RelayArgs) (relaytypes.ConfigProvider, error) { - configProvider, err := newConfigProvider(r.lggr, r.chainSet, args, r.eventBroadcaster) + relayOpts := types.NewRelayOpts(args) + relayConfig, err := relayOpts.RelayConfig() + if err != nil { + return nil, fmt.Errorf("failed to get relay config: %w", err) + } + expectedChainID := relayConfig.ChainID.String() + if expectedChainID != r.chain.ID().String() { + return nil, fmt.Errorf("internal error: chain id in spec does not match this relayer's chain: have %s expected %s", relayConfig.ChainID.String(), r.chain.ID().String()) + } + + configProvider, err := newConfigProvider(r.lggr, r.chain, relayOpts, r.eventBroadcaster) if err != nil { // Never return (*configProvider)(nil) return nil, err @@ -241,27 +272,22 @@ func (c *configWatcher) ContractConfigTracker() ocrtypes.ContractConfigTracker { return c.configPoller } -func newConfigProvider(lggr logger.Logger, chainSet evm.ChainSet, args relaytypes.RelayArgs, eventBroadcaster pg.EventBroadcaster) (*configWatcher, error) { - var relayConfig types.RelayConfig - err := json.Unmarshal(args.RelayConfig, &relayConfig) - if err != nil { - return nil, err - } - chain, err := chainSet.Get(relayConfig.ChainID.ToInt()) - if err != nil { - return nil, err - } - if !common.IsHexAddress(args.ContractID) { +func newConfigProvider(lggr logger.Logger, chain evm.Chain, opts *types.RelayOpts, eventBroadcaster pg.EventBroadcaster) (*configWatcher, error) { + if !common.IsHexAddress(opts.ContractID) { return nil, errors.Errorf("invalid contractID, expected hex address") } - contractAddress := common.HexToAddress(args.ContractID) + contractAddress := common.HexToAddress(opts.ContractID) contractABI, err := abi.JSON(strings.NewReader(ocr2aggregator.OCR2AggregatorMetaData.ABI)) if err != nil { return nil, errors.Wrap(err, "could not get contract ABI JSON") } var cp types.ConfigPoller + relayConfig, err := opts.RelayConfig() + if err != nil { + return nil, fmt.Errorf("failed to get relay config: %w", err) + } if relayConfig.FeedID != nil { cp, err = mercury.NewConfigPoller( lggr, @@ -291,7 +317,7 @@ func newConfigProvider(lggr logger.Logger, chainSet evm.ChainSet, args relaytype ContractAddress: contractAddress, } } - return newConfigWatcher(lggr, contractAddress, contractABI, offchainConfigDigester, cp, chain, relayConfig.FromBlock, args.New), nil + return newConfigWatcher(lggr, contractAddress, contractABI, offchainConfigDigester, cp, chain, relayConfig.FromBlock, opts.New), nil } func newContractTransmitter(lggr logger.Logger, rargs relaytypes.RelayArgs, transmitterID string, configWatcher *configWatcher, ethKeystore keystore.Eth) (*contractTransmitter, error) { @@ -413,15 +439,21 @@ func newPipelineContractTransmitter(lggr logger.Logger, rargs relaytypes.RelayAr } func (r *Relayer) NewMedianProvider(rargs relaytypes.RelayArgs, pargs relaytypes.PluginArgs) (relaytypes.MedianProvider, error) { - configWatcher, err := newConfigProvider(r.lggr, r.chainSet, rargs, r.eventBroadcaster) + relayOpts := types.NewRelayOpts(rargs) + relayConfig, err := relayOpts.RelayConfig() if err != nil { - return nil, err + return nil, fmt.Errorf("failed to get relay config: %w", err) + } + expectedChainID := relayConfig.ChainID.String() + if expectedChainID != r.chain.ID().String() { + return nil, fmt.Errorf("internal error: chain id in spec does not match this relayer's chain: have %s expected %s", relayConfig.ChainID.String(), r.chain.ID().String()) } - var relayConfig types.RelayConfig - if err = json.Unmarshal(rargs.RelayConfig, &relayConfig); err != nil { + configWatcher, err := newConfigProvider(r.lggr, r.chain, relayOpts, r.eventBroadcaster) + if err != nil { return nil, err } + var contractTransmitter ContractTransmitter var reportCodec median.ReportCodec diff --git a/core/services/relay/evm/functions.go b/core/services/relay/evm/functions.go index c5bf13c0854..43a3d2ff86f 100644 --- a/core/services/relay/evm/functions.go +++ b/core/services/relay/evm/functions.go @@ -1,84 +1,226 @@ package evm import ( + "context" "encoding/json" + "fmt" "strings" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" - "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" - "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "go.uber.org/multierr" relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types" + txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" "github.com/smartcontractkit/chainlink/v2/core/chains/evm" + txm "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" functionsRelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/functions" evmRelayTypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/utils" ) type functionsProvider struct { - *configWatcher + utils.StartStopOnce + configWatcher *configWatcher contractTransmitter ContractTransmitter + logPollerWrapper evmRelayTypes.LogPollerWrapper } -var ( - _ relaytypes.Plugin = (*functionsProvider)(nil) -) +var _ evmRelayTypes.FunctionsProvider = (*functionsProvider)(nil) -func (p *functionsProvider) ContractTransmitter() types.ContractTransmitter { +func (p *functionsProvider) ContractTransmitter() ocrtypes.ContractTransmitter { return p.contractTransmitter } -func NewFunctionsProvider(chainSet evm.ChainSet, rargs relaytypes.RelayArgs, pargs relaytypes.PluginArgs, lggr logger.Logger, ethKeystore keystore.Eth, pluginType functionsRelay.FunctionsPluginType) (relaytypes.Plugin, error) { - configWatcher, err := newFunctionsConfigProvider(pluginType, chainSet, rargs, lggr) +func (p *functionsProvider) LogPollerWrapper() evmRelayTypes.LogPollerWrapper { + return p.logPollerWrapper +} + +func (p *functionsProvider) FunctionsEvents() relaytypes.FunctionsEvents { + // TODO (FUN-668): implement + return nil +} + +func (p *functionsProvider) Start(ctx context.Context) error { + return p.StartOnce("FunctionsProvider", func() error { + if err := p.configWatcher.Start(ctx); err != nil { + return err + } + return p.logPollerWrapper.Start(ctx) + }) +} + +func (p *functionsProvider) Close() error { + return p.StopOnce("FunctionsProvider", func() (err error) { + err = multierr.Combine(err, p.logPollerWrapper.Close()) + err = multierr.Combine(err, p.configWatcher.Close()) + return + }) +} + +// Forward all calls to the underlying configWatcher +func (p *functionsProvider) OffchainConfigDigester() ocrtypes.OffchainConfigDigester { + return p.configWatcher.OffchainConfigDigester() +} + +func (p *functionsProvider) ContractConfigTracker() ocrtypes.ContractConfigTracker { + return p.configWatcher.ContractConfigTracker() +} + +func (p *functionsProvider) HealthReport() map[string]error { + return p.configWatcher.HealthReport() +} + +func (p *functionsProvider) Name() string { + return p.configWatcher.Name() +} + +func NewFunctionsProvider(chain evm.Chain, rargs relaytypes.RelayArgs, pargs relaytypes.PluginArgs, lggr logger.Logger, ethKeystore keystore.Eth, pluginType functionsRelay.FunctionsPluginType) (evmRelayTypes.FunctionsProvider, error) { + relayOpts := evmRelayTypes.NewRelayOpts(rargs) + relayConfig, err := relayOpts.RelayConfig() if err != nil { return nil, err } - contractTransmitter, err := newContractTransmitter(lggr, rargs, pargs.TransmitterID, configWatcher, ethKeystore) + expectedChainID := relayConfig.ChainID.String() + if expectedChainID != chain.ID().String() { + return nil, fmt.Errorf("internal error: chain id in spec does not match this relayer's chain: have %s expected %s", relayConfig.ChainID.String(), chain.ID().String()) + } if err != nil { return nil, err } - return &functionsProvider{ - configWatcher: configWatcher, - contractTransmitter: contractTransmitter, - }, nil -} - -func newFunctionsConfigProvider(pluginType functionsRelay.FunctionsPluginType, chainSet evm.ChainSet, args relaytypes.RelayArgs, lggr logger.Logger) (*configWatcher, error) { - var relayConfig evmRelayTypes.RelayConfig - err := json.Unmarshal(args.RelayConfig, &relayConfig) + if !common.IsHexAddress(rargs.ContractID) { + return nil, errors.Errorf("invalid contractID, expected hex address") + } + var pluginConfig config.PluginConfig + if err2 := json.Unmarshal(pargs.PluginConfig, &pluginConfig); err2 != nil { + return nil, err2 + } + routerContractAddress := common.HexToAddress(rargs.ContractID) + logPollerWrapper, err := functionsRelay.NewLogPollerWrapper(routerContractAddress, pluginConfig, chain.Client(), chain.LogPoller(), lggr) if err != nil { return nil, err } - chain, err := chainSet.Get(relayConfig.ChainID.ToInt()) + configWatcher, err := newFunctionsConfigProvider(pluginType, chain, rargs, relayConfig.FromBlock, logPollerWrapper, lggr) if err != nil { return nil, err } + var contractTransmitter ContractTransmitter + if relayConfig.SendingKeys != nil { + contractTransmitter, err = newFunctionsContractTransmitter(pluginConfig.ContractVersion, rargs, pargs.TransmitterID, configWatcher, ethKeystore, logPollerWrapper, lggr) + if err != nil { + return nil, err + } + } else { + lggr.Warn("no sending keys configured for functions plugin, not starting contract transmitter") + } + return &functionsProvider{ + configWatcher: configWatcher, + contractTransmitter: contractTransmitter, + logPollerWrapper: logPollerWrapper, + }, nil +} + +func newFunctionsConfigProvider(pluginType functionsRelay.FunctionsPluginType, chain evm.Chain, args relaytypes.RelayArgs, fromBlock uint64, logPollerWrapper evmRelayTypes.LogPollerWrapper, lggr logger.Logger) (*configWatcher, error) { if !common.IsHexAddress(args.ContractID) { return nil, errors.Errorf("invalid contractID, expected hex address") } - contractAddress := common.HexToAddress(args.ContractID) + routerContractAddress := common.HexToAddress(args.ContractID) contractABI, err := abi.JSON(strings.NewReader(ocr2aggregator.OCR2AggregatorMetaData.ABI)) if err != nil { return nil, errors.Wrap(err, "could not get contract ABI JSON") } - cp, err := functionsRelay.NewFunctionsConfigPoller(pluginType, chain.LogPoller(), contractAddress, lggr) + cp, err := functionsRelay.NewFunctionsConfigPoller(pluginType, chain.LogPoller(), lggr) if err != nil { return nil, err } + logPollerWrapper.SubscribeToUpdates("FunctionsConfigPoller", cp) + + offchainConfigDigester := functionsRelay.NewFunctionsOffchainConfigDigester(pluginType, chain.ID().Uint64()) + logPollerWrapper.SubscribeToUpdates("FunctionsOffchainConfigDigester", offchainConfigDigester) + + return newConfigWatcher(lggr, routerContractAddress, contractABI, offchainConfigDigester, cp, chain, fromBlock, args.New), nil +} + +func newFunctionsContractTransmitter(contractVersion uint32, rargs relaytypes.RelayArgs, transmitterID string, configWatcher *configWatcher, ethKeystore keystore.Eth, logPollerWrapper evmRelayTypes.LogPollerWrapper, lggr logger.Logger) (ContractTransmitter, error) { + var relayConfig evmRelayTypes.RelayConfig + if err := json.Unmarshal(rargs.RelayConfig, &relayConfig); err != nil { + return nil, err + } + var fromAddresses []common.Address + sendingKeys := relayConfig.SendingKeys + if !relayConfig.EffectiveTransmitterID.Valid { + return nil, errors.New("EffectiveTransmitterID must be specified") + } + effectiveTransmitterAddress := common.HexToAddress(relayConfig.EffectiveTransmitterID.String) - offchainConfigDigester := functionsRelay.FunctionsOffchainConfigDigester{ - PluginType: pluginType, - BaseDigester: evmutil.EVMOffchainConfigDigester{ - ChainID: chain.ID().Uint64(), - ContractAddress: contractAddress, - }, + sendingKeysLength := len(sendingKeys) + if sendingKeysLength == 0 { + return nil, errors.New("no sending keys provided") } - return newConfigWatcher(lggr, contractAddress, contractABI, offchainConfigDigester, cp, chain, relayConfig.FromBlock, args.New), nil + // If we are using multiple sending keys, then a forwarder is needed to rotate transmissions. + // Ensure that this forwarder is not set to a local sending key, and ensure our sending keys are enabled. + for _, s := range sendingKeys { + if sendingKeysLength > 1 && s == effectiveTransmitterAddress.String() { + return nil, errors.New("the transmitter is a local sending key with transaction forwarding enabled") + } + if err := ethKeystore.CheckEnabled(common.HexToAddress(s), configWatcher.chain.Config().EVM().ChainID()); err != nil { + return nil, errors.Wrap(err, "one of the sending keys given is not enabled") + } + fromAddresses = append(fromAddresses, common.HexToAddress(s)) + } + + scoped := configWatcher.chain.Config() + strategy := txmgrcommon.NewQueueingTxStrategy(rargs.ExternalJobID, scoped.OCR2().DefaultTransactionQueueDepth(), scoped.Database().DefaultQueryTimeout()) + + var checker txm.TransmitCheckerSpec + if configWatcher.chain.Config().OCR2().SimulateTransactions() { + checker.CheckerType = txm.TransmitCheckerTypeSimulate + } + + gasLimit := configWatcher.chain.Config().EVM().GasEstimator().LimitDefault() + ocr2Limit := configWatcher.chain.Config().EVM().GasEstimator().LimitJobType().OCR2() + if ocr2Limit != nil { + gasLimit = *ocr2Limit + } + + transmitter, err := ocrcommon.NewTransmitter( + configWatcher.chain.TxManager(), + fromAddresses, + gasLimit, + effectiveTransmitterAddress, + strategy, + checker, + configWatcher.chain.ID(), + ethKeystore, + ) + + if err != nil { + return nil, errors.Wrap(err, "failed to create transmitter") + } + + functionsTransmitter, err := functionsRelay.NewFunctionsContractTransmitter( + configWatcher.chain.Client(), + configWatcher.contractABI, + transmitter, + configWatcher.chain.LogPoller(), + lggr, + nil, + contractVersion, + ) + if err != nil { + return nil, err + } + logPollerWrapper.SubscribeToUpdates("FunctionsConfigTransmitter", functionsTransmitter) + return functionsTransmitter, err } diff --git a/core/services/relay/evm/functions/config_poller.go b/core/services/relay/evm/functions/config_poller.go index 0c8ef42adfa..4feff842ce3 100644 --- a/core/services/relay/evm/functions/config_poller.go +++ b/core/services/relay/evm/functions/config_poller.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "encoding/binary" + "sync/atomic" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" @@ -18,8 +19,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) -var _ types.ConfigPoller = &configPoller{} - type FunctionsPluginType int const ( @@ -30,12 +29,14 @@ const ( type configPoller struct { lggr logger.Logger - filterName string destChainLogPoller logpoller.LogPoller - addr common.Address + targetContract atomic.Pointer[common.Address] pluginType FunctionsPluginType } +var _ types.ConfigPoller = &configPoller{} +var _ types.RouteUpdateSubscriber = &configPoller{} + // ConfigSet Common to all OCR2 evm based contracts: https://github.com/smartcontractkit/libocr/blob/master/contract2/dev/OCR2Abstract.sol var ConfigSet common.Hash @@ -103,23 +104,15 @@ func configFromLog(logData []byte, pluginType FunctionsPluginType) (ocrtypes.Con } func configPollerFilterName(addr common.Address) string { - return logpoller.FilterName("OCR2ConfigPoller", addr.String()) + return logpoller.FilterName("FunctionsOCR2ConfigPoller", addr.String()) } -func NewFunctionsConfigPoller(pluginType FunctionsPluginType, destChainPoller logpoller.LogPoller, addr common.Address, lggr logger.Logger) (types.ConfigPoller, error) { - err := destChainPoller.RegisterFilter(logpoller.Filter{Name: configPollerFilterName(addr), EventSigs: []common.Hash{ConfigSet}, Addresses: []common.Address{addr}}) - if err != nil { - return nil, err - } - +func NewFunctionsConfigPoller(pluginType FunctionsPluginType, destChainPoller logpoller.LogPoller, lggr logger.Logger) (*configPoller, error) { cp := &configPoller{ lggr: lggr, - filterName: configPollerFilterName(addr), destChainLogPoller: destChainPoller, - addr: addr, pluginType: pluginType, } - return cp, nil } @@ -138,7 +131,12 @@ func (cp *configPoller) Replay(ctx context.Context, fromBlock int64) error { } func (cp *configPoller) LatestConfigDetails(ctx context.Context) (changedInBlock uint64, configDigest ocrtypes.ConfigDigest, err error) { - latest, err := cp.destChainLogPoller.LatestLogByEventSigWithConfs(ConfigSet, cp.addr, 1, pg.WithParentCtx(ctx)) + contractAddr := cp.targetContract.Load() + if contractAddr == nil { + return 0, ocrtypes.ConfigDigest{}, nil + } + + latest, err := cp.destChainLogPoller.LatestLogByEventSigWithConfs(ConfigSet, *contractAddr, 1, pg.WithParentCtx(ctx)) if err != nil { if errors.Is(err, sql.ErrNoRows) { return 0, ocrtypes.ConfigDigest{}, nil @@ -153,7 +151,14 @@ func (cp *configPoller) LatestConfigDetails(ctx context.Context) (changedInBlock } func (cp *configPoller) LatestConfig(ctx context.Context, changedInBlock uint64) (ocrtypes.ContractConfig, error) { - lgs, err := cp.destChainLogPoller.Logs(int64(changedInBlock), int64(changedInBlock), ConfigSet, cp.addr, pg.WithParentCtx(ctx)) + // NOTE: if targetContract changes between invocations of LatestConfigDetails() and LatestConfig() + // (unlikely), we'll return an error here and libocr will re-try. + contractAddr := cp.targetContract.Load() + if contractAddr == nil { + return ocrtypes.ContractConfig{}, errors.New("no target contract address set yet") + } + + lgs, err := cp.destChainLogPoller.Logs(int64(changedInBlock), int64(changedInBlock), ConfigSet, *contractAddr, pg.WithParentCtx(ctx)) if err != nil { return ocrtypes.ContractConfig{}, err } @@ -175,3 +180,19 @@ func (cp *configPoller) LatestBlockHeight(ctx context.Context) (blockHeight uint } return uint64(latest), nil } + +// called from LogPollerWrapper in a separate goroutine +func (cp *configPoller) UpdateRoutes(activeCoordinator common.Address, proposedCoordinator common.Address) error { + cp.targetContract.Store(&activeCoordinator) + // Register filters for both active and proposed + err := cp.destChainLogPoller.RegisterFilter(logpoller.Filter{Name: configPollerFilterName(activeCoordinator), EventSigs: []common.Hash{ConfigSet}, Addresses: []common.Address{activeCoordinator}}) + if err != nil { + return err + } + err = cp.destChainLogPoller.RegisterFilter(logpoller.Filter{Name: configPollerFilterName(proposedCoordinator), EventSigs: []common.Hash{ConfigSet}, Addresses: []common.Address{activeCoordinator}}) + if err != nil { + return err + } + // TODO: unregister old filter (needs refactor to get pg.Queryer) + return nil +} diff --git a/core/services/relay/evm/functions/config_poller_test.go b/core/services/relay/evm/functions/config_poller_test.go index e3300a59d69..b6de78b49df 100644 --- a/core/services/relay/evm/functions/config_poller_test.go +++ b/core/services/relay/evm/functions/config_poller_test.go @@ -40,7 +40,9 @@ func TestFunctionsConfigPoller(t *testing.T) { t.Run("ThresholdPlugin", func(t *testing.T) { runTest(t, functions.ThresholdPlugin, functions.ThresholdDigestPrefix) }) - // TODO: Test config poller for S4Plugin (requires S4Plugin to be implemented & corresponding updates to pluginConfig) + t.Run("S4Plugin", func(t *testing.T) { + runTest(t, functions.S4Plugin, functions.S4DigestPrefix) + }) } func runTest(t *testing.T, pluginType functions.FunctionsPluginType, expectedDigestPrefix ocrtypes2.ConfigDigestPrefix) { @@ -80,10 +82,11 @@ func runTest(t *testing.T, pluginType functions.FunctionsPluginType, expectedDig lp := logpoller.NewLogPoller(lorm, ethClient, lggr, 100*time.Millisecond, 1, 2, 2, 1000) defer lp.Close() require.NoError(t, lp.Start(ctx)) - logPoller, err := functions.NewFunctionsConfigPoller(pluginType, lp, ocrAddress, lggr) + configPoller, err := functions.NewFunctionsConfigPoller(pluginType, lp, lggr) require.NoError(t, err) + require.NoError(t, configPoller.UpdateRoutes(ocrAddress, ocrAddress)) // Should have no config to begin with. - _, config, err := logPoller.LatestConfigDetails(testutils.Context(t)) + _, config, err := configPoller.LatestConfigDetails(testutils.Context(t)) require.NoError(t, err) require.Equal(t, ocrtypes2.ConfigDigest{}, config) @@ -119,13 +122,13 @@ func runTest(t *testing.T, pluginType functions.FunctionsPluginType, expectedDig var digest [32]byte gomega.NewGomegaWithT(t).Eventually(func() bool { b.Commit() - configBlock, digest, err = logPoller.LatestConfigDetails(testutils.Context(t)) + configBlock, digest, err = configPoller.LatestConfigDetails(testutils.Context(t)) require.NoError(t, err) return ocrtypes2.ConfigDigest{} != digest }, testutils.WaitTimeout(t), 100*time.Millisecond).Should(gomega.BeTrue()) // Assert the config returned is the one we configured. - newConfig, err := logPoller.LatestConfig(testutils.Context(t), configBlock) + newConfig, err := configPoller.LatestConfig(testutils.Context(t), configBlock) require.NoError(t, err) // Get actual configDigest value from contracts diff --git a/core/services/relay/evm/functions/contract_transmitter.go b/core/services/relay/evm/functions/contract_transmitter.go new file mode 100644 index 00000000000..ecbe3c49f96 --- /dev/null +++ b/core/services/relay/evm/functions/contract_transmitter.go @@ -0,0 +1,253 @@ +package functions + +import ( + "context" + "database/sql" + "fmt" + "math/big" + "sync/atomic" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/encoding" + "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/utils" +) + +type FunctionsContractTransmitter interface { + services.ServiceCtx + ocrtypes.ContractTransmitter +} + +type Transmitter interface { + CreateEthTransaction(ctx context.Context, toAddress common.Address, payload []byte, txMeta *txmgr.TxMeta) error + FromAddress() common.Address +} + +type ReportToEthMetadata func([]byte) (*txmgr.TxMeta, error) + +func reportToEvmTxMetaNoop([]byte) (*txmgr.TxMeta, error) { + return nil, nil +} + +type contractTransmitter struct { + contractAddress atomic.Pointer[common.Address] + contractABI abi.ABI + transmitter Transmitter + transmittedEventSig common.Hash + contractReader contractReader + lp logpoller.LogPoller + lggr logger.Logger + reportToEvmTxMeta ReportToEthMetadata + contractVersion uint32 + reportCodec encoding.ReportCodec +} + +var _ FunctionsContractTransmitter = &contractTransmitter{} +var _ evmRelayTypes.RouteUpdateSubscriber = &contractTransmitter{} + +func transmitterFilterName(addr common.Address) string { + return logpoller.FilterName("FunctionsOCR2ContractTransmitter", addr.String()) +} + +func NewFunctionsContractTransmitter( + caller contractReader, + contractABI abi.ABI, + transmitter Transmitter, + lp logpoller.LogPoller, + lggr logger.Logger, + reportToEvmTxMeta ReportToEthMetadata, + contractVersion uint32, +) (*contractTransmitter, error) { + transmitted, ok := contractABI.Events["Transmitted"] + if !ok { + return nil, errors.New("invalid ABI, missing transmitted") + } + + if reportToEvmTxMeta == nil { + reportToEvmTxMeta = reportToEvmTxMetaNoop + } + codec, err := encoding.NewReportCodec(contractVersion) + if err != nil { + return nil, err + } + return &contractTransmitter{ + contractABI: contractABI, + transmitter: transmitter, + transmittedEventSig: transmitted.ID, + lp: lp, + contractReader: caller, + lggr: lggr.Named("OCRContractTransmitter"), + reportToEvmTxMeta: reportToEvmTxMeta, + contractVersion: contractVersion, + reportCodec: codec, + }, nil +} + +// Transmit sends the report to the on-chain smart contract's Transmit method. +func (oc *contractTransmitter) Transmit(ctx context.Context, reportCtx ocrtypes.ReportContext, report ocrtypes.Report, signatures []ocrtypes.AttributedOnchainSignature) error { + var rs [][32]byte + var ss [][32]byte + var vs [32]byte + for i, as := range signatures { + r, s, v, err := evmutil.SplitSignature(as.Signature) + if err != nil { + panic("eventTransmit(ev): error in SplitSignature") + } + rs = append(rs, r) + ss = append(ss, s) + vs[i] = v + } + rawReportCtx := evmutil.RawReportContext(reportCtx) + + txMeta, err := oc.reportToEvmTxMeta(report) + if err != nil { + oc.lggr.Warnw("failed to generate tx metadata for report", "err", err) + } + + var destinationContract common.Address + if oc.contractVersion == 0 { + destinationContractPtr := oc.contractAddress.Load() + if destinationContractPtr == nil { + return errors.New("destination contract address not set") + } + destinationContract = *destinationContractPtr + } else if oc.contractVersion == 1 { + oc.lggr.Debugw("FunctionsContractTransmitter: start", "reportLenBytes", len(report)) + requests, err2 := oc.reportCodec.DecodeReport(report) + if err2 != nil { + return errors.Wrap(err2, "FunctionsContractTransmitter: DecodeReport failed") + } + if len(requests) == 0 { + return errors.New("FunctionsContractTransmitter: no requests in report") + } + if len(requests[0].CoordinatorContract) != common.AddressLength { + return fmt.Errorf("FunctionsContractTransmitter: incorrect length of CoordinatorContract field: %d", len(requests[0].CoordinatorContract)) + } + // NOTE: this is incorrect if batch contains requests destined for different contracts (unlikely) + // it will be fixed when we get rid of batching + destinationContract.SetBytes(requests[0].CoordinatorContract) + oc.lggr.Debugw("FunctionsContractTransmitter: ready", "nRequests", len(requests), "coordinatorContract", destinationContract.Hex()) + } else { + return fmt.Errorf("unsupported contract version: %d", oc.contractVersion) + } + payload, err := oc.contractABI.Pack("transmit", rawReportCtx, []byte(report), rs, ss, vs) + if err != nil { + return errors.Wrap(err, "abi.Pack failed") + } + + oc.lggr.Debugw("FunctionsContractTransmitter: transmitting report", "contractAddress", destinationContract, "txMeta", txMeta, "payloadSize", len(payload)) + return errors.Wrap(oc.transmitter.CreateEthTransaction(ctx, destinationContract, payload, txMeta), "failed to send Eth transaction") +} + +type contractReader interface { + CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) +} + +func parseTransmitted(log []byte) ([32]byte, uint32, error) { + var args abi.Arguments = []abi.Argument{ + { + Name: "configDigest", + Type: utils.MustAbiType("bytes32", nil), + }, + { + Name: "epoch", + Type: utils.MustAbiType("uint32", nil), + }, + } + transmitted, err := args.Unpack(log) + if err != nil { + return [32]byte{}, 0, err + } + configDigest := *abi.ConvertType(transmitted[0], new([32]byte)).(*[32]byte) + epoch := *abi.ConvertType(transmitted[1], new(uint32)).(*uint32) + return configDigest, epoch, err +} + +func callContract(ctx context.Context, addr common.Address, contractABI abi.ABI, method string, args []interface{}, caller contractReader) ([]interface{}, error) { + input, err := contractABI.Pack(method, args...) + if err != nil { + return nil, err + } + output, err := caller.CallContract(ctx, ethereum.CallMsg{To: &addr, Data: input}, nil) + if err != nil { + return nil, err + } + return contractABI.Unpack(method, output) +} + +// LatestConfigDigestAndEpoch retrieves the latest config digest and epoch from the OCR2 contract. +// It is plugin independent, in particular avoids use of the plugin specific generated evm wrappers +// by using the evm client Call directly for functions/events that are part of OCR2Abstract. +func (oc *contractTransmitter) LatestConfigDigestAndEpoch(ctx context.Context) (ocrtypes.ConfigDigest, uint32, error) { + contractAddr := oc.contractAddress.Load() + if contractAddr == nil { + return ocrtypes.ConfigDigest{}, 0, errors.New("destination contract address not set") + } + latestConfigDigestAndEpoch, err := callContract(ctx, *contractAddr, oc.contractABI, "latestConfigDigestAndEpoch", nil, oc.contractReader) + if err != nil { + return ocrtypes.ConfigDigest{}, 0, err + } + // Panic on these conversions erroring, would mean a broken contract. + scanLogs := *abi.ConvertType(latestConfigDigestAndEpoch[0], new(bool)).(*bool) + configDigest := *abi.ConvertType(latestConfigDigestAndEpoch[1], new([32]byte)).(*[32]byte) + epoch := *abi.ConvertType(latestConfigDigestAndEpoch[2], new(uint32)).(*uint32) + if !scanLogs { + return configDigest, epoch, nil + } + + // Otherwise, we have to scan for the logs. + if err != nil { + return ocrtypes.ConfigDigest{}, 0, err + } + latest, err := oc.lp.LatestLogByEventSigWithConfs( + oc.transmittedEventSig, *contractAddr, 1, pg.WithParentCtx(ctx)) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + // No transmissions yet + return configDigest, 0, nil + } + return ocrtypes.ConfigDigest{}, 0, err + } + return parseTransmitted(latest.Data) +} + +// FromAccount returns the account from which the transmitter invokes the contract +func (oc *contractTransmitter) FromAccount() (ocrtypes.Account, error) { + return ocrtypes.Account(oc.transmitter.FromAddress().String()), nil +} + +func (oc *contractTransmitter) Start(ctx context.Context) error { return nil } +func (oc *contractTransmitter) Close() error { return nil } + +// Has no state/lifecycle so it's always healthy and ready +func (oc *contractTransmitter) Ready() error { return nil } +func (oc *contractTransmitter) HealthReport() map[string]error { + return map[string]error{oc.Name(): nil} +} +func (oc *contractTransmitter) Name() string { return oc.lggr.Name() } + +func (oc *contractTransmitter) UpdateRoutes(activeCoordinator common.Address, proposedCoordinator common.Address) error { + // transmitter only cares about the active coordinator + previousContract := oc.contractAddress.Swap(&activeCoordinator) + if previousContract != nil && *previousContract == activeCoordinator { + return nil + } + oc.lggr.Debugw("FunctionsContractTransmitter: updating routes", "previousContract", previousContract, "activeCoordinator", activeCoordinator) + err := oc.lp.RegisterFilter(logpoller.Filter{Name: transmitterFilterName(activeCoordinator), EventSigs: []common.Hash{oc.transmittedEventSig}, Addresses: []common.Address{activeCoordinator}}) + if err != nil { + return err + } + // TODO: unregister old filter (needs refactor to get pg.Queryer) + return nil +} diff --git a/core/services/relay/evm/functions/contract_transmitter_test.go b/core/services/relay/evm/functions/contract_transmitter_test.go new file mode 100644 index 00000000000..fb4a071de2a --- /dev/null +++ b/core/services/relay/evm/functions/contract_transmitter_test.go @@ -0,0 +1,121 @@ +package functions_test + +import ( + "context" + "encoding/hex" + "strings" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi" + gethcommon "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + evmclimocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" + lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/encoding" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/functions" +) + +type mockTransmitter struct { + toAddress gethcommon.Address +} + +func (m *mockTransmitter) CreateEthTransaction(ctx context.Context, toAddress gethcommon.Address, payload []byte, _ *txmgr.TxMeta) error { + m.toAddress = toAddress + return nil +} +func (mockTransmitter) FromAddress() gethcommon.Address { return testutils.NewAddress() } + +func TestContractTransmitter_LatestConfigDigestAndEpoch(t *testing.T) { + t.Parallel() + + digestStr := "000130da6b9315bd59af6b0a3f5463c0d0a39e92eaa34cbcbdbace7b3bfcc776" + lggr := logger.TestLogger(t) + c := evmclimocks.NewClient(t) + lp := lpmocks.NewLogPoller(t) + digestAndEpochDontScanLogs, err := hex.DecodeString( + "0000000000000000000000000000000000000000000000000000000000000000" + // scan logs = false + digestStr + + "0000000000000000000000000000000000000000000000000000000000000002") // epoch + require.NoError(t, err) + c.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(digestAndEpochDontScanLogs, nil).Once() + contractABI, err := abi.JSON(strings.NewReader(ocr2aggregator.OCR2AggregatorABI)) + require.NoError(t, err) + lp.On("RegisterFilter", mock.Anything).Return(nil) + + functionsTransmitter, err := functions.NewFunctionsContractTransmitter(c, contractABI, &mockTransmitter{}, lp, lggr, func(b []byte) (*txmgr.TxMeta, error) { + return &txmgr.TxMeta{}, nil + }, 0) + require.NoError(t, err) + require.NoError(t, functionsTransmitter.UpdateRoutes(gethcommon.Address{}, gethcommon.Address{})) + + digest, epoch, err := functionsTransmitter.LatestConfigDigestAndEpoch(testutils.Context(t)) + require.NoError(t, err) + assert.Equal(t, digestStr, hex.EncodeToString(digest[:])) + assert.Equal(t, uint32(2), epoch) +} + +func TestContractTransmitter_Transmit_V0(t *testing.T) { + t.Parallel() + + contractVersion := uint32(0) + destAddress := testutils.NewAddress() + lggr := logger.TestLogger(t) + c := evmclimocks.NewClient(t) + lp := lpmocks.NewLogPoller(t) + contractABI, err := abi.JSON(strings.NewReader(ocr2aggregator.OCR2AggregatorABI)) + require.NoError(t, err) + lp.On("RegisterFilter", mock.Anything).Return(nil) + + ocrTransmitter := mockTransmitter{} + ot, err := functions.NewFunctionsContractTransmitter(c, contractABI, &ocrTransmitter, lp, lggr, func(b []byte) (*txmgr.TxMeta, error) { + return &txmgr.TxMeta{}, nil + }, contractVersion) + require.NoError(t, err) + require.NoError(t, ot.UpdateRoutes(destAddress, destAddress)) + + require.NoError(t, ot.Transmit(testutils.Context(t), ocrtypes.ReportContext{}, []byte("bar"), []ocrtypes.AttributedOnchainSignature{})) + require.Equal(t, destAddress, ocrTransmitter.toAddress) +} + +func TestContractTransmitter_Transmit_V1(t *testing.T) { + t.Parallel() + + contractVersion := uint32(1) + configuredDestAddress, coordinatorAddress := testutils.NewAddress(), testutils.NewAddress() + lggr := logger.TestLogger(t) + c := evmclimocks.NewClient(t) + lp := lpmocks.NewLogPoller(t) + contractABI, _ := abi.JSON(strings.NewReader(ocr2aggregator.OCR2AggregatorABI)) + lp.On("RegisterFilter", mock.Anything).Return(nil) + + ocrTransmitter := mockTransmitter{} + ot, err := functions.NewFunctionsContractTransmitter(c, contractABI, &ocrTransmitter, lp, lggr, func(b []byte) (*txmgr.TxMeta, error) { + return &txmgr.TxMeta{}, nil + }, contractVersion) + require.NoError(t, err) + require.NoError(t, ot.UpdateRoutes(configuredDestAddress, configuredDestAddress)) + + reqId, err := hex.DecodeString("000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f") + require.NoError(t, err) + processedRequests := []*encoding.ProcessedRequest{ + { + RequestID: reqId, + CoordinatorContract: coordinatorAddress.Bytes(), + }, + } + codec, err := encoding.NewReportCodec(contractVersion) + require.NoError(t, err) + reportBytes, err := codec.EncodeReport(processedRequests) + require.NoError(t, err) + + require.NoError(t, ot.Transmit(testutils.Context(t), ocrtypes.ReportContext{}, reportBytes, []ocrtypes.AttributedOnchainSignature{})) + require.Equal(t, coordinatorAddress, ocrTransmitter.toAddress) +} diff --git a/core/services/relay/evm/functions/logpoller_wrapper.go b/core/services/relay/evm/functions/logpoller_wrapper.go new file mode 100644 index 00000000000..eae1970da93 --- /dev/null +++ b/core/services/relay/evm/functions/logpoller_wrapper.go @@ -0,0 +1,361 @@ +package functions + +import ( + "context" + "sync" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_coordinator" + "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/ocr2/plugins/functions/config" + evmRelayTypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +type logPollerWrapper struct { + utils.StartStopOnce + + routerContract *functions_router.FunctionsRouter + pluginConfig config.PluginConfig + client client.Client + logPoller logpoller.LogPoller + subscribers map[string]evmRelayTypes.RouteUpdateSubscriber + activeCoordinator common.Address + proposedCoordinator common.Address + nextBlock int64 + mu sync.Mutex + closeWait sync.WaitGroup + stopCh utils.StopChan + lggr logger.Logger +} + +var _ evmRelayTypes.LogPollerWrapper = &logPollerWrapper{} + +func NewLogPollerWrapper(routerContractAddress common.Address, pluginConfig config.PluginConfig, client client.Client, logPoller logpoller.LogPoller, lggr logger.Logger) (evmRelayTypes.LogPollerWrapper, error) { + routerContract, err := functions_router.NewFunctionsRouter(routerContractAddress, client) + if err != nil { + return nil, err + } + + return &logPollerWrapper{ + routerContract: routerContract, + pluginConfig: pluginConfig, + logPoller: logPoller, + client: client, + subscribers: make(map[string]evmRelayTypes.RouteUpdateSubscriber), + stopCh: make(utils.StopChan), + lggr: lggr, + }, nil +} + +func (l *logPollerWrapper) Start(context.Context) error { + return l.StartOnce("LogPollerWrapper", func() error { + l.lggr.Infow("starting LogPollerWrapper", "routerContract", l.routerContract.Address().Hex(), "contractVersion", l.pluginConfig.ContractVersion) + l.mu.Lock() + defer l.mu.Unlock() + if l.pluginConfig.ContractVersion == 0 { + l.activeCoordinator = l.routerContract.Address() + l.proposedCoordinator = l.routerContract.Address() + } else if l.pluginConfig.ContractVersion == 1 { + nextBlock, err := l.logPoller.LatestBlock() + l.nextBlock = nextBlock + if err != nil { + l.lggr.Errorw("LogPollerWrapper: LatestBlock() failed, starting from 0", "error", err) + } else { + l.lggr.Debugw("LogPollerWrapper: LatestBlock() got starting block", "block", nextBlock) + } + l.closeWait.Add(1) + go l.checkForRouteUpdates() + } + return nil + }) +} + +func (l *logPollerWrapper) Close() error { + return l.StopOnce("LogPollerWrapper", func() (err error) { + l.lggr.Info("closing LogPollerWrapper") + close(l.stopCh) + l.closeWait.Wait() + return nil + }) +} + +func (l *logPollerWrapper) HealthReport() map[string]error { + return make(map[string]error) +} + +func (l *logPollerWrapper) Name() string { + return "LogPollerWrapper" +} + +func (l *logPollerWrapper) Ready() error { + return nil +} + +// methods of LogPollerWrapper +func (l *logPollerWrapper) LatestEvents() ([]evmRelayTypes.OracleRequest, []evmRelayTypes.OracleResponse, error) { + l.mu.Lock() + coordinators := []common.Address{} + if l.activeCoordinator != (common.Address{}) { + coordinators = append(coordinators, l.activeCoordinator) + } + if l.proposedCoordinator != (common.Address{}) && l.activeCoordinator != l.proposedCoordinator { + coordinators = append(coordinators, l.proposedCoordinator) + } + nextBlock := l.nextBlock + latest, err := l.logPoller.LatestBlock() + if err != nil { + l.mu.Unlock() + return nil, nil, err + } + if latest >= nextBlock { + l.nextBlock = latest + 1 + } + l.mu.Unlock() + + // outside of the lock + resultsReq := []evmRelayTypes.OracleRequest{} + resultsResp := []evmRelayTypes.OracleResponse{} + if len(coordinators) == 0 { + l.lggr.Debug("LatestEvents: no non-zero coordinators to check") + return resultsReq, resultsResp, errors.New("no non-zero coordinators to check") + } + if latest < nextBlock { + l.lggr.Debugw("LatestEvents: no new blocks to check", "latest", latest, "nextBlock", nextBlock) + return resultsReq, resultsResp, nil + } + + for _, coordinator := range coordinators { + requestLogs, err := l.logPoller.Logs(nextBlock, latest, functions_coordinator.FunctionsCoordinatorOracleRequest{}.Topic(), coordinator) + if err != nil { + l.lggr.Errorw("LatestEvents: fetching request logs from LogPoller failed", "latest", latest, "nextBlock", nextBlock) + return nil, nil, err + } + responseLogs, err := l.logPoller.Logs(nextBlock, latest, functions_coordinator.FunctionsCoordinatorOracleResponse{}.Topic(), coordinator) + if err != nil { + l.lggr.Errorw("LatestEvents: fetching response logs from LogPoller failed", "latest", latest, "nextBlock", nextBlock) + return nil, nil, err + } + + parsingContract, err := functions_coordinator.NewFunctionsCoordinator(coordinator, l.client) + if err != nil { + l.lggr.Error("LatestEvents: creating a contract instance for parsing failed") + return nil, nil, err + } + + l.lggr.Debugw("LatestEvents: parsing logs", "nRequestLogs", len(requestLogs), "nResponseLogs", len(responseLogs), "coordinatorAddress", coordinator.Hex()) + for _, log := range requestLogs { + gethLog := log.ToGethLog() + oracleRequest, err := parsingContract.ParseOracleRequest(gethLog) + if err != nil { + l.lggr.Errorw("LatestEvents: failed to parse a request log, skipping") + continue + } + + uint32Type, errType1 := abi.NewType("uint32", "uint32", nil) + uint40Type, errType2 := abi.NewType("uint40", "uint40", nil) + uint64Type, errType3 := abi.NewType("uint64", "uint64", nil) + uint72Type, errType4 := abi.NewType("uint72", "uint72", nil) + uint96Type, errType5 := abi.NewType("uint96", "uint96", nil) + addressType, errType6 := abi.NewType("address", "address", nil) + bytes32Type, errType7 := abi.NewType("bytes32", "bytes32", nil) + + if errType1 != nil || errType2 != nil || errType3 != nil || errType4 != nil || errType5 != nil || errType6 != nil || errType7 != nil { + l.lggr.Errorw("LatestEvents: failed to initialize types", "errType1", errType1, + "errType2", errType2, "errType3", errType3, "errType4", errType4, "errType5", errType5, "errType6", errType6, "errType7", errType7, + ) + continue + } + commitmentABI := abi.Arguments{ + {Type: bytes32Type}, // RequestId + {Type: addressType}, // Coordinator + {Type: uint96Type}, // EstimatedTotalCostJuels + {Type: addressType}, // Client + {Type: uint64Type}, // SubscriptionId + {Type: uint32Type}, // CallbackGasLimit + {Type: uint72Type}, // AdminFee + {Type: uint72Type}, // DonFee + {Type: uint40Type}, // GasOverheadBeforeCallback + {Type: uint40Type}, // GasOverheadAfterCallback + {Type: uint32Type}, // TimeoutTimestamp + } + commitmentBytes, err := commitmentABI.Pack( + oracleRequest.Commitment.RequestId, + oracleRequest.Commitment.Coordinator, + oracleRequest.Commitment.EstimatedTotalCostJuels, + oracleRequest.Commitment.Client, + oracleRequest.Commitment.SubscriptionId, + oracleRequest.Commitment.CallbackGasLimit, + oracleRequest.Commitment.AdminFee, + oracleRequest.Commitment.DonFee, + oracleRequest.Commitment.GasOverheadBeforeCallback, + oracleRequest.Commitment.GasOverheadAfterCallback, + oracleRequest.Commitment.TimeoutTimestamp, + ) + if err != nil { + l.lggr.Errorw("LatestEvents: failed to pack commitment bytes, skipping", err) + } + + resultsReq = append(resultsReq, evmRelayTypes.OracleRequest{ + RequestId: oracleRequest.RequestId, + RequestingContract: oracleRequest.RequestingContract, + RequestInitiator: oracleRequest.RequestInitiator, + SubscriptionId: oracleRequest.SubscriptionId, + SubscriptionOwner: oracleRequest.SubscriptionOwner, + Data: oracleRequest.Data, + DataVersion: oracleRequest.DataVersion, + Flags: oracleRequest.Flags, + CallbackGasLimit: oracleRequest.CallbackGasLimit, + TxHash: oracleRequest.Raw.TxHash, + OnchainMetadata: commitmentBytes, + CoordinatorContract: coordinator, + }) + } + for _, log := range responseLogs { + gethLog := log.ToGethLog() + oracleResponse, err := parsingContract.ParseOracleResponse(gethLog) + if err != nil { + l.lggr.Errorw("LatestEvents: failed to parse a response log, skipping") + continue + } + resultsResp = append(resultsResp, evmRelayTypes.OracleResponse{ + RequestId: oracleResponse.RequestId, + }) + } + } + + l.lggr.Debugw("LatestEvents: done", "nRequestLogs", len(resultsReq), "nResponseLogs", len(resultsResp), "nextBlock", nextBlock, "latest", latest) + return resultsReq, resultsResp, nil +} + +// "internal" method called only by EVM relayer components +func (l *logPollerWrapper) SubscribeToUpdates(subscriberName string, subscriber evmRelayTypes.RouteUpdateSubscriber) { + if l.pluginConfig.ContractVersion == 0 { + // in V0, immediately set contract address to Oracle contract and never update again + if err := subscriber.UpdateRoutes(l.routerContract.Address(), l.routerContract.Address()); err != nil { + l.lggr.Errorw("LogPollerWrapper: Failed to update routes", "subscriberName", subscriberName, "error", err) + } + } else if l.pluginConfig.ContractVersion == 1 { + l.mu.Lock() + defer l.mu.Unlock() + l.subscribers[subscriberName] = subscriber + } +} + +func (l *logPollerWrapper) checkForRouteUpdates() { + defer l.closeWait.Done() + freqSec := l.pluginConfig.ContractUpdateCheckFrequencySec + if freqSec == 0 { + l.lggr.Errorw("LogPollerWrapper: ContractUpdateCheckFrequencySec is zero - route update checks disabled") + return + } + + updateOnce := func() { + // NOTE: timeout == frequency here, could be changed to a separate config value + timeoutCtx, cancel := utils.ContextFromChanWithTimeout(l.stopCh, time.Duration(l.pluginConfig.ContractUpdateCheckFrequencySec)*time.Second) + defer cancel() + active, proposed, err := l.getCurrentCoordinators(timeoutCtx) + if err != nil { + l.lggr.Errorw("LogPollerWrapper: error calling getCurrentCoordinators", "err", err) + return + } + l.handleRouteUpdate(active, proposed) + } + + updateOnce() // update once right away + ticker := time.NewTicker(time.Duration(freqSec) * time.Second) + defer ticker.Stop() + for { + select { + case <-l.stopCh: + return + case <-ticker.C: + updateOnce() + } + } +} + +func (l *logPollerWrapper) getCurrentCoordinators(ctx context.Context) (common.Address, common.Address, error) { + if l.pluginConfig.ContractVersion == 0 { + return l.routerContract.Address(), l.routerContract.Address(), nil + } + var donId [32]byte + copy(donId[:], []byte(l.pluginConfig.DONID)) + + activeCoordinator, err := l.routerContract.GetContractById(&bind.CallOpts{ + Pending: false, + Context: ctx, + }, donId) + if err != nil { + return common.Address{}, common.Address{}, err + } + + proposedCoordinator, err := l.routerContract.GetProposedContractById(&bind.CallOpts{ + Pending: false, + Context: ctx, + }, donId) + if err != nil { + return activeCoordinator, l.proposedCoordinator, nil + } + + return activeCoordinator, proposedCoordinator, nil +} + +func (l *logPollerWrapper) handleRouteUpdate(activeCoordinator common.Address, proposedCoordinator common.Address) { + l.mu.Lock() + defer l.mu.Unlock() + + if activeCoordinator == (common.Address{}) { + l.lggr.Error("LogPollerWrapper: cannot update activeCoordinator to zero address") + return + } + + if activeCoordinator == l.activeCoordinator && proposedCoordinator == l.proposedCoordinator { + l.lggr.Debug("LogPollerWrapper: no changes to routes") + return + } + errActive := l.registerFilters(activeCoordinator) + errProposed := l.registerFilters(proposedCoordinator) + if errActive != nil || errProposed != nil { + l.lggr.Errorw("LogPollerWrapper: Failed to register filters", "errorActive", errActive, "errorProposed", errProposed) + return + } + + l.lggr.Debugw("LogPollerWrapper: new routes", "activeCoordinator", activeCoordinator.Hex(), "proposedCoordinator", proposedCoordinator.Hex()) + l.activeCoordinator = activeCoordinator + l.proposedCoordinator = proposedCoordinator + + for _, subscriber := range l.subscribers { + err := subscriber.UpdateRoutes(activeCoordinator, proposedCoordinator) + if err != nil { + l.lggr.Errorw("LogPollerWrapper: Failed to update routes", "error", err) + } + } +} + +func filterName(addr common.Address) string { + return logpoller.FilterName("FunctionsLogPollerWrapper", addr.String()) +} + +func (l *logPollerWrapper) registerFilters(coordinatorAddress common.Address) error { + if (coordinatorAddress == common.Address{}) { + return nil + } + return l.logPoller.RegisterFilter( + logpoller.Filter{ + Name: filterName(coordinatorAddress), + EventSigs: []common.Hash{ + functions_coordinator.FunctionsCoordinatorOracleRequest{}.Topic(), + functions_coordinator.FunctionsCoordinatorOracleResponse{}.Topic(), + }, + Addresses: []common.Address{coordinatorAddress}, + }) +} diff --git a/core/services/relay/evm/functions/logpoller_wrapper_test.go b/core/services/relay/evm/functions/logpoller_wrapper_test.go new file mode 100644 index 00000000000..224aa51a5da --- /dev/null +++ b/core/services/relay/evm/functions/logpoller_wrapper_test.go @@ -0,0 +1,98 @@ +package functions_test + +import ( + "encoding/hex" + "sync" + "testing" + + "github.com/ethereum/go-ethereum/common" + gethcommon "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + evmclimocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/config" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/functions" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" +) + +type subscriber struct { + updates sync.WaitGroup + expectedCalls int +} + +func (s *subscriber) UpdateRoutes(activeCoordinator common.Address, proposedCoordinator common.Address) error { + if s.expectedCalls == 0 { + panic("unexpected call to UpdateRoutes") + } + if activeCoordinator == (common.Address{}) { + panic("activeCoordinator should not be zero") + } + s.expectedCalls-- + s.updates.Done() + return nil +} + +func newSubscriber(expectedCalls int) *subscriber { + sub := &subscriber{expectedCalls: expectedCalls} + sub.updates.Add(expectedCalls) + return sub +} + +func addr(t *testing.T, lastByte string) []byte { + contractAddr, err := hex.DecodeString("00000000000000000000000000000000000000000000000000000000000000" + lastByte) + require.NoError(t, err) + return contractAddr +} + +func setUp(t *testing.T, updateFrequencySec uint32) (*lpmocks.LogPoller, types.LogPollerWrapper, *evmclimocks.Client) { + lggr := logger.TestLogger(t) + client := evmclimocks.NewClient(t) + lp := lpmocks.NewLogPoller(t) + config := config.PluginConfig{ + ContractUpdateCheckFrequencySec: updateFrequencySec, + ContractVersion: 1, + } + lpWrapper, err := functions.NewLogPollerWrapper(gethcommon.Address{}, config, client, lp, lggr) + require.NoError(t, err) + + lp.On("LatestBlock").Return(int64(100), nil) + + return lp, lpWrapper, client +} + +func TestLogPollerWrapper_SingleSubscriberEmptyEvents(t *testing.T) { + t.Parallel() + lp, lpWrapper, client := setUp(t, 100_000) // check only once + + lp.On("Logs", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]logpoller.Log{}, nil) + client.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(addr(t, "01"), nil) + lp.On("RegisterFilter", mock.Anything).Return(nil) + + subscriber := newSubscriber(1) + lpWrapper.SubscribeToUpdates("mock_subscriber", subscriber) + + require.NoError(t, lpWrapper.Start(testutils.Context(t))) + subscriber.updates.Wait() + reqs, resps, err := lpWrapper.LatestEvents() + require.NoError(t, err) + require.Equal(t, 0, len(reqs)) + require.Equal(t, 0, len(resps)) + lpWrapper.Close() +} + +func TestLogPollerWrapper_ErrorOnZeroAddresses(t *testing.T) { + t.Parallel() + _, lpWrapper, client := setUp(t, 100_000) // check only once + + client.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(addr(t, "00"), nil) + + require.NoError(t, lpWrapper.Start(testutils.Context(t))) + _, _, err := lpWrapper.LatestEvents() + require.Error(t, err) + lpWrapper.Close() +} diff --git a/core/services/relay/evm/functions/offchain_config_digester.go b/core/services/relay/evm/functions/offchain_config_digester.go index edb43efd195..b4467543d98 100644 --- a/core/services/relay/evm/functions/offchain_config_digester.go +++ b/core/services/relay/evm/functions/offchain_config_digester.go @@ -4,33 +4,55 @@ import ( "encoding/binary" "errors" "fmt" + "sync/atomic" - "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" + "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil" "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + relaytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) var ( - _ types.OffchainConfigDigester = FunctionsOffchainConfigDigester{} - FunctionsDigestPrefix = types.ConfigDigestPrefixEVM + _ types.OffchainConfigDigester = &functionsOffchainConfigDigester{} + _ relaytypes.RouteUpdateSubscriber = &functionsOffchainConfigDigester{} + FunctionsDigestPrefix = types.ConfigDigestPrefixEVM // In order to support multiple OCR plugins with a single jobspec & OCR2Base contract, each plugin must have a unique config digest. // This is accomplished by overriding the single config digest from the contract with a unique prefix for each plugin via this custom offchain digester & config poller. ThresholdDigestPrefix = types.ConfigDigestPrefix(7) S4DigestPrefix = types.ConfigDigestPrefix(8) ) -type FunctionsOffchainConfigDigester struct { - PluginType FunctionsPluginType - BaseDigester evmutil.EVMOffchainConfigDigester +type functionsOffchainConfigDigester struct { + pluginType FunctionsPluginType + chainID uint64 + contractAddress atomic.Pointer[common.Address] } -func (d FunctionsOffchainConfigDigester) ConfigDigest(cc types.ContractConfig) (types.ConfigDigest, error) { - configDigest, err := d.BaseDigester.ConfigDigest(cc) +func NewFunctionsOffchainConfigDigester(pluginType FunctionsPluginType, chainID uint64) *functionsOffchainConfigDigester { + return &functionsOffchainConfigDigester{ + pluginType: pluginType, + chainID: chainID, + } +} + +func (d *functionsOffchainConfigDigester) ConfigDigest(cc types.ContractConfig) (types.ConfigDigest, error) { + contractAddress := d.contractAddress.Load() + if contractAddress == nil { + return types.ConfigDigest{}, errors.New("contract address not set") + } + baseDigester := evmutil.EVMOffchainConfigDigester{ + ChainID: d.chainID, + ContractAddress: *contractAddress, + } + + configDigest, err := baseDigester.ConfigDigest(cc) if err != nil { return types.ConfigDigest{}, err } var prefix types.ConfigDigestPrefix - switch d.PluginType { + switch d.pluginType { case FunctionsPlugin: prefix = FunctionsDigestPrefix case ThresholdPlugin: @@ -46,8 +68,8 @@ func (d FunctionsOffchainConfigDigester) ConfigDigest(cc types.ContractConfig) ( return configDigest, nil } -func (d FunctionsOffchainConfigDigester) ConfigDigestPrefix() (types.ConfigDigestPrefix, error) { - switch d.PluginType { +func (d *functionsOffchainConfigDigester) ConfigDigestPrefix() (types.ConfigDigestPrefix, error) { + switch d.pluginType { case FunctionsPlugin: return FunctionsDigestPrefix, nil case ThresholdPlugin: @@ -55,6 +77,12 @@ func (d FunctionsOffchainConfigDigester) ConfigDigestPrefix() (types.ConfigDiges case S4Plugin: return S4DigestPrefix, nil default: - return 0, fmt.Errorf("unknown plugin type: %v", d.PluginType) + return 0, fmt.Errorf("unknown plugin type: %v", d.pluginType) } } + +// called from LogPollerWrapper in a separate goroutine +func (d *functionsOffchainConfigDigester) UpdateRoutes(activeCoordinator common.Address, proposedCoordinator common.Address) error { + d.contractAddress.Store(&activeCoordinator) + return nil +} diff --git a/core/services/relay/evm/loop_impl.go b/core/services/relay/evm/loop_impl.go new file mode 100644 index 00000000000..02a9194b380 --- /dev/null +++ b/core/services/relay/evm/loop_impl.go @@ -0,0 +1,36 @@ +package evm + +import ( + "github.com/smartcontractkit/chainlink-relay/pkg/loop" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" +) + +//go:generate mockery --quiet --name LoopRelayAdapter --output ./mocks/ --case=underscore +type LoopRelayAdapter interface { + loop.Relayer + Chain() evm.Chain + Default() bool +} +type LoopRelayer struct { + loop.Relayer + ext EVMChainRelayerExtender +} + +var _ loop.Relayer = &LoopRelayer{} + +func NewLoopRelayAdapter(r *Relayer, cs EVMChainRelayerExtender) *LoopRelayer { + ra := relay.NewRelayerAdapter(r, cs) + return &LoopRelayer{ + Relayer: ra, + ext: cs, + } +} + +func (la *LoopRelayer) Chain() evm.Chain { + return la.ext.Chain() +} + +func (la *LoopRelayer) Default() bool { + return la.ext.Default() +} diff --git a/core/services/relay/evm/mercury/config_digest.go b/core/services/relay/evm/mercury/config_digest.go index 4fb57b75f90..b9431fe923f 100644 --- a/core/services/relay/evm/mercury/config_digest.go +++ b/core/services/relay/evm/mercury/config_digest.go @@ -12,11 +12,11 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/wsrpc/credentials" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mercury_exposed_verifier" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/exposed_verifier" ) func makeConfigDigestArgs() abi.Arguments { - abi, err := abi.JSON(strings.NewReader(mercury_exposed_verifier.MercuryExposedVerifierABI)) + abi, err := abi.JSON(strings.NewReader(exposed_verifier.ExposedVerifierABI)) if err != nil { // assertion panic(fmt.Sprintf("could not parse aggregator ABI: %s", err.Error())) diff --git a/core/services/relay/evm/mercury/config_digest_test.go b/core/services/relay/evm/mercury/config_digest_test.go index bfcbb7ad22a..3e94d075dce 100644 --- a/core/services/relay/evm/mercury/config_digest_test.go +++ b/core/services/relay/evm/mercury/config_digest_test.go @@ -18,7 +18,7 @@ import ( "github.com/smartcontractkit/wsrpc/credentials" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mercury_exposed_verifier" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/exposed_verifier" ) // Adapted from: https://github.com/smartcontractkit/offchain-reporting/blob/991ebe1462fd56826a1ddfb34287d542acb2baee/lib/offchainreporting2/chains/evmutil/config_digest_test.go @@ -32,7 +32,7 @@ func TestConfigCalculationMatches(t *testing.T) { core.GenesisAlloc{owner.From: {Balance: new(big.Int).Lsh(big.NewInt(1), 60)}}, ethconfig.Defaults.Miner.GasCeil, ) - _, _, eoa, err := mercury_exposed_verifier.DeployMercuryExposedVerifier( + _, _, eoa, err := exposed_verifier.DeployExposedVerifier( owner, backend, ) backend.Commit() diff --git a/core/services/relay/evm/mercury/config_poller.go b/core/services/relay/evm/mercury/config_poller.go index 59399070266..2f16157bfac 100644 --- a/core/services/relay/evm/mercury/config_poller.go +++ b/core/services/relay/evm/mercury/config_poller.go @@ -12,9 +12,10 @@ import ( ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mercury_verifier" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/verifier" "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/utils" ) // FeedScopedConfigSet ConfigSet with FeedID for use with mercury (and multi-config DON) @@ -29,7 +30,7 @@ const ( func init() { var err error - verifierABI, err = abi.JSON(strings.NewReader(mercury_verifier.MercuryVerifierABI)) + verifierABI, err = abi.JSON(strings.NewReader(verifier.VerifierABI)) if err != nil { panic(err) } @@ -39,11 +40,11 @@ func init() { // FullConfigFromLog defines the contract config with the feedID type FullConfigFromLog struct { ocrtypes.ContractConfig - feedID [32]byte + feedID utils.FeedID } -func unpackLogData(d []byte) (*mercury_verifier.MercuryVerifierConfigSet, error) { - unpacked := new(mercury_verifier.MercuryVerifierConfigSet) +func unpackLogData(d []byte) (*verifier.VerifierConfigSet, error) { + unpacked := new(verifier.VerifierConfigSet) err := verifierABI.UnpackIntoInterface(unpacked, configSetEventName, d) if err != nil { @@ -191,7 +192,10 @@ func (cp *ConfigPoller) LatestBlockHeight(ctx context.Context) (blockHeight uint } func (cp *ConfigPoller) startLogSubscription() { - feedIdPgHex := cp.feedId.Hex()[2:] // trim the leading 0x to make it comparable to pg's hex encoding. + // trim the leading 0x to make it comparable to pg's hex encoding. + addressPgHex := cp.addr.Hex()[2:] + feedIdPgHex := cp.feedId.Hex()[2:] + for { event, ok := <-cp.subscription.Events() if !ok { @@ -206,6 +210,11 @@ func (cp *ConfigPoller) startLogSubscription() { continue } + address := addressTopicValues[0] + if address != addressPgHex { + continue + } + topicValues := strings.Split(addressTopicValues[1], ",") if len(topicValues) <= feedIdTopicIndex { continue diff --git a/core/services/relay/evm/mercury/config_poller_test.go b/core/services/relay/evm/mercury/config_poller_test.go index 3e63c064cb1..6a692b0eacd 100644 --- a/core/services/relay/evm/mercury/config_poller_test.go +++ b/core/services/relay/evm/mercury/config_poller_test.go @@ -82,7 +82,8 @@ func TestMercuryConfigPoller(t *testing.T) { offchainTransmitters[i] = oracles[i].OffchainPublicKey encodedTransmitter[i] = ocrtypes2.Account(fmt.Sprintf("%x", oracles[i].OffchainPublicKey[:])) } - _, err = th.verifierContract.SetConfig(th.user, feedIDBytes, signerAddresses, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) + + _, err = th.verifierContract.SetConfig(th.user, feedIDBytes, signerAddresses, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, nil) require.NoError(t, err, "failed to setConfig with feed ID") th.backend.Commit() @@ -124,34 +125,39 @@ func TestNotify(t *testing.T) { th := SetupTH(t, feedID) th.subscription.On("Events").Return((<-chan pg.Event)(eventCh)) + addressPgHex := th.verifierAddress.Hex()[2:] + notify := th.configPoller.Notify() assert.Empty(t, notify) eventCh <- pg.Event{} // Empty event assert.Empty(t, notify) - eventCh <- pg.Event{Payload: "address"} // missing topic values + eventCh <- pg.Event{Payload: addressPgHex} // missing topic values + assert.Empty(t, notify) + + eventCh <- pg.Event{Payload: addressPgHex + ":val1"} // missing feedId topic value assert.Empty(t, notify) - eventCh <- pg.Event{Payload: "address:val1"} // missing feedId topic value + eventCh <- pg.Event{Payload: addressPgHex + ":8257737fdf4f79639585fd0ed01bea93c248a9ad940e98dd27f41c9b6230fed1,val2"} // wrong index assert.Empty(t, notify) - eventCh <- pg.Event{Payload: "address:8257737fdf4f79639585fd0ed01bea93c248a9ad940e98dd27f41c9b6230fed1,val2"} // wrong index + eventCh <- pg.Event{Payload: addressPgHex + ":val1,val2,8257737fdf4f79639585fd0ed01bea93c248a9ad940e98dd27f41c9b6230fed1"} // wrong index assert.Empty(t, notify) - eventCh <- pg.Event{Payload: "address:val1,val2,8257737fdf4f79639585fd0ed01bea93c248a9ad940e98dd27f41c9b6230fed1"} // wrong index + eventCh <- pg.Event{Payload: addressPgHex + ":val1,0x8257737fdf4f79639585fd0ed01bea93c248a9ad940e98dd27f41c9b6230fed1"} // 0x prefix assert.Empty(t, notify) - eventCh <- pg.Event{Payload: "address:val1,0x8257737fdf4f79639585fd0ed01bea93c248a9ad940e98dd27f41c9b6230fed1"} // 0x prefix + eventCh <- pg.Event{Payload: "wrong_address:val1,8257737fdf4f79639585fd0ed01bea93c248a9ad940e98dd27f41c9b6230fed1"} // wrong address assert.Empty(t, notify) - eventCh <- pg.Event{Payload: "address:val1,8257737fdf4f79639585fd0ed01bea93c248a9ad940e98dd27f41c9b6230fed1"} + eventCh <- pg.Event{Payload: addressPgHex + ":val1,8257737fdf4f79639585fd0ed01bea93c248a9ad940e98dd27f41c9b6230fed1"} // expected event to notify on assert.Eventually(t, func() bool { <-notify; return true }, time.Second, 10*time.Millisecond) - eventCh <- pg.Event{Payload: "address:val1,8257737fdf4f79639585fd0ed01bea93c248a9ad940e98dd27f41c9b6230fed1"} // try second time + eventCh <- pg.Event{Payload: addressPgHex + ":val1,8257737fdf4f79639585fd0ed01bea93c248a9ad940e98dd27f41c9b6230fed1"} // try second time assert.Eventually(t, func() bool { <-notify; return true }, time.Second, 10*time.Millisecond) - eventCh <- pg.Event{Payload: "address:val1,8257737fdf4f79639585fd0ed01bea93c248a9ad940e98dd27f41c9b6230fed1:additional"} + eventCh <- pg.Event{Payload: addressPgHex + ":val1,8257737fdf4f79639585fd0ed01bea93c248a9ad940e98dd27f41c9b6230fed1:additional"} // additional colon separated parts assert.Eventually(t, func() bool { <-notify; return true }, time.Second, 10*time.Millisecond) } diff --git a/core/services/relay/evm/mercury/helper_test.go b/core/services/relay/evm/mercury/helper_test.go deleted file mode 100644 index ca2b2123a1a..00000000000 --- a/core/services/relay/evm/mercury/helper_test.go +++ /dev/null @@ -1,81 +0,0 @@ -package mercury - -import ( - "math/big" - "testing" - "time" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/eth/ethconfig" - "github.com/stretchr/testify/require" - - evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mercury_verifier" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mercury_verifier_proxy" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" - "github.com/smartcontractkit/chainlink/v2/core/logger" - pgmocks "github.com/smartcontractkit/chainlink/v2/core/services/pg/mocks" -) - -type TestHarness struct { - configPoller *ConfigPoller - user *bind.TransactOpts - backend *backends.SimulatedBackend - verifierContract *mercury_verifier.MercuryVerifier - logPoller logpoller.LogPoller - eventBroadcaster *pgmocks.EventBroadcaster - subscription *pgmocks.Subscription -} - -func SetupTH(t *testing.T, feedID common.Hash) TestHarness { - key, err := crypto.GenerateKey() - require.NoError(t, err) - user, err := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - require.NoError(t, err) - b := backends.NewSimulatedBackend(core.GenesisAlloc{ - user.From: {Balance: big.NewInt(1000000000000000000)}}, - 5*ethconfig.Defaults.Miner.GasCeil) - - proxyAddress, _, verifierProxy, err := mercury_verifier_proxy.DeployMercuryVerifierProxy(user, b, common.Address{}) - require.NoError(t, err, "failed to deploy test mercury verifier proxy contract") - verifierAddress, _, verifierContract, err := mercury_verifier.DeployMercuryVerifier(user, b, proxyAddress) - require.NoError(t, err, "failed to deploy test mercury verifier contract") - _, err = verifierProxy.InitializeVerifier(user, verifierAddress) - require.NoError(t, err) - b.Commit() - - db := pgtest.NewSqlxDB(t) - cfg := pgtest.NewQConfig(false) - ethClient := evmclient.NewSimulatedBackendClient(t, b, big.NewInt(1337)) - lggr := logger.TestLogger(t) - ctx := testutils.Context(t) - lorm := logpoller.NewORM(big.NewInt(1337), db, lggr, cfg) - lp := logpoller.NewLogPoller(lorm, ethClient, lggr, 100*time.Millisecond, 1, 2, 2, 1000) - eventBroadcaster := pgmocks.NewEventBroadcaster(t) - subscription := pgmocks.NewSubscription(t) - require.NoError(t, lp.Start(ctx)) - t.Cleanup(func() { lp.Close() }) - - eventBroadcaster.On("Subscribe", "insert_on_evm_logs", "").Return(subscription, nil) - - configPoller, err := NewConfigPoller(lggr, lp, verifierAddress, feedID, eventBroadcaster) - require.NoError(t, err) - - configPoller.Start() - - return TestHarness{ - configPoller: configPoller, - user: user, - backend: b, - verifierContract: verifierContract, - logPoller: lp, - eventBroadcaster: eventBroadcaster, - subscription: subscription, - } -} diff --git a/core/services/relay/evm/mercury/helpers_test.go b/core/services/relay/evm/mercury/helpers_test.go index 349aa73e2cc..4a7b8f70d75 100644 --- a/core/services/relay/evm/mercury/helpers_test.go +++ b/core/services/relay/evm/mercury/helpers_test.go @@ -1,22 +1,71 @@ package mercury import ( - "encoding/base64" "math/big" + "testing" + "time" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/stretchr/testify/require" "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/reportcodec" + evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/verifier" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/verifier_proxy" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + pgmocks "github.com/smartcontractkit/chainlink/v2/core/services/pg/mocks" + reportcodecv1 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v1/reportcodec" + reportcodecv2 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v2/reportcodec" + reportcodecv3 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/reportcodec" "github.com/smartcontractkit/chainlink/v2/core/utils" ) -func buildSampleReport() []byte { - feedID := [32]byte{'f', 'o', 'o'} +var ( + sampleFeedID = [32]uint8{28, 145, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114} + sampleClientPubKey = hexutil.MustDecode("0x724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93") +) + +var sampleReports [][]byte + +var ( + sampleV1Report = buildSampleV1Report(242) + sampleV2Report = buildSampleV2Report(242) + sampleV3Report = buildSampleV3Report(242) + sig2 = ocrtypes.AttributedOnchainSignature{Signature: testutils.MustDecodeBase64("kbeuRczizOJCxBzj7MUAFpz3yl2WRM6K/f0ieEBvA+oTFUaKslbQey10krumVjzAvlvKxMfyZo0WkOgNyfF6xwE="), Signer: 2} + sig3 = ocrtypes.AttributedOnchainSignature{Signature: testutils.MustDecodeBase64("9jz4b6Dh2WhXxQ97a6/S9UNjSfrEi9016XKTrfN0mLQFDiNuws23x7Z4n+6g0sqKH/hnxx1VukWUH/ohtw83/wE="), Signer: 3} + sampleSigs = []ocrtypes.AttributedOnchainSignature{sig2, sig3} + sampleReportContext = ocrtypes.ReportContext{ + ReportTimestamp: ocrtypes.ReportTimestamp{ + ConfigDigest: MustHexToConfigDigest("0x0006fc30092226b37f6924b464e16a54a7978a9a524519a73403af64d487dc45"), + Epoch: 6, + Round: 28, + }, + ExtraHash: [32]uint8{27, 144, 106, 73, 166, 228, 123, 166, 179, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}, + } +) + +func init() { + sampleReports = make([][]byte, 4) + for i := 0; i < len(sampleReports); i++ { + sampleReports[i] = buildSampleV1Report(int64(i)) + } +} + +func buildSampleV1Report(p int64) []byte { + feedID := sampleFeedID timestamp := uint32(42) - bp := big.NewInt(242) + bp := big.NewInt(p) bid := big.NewInt(243) ask := big.NewInt(244) currentBlockNumber := uint64(143) @@ -24,14 +73,48 @@ func buildSampleReport() []byte { currentBlockTimestamp := uint64(123) validFromBlockNum := uint64(142) - b, err := reportcodec.ReportTypes.Pack(feedID, timestamp, bp, bid, ask, currentBlockNumber, currentBlockHash, currentBlockTimestamp, validFromBlockNum) + b, err := reportcodecv1.ReportTypes.Pack(feedID, timestamp, bp, bid, ask, currentBlockNumber, currentBlockHash, currentBlockTimestamp, validFromBlockNum) if err != nil { panic(err) } return b } -func buildSamplePayload() []byte { +func buildSampleV2Report(ts int64) []byte { + feedID := sampleFeedID + timestamp := uint32(ts) + bp := big.NewInt(242) + validFromTimestamp := uint32(123) + expiresAt := uint32(456) + linkFee := big.NewInt(3334455) + nativeFee := big.NewInt(556677) + + b, err := reportcodecv2.ReportTypes.Pack(feedID, validFromTimestamp, timestamp, nativeFee, linkFee, expiresAt, bp) + if err != nil { + panic(err) + } + return b +} + +func buildSampleV3Report(ts int64) []byte { + feedID := sampleFeedID + timestamp := uint32(ts) + bp := big.NewInt(242) + bid := big.NewInt(243) + ask := big.NewInt(244) + validFromTimestamp := uint32(123) + expiresAt := uint32(456) + linkFee := big.NewInt(3334455) + nativeFee := big.NewInt(556677) + + b, err := reportcodecv3.ReportTypes.Pack(feedID, validFromTimestamp, timestamp, nativeFee, linkFee, expiresAt, bp, bid, ask) + if err != nil { + panic(err) + } + return b +} + +func buildSamplePayload(report []byte) []byte { var rs [][32]byte var ss [][32]byte var vs [32]byte @@ -45,47 +128,68 @@ func buildSamplePayload() []byte { vs[i] = v } rawReportCtx := evmutil.RawReportContext(sampleReportContext) - payload, err := PayloadTypes.Pack(rawReportCtx, []byte(sampleReport), rs, ss, vs) + payload, err := PayloadTypes.Pack(rawReportCtx, report, rs, ss, vs) if err != nil { panic(err) } return payload } -var ( - sampleFeedID = [32]uint8{28, 145, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114} - sampleReport = buildSampleReport() - sampleClientPubKey = hexutil.MustDecode("0x724ff6eae9e900270edfff233e16322a70ec06e1a6e62a81ef13921f398f6c93") - sig2 = ocrtypes.AttributedOnchainSignature{Signature: mustDecodeBase64("kbeuRczizOJCxBzj7MUAFpz3yl2WRM6K/f0ieEBvA+oTFUaKslbQey10krumVjzAvlvKxMfyZo0WkOgNyfF6xwE="), Signer: 2} - sig3 = ocrtypes.AttributedOnchainSignature{Signature: mustDecodeBase64("9jz4b6Dh2WhXxQ97a6/S9UNjSfrEi9016XKTrfN0mLQFDiNuws23x7Z4n+6g0sqKH/hnxx1VukWUH/ohtw83/wE="), Signer: 3} - sampleSigs = []ocrtypes.AttributedOnchainSignature{sig2, sig3} - sampleReportContext = ocrtypes.ReportContext{ - ReportTimestamp: ocrtypes.ReportTimestamp{ - ConfigDigest: mustHexToConfigDigest("0x0006fc30092226b37f6924b464e16a54a7978a9a524519a73403af64d487dc45"), - Epoch: 6, - Round: 28, - }, - ExtraHash: [32]uint8{27, 144, 106, 73, 166, 228, 123, 166, 179, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}, - } - samplePayload = buildSamplePayload() - samplePayloadHex = hexutil.Encode(samplePayload) -) - -func mustDecodeBase64(s string) (b []byte) { - var err error - b, err = base64.StdEncoding.DecodeString(s) - if err != nil { - panic(err) - } - return +type TestHarness struct { + configPoller *ConfigPoller + user *bind.TransactOpts + backend *backends.SimulatedBackend + verifierAddress common.Address + verifierContract *verifier.Verifier + logPoller logpoller.LogPoller + eventBroadcaster *pgmocks.EventBroadcaster + subscription *pgmocks.Subscription } -func mustHexToConfigDigest(s string) (cd ocrtypes.ConfigDigest) { - b := hexutil.MustDecode(s) - var err error - cd, err = ocrtypes.BytesToConfigDigest(b) - if err != nil { - panic(err) +func SetupTH(t *testing.T, feedID common.Hash) TestHarness { + key, err := crypto.GenerateKey() + require.NoError(t, err) + user, err := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) + require.NoError(t, err) + b := backends.NewSimulatedBackend(core.GenesisAlloc{ + user.From: {Balance: big.NewInt(1000000000000000000)}}, + 5*ethconfig.Defaults.Miner.GasCeil) + + proxyAddress, _, verifierProxy, err := verifier_proxy.DeployVerifierProxy(user, b, common.Address{}) + require.NoError(t, err, "failed to deploy test mercury verifier proxy contract") + verifierAddress, _, verifierContract, err := verifier.DeployVerifier(user, b, proxyAddress) + require.NoError(t, err, "failed to deploy test mercury verifier contract") + _, err = verifierProxy.InitializeVerifier(user, verifierAddress) + require.NoError(t, err) + b.Commit() + + db := pgtest.NewSqlxDB(t) + cfg := pgtest.NewQConfig(false) + ethClient := evmclient.NewSimulatedBackendClient(t, b, big.NewInt(1337)) + lggr := logger.TestLogger(t) + ctx := testutils.Context(t) + lorm := logpoller.NewORM(big.NewInt(1337), db, lggr, cfg) + lp := logpoller.NewLogPoller(lorm, ethClient, lggr, 100*time.Millisecond, 1, 2, 2, 1000) + eventBroadcaster := pgmocks.NewEventBroadcaster(t) + subscription := pgmocks.NewSubscription(t) + require.NoError(t, lp.Start(ctx)) + t.Cleanup(func() { lp.Close() }) + + eventBroadcaster.On("Subscribe", "insert_on_evm_logs", "").Return(subscription, nil) + + configPoller, err := NewConfigPoller(lggr, lp, verifierAddress, feedID, eventBroadcaster) + require.NoError(t, err) + + configPoller.Start() + + return TestHarness{ + configPoller: configPoller, + user: user, + backend: b, + verifierAddress: verifierAddress, + verifierContract: verifierContract, + logPoller: lp, + eventBroadcaster: eventBroadcaster, + subscription: subscription, } - return } diff --git a/core/services/relay/evm/mercury/mocks/chain_head_tracker.go b/core/services/relay/evm/mercury/mocks/chain_head_tracker.go index 72ce3d544a2..84d74673cbc 100644 --- a/core/services/relay/evm/mercury/mocks/chain_head_tracker.go +++ b/core/services/relay/evm/mercury/mocks/chain_head_tracker.go @@ -6,11 +6,11 @@ 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" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" mock "github.com/stretchr/testify/mock" - - types "github.com/smartcontractkit/chainlink/v2/common/types" ) // ChainHeadTracker is an autogenerated mock type for the ChainHeadTracker type @@ -35,15 +35,15 @@ func (_m *ChainHeadTracker) Client() client.Client { } // HeadTracker provides a mock function with given fields: -func (_m *ChainHeadTracker) HeadTracker() types.HeadTracker[*evmtypes.Head, common.Hash] { +func (_m *ChainHeadTracker) HeadTracker() commontypes.HeadTracker[*evmtypes.Head, common.Hash] { ret := _m.Called() - var r0 types.HeadTracker[*evmtypes.Head, common.Hash] - if rf, ok := ret.Get(0).(func() types.HeadTracker[*evmtypes.Head, common.Hash]); ok { + var r0 commontypes.HeadTracker[*evmtypes.Head, common.Hash] + if rf, ok := ret.Get(0).(func() commontypes.HeadTracker[*evmtypes.Head, common.Hash]); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(types.HeadTracker[*evmtypes.Head, common.Hash]) + r0 = ret.Get(0).(commontypes.HeadTracker[*evmtypes.Head, common.Hash]) } } diff --git a/core/services/relay/evm/mercury/mocks/pipeline.go b/core/services/relay/evm/mercury/mocks/pipeline.go new file mode 100644 index 00000000000..317404e4409 --- /dev/null +++ b/core/services/relay/evm/mercury/mocks/pipeline.go @@ -0,0 +1,39 @@ +package mocks + +import ( + "context" + "time" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" +) + +type MockRunner struct { + Trrs pipeline.TaskRunResults + Err error +} + +func (m *MockRunner) ExecuteRun(ctx context.Context, spec pipeline.Spec, vars pipeline.Vars, l logger.Logger) (run pipeline.Run, trrs pipeline.TaskRunResults, err error) { + return pipeline.Run{ID: 42}, m.Trrs, m.Err +} + +var _ pipeline.Task = &MockTask{} + +type MockTask struct { + result pipeline.Result +} + +func (m *MockTask) Type() pipeline.TaskType { return "MockTask" } +func (m *MockTask) ID() int { return 0 } +func (m *MockTask) DotID() string { return "" } +func (m *MockTask) Run(ctx context.Context, lggr logger.Logger, vars pipeline.Vars, inputs []pipeline.Result) (pipeline.Result, pipeline.RunInfo) { + return m.result, pipeline.RunInfo{} +} +func (m *MockTask) Base() *pipeline.BaseTask { return nil } +func (m *MockTask) Outputs() []pipeline.Task { return nil } +func (m *MockTask) Inputs() []pipeline.TaskDependency { return nil } +func (m *MockTask) OutputIndex() int32 { return 0 } +func (m *MockTask) TaskTimeout() (time.Duration, bool) { return 0, false } +func (m *MockTask) TaskRetries() uint32 { return 0 } +func (m *MockTask) TaskMinBackoff() time.Duration { return 0 } +func (m *MockTask) TaskMaxBackoff() time.Duration { return 0 } diff --git a/core/services/relay/evm/mercury/offchain_config_digester.go b/core/services/relay/evm/mercury/offchain_config_digester.go index 7fb215c0e60..a12198738a9 100644 --- a/core/services/relay/evm/mercury/offchain_config_digester.go +++ b/core/services/relay/evm/mercury/offchain_config_digester.go @@ -7,9 +7,10 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" - "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/wsrpc/credentials" + + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" ) // Originally sourced from: https://github.com/smartcontractkit/offchain-reporting/blob/991ebe1462fd56826a1ddfb34287d542acb2baee/lib/offchainreporting2/chains/evmutil/offchain_config_digester.go @@ -21,16 +22,16 @@ func NewOffchainConfigDigester(feedID [32]byte, chainID *big.Int, contractAddres } type OffchainConfigDigester struct { - FeedID [32]byte + FeedID utils.FeedID ChainID *big.Int ContractAddress common.Address } -func (d OffchainConfigDigester) ConfigDigest(cc types.ContractConfig) (types.ConfigDigest, error) { +func (d OffchainConfigDigester) ConfigDigest(cc ocrtypes.ContractConfig) (ocrtypes.ConfigDigest, error) { signers := []common.Address{} for i, signer := range cc.Signers { if len(signer) != 20 { - return types.ConfigDigest{}, errors.Errorf("%v-th evm signer should be a 20 byte address, but got %x", i, signer) + return ocrtypes.ConfigDigest{}, errors.Errorf("%v-th evm signer should be a 20 byte address, but got %x", i, signer) } a := common.BytesToAddress(signer) signers = append(signers, a) @@ -38,12 +39,12 @@ func (d OffchainConfigDigester) ConfigDigest(cc types.ContractConfig) (types.Con transmitters := []credentials.StaticSizedPublicKey{} for i, transmitter := range cc.Transmitters { if len(transmitter) != 2*ed25519.PublicKeySize { - return types.ConfigDigest{}, errors.Errorf("%v-th evm transmitter should be a 64 character hex-encoded ed25519 public key, but got '%v' (%d chars)", i, transmitter, len(transmitter)) + return ocrtypes.ConfigDigest{}, errors.Errorf("%v-th evm transmitter should be a 64 character hex-encoded ed25519 public key, but got '%v' (%d chars)", i, transmitter, len(transmitter)) } var t credentials.StaticSizedPublicKey b, err := hex.DecodeString(string(transmitter)) if err != nil { - return types.ConfigDigest{}, errors.Wrapf(err, "%v-th evm transmitter is not valid hex, got: %q", i, transmitter) + return ocrtypes.ConfigDigest{}, errors.Wrapf(err, "%v-th evm transmitter is not valid hex, got: %q", i, transmitter) } copy(t[:], b) @@ -51,7 +52,7 @@ func (d OffchainConfigDigester) ConfigDigest(cc types.ContractConfig) (types.Con } return configDigest( - d.FeedID, + common.Hash(d.FeedID), d.ChainID, d.ContractAddress, cc.ConfigCount, @@ -64,6 +65,6 @@ func (d OffchainConfigDigester) ConfigDigest(cc types.ContractConfig) (types.Con ), nil } -func (d OffchainConfigDigester) ConfigDigestPrefix() (types.ConfigDigestPrefix, error) { - return types.ConfigDigestPrefixMercuryV02, nil +func (d OffchainConfigDigester) ConfigDigestPrefix() (ocrtypes.ConfigDigestPrefix, error) { + return ocrtypes.ConfigDigestPrefixMercuryV02, nil } diff --git a/core/services/relay/evm/mercury/orm.go b/core/services/relay/evm/mercury/orm.go index 208c403caff..49a5f250e14 100644 --- a/core/services/relay/evm/mercury/orm.go +++ b/core/services/relay/evm/mercury/orm.go @@ -1,44 +1,88 @@ package mercury import ( + "context" "crypto/sha256" + "database/sql" + "errors" + "sync" "github.com/ethereum/go-ethereum/common" "github.com/lib/pq" + pkgerrors "github.com/pkg/errors" "github.com/smartcontractkit/sqlx" 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/v2/core/services/relay/evm/mercury/utils" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" ) -type ORM struct { +type ORM interface { + InsertTransmitRequest(req *pb.TransmitRequest, reportCtx ocrtypes.ReportContext, qopts ...pg.QOpt) error + DeleteTransmitRequests(reqs []*pb.TransmitRequest, qopts ...pg.QOpt) error + GetTransmitRequests(qopts ...pg.QOpt) ([]*Transmission, error) + PruneTransmitRequests(maxSize int, qopts ...pg.QOpt) error + LatestReport(ctx context.Context, feedID [32]byte, qopts ...pg.QOpt) (report []byte, err error) +} + +func FeedIDFromReport(report ocrtypes.Report) (feedID utils.FeedID, err error) { + if n := copy(feedID[:], report); n != 32 { + return feedID, pkgerrors.Errorf("invalid length for report: %d", len(report)) + } + return feedID, nil +} + +type orm struct { q pg.Q } -func NewORM(db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig) *ORM { +func NewORM(db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig) ORM { namedLogger := lggr.Named("MercuryORM") q := pg.NewQ(db, namedLogger, cfg) - return &ORM{ + return &orm{ q: q, } } // InsertTransmitRequest inserts one transmit request if the payload does not exist already. -func (o *ORM) InsertTransmitRequest(req *pb.TransmitRequest, reportCtx ocrtypes.ReportContext, qopts ...pg.QOpt) error { +func (o *orm) InsertTransmitRequest(req *pb.TransmitRequest, reportCtx ocrtypes.ReportContext, qopts ...pg.QOpt) error { q := o.q.WithOpts(qopts...) - err := q.ExecQ(` + var wg sync.WaitGroup + wg.Add(2) + var err1, err2 error + + go func() { + defer wg.Done() + err1 = q.ExecQ(` INSERT INTO mercury_transmit_requests (payload, payload_hash, config_digest, epoch, round, extra_hash) VALUES ($1, $2, $3, $4, $5, $6) ON CONFLICT (payload_hash) DO NOTHING `, req.Payload, hashPayload(req.Payload), reportCtx.ConfigDigest[:], reportCtx.Epoch, reportCtx.Round, reportCtx.ExtraHash[:]) - return err + }() + + feedID, err := FeedIDFromReport(req.Payload) + if err != nil { + return err + } + go func() { + defer wg.Done() + err2 = q.ExecQ(` + INSERT INTO feed_latest_reports (feed_id, report, epoch, round, updated_at) + VALUES ($1, $2, $3, $4, NOW()) + ON CONFLICT (feed_id) DO UPDATE + SET feed_id=$1, report=$2, epoch=$3, round=$4, updated_at=NOW() + WHERE excluded.epoch > feed_latest_reports.epoch OR (excluded.epoch = feed_latest_reports.epoch AND excluded.round > feed_latest_reports.round) + `, feedID[:], req.Payload, reportCtx.Epoch, reportCtx.Round) + }() + wg.Wait() + return errors.Join(err1, err2) } // DeleteTransmitRequest deletes the given transmit requests if they exist. -func (o *ORM) DeleteTransmitRequests(reqs []*pb.TransmitRequest, qopts ...pg.QOpt) error { +func (o *orm) DeleteTransmitRequests(reqs []*pb.TransmitRequest, qopts ...pg.QOpt) error { if len(reqs) == 0 { return nil } @@ -57,7 +101,7 @@ func (o *ORM) DeleteTransmitRequests(reqs []*pb.TransmitRequest, qopts ...pg.QOp } // GetTransmitRequests returns all transmit requests in chronologically descending order. -func (o *ORM) GetTransmitRequests(qopts ...pg.QOpt) ([]*Transmission, error) { +func (o *orm) GetTransmitRequests(qopts ...pg.QOpt) ([]*Transmission, error) { q := o.q.WithOpts(qopts...) // The priority queue uses epoch and round to sort transmissions so order by // the same fields here for optimal insertion into the pq. @@ -100,7 +144,7 @@ func (o *ORM) GetTransmitRequests(qopts ...pg.QOpt) ([]*Transmission, error) { // PruneTransmitRequests keeps at most maxSize rows in the table, deleting the // oldest transactions. -func (o *ORM) PruneTransmitRequests(maxSize int, qopts ...pg.QOpt) error { +func (o *orm) PruneTransmitRequests(maxSize int, qopts ...pg.QOpt) error { q := o.q.WithOpts(qopts...) // Prune the oldest requests by epoch and round. return q.ExecQ(` @@ -114,6 +158,15 @@ func (o *ORM) PruneTransmitRequests(maxSize int, qopts ...pg.QOpt) error { `, maxSize) } +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[:]) + if errors.Is(err, sql.ErrNoRows) { + return nil, nil + } + return report, err +} + func hashPayload(payload []byte) []byte { checksum := sha256.Sum256(payload) return checksum[:] diff --git a/core/services/relay/evm/mercury/orm_test.go b/core/services/relay/evm/mercury/orm_test.go index 2605c2e1926..39db450442f 100644 --- a/core/services/relay/evm/mercury/orm_test.go +++ b/core/services/relay/evm/mercury/orm_test.go @@ -4,8 +4,10 @@ import ( "testing" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "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/relay/evm/mercury/wsrpc/pb" @@ -15,43 +17,61 @@ func TestORM(t *testing.T) { db := pgtest.NewSqlxDB(t) lggr := logger.TestLogger(t) orm := NewORM(db, lggr, pgtest.NewQConfig(true)) + feedID := sampleFeedID - reportContext := ocrtypes.ReportContext{ - ReportTimestamp: ocrtypes.ReportTimestamp{ - ConfigDigest: ocrtypes.ConfigDigest{'1'}, - Epoch: 10, - Round: 20, - }, - ExtraHash: [32]byte{'2'}, + reports := sampleReports + reportContexts := make([]ocrtypes.ReportContext, 4) + for i := range reportContexts { + reportContexts[i] = ocrtypes.ReportContext{ + ReportTimestamp: ocrtypes.ReportTimestamp{ + ConfigDigest: ocrtypes.ConfigDigest{'1'}, + Epoch: 10, + Round: uint8(i), + }, + ExtraHash: [32]byte{'2'}, + } } + l, err := orm.LatestReport(testutils.Context(t), feedID) + require.NoError(t, err) + assert.Nil(t, l) + // Test insert and get requests. - err := orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: []byte("report-1")}, reportContext) + err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[0]}, reportContexts[0]) require.NoError(t, err) - err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: []byte("report-2")}, reportContext) + err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[1]}, reportContexts[1]) require.NoError(t, err) - err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: []byte("report-3")}, reportContext) + err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[2]}, reportContexts[2]) require.NoError(t, err) transmissions, err := orm.GetTransmitRequests() require.NoError(t, err) require.Equal(t, transmissions, []*Transmission{ - {Req: &pb.TransmitRequest{Payload: []byte("report-1")}, ReportCtx: reportContext}, - {Req: &pb.TransmitRequest{Payload: []byte("report-2")}, ReportCtx: reportContext}, - {Req: &pb.TransmitRequest{Payload: []byte("report-3")}, ReportCtx: reportContext}, + {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]}, }) + l, err = orm.LatestReport(testutils.Context(t), feedID) + require.NoError(t, err) + assert.NotEqual(t, reports[0], l) + assert.Equal(t, reports[2], l) + // Test requests can be deleted. - err = orm.DeleteTransmitRequests([]*pb.TransmitRequest{{Payload: []byte("report-2")}}) + err = orm.DeleteTransmitRequests([]*pb.TransmitRequest{{Payload: reports[1]}}) require.NoError(t, err) transmissions, err = orm.GetTransmitRequests() require.NoError(t, err) require.Equal(t, transmissions, []*Transmission{ - {Req: &pb.TransmitRequest{Payload: []byte("report-1")}, ReportCtx: reportContext}, - {Req: &pb.TransmitRequest{Payload: []byte("report-3")}, ReportCtx: reportContext}, + {Req: &pb.TransmitRequest{Payload: reports[2]}, ReportCtx: reportContexts[2]}, + {Req: &pb.TransmitRequest{Payload: reports[0]}, ReportCtx: reportContexts[0]}, }) + l, err = orm.LatestReport(testutils.Context(t), feedID) + require.NoError(t, err) + assert.Equal(t, reports[2], l) + // Test deleting non-existent requests does not error. err = orm.DeleteTransmitRequests([]*pb.TransmitRequest{{Payload: []byte("does-not-exist")}}) require.NoError(t, err) @@ -59,42 +79,50 @@ func TestORM(t *testing.T) { transmissions, err = orm.GetTransmitRequests() require.NoError(t, err) require.Equal(t, transmissions, []*Transmission{ - {Req: &pb.TransmitRequest{Payload: []byte("report-1")}, ReportCtx: reportContext}, - {Req: &pb.TransmitRequest{Payload: []byte("report-3")}, ReportCtx: reportContext}, + {Req: &pb.TransmitRequest{Payload: reports[2]}, ReportCtx: reportContexts[2]}, + {Req: &pb.TransmitRequest{Payload: reports[0]}, ReportCtx: reportContexts[0]}, }) // Test deleting multiple requests. err = orm.DeleteTransmitRequests([]*pb.TransmitRequest{ - {Payload: []byte("report-1")}, - {Payload: []byte("report-3")}, + {Payload: reports[0]}, + {Payload: reports[2]}, }) require.NoError(t, err) + l, err = orm.LatestReport(testutils.Context(t), feedID) + require.NoError(t, err) + assert.Equal(t, reports[2], l) + transmissions, err = orm.GetTransmitRequests() require.NoError(t, err) require.Empty(t, transmissions) // More inserts. - err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: []byte("report-4")}, reportContext) + err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[3]}, reportContexts[3]) require.NoError(t, err) transmissions, err = orm.GetTransmitRequests() require.NoError(t, err) require.Equal(t, transmissions, []*Transmission{ - {Req: &pb.TransmitRequest{Payload: []byte("report-4")}, ReportCtx: reportContext}, + {Req: &pb.TransmitRequest{Payload: reports[3]}, ReportCtx: reportContexts[3]}, }) // Duplicate requests are ignored. - err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: []byte("report-4")}, reportContext) + err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[3]}, reportContexts[3]) require.NoError(t, err) - err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: []byte("report-4")}, reportContext) + err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[3]}, reportContexts[3]) require.NoError(t, err) transmissions, err = orm.GetTransmitRequests() require.NoError(t, err) require.Equal(t, transmissions, []*Transmission{ - {Req: &pb.TransmitRequest{Payload: []byte("report-4")}, ReportCtx: reportContext}, + {Req: &pb.TransmitRequest{Payload: reports[3]}, ReportCtx: reportContexts[3]}, }) + + l, err = orm.LatestReport(testutils.Context(t), feedID) + require.NoError(t, err) + assert.Equal(t, reports[3], l) } func TestORM_PruneTransmitRequests(t *testing.T) { @@ -102,6 +130,8 @@ func TestORM_PruneTransmitRequests(t *testing.T) { lggr := logger.TestLogger(t) orm := NewORM(db, lggr, pgtest.NewQConfig(true)) + reports := sampleReports + makeReportContext := func(epoch uint32, round uint8) ocrtypes.ReportContext { return ocrtypes.ReportContext{ ReportTimestamp: ocrtypes.ReportTimestamp{ @@ -113,9 +143,9 @@ func TestORM_PruneTransmitRequests(t *testing.T) { } } - err := orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: []byte("1")}, makeReportContext(1, 1)) + err := orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[0]}, makeReportContext(1, 1)) require.NoError(t, err) - err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: []byte("2")}, makeReportContext(1, 2)) + err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[1]}, makeReportContext(1, 2)) require.NoError(t, err) // Max size greater than table size, expect no-op @@ -125,8 +155,8 @@ func TestORM_PruneTransmitRequests(t *testing.T) { transmissions, err := orm.GetTransmitRequests() require.NoError(t, err) require.Equal(t, transmissions, []*Transmission{ - {Req: &pb.TransmitRequest{Payload: []byte("2")}, ReportCtx: makeReportContext(1, 2)}, - {Req: &pb.TransmitRequest{Payload: []byte("1")}, ReportCtx: makeReportContext(1, 1)}, + {Req: &pb.TransmitRequest{Payload: reports[1]}, ReportCtx: makeReportContext(1, 2)}, + {Req: &pb.TransmitRequest{Payload: reports[0]}, ReportCtx: makeReportContext(1, 1)}, }) // Max size equal to table size, expect no-op @@ -136,13 +166,13 @@ func TestORM_PruneTransmitRequests(t *testing.T) { transmissions, err = orm.GetTransmitRequests() require.NoError(t, err) require.Equal(t, transmissions, []*Transmission{ - {Req: &pb.TransmitRequest{Payload: []byte("2")}, ReportCtx: makeReportContext(1, 2)}, - {Req: &pb.TransmitRequest{Payload: []byte("1")}, ReportCtx: makeReportContext(1, 1)}, + {Req: &pb.TransmitRequest{Payload: reports[1]}, ReportCtx: makeReportContext(1, 2)}, + {Req: &pb.TransmitRequest{Payload: reports[0]}, ReportCtx: makeReportContext(1, 1)}, }) - err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: []byte("3")}, makeReportContext(2, 1)) + err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[2]}, makeReportContext(2, 1)) require.NoError(t, err) - err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: []byte("4")}, makeReportContext(2, 2)) + err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[3]}, makeReportContext(2, 2)) require.NoError(t, err) // Max size is table size + 1, expect the oldest row to be pruned. @@ -152,8 +182,87 @@ func TestORM_PruneTransmitRequests(t *testing.T) { transmissions, err = orm.GetTransmitRequests() require.NoError(t, err) require.Equal(t, transmissions, []*Transmission{ - {Req: &pb.TransmitRequest{Payload: []byte("4")}, ReportCtx: makeReportContext(2, 2)}, - {Req: &pb.TransmitRequest{Payload: []byte("3")}, ReportCtx: makeReportContext(2, 1)}, - {Req: &pb.TransmitRequest{Payload: []byte("2")}, ReportCtx: makeReportContext(1, 2)}, + {Req: &pb.TransmitRequest{Payload: reports[3]}, ReportCtx: makeReportContext(2, 2)}, + {Req: &pb.TransmitRequest{Payload: reports[2]}, ReportCtx: makeReportContext(2, 1)}, + {Req: &pb.TransmitRequest{Payload: reports[1]}, ReportCtx: makeReportContext(1, 2)}, + }) +} + +func TestORM_InsertTransmitRequest_LatestReport(t *testing.T) { + db := pgtest.NewSqlxDB(t) + lggr := logger.TestLogger(t) + orm := NewORM(db, lggr, pgtest.NewQConfig(true)) + feedID := sampleFeedID + + reports := sampleReports + + makeReportContext := func(epoch uint32, round uint8) ocrtypes.ReportContext { + return ocrtypes.ReportContext{ + ReportTimestamp: ocrtypes.ReportTimestamp{ + ConfigDigest: ocrtypes.ConfigDigest{'1'}, + Epoch: epoch, + Round: round, + }, + ExtraHash: [32]byte{'2'}, + } + } + + err := orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[0]}, makeReportContext( + 0, 0, + )) + require.NoError(t, err) + + l, err := orm.LatestReport(testutils.Context(t), feedID) + require.NoError(t, err) + assert.Equal(t, reports[0], l) + + t.Run("replaces if epoch and round are larger", func(t *testing.T) { + err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[1]}, makeReportContext(1, 1)) + require.NoError(t, err) + + l, err = orm.LatestReport(testutils.Context(t), feedID) + require.NoError(t, err) + 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(&pb.TransmitRequest{Payload: reports[2]}, makeReportContext(1, 2)) + require.NoError(t, err) + + l, err = orm.LatestReport(testutils.Context(t), feedID) + require.NoError(t, err) + assert.Equal(t, reports[2], l) + }) + t.Run("replaces if epoch is larger but round is smaller", func(t *testing.T) { + err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[3]}, makeReportContext(2, 1)) + require.NoError(t, err) + + l, err = orm.LatestReport(testutils.Context(t), feedID) + require.NoError(t, err) + assert.Equal(t, reports[3], l) + }) + t.Run("does not overwrite if epoch/round is the same", func(t *testing.T) { + err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[0]}, makeReportContext(2, 1)) + require.NoError(t, err) + + l, err = orm.LatestReport(testutils.Context(t), feedID) + require.NoError(t, err) + assert.Equal(t, reports[3], l) + }) +} + +func Test_ReportCodec_FeedIDFromReport(t *testing.T) { + t.Run("FeedIDFromReport extracts the current block number from a valid report", func(t *testing.T) { + report := buildSampleV1Report(42) + + f, err := FeedIDFromReport(report) + require.NoError(t, err) + + assert.Equal(t, sampleFeedID[:], f[:]) + }) + t.Run("FeedIDFromReport returns error if report is invalid", func(t *testing.T) { + report := []byte{1} + + _, err := FeedIDFromReport(report) + assert.EqualError(t, err, "invalid length for report: 1") }) } diff --git a/core/services/relay/evm/mercury/persistence_manager.go b/core/services/relay/evm/mercury/persistence_manager.go index ee493acf130..df170313839 100644 --- a/core/services/relay/evm/mercury/persistence_manager.go +++ b/core/services/relay/evm/mercury/persistence_manager.go @@ -20,7 +20,7 @@ var ( type PersistenceManager struct { lggr logger.Logger - orm *ORM + orm ORM once utils.StartStopOnce stopCh utils.StopChan @@ -30,7 +30,7 @@ type PersistenceManager struct { deleteQueue []*pb.TransmitRequest } -func NewPersistenceManager(lggr logger.Logger, orm *ORM) *PersistenceManager { +func NewPersistenceManager(lggr logger.Logger, orm ORM) *PersistenceManager { return &PersistenceManager{ lggr: lggr.Named("MercuryPersistenceManager"), orm: orm, diff --git a/core/services/relay/evm/mercury/persistence_manager_test.go b/core/services/relay/evm/mercury/persistence_manager_test.go index 2cd299c2ef8..5ad1efedf1b 100644 --- a/core/services/relay/evm/mercury/persistence_manager_test.go +++ b/core/services/relay/evm/mercury/persistence_manager_test.go @@ -24,25 +24,27 @@ func TestPersistenceManager(t *testing.T) { ctx := context.Background() pm := bootstrapPersistenceManager(t) - err := pm.Insert(ctx, &pb.TransmitRequest{Payload: []byte("report-1")}, ocrtypes.ReportContext{}) + reports := sampleReports + + err := pm.Insert(ctx, &pb.TransmitRequest{Payload: reports[0]}, ocrtypes.ReportContext{}) require.NoError(t, err) - err = pm.Insert(ctx, &pb.TransmitRequest{Payload: []byte("report-2")}, ocrtypes.ReportContext{}) + err = pm.Insert(ctx, &pb.TransmitRequest{Payload: reports[1]}, ocrtypes.ReportContext{}) require.NoError(t, err) transmissions, err := pm.Load(ctx) require.NoError(t, err) require.Equal(t, []*Transmission{ - {Req: &pb.TransmitRequest{Payload: []byte("report-1")}}, - {Req: &pb.TransmitRequest{Payload: []byte("report-2")}}, + {Req: &pb.TransmitRequest{Payload: reports[0]}}, + {Req: &pb.TransmitRequest{Payload: reports[1]}}, }, transmissions) - err = pm.Delete(ctx, &pb.TransmitRequest{Payload: []byte("report-1")}) + err = pm.Delete(ctx, &pb.TransmitRequest{Payload: reports[0]}) require.NoError(t, err) transmissions, err = pm.Load(ctx) require.NoError(t, err) require.Equal(t, []*Transmission{ - {Req: &pb.TransmitRequest{Payload: []byte("report-2")}}, + {Req: &pb.TransmitRequest{Payload: reports[1]}}, }, transmissions) } @@ -50,37 +52,39 @@ func TestPersistenceManagerAsyncDelete(t *testing.T) { ctx := context.Background() pm := bootstrapPersistenceManager(t) - err := pm.Insert(ctx, &pb.TransmitRequest{Payload: []byte("report-1")}, ocrtypes.ReportContext{}) + reports := sampleReports + + err := pm.Insert(ctx, &pb.TransmitRequest{Payload: reports[0]}, ocrtypes.ReportContext{}) require.NoError(t, err) - err = pm.Insert(ctx, &pb.TransmitRequest{Payload: []byte("report-2")}, ocrtypes.ReportContext{}) + err = pm.Insert(ctx, &pb.TransmitRequest{Payload: reports[1]}, ocrtypes.ReportContext{}) require.NoError(t, err) flushDeletesFrequency = 10 * time.Millisecond err = pm.Start(ctx) require.NoError(t, err) - pm.AsyncDelete(&pb.TransmitRequest{Payload: []byte("report-1")}) + pm.AsyncDelete(&pb.TransmitRequest{Payload: reports[0]}) time.Sleep(15 * time.Millisecond) transmissions, err := pm.Load(ctx) require.NoError(t, err) require.Equal(t, []*Transmission{ - {Req: &pb.TransmitRequest{Payload: []byte("report-2")}}, + {Req: &pb.TransmitRequest{Payload: reports[1]}}, }, transmissions) // Test AsyncDelete is a no-op after Close. err = pm.Close() require.NoError(t, err) - pm.AsyncDelete(&pb.TransmitRequest{Payload: []byte("report-2")}) + pm.AsyncDelete(&pb.TransmitRequest{Payload: reports[1]}) time.Sleep(15 * time.Millisecond) transmissions, err = pm.Load(ctx) require.NoError(t, err) require.Equal(t, []*Transmission{ - {Req: &pb.TransmitRequest{Payload: []byte("report-2")}}, + {Req: &pb.TransmitRequest{Payload: reports[1]}}, }, transmissions) } @@ -88,11 +92,13 @@ func TestPersistenceManagerPrune(t *testing.T) { ctx := context.Background() pm := bootstrapPersistenceManager(t) - err := pm.Insert(ctx, &pb.TransmitRequest{Payload: []byte("report-1")}, ocrtypes.ReportContext{ReportTimestamp: ocrtypes.ReportTimestamp{Epoch: 1}}) + reports := sampleReports + + err := pm.Insert(ctx, &pb.TransmitRequest{Payload: reports[0]}, ocrtypes.ReportContext{ReportTimestamp: ocrtypes.ReportTimestamp{Epoch: 1}}) require.NoError(t, err) - err = pm.Insert(ctx, &pb.TransmitRequest{Payload: []byte("report-2")}, ocrtypes.ReportContext{ReportTimestamp: ocrtypes.ReportTimestamp{Epoch: 2}}) + err = pm.Insert(ctx, &pb.TransmitRequest{Payload: reports[1]}, ocrtypes.ReportContext{ReportTimestamp: ocrtypes.ReportTimestamp{Epoch: 2}}) require.NoError(t, err) - err = pm.Insert(ctx, &pb.TransmitRequest{Payload: []byte("report-3")}, ocrtypes.ReportContext{ReportTimestamp: ocrtypes.ReportTimestamp{Epoch: 3}}) + err = pm.Insert(ctx, &pb.TransmitRequest{Payload: reports[2]}, ocrtypes.ReportContext{ReportTimestamp: ocrtypes.ReportTimestamp{Epoch: 3}}) require.NoError(t, err) maxTransmitQueueSize = 2 @@ -105,15 +111,15 @@ func TestPersistenceManagerPrune(t *testing.T) { transmissions, err := pm.Load(ctx) require.NoError(t, err) require.Equal(t, []*Transmission{ - {Req: &pb.TransmitRequest{Payload: []byte("report-3")}, ReportCtx: ocrtypes.ReportContext{ReportTimestamp: ocrtypes.ReportTimestamp{Epoch: 3}}}, - {Req: &pb.TransmitRequest{Payload: []byte("report-2")}, ReportCtx: ocrtypes.ReportContext{ReportTimestamp: ocrtypes.ReportTimestamp{Epoch: 2}}}, + {Req: &pb.TransmitRequest{Payload: reports[2]}, ReportCtx: ocrtypes.ReportContext{ReportTimestamp: ocrtypes.ReportTimestamp{Epoch: 3}}}, + {Req: &pb.TransmitRequest{Payload: reports[1]}, ReportCtx: ocrtypes.ReportContext{ReportTimestamp: ocrtypes.ReportTimestamp{Epoch: 2}}}, }, transmissions) // Test pruning stops after Close. err = pm.Close() require.NoError(t, err) - err = pm.Insert(ctx, &pb.TransmitRequest{Payload: []byte("report-4")}, ocrtypes.ReportContext{ReportTimestamp: ocrtypes.ReportTimestamp{Epoch: 4}}) + err = pm.Insert(ctx, &pb.TransmitRequest{Payload: reports[3]}, ocrtypes.ReportContext{ReportTimestamp: ocrtypes.ReportTimestamp{Epoch: 4}}) require.NoError(t, err) time.Sleep(15 * time.Millisecond) @@ -121,8 +127,8 @@ func TestPersistenceManagerPrune(t *testing.T) { transmissions, err = pm.Load(ctx) require.NoError(t, err) require.Equal(t, []*Transmission{ - {Req: &pb.TransmitRequest{Payload: []byte("report-4")}, ReportCtx: ocrtypes.ReportContext{ReportTimestamp: ocrtypes.ReportTimestamp{Epoch: 4}}}, - {Req: &pb.TransmitRequest{Payload: []byte("report-3")}, ReportCtx: ocrtypes.ReportContext{ReportTimestamp: ocrtypes.ReportTimestamp{Epoch: 3}}}, - {Req: &pb.TransmitRequest{Payload: []byte("report-2")}, ReportCtx: ocrtypes.ReportContext{ReportTimestamp: ocrtypes.ReportTimestamp{Epoch: 2}}}, + {Req: &pb.TransmitRequest{Payload: reports[3]}, ReportCtx: ocrtypes.ReportContext{ReportTimestamp: ocrtypes.ReportTimestamp{Epoch: 4}}}, + {Req: &pb.TransmitRequest{Payload: reports[2]}, ReportCtx: ocrtypes.ReportContext{ReportTimestamp: ocrtypes.ReportTimestamp{Epoch: 3}}}, + {Req: &pb.TransmitRequest{Payload: reports[1]}, ReportCtx: ocrtypes.ReportContext{ReportTimestamp: ocrtypes.ReportTimestamp{Epoch: 2}}}, }, transmissions) } diff --git a/core/services/relay/evm/mercury/reportcodec/factories_test.go b/core/services/relay/evm/mercury/reportcodec/factories_test.go deleted file mode 100644 index 89cf6cee7a9..00000000000 --- a/core/services/relay/evm/mercury/reportcodec/factories_test.go +++ /dev/null @@ -1,94 +0,0 @@ -package reportcodec - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/common/hexutil" - - "github.com/smartcontractkit/libocr/commontypes" - - relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" -) - -func NewValidParsedAttributedObservations() []relaymercury.ParsedAttributedObservation { - return []relaymercury.ParsedAttributedObservation{ - relaymercury.ParsedAttributedObservation{ - Timestamp: 1676484822, - Observer: commontypes.OracleID(1), - - BenchmarkPrice: big.NewInt(345), - Bid: big.NewInt(343), - Ask: big.NewInt(347), - PricesValid: true, - - CurrentBlockNum: 16634364, - CurrentBlockHash: hexutil.MustDecode("8f30cda279821c5bb6f72f7ab900aa5118215ce59fcf8835b12d0cdbadc9d7b0"), - CurrentBlockTimestamp: 1682908180, - CurrentBlockValid: true, - - MaxFinalizedBlockNumber: 16634355, - MaxFinalizedBlockNumberValid: true, - }, - relaymercury.ParsedAttributedObservation{ - Timestamp: 1676484826, - Observer: commontypes.OracleID(2), - - BenchmarkPrice: big.NewInt(335), - Bid: big.NewInt(332), - Ask: big.NewInt(336), - PricesValid: true, - - CurrentBlockNum: 16634364, - CurrentBlockHash: hexutil.MustDecode("8f30cda279821c5bb6f72f7ab900aa5118215ce59fcf8835b12d0cdbadc9d7b0"), - CurrentBlockTimestamp: 1682908180, - CurrentBlockValid: true, - - MaxFinalizedBlockNumber: 16634355, - MaxFinalizedBlockNumberValid: true, - }, - relaymercury.ParsedAttributedObservation{ - Timestamp: 1676484828, - Observer: commontypes.OracleID(3), - - BenchmarkPrice: big.NewInt(347), - Bid: big.NewInt(345), - Ask: big.NewInt(350), - PricesValid: true, - - CurrentBlockNum: 16634365, - CurrentBlockHash: hexutil.MustDecode("40044147503a81e9f2a225f4717bf5faf5dc574f69943bdcd305d5ed97504a7e"), - CurrentBlockTimestamp: 1682591344, - CurrentBlockValid: true, - - MaxFinalizedBlockNumber: 16634355, - MaxFinalizedBlockNumberValid: true, - }, - relaymercury.ParsedAttributedObservation{ - Timestamp: 1676484830, - Observer: commontypes.OracleID(4), - - BenchmarkPrice: big.NewInt(346), - Bid: big.NewInt(347), - Ask: big.NewInt(350), - PricesValid: true, - - CurrentBlockNum: 16634365, - CurrentBlockHash: hexutil.MustDecode("40044147503a81e9f2a225f4717bf5faf5dc574f69943bdcd305d5ed97504a7e"), - CurrentBlockTimestamp: 1682591344, - CurrentBlockValid: true, - - MaxFinalizedBlockNumber: 16634355, - MaxFinalizedBlockNumberValid: true, - }, - } -} - -func NewInvalidParsedAttributedObservations() []relaymercury.ParsedAttributedObservation { - invalidPaos := NewValidParsedAttributedObservations() - for i := range invalidPaos { - invalidPaos[i].PricesValid = false - invalidPaos[i].CurrentBlockValid = false - invalidPaos[i].MaxFinalizedBlockNumberValid = false - } - return invalidPaos -} diff --git a/core/services/relay/evm/mercury/reportcodec/report_codec.go b/core/services/relay/evm/mercury/reportcodec/report_codec.go deleted file mode 100644 index 9f08e413363..00000000000 --- a/core/services/relay/evm/mercury/reportcodec/report_codec.go +++ /dev/null @@ -1,147 +0,0 @@ -package reportcodec - -import ( - "fmt" - "math" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/pkg/errors" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - - relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" - - "github.com/smartcontractkit/chainlink/v2/core/logger" -) - -// NOTE: -// This report codec is based on the original median evmreportcodec -// here: -// https://github.com/smartcontractkit/offchain-reporting/blob/master/lib/offchainreporting2/reportingplugin/median/evmreportcodec/reportcodec.go - -var ReportTypes = getReportTypes() -var maxReportLength = 32 * len(ReportTypes) // each arg is 256 bit EVM word - -func getReportTypes() abi.Arguments { - mustNewType := func(t string) abi.Type { - result, err := abi.NewType(t, "", []abi.ArgumentMarshaling{}) - if err != nil { - panic(fmt.Sprintf("Unexpected error during abi.NewType: %s", err)) - } - return result - } - return abi.Arguments([]abi.Argument{ - {Name: "feedId", Type: mustNewType("bytes32")}, - {Name: "observationsTimestamp", Type: mustNewType("uint32")}, - {Name: "benchmarkPrice", Type: mustNewType("int192")}, - {Name: "bid", Type: mustNewType("int192")}, - {Name: "ask", Type: mustNewType("int192")}, - {Name: "currentBlockNum", Type: mustNewType("uint64")}, - {Name: "currentBlockHash", Type: mustNewType("bytes32")}, - {Name: "validFromBlockNum", Type: mustNewType("uint64")}, - {Name: "currentBlockTimestamp", Type: mustNewType("uint64")}, - }) -} - -var _ relaymercury.ReportCodec = &EVMReportCodec{} - -type EVMReportCodec struct { - logger logger.Logger - feedID [32]byte -} - -func NewEVMReportCodec(feedID [32]byte, lggr logger.Logger) *EVMReportCodec { - return &EVMReportCodec{lggr, feedID} -} - -func (r *EVMReportCodec) BuildReport(paos []relaymercury.ParsedAttributedObservation, f int, validFromBlockNum int64) (ocrtypes.Report, error) { - if len(paos) == 0 { - return nil, errors.Errorf("cannot build report from empty attributed observations") - } - - // copy so we can safely sort in place - paos = append([]relaymercury.ParsedAttributedObservation{}, paos...) - - timestamp := relaymercury.GetConsensusTimestamp(paos) - benchmarkPrice, err := relaymercury.GetConsensusBenchmarkPrice(paos, f) - if err != nil { - return nil, errors.Wrap(err, "GetConsensusBenchmarkPrice failed") - } - bid, err := relaymercury.GetConsensusBid(paos, f) - if err != nil { - return nil, errors.Wrap(err, "GetConsensusBid failed") - } - ask, err := relaymercury.GetConsensusAsk(paos, f) - if err != nil { - return nil, errors.Wrap(err, "GetConsensusAsk failed") - } - - currentBlockHash, currentBlockNum, currentBlockTimestamp, err := relaymercury.GetConsensusCurrentBlock(paos, f) - if err != nil { - return nil, errors.Wrap(err, "GetConsensusCurrentBlock failed") - } - - if validFromBlockNum > currentBlockNum { - return nil, errors.Errorf("validFromBlockNum=%d may not be greater than currentBlockNum=%d", validFromBlockNum, currentBlockNum) - } - - if len(currentBlockHash) != 32 { - return nil, errors.Errorf("invalid length for currentBlockHash, expected: 32, got: %d", len(currentBlockHash)) - } - currentBlockHashArray := [32]byte{} - copy(currentBlockHashArray[:], currentBlockHash) - - reportBytes, err := ReportTypes.Pack(r.feedID, timestamp, benchmarkPrice, bid, ask, uint64(currentBlockNum), currentBlockHashArray, uint64(validFromBlockNum), currentBlockTimestamp) - return ocrtypes.Report(reportBytes), errors.Wrap(err, "failed to pack report blob") -} - -// Maximum length in bytes of Report returned by BuildReport. Used for -// defending against spam attacks. -func (r *EVMReportCodec) MaxReportLength(n int) (int, error) { - return maxReportLength, nil -} - -func (r *EVMReportCodec) CurrentBlockNumFromReport(report ocrtypes.Report) (int64, error) { - reportElems := map[string]interface{}{} - if err := ReportTypes.UnpackIntoMap(reportElems, report); err != nil { - return 0, errors.Errorf("error during unpack: %v", err) - } - - blockNumIface, ok := reportElems["currentBlockNum"] - if !ok { - return 0, errors.Errorf("unpacked report has no 'currentBlockNum' field") - } - - blockNum, ok := blockNumIface.(uint64) - if !ok { - return 0, errors.Errorf("cannot cast blockNum to int64, type is %T", blockNumIface) - } - - if blockNum > math.MaxInt64 { - return 0, errors.Errorf("blockNum overflows max int64, got: %d", blockNum) - } - - return int64(blockNum), nil -} - -func (r *EVMReportCodec) ValidFromBlockNumFromReport(report ocrtypes.Report) (int64, error) { - reportElems := map[string]interface{}{} - if err := ReportTypes.UnpackIntoMap(reportElems, report); err != nil { - return 0, errors.Errorf("error during unpack: %v", err) - } - - blockNumIface, ok := reportElems["validFromBlockNum"] - if !ok { - return 0, errors.Errorf("unpacked report has no 'validFromBlockNum' field") - } - - blockNum, ok := blockNumIface.(uint64) - if !ok { - return 0, errors.Errorf("cannot cast blockNum to int64, type is %T", blockNumIface) - } - - if blockNum > math.MaxInt64 { - return 0, errors.Errorf("blockNum overflows max int64, got: %d", blockNum) - } - - return int64(blockNum), nil -} diff --git a/core/services/relay/evm/mercury/test_helpers.go b/core/services/relay/evm/mercury/test_helpers.go new file mode 100644 index 00000000000..27093268b3e --- /dev/null +++ b/core/services/relay/evm/mercury/test_helpers.go @@ -0,0 +1,39 @@ +package mercury + +import ( + "github.com/ethereum/go-ethereum/common/hexutil" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" +) + +func BuildSamplePayload(report []byte, reportCtx ocrtypes.ReportContext, sigs []ocrtypes.AttributedOnchainSignature) []byte { + var rs [][32]byte + var ss [][32]byte + var vs [32]byte + for i, as := range sigs { + r, s, v, err := evmutil.SplitSignature(as.Signature) + if err != nil { + panic("eventTransmit(ev): error in SplitSignature") + } + rs = append(rs, r) + ss = append(ss, s) + vs[i] = v + } + rawReportCtx := evmutil.RawReportContext(reportCtx) + payload, err := PayloadTypes.Pack(rawReportCtx, report, rs, ss, vs) + if err != nil { + panic(err) + } + return payload +} + +func MustHexToConfigDigest(s string) (cd ocrtypes.ConfigDigest) { + b := hexutil.MustDecode(s) + var err error + cd, err = ocrtypes.BytesToConfigDigest(b) + if err != nil { + panic(err) + } + return +} diff --git a/core/services/relay/evm/mercury/transmitter.go b/core/services/relay/evm/mercury/transmitter.go index 76c294b5418..a98d7c28928 100644 --- a/core/services/relay/evm/mercury/transmitter.go +++ b/core/services/relay/evm/mercury/transmitter.go @@ -6,6 +6,7 @@ import ( "crypto/ed25519" "errors" "fmt" + "math/big" "sync" "time" @@ -21,11 +22,12 @@ import ( "github.com/smartcontractkit/sqlx" relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" + mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/reportcodec" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -86,8 +88,7 @@ type mercuryTransmitter struct { cfgTracker ConfigTracker persistenceManager *PersistenceManager - feedID [32]byte - feedIDHex string + feedID mercuryutils.FeedID fromAccount string stopCh utils.StopChan @@ -128,7 +129,6 @@ func NewTransmitter(lggr logger.Logger, cfgTracker ConfigTracker, rpcClient wsrp cfgTracker, persistenceManager, feedID, - feedIDHex, fmt.Sprintf("%x", fromAccount), make(chan (struct{})), NewTransmitQueue(lggr, feedIDHex, maxTransmitQueueSize, nil, persistenceManager), @@ -149,7 +149,7 @@ func (mt *mercuryTransmitter) Start(ctx context.Context) (err error) { if err != nil { return err } - mt.queue = NewTransmitQueue(mt.lggr, mt.feedIDHex, maxTransmitQueueSize, transmissions, mt.persistenceManager) + mt.queue = NewTransmitQueue(mt.lggr, mt.feedID.String(), maxTransmitQueueSize, transmissions, mt.persistenceManager) if err := mt.rpcClient.Start(ctx); err != nil { return err @@ -244,25 +244,8 @@ func (mt *mercuryTransmitter) runQueueLoop() { mt.transmitDuplicateCount.Inc() mt.lggr.Tracew("Transmit report succeeded; duplicate report", "code", res.Code) default: - elems := map[string]interface{}{} - var validFrom int64 - var currentBlock int64 - var unpackErr error - if err = PayloadTypes.UnpackIntoMap(elems, t.Req.Payload); err != nil { - unpackErr = err - } else { - report := elems["report"].([]byte) - validFrom, err = (&reportcodec.EVMReportCodec{}).ValidFromBlockNumFromReport(report) - if err != nil { - unpackErr = err - } - currentBlock, err = (&reportcodec.EVMReportCodec{}).CurrentBlockNumFromReport(report) - if err != nil { - unpackErr = errors.Join(unpackErr, err) - } - } - transmitServerErrorCount.WithLabelValues(mt.feedIDHex, fmt.Sprintf("%d", res.Code)).Inc() - mt.lggr.Errorw("Transmit report failed; mercury server returned error", "unpackErr", unpackErr, "validFromBlock", validFrom, "currentBlock", currentBlock, "response", res, "reportCtx", t.ReportCtx, "err", res.Error, "code", res.Code) + transmitServerErrorCount.WithLabelValues(mt.feedID.String(), fmt.Sprintf("%d", res.Code)).Inc() + mt.lggr.Errorw("Transmit report failed; mercury server returned error", "response", res, "reportCtx", t.ReportCtx, "err", res.Error, "code", res.Code) } } @@ -321,29 +304,87 @@ func (mt *mercuryTransmitter) LatestConfigDigestAndEpoch(ctx context.Context) (c func (mt *mercuryTransmitter) FetchInitialMaxFinalizedBlockNumber(ctx context.Context) (*int64, error) { mt.lggr.Trace("FetchInitialMaxFinalizedBlockNumber") + + report, err := mt.latestReport(ctx, mt.feedID) + if err != nil { + return nil, err + } + + if report == nil { + mt.lggr.Debugw("FetchInitialMaxFinalizedBlockNumber success; got nil report") + return nil, nil + } + + mt.lggr.Debugw("FetchInitialMaxFinalizedBlockNumber success", "currentBlockNum", report.CurrentBlockNumber) + + return &report.CurrentBlockNumber, nil +} + +func (mt *mercuryTransmitter) LatestPrice(ctx context.Context, feedID [32]byte) (*big.Int, error) { + mt.lggr.Trace("LatestPrice") + + report, err := mt.latestReport(ctx, feedID) + if err != nil { + return nil, err + } + if report == nil { + return nil, nil + } + price, err := relaymercury.DecodeValueInt192(report.Price) + if err != nil { + return nil, pkgerrors.Wrap(err, "failed to decode report.Price as *big.Int") + } + return price, nil +} + +// LatestTimestamp will return -1, nil if the feed is missing +func (mt *mercuryTransmitter) LatestTimestamp(ctx context.Context) (int64, error) { + mt.lggr.Trace("LatestTimestamp") + + report, err := mt.latestReport(ctx, mt.feedID) + if err != nil { + return 0, err + } + + if report == nil { + mt.lggr.Debugw("LatestTimestamp success; got nil report") + return -1, nil + } + + mt.lggr.Debugw("LatestTimestamp success", "timestamp", report.ObservationsTimestamp) + + return report.ObservationsTimestamp, nil +} + +func (mt *mercuryTransmitter) latestReport(ctx context.Context, feedID [32]byte) (*pb.Report, error) { + mt.lggr.Trace("latestReport") + req := &pb.LatestReportRequest{ - FeedId: mt.feedID[:], + FeedId: feedID[:], } resp, err := mt.rpcClient.LatestReport(ctx, req) if err != nil { - mt.lggr.Errorw("FetchInitialMaxFinalizedBlockNumber failed", "err", err) - return nil, pkgerrors.Wrap(err, "FetchInitialMaxFinalizedBlockNumber failed to fetch LatestReport") + mt.lggr.Warnw("latestReport failed", "err", err) + return nil, pkgerrors.Wrap(err, "latestReport failed") } if resp == nil { - return nil, errors.New("FetchInitialMaxFinalizedBlockNumber expected LatestReport to return non-nil response") + return nil, errors.New("latestReport expected non-nil response") } if resp.Error != "" { err = errors.New(resp.Error) - mt.lggr.Errorw("FetchInitialMaxFinalizedBlockNumber failed; mercury server returned error", "err", err) + mt.lggr.Warnw("latestReport failed; mercury server returned error", "err", err) return nil, err } if resp.Report == nil { + mt.lggr.Tracew("latestReport success: returned nil") return nil, nil - } else if !bytes.Equal(resp.Report.FeedId, mt.feedID[:]) { - return nil, fmt.Errorf("FetchInitialMaxFinalizedBlockNumber failed; mismatched feed IDs, expected: 0x%x, got: 0x%x", mt.feedID, resp.Report.FeedId) + } else if !bytes.Equal(resp.Report.FeedId, feedID[:]) { + err = fmt.Errorf("latestReport failed; mismatched feed IDs, expected: 0x%x, got: 0x%x", mt.feedID[:], resp.Report.FeedId[:]) + mt.lggr.Errorw("latestReport failed", "err", err) + return nil, err } - mt.lggr.Debugw("FetchInitialMaxFinalizedBlockNumber success", "currentBlockNum", resp.Report.CurrentBlockNumber) + mt.lggr.Tracew("latestReport success", "currentBlockNum", resp.Report.CurrentBlockNumber) - return &resp.Report.CurrentBlockNumber, nil + return resp.Report, nil } diff --git a/core/services/relay/evm/mercury/transmitter_test.go b/core/services/relay/evm/mercury/transmitter_test.go index af0d06ce9c5..f4682d0b32e 100644 --- a/core/services/relay/evm/mercury/transmitter_test.go +++ b/core/services/relay/evm/mercury/transmitter_test.go @@ -2,6 +2,7 @@ package mercury import ( "context" + "math/big" "testing" "github.com/ethereum/go-ethereum/common/hexutil" @@ -9,36 +10,25 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" "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/mocks" + 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" ) -type MockTracker struct { - latestConfigDetails func(ctx context.Context) (changedInBlock uint64, configDigest ocrtypes.ConfigDigest, err error) -} - -func (m MockTracker) LatestConfigDetails(ctx context.Context) (changedInBlock uint64, configDigest ocrtypes.ConfigDigest, err error) { - return m.latestConfigDetails(ctx) -} - -var _ ConfigTracker = &MockTracker{} - func Test_MercuryTransmitter_Transmit(t *testing.T) { - t.Parallel() - lggr := logger.TestLogger(t) db := pgtest.NewSqlxDB(t) - t.Run("transmission successfully enqueued", func(t *testing.T) { + t.Run("v1 report transmission successfully enqueued", func(t *testing.T) { + report := sampleV1Report c := mocks.MockWSRPCClient{ TransmitF: func(ctx context.Context, in *pb.TransmitRequest) (out *pb.TransmitResponse, err error) { require.NotNil(t, in) - assert.Equal(t, samplePayloadHex, hexutil.Encode(in.Payload)) + assert.Equal(t, hexutil.Encode(buildSamplePayload(report)), hexutil.Encode(in.Payload)) out = new(pb.TransmitResponse) out.Code = 42 out.Error = "" @@ -46,9 +36,149 @@ func Test_MercuryTransmitter_Transmit(t *testing.T) { }, } mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true)) - err := mt.Transmit(testutils.Context(t), sampleReportContext, sampleReport, sampleSigs) + err := mt.Transmit(testutils.Context(t), sampleReportContext, report, sampleSigs) + + require.NoError(t, err) + }) + t.Run("v2 report transmission successfully enqueued", func(t *testing.T) { + report := sampleV2Report + c := mocks.MockWSRPCClient{ + TransmitF: func(ctx context.Context, in *pb.TransmitRequest) (out *pb.TransmitResponse, err error) { + require.NotNil(t, in) + assert.Equal(t, hexutil.Encode(buildSamplePayload(report)), hexutil.Encode(in.Payload)) + out = new(pb.TransmitResponse) + out.Code = 42 + out.Error = "" + return out, nil + }, + } + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true)) + err := mt.Transmit(testutils.Context(t), sampleReportContext, report, sampleSigs) + + require.NoError(t, err) + }) + t.Run("v3 report transmission successfully enqueued", func(t *testing.T) { + report := sampleV3Report + c := mocks.MockWSRPCClient{ + TransmitF: func(ctx context.Context, in *pb.TransmitRequest) (out *pb.TransmitResponse, err error) { + require.NotNil(t, in) + assert.Equal(t, hexutil.Encode(buildSamplePayload(report)), hexutil.Encode(in.Payload)) + out = new(pb.TransmitResponse) + out.Code = 42 + out.Error = "" + return out, nil + }, + } + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true)) + err := mt.Transmit(testutils.Context(t), sampleReportContext, report, sampleSigs) + + require.NoError(t, err) + }) +} + +func Test_MercuryTransmitter_LatestTimestamp(t *testing.T) { + t.Parallel() + lggr := logger.TestLogger(t) + db := pgtest.NewSqlxDB(t) + + t.Run("successful query", func(t *testing.T) { + c := mocks.MockWSRPCClient{ + LatestReportF: func(ctx context.Context, in *pb.LatestReportRequest) (out *pb.LatestReportResponse, err error) { + require.NotNil(t, in) + assert.Equal(t, hexutil.Encode(sampleFeedID[:]), hexutil.Encode(in.FeedId)) + out = new(pb.LatestReportResponse) + out.Report = new(pb.Report) + out.Report.FeedId = sampleFeedID[:] + out.Report.ObservationsTimestamp = 42 + return out, nil + }, + } + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true)) + ts, err := mt.LatestTimestamp(testutils.Context(t)) + require.NoError(t, err) + + assert.Equal(t, int64(42), ts) + }) + + t.Run("successful query returning nil report (new feed) gives latest timestamp = -1", func(t *testing.T) { + c := mocks.MockWSRPCClient{ + LatestReportF: func(ctx context.Context, in *pb.LatestReportRequest) (out *pb.LatestReportResponse, err error) { + out = new(pb.LatestReportResponse) + out.Report = nil + return out, nil + }, + } + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true)) + ts, err := mt.LatestTimestamp(testutils.Context(t)) + require.NoError(t, err) + + assert.Equal(t, int64(-1), ts) + }) + t.Run("failing query", func(t *testing.T) { + c := mocks.MockWSRPCClient{ + LatestReportF: func(ctx context.Context, in *pb.LatestReportRequest) (out *pb.LatestReportResponse, err error) { + return nil, errors.New("something exploded") + }, + } + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true)) + _, err := mt.LatestTimestamp(testutils.Context(t)) + require.Error(t, err) + assert.Contains(t, err.Error(), "something exploded") + }) +} + +func Test_MercuryTransmitter_LatestPrice(t *testing.T) { + t.Parallel() + lggr := logger.TestLogger(t) + db := pgtest.NewSqlxDB(t) + + t.Run("successful query", func(t *testing.T) { + originalPrice := big.NewInt(123456789) + encodedPrice, _ := relaymercury.EncodeValueInt192(originalPrice) + c := mocks.MockWSRPCClient{ + LatestReportF: func(ctx context.Context, in *pb.LatestReportRequest) (out *pb.LatestReportResponse, err error) { + require.NotNil(t, in) + assert.Equal(t, hexutil.Encode(sampleFeedID[:]), hexutil.Encode(in.FeedId)) + out = new(pb.LatestReportResponse) + out.Report = new(pb.Report) + out.Report.FeedId = sampleFeedID[:] + out.Report.Price = encodedPrice + return out, nil + }, + } + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true)) + price, err := mt.LatestPrice(testutils.Context(t), sampleFeedID) + require.NoError(t, err) + + assert.Equal(t, price, originalPrice) + }) + + t.Run("successful query returning nil report (new feed)", func(t *testing.T) { + c := mocks.MockWSRPCClient{ + LatestReportF: func(ctx context.Context, in *pb.LatestReportRequest) (out *pb.LatestReportResponse, err error) { + out = new(pb.LatestReportResponse) + out.Report = nil + return out, nil + }, + } + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true)) + price, err := mt.LatestPrice(testutils.Context(t), sampleFeedID) require.NoError(t, err) + + assert.Nil(t, price) + }) + + t.Run("failing query", func(t *testing.T) { + c := mocks.MockWSRPCClient{ + LatestReportF: func(ctx context.Context, in *pb.LatestReportRequest) (out *pb.LatestReportResponse, err error) { + return nil, errors.New("something exploded") + }, + } + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true)) + _, err := mt.LatestPrice(testutils.Context(t), sampleFeedID) + require.Error(t, err) + assert.Contains(t, err.Error(), "something exploded") }) } @@ -117,6 +247,6 @@ func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) { mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true)) _, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t)) require.Error(t, err) - assert.Contains(t, err.Error(), "FetchInitialMaxFinalizedBlockNumber failed; mismatched feed IDs, expected: 0x1c916b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472, got: 0x") + assert.Contains(t, err.Error(), "latestReport failed; mismatched feed IDs, expected: 0x1c916b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472, got: 0x") }) } diff --git a/core/services/relay/evm/mercury/types/types.go b/core/services/relay/evm/mercury/types/types.go new file mode 100644 index 00000000000..6affba58169 --- /dev/null +++ b/core/services/relay/evm/mercury/types/types.go @@ -0,0 +1,19 @@ +package types + +import ( + "context" + + evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" +) + +//go:generate mockery --quiet --name ChainHeadTracker --output ../mocks/ --case=underscore +type ChainHeadTracker interface { + Client() evmclient.Client + HeadTracker() httypes.HeadTracker +} + +type DataSourceORM interface { + LatestReport(ctx context.Context, feedID [32]byte, qopts ...pg.QOpt) (report []byte, err error) +} diff --git a/core/services/relay/evm/mercury/utils/feeds.go b/core/services/relay/evm/mercury/utils/feeds.go new file mode 100644 index 00000000000..d2fd2106e98 --- /dev/null +++ b/core/services/relay/evm/mercury/utils/feeds.go @@ -0,0 +1,35 @@ +package utils + +import ( + "encoding/binary" + + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +type FeedVersion uint16 + +const ( + _ FeedVersion = iota + REPORT_V1 + REPORT_V2 + REPORT_V3 + _ +) + +type FeedID [32]byte + +func (f FeedID) Hex() string { return (utils.Hash)(f).Hex() } + +func (f FeedID) String() string { return (utils.Hash)(f).String() } + +func (f *FeedID) UnmarshalText(input []byte) error { + return (*utils.Hash)(f).UnmarshalText(input) +} + +func (f FeedID) Version() FeedVersion { + return FeedVersion(binary.BigEndian.Uint16(f[:2])) +} + +func (f FeedID) IsV1() bool { return f.Version() == REPORT_V1 } +func (f FeedID) IsV2() bool { return f.Version() == REPORT_V2 } +func (f FeedID) IsV3() bool { return f.Version() == REPORT_V3 } diff --git a/core/services/relay/evm/mercury/utils/feeds_test.go b/core/services/relay/evm/mercury/utils/feeds_test.go new file mode 100644 index 00000000000..dddd125a602 --- /dev/null +++ b/core/services/relay/evm/mercury/utils/feeds_test.go @@ -0,0 +1,30 @@ +package utils + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +var ( + v1FeedId = (FeedID)([32]uint8{00, 01, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}) + v2FeedId = (FeedID)([32]uint8{00, 02, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}) + v3FeedId = (FeedID)([32]uint8{00, 03, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}) +) + +func Test_FeedID(t *testing.T) { + assert.Equal(t, REPORT_V1, v1FeedId.Version()) + assert.True(t, v1FeedId.IsV1()) + assert.False(t, v1FeedId.IsV2()) + assert.False(t, v1FeedId.IsV3()) + + assert.Equal(t, REPORT_V2, v2FeedId.Version()) + assert.False(t, v2FeedId.IsV1()) + assert.True(t, v2FeedId.IsV2()) + assert.False(t, v2FeedId.IsV3()) + + assert.Equal(t, REPORT_V3, v3FeedId.Version()) + assert.False(t, v3FeedId.IsV1()) + assert.False(t, v3FeedId.IsV2()) + assert.True(t, v3FeedId.IsV3()) +} diff --git a/core/services/relay/evm/mercury/data_source.go b/core/services/relay/evm/mercury/v1/data_source.go similarity index 86% rename from core/services/relay/evm/mercury/data_source.go rename to core/services/relay/evm/mercury/v1/data_source.go index 533cbca700e..ff7a2c0ab7f 100644 --- a/core/services/relay/evm/mercury/data_source.go +++ b/core/services/relay/evm/mercury/v1/data_source.go @@ -1,4 +1,4 @@ -package mercury +package mercury_v1 import ( "context" @@ -12,30 +12,26 @@ import ( ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" + relaymercuryv1 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v1" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/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" "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/pipeline" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v1/reportcodec" "github.com/smartcontractkit/chainlink/v2/core/utils" ) -//go:generate mockery --quiet --name ChainHeadTracker --output ./mocks/ --case=underscore -type ChainHeadTracker interface { - Client() evmclient.Client - HeadTracker() httypes.HeadTracker -} - type Runner interface { ExecuteRun(ctx context.Context, spec pipeline.Spec, vars pipeline.Vars, l logger.Logger) (run pipeline.Run, trrs pipeline.TaskRunResults, err error) } +// Fetcher fetcher data from Mercury server type Fetcher interface { - // FetchInitialMaxFinalizedBlockNumber should fetch the initial max - // finalized block number from the mercury server. + // FetchInitialMaxFinalizedBlockNumber should fetch the initial max finalized block number FetchInitialMaxFinalizedBlockNumber(context.Context) (*int64, error) } @@ -45,22 +41,25 @@ type datasource struct { spec pipeline.Spec lggr logger.Logger runResults chan<- pipeline.Run + orm types.DataSourceORM + codec reportcodec.ReportCodec + feedID [32]byte mu sync.RWMutex chEnhancedTelem chan<- ocrcommon.EnhancedTelemetryMercuryData - chainHeadTracker ChainHeadTracker + chainHeadTracker types.ChainHeadTracker fetcher Fetcher initialBlockNumber *int64 } -var _ relaymercury.DataSource = &datasource{} +var _ relaymercuryv1.DataSource = &datasource{} -func NewDataSource(pr pipeline.Runner, jb job.Job, spec pipeline.Spec, lggr logger.Logger, rr chan pipeline.Run, enhancedTelemChan chan ocrcommon.EnhancedTelemetryMercuryData, chainHeadTracker ChainHeadTracker, fetcher Fetcher, initialBlockNumber *int64) *datasource { - return &datasource{pr, jb, spec, lggr, rr, sync.RWMutex{}, enhancedTelemChan, chainHeadTracker, fetcher, initialBlockNumber} +func NewDataSource(orm types.DataSourceORM, pr pipeline.Runner, jb job.Job, spec pipeline.Spec, lggr logger.Logger, rr chan pipeline.Run, enhancedTelemChan chan ocrcommon.EnhancedTelemetryMercuryData, chainHeadTracker types.ChainHeadTracker, fetcher Fetcher, initialBlockNumber *int64, feedID [32]byte) *datasource { + return &datasource{pr, jb, spec, lggr, rr, orm, reportcodec.ReportCodec{}, feedID, sync.RWMutex{}, enhancedTelemChan, chainHeadTracker, fetcher, initialBlockNumber} } -func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestamp, fetchMaxFinalizedBlockNum bool) (obs relaymercury.Observation, err error) { +func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestamp, fetchMaxFinalizedBlockNum bool) (obs relaymercuryv1.Observation, err error) { // setCurrentBlock must come first, along with observationTimestamp, to // avoid front-running ds.setCurrentBlock(ctx, &obs) @@ -70,6 +69,15 @@ func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestam wg.Add(1) go func() { defer wg.Done() + latest, dbErr := ds.orm.LatestReport(ctx, ds.feedID) + if dbErr != nil { + obs.MaxFinalizedBlockNumber.Err = dbErr + return + } + if latest != nil { + obs.MaxFinalizedBlockNumber.Val, obs.MaxFinalizedBlockNumber.Err = ds.codec.CurrentBlockNumFromReport(latest) + return + } val, fetchErr := ds.fetcher.FetchInitialMaxFinalizedBlockNumber(ctx) if fetchErr != nil { obs.MaxFinalizedBlockNumber.Err = fetchErr @@ -247,7 +255,7 @@ func (ds *datasource) executeRun(ctx context.Context) (pipeline.Run, pipeline.Ta return run, trrs, err } -func (ds *datasource) setCurrentBlock(ctx context.Context, obs *relaymercury.Observation) { +func (ds *datasource) setCurrentBlock(ctx context.Context, obs *relaymercuryv1.Observation) { latestHead, err := ds.getCurrentBlock(ctx) if err != nil { obs.CurrentBlockNum.Err = err diff --git a/core/services/relay/evm/mercury/data_source_test.go b/core/services/relay/evm/mercury/v1/data_source_test.go similarity index 71% rename from core/services/relay/evm/mercury/data_source_test.go rename to core/services/relay/evm/mercury/v1/data_source_test.go index f30b9e629de..b518ee1818d 100644 --- a/core/services/relay/evm/mercury/data_source_test.go +++ b/core/services/relay/evm/mercury/v1/data_source_test.go @@ -1,4 +1,4 @@ -package mercury +package mercury_v1 import ( "context" @@ -16,6 +16,7 @@ import ( ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" + relaymercuryv1 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v1" commonmocks "github.com/smartcontractkit/chainlink/v2/common/mocks" "github.com/smartcontractkit/chainlink/v2/core/assets" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" @@ -23,14 +24,17 @@ import ( httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/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/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/types" + reportcodecv1 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v1/reportcodec" "github.com/smartcontractkit/chainlink/v2/core/utils" ) -var _ relaymercury.Fetcher = &mockFetcher{} +var _ relaymercury.MercuryServerFetcher = &mockFetcher{} type mockFetcher struct { num *int64 @@ -41,39 +45,15 @@ func (m *mockFetcher) FetchInitialMaxFinalizedBlockNumber(context.Context) (*int return m.num, m.err } -var _ Runner = &mockRunner{} - -type mockRunner struct { - trrs pipeline.TaskRunResults - err error -} - -func (m *mockRunner) ExecuteRun(ctx context.Context, spec pipeline.Spec, vars pipeline.Vars, l logger.Logger) (run pipeline.Run, trrs pipeline.TaskRunResults, err error) { - return pipeline.Run{ID: 42}, m.trrs, m.err +func (m *mockFetcher) LatestPrice(ctx context.Context, feedID [32]byte) (*big.Int, error) { + return nil, nil } -var _ pipeline.Task = &mockTask{} - -type mockTask struct { - result pipeline.Result -} - -func (m *mockTask) Type() pipeline.TaskType { return "MockTask" } -func (m *mockTask) ID() int { return 0 } -func (m *mockTask) DotID() string { return "" } -func (m *mockTask) Run(ctx context.Context, lggr logger.Logger, vars pipeline.Vars, inputs []pipeline.Result) (pipeline.Result, pipeline.RunInfo) { - return m.result, pipeline.RunInfo{} +func (m *mockFetcher) LatestTimestamp(context.Context) (int64, error) { + return 0, nil } -func (m *mockTask) Base() *pipeline.BaseTask { return nil } -func (m *mockTask) Outputs() []pipeline.Task { return nil } -func (m *mockTask) Inputs() []pipeline.TaskDependency { return nil } -func (m *mockTask) OutputIndex() int32 { return 0 } -func (m *mockTask) TaskTimeout() (time.Duration, bool) { return 0, false } -func (m *mockTask) TaskRetries() uint32 { return 0 } -func (m *mockTask) TaskMinBackoff() time.Duration { return 0 } -func (m *mockTask) TaskMaxBackoff() time.Duration { return 0 } -var _ ChainHeadTracker = &mockHeadTracker{} +var _ types.ChainHeadTracker = &mockHeadTracker{} type mockHeadTracker struct { c evmclient.Client @@ -83,8 +63,18 @@ type mockHeadTracker struct { func (m *mockHeadTracker) Client() evmclient.Client { return m.c } func (m *mockHeadTracker) HeadTracker() httypes.HeadTracker { return m.h } +type mockORM struct { + report []byte + err error +} + +func (m *mockORM) LatestReport(ctx context.Context, feedID [32]byte, qopts ...pg.QOpt) (report []byte, err error) { + return m.report, m.err +} + func TestMercury_Observe(t *testing.T) { - ds := &datasource{lggr: logger.TestLogger(t)} + orm := &mockORM{} + ds := &datasource{lggr: logger.TestLogger(t), orm: orm, codec: (reportcodecv1.ReportCodec{})} ctx := testutils.Context(t) repts := ocrtypes.ReportTimestamp{} @@ -92,25 +82,25 @@ func TestMercury_Observe(t *testing.T) { ds.fetcher = fetcher trrs := []pipeline.TaskRunResult{ - pipeline.TaskRunResult{ + { // benchmark price Result: pipeline.Result{Value: "122.345"}, - Task: &mockTask{}, + Task: &mercurymocks.MockTask{}, }, - pipeline.TaskRunResult{ + { // bid Result: pipeline.Result{Value: "121.993"}, - Task: &mockTask{}, + Task: &mercurymocks.MockTask{}, }, - pipeline.TaskRunResult{ + { // ask Result: pipeline.Result{Value: "123.111"}, - Task: &mockTask{}, + Task: &mercurymocks.MockTask{}, }, } - runner := &mockRunner{ - trrs: trrs, + runner := &mercurymocks.MockRunner{ + Trrs: trrs, } ds.pipelineRunner = runner @@ -118,7 +108,7 @@ func TestMercury_Observe(t *testing.T) { ds.spec = spec h := commonmocks.NewHeadTracker[*evmtypes.Head, common.Hash](t) - c := evmtest.NewEthClientMock(t) + c := evmclimocks.NewClient(t) ht := &mockHeadTracker{ c: c, h: h, @@ -133,62 +123,88 @@ func TestMercury_Observe(t *testing.T) { h.On("LatestChain").Return(head) t.Run("when fetchMaxFinalizedBlockNum=true", func(t *testing.T) { - t.Run("if FetchInitialMaxFinalizedBlockNumber returns error", func(t *testing.T) { - fetcher.err = errors.New("mock fetcher error") + t.Run("with latest report in database", func(t *testing.T) { + orm.report = buildSampleV1Report() + orm.err = nil obs, err := ds.Observe(ctx, repts, true) assert.NoError(t, err) - assert.EqualError(t, obs.MaxFinalizedBlockNumber.Err, "mock fetcher error") - assert.Zero(t, obs.MaxFinalizedBlockNumber.Val) + assert.NoError(t, obs.MaxFinalizedBlockNumber.Err) + assert.Equal(t, int64(143), obs.MaxFinalizedBlockNumber.Val) }) - t.Run("if FetchInitialMaxFinalizedBlockNumber succeeds", func(t *testing.T) { - fetcher.err = nil - var num int64 = 32 - fetcher.num = &num + t.Run("if querying latest report fails", func(t *testing.T) { + orm.report = nil + orm.err = errors.New("something exploded") obs, err := ds.Observe(ctx, repts, true) assert.NoError(t, err) - assert.NoError(t, obs.MaxFinalizedBlockNumber.Err) - assert.Equal(t, int64(32), obs.MaxFinalizedBlockNumber.Val) + assert.EqualError(t, obs.MaxFinalizedBlockNumber.Err, "something exploded") + assert.Zero(t, obs.MaxFinalizedBlockNumber.Val) }) - t.Run("if FetchInitialMaxFinalizedBlockNumber returns nil (new feed) and initialBlockNumber is set", func(t *testing.T) { - var initialBlockNumber int64 = 50 - ds.initialBlockNumber = &initialBlockNumber - fetcher.err = nil - fetcher.num = nil - obs, err := ds.Observe(ctx, repts, true) - assert.NoError(t, err) + orm.report = nil + orm.err = nil - assert.NoError(t, obs.MaxFinalizedBlockNumber.Err) - assert.Equal(t, int64(49), obs.MaxFinalizedBlockNumber.Val) - }) - t.Run("if FetchInitialMaxFinalizedBlockNumber returns nil (new feed) and initialBlockNumber is not set", func(t *testing.T) { - ds.initialBlockNumber = nil - t.Run("if current block num is valid", func(t *testing.T) { + t.Run("without latest report in database", func(t *testing.T) { + t.Run("if FetchInitialMaxFinalizedBlockNumber returns error", func(t *testing.T) { + fetcher.err = errors.New("mock fetcher error") + + obs, err := ds.Observe(ctx, repts, true) + assert.NoError(t, err) + + assert.EqualError(t, obs.MaxFinalizedBlockNumber.Err, "mock fetcher error") + assert.Zero(t, obs.MaxFinalizedBlockNumber.Val) + }) + t.Run("if FetchInitialMaxFinalizedBlockNumber succeeds", func(t *testing.T) { fetcher.err = nil - fetcher.num = nil + var num int64 = 32 + fetcher.num = &num obs, err := ds.Observe(ctx, repts, true) assert.NoError(t, err) assert.NoError(t, obs.MaxFinalizedBlockNumber.Err) - assert.Equal(t, head.Number-1, obs.MaxFinalizedBlockNumber.Val) + assert.Equal(t, int64(32), obs.MaxFinalizedBlockNumber.Val) }) - t.Run("if current block num errored", func(t *testing.T) { - h2 := commonmocks.NewHeadTracker[*evmtypes.Head, common.Hash](t) - h2.On("LatestChain").Return((*evmtypes.Head)(nil)) - ht.h = h2 - c2 := evmtest.NewEthClientMock(t) - c2.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(nil, errors.New("head retrieval failed")) - ht.c = c2 + t.Run("if FetchInitialMaxFinalizedBlockNumber returns nil (new feed) and initialBlockNumber is set", func(t *testing.T) { + var initialBlockNumber int64 = 50 + ds.initialBlockNumber = &initialBlockNumber + fetcher.err = nil + fetcher.num = nil obs, err := ds.Observe(ctx, repts, true) assert.NoError(t, err) - assert.EqualError(t, obs.MaxFinalizedBlockNumber.Err, "FetchInitialMaxFinalizedBlockNumber returned empty LatestReport; this is a new feed. No initialBlockNumber was set, tried to use current block number to determine maxFinalizedBlockNumber but got error: head retrieval failed") + assert.NoError(t, obs.MaxFinalizedBlockNumber.Err) + assert.Equal(t, int64(49), obs.MaxFinalizedBlockNumber.Val) + }) + t.Run("if FetchInitialMaxFinalizedBlockNumber returns nil (new feed) and initialBlockNumber is not set", func(t *testing.T) { + ds.initialBlockNumber = nil + t.Run("if current block num is valid", func(t *testing.T) { + fetcher.err = nil + fetcher.num = nil + + obs, err := ds.Observe(ctx, repts, true) + assert.NoError(t, err) + + assert.NoError(t, obs.MaxFinalizedBlockNumber.Err) + assert.Equal(t, head.Number-1, obs.MaxFinalizedBlockNumber.Val) + }) + t.Run("if current block num errored", func(t *testing.T) { + h2 := commonmocks.NewHeadTracker[*evmtypes.Head, common.Hash](t) + h2.On("LatestChain").Return((*evmtypes.Head)(nil)) + ht.h = h2 + c2 := evmclimocks.NewClient(t) + c2.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(nil, errors.New("head retrieval failed")) + ht.c = c2 + + obs, err := ds.Observe(ctx, repts, true) + assert.NoError(t, err) + + assert.EqualError(t, obs.MaxFinalizedBlockNumber.Err, "FetchInitialMaxFinalizedBlockNumber returned empty LatestReport; this is a new feed. No initialBlockNumber was set, tried to use current block number to determine maxFinalizedBlockNumber but got error: head retrieval failed") + }) }) }) }) @@ -199,9 +215,9 @@ func TestMercury_Observe(t *testing.T) { t.Run("when fetchMaxFinalizedBlockNum=false", func(t *testing.T) { t.Run("when run execution fails, returns error", func(t *testing.T) { t.Cleanup(func() { - runner.err = nil + runner.Err = nil }) - runner.err = errors.New("run execution failed") + runner.Err = errors.New("run execution failed") _, err := ds.Observe(ctx, repts, false) assert.EqualError(t, err, "Observe failed while executing run: error executing run for spec ID 0: run execution failed") @@ -317,7 +333,7 @@ func TestMercury_Observe(t *testing.T) { c.AssertExpectations(t) }) t.Run("if call fails, returns error for that observation", func(t *testing.T) { - c = evmtest.NewEthClientMock(t) + c = evmclimocks.NewClient(t) ht.c = c c.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(nil, errors.New("client call failed")).Once() @@ -363,7 +379,7 @@ func TestMercury_SetCurrentBlock(t *testing.T) { ds.chainHeadTracker = chainHeadTracker - obs := relaymercury.Observation{} + obs := relaymercuryv1.Observation{} ds.setCurrentBlock(context.Background(), &obs) assert.Equal(t, h.Number, obs.CurrentBlockNum.Val) @@ -387,7 +403,7 @@ func TestMercury_SetCurrentBlock(t *testing.T) { ds.chainHeadTracker = chainHeadTracker - obs := relaymercury.Observation{} + obs := relaymercuryv1.Observation{} ds.setCurrentBlock(context.Background(), &obs) assert.Equal(t, h.Number, obs.CurrentBlockNum.Val) @@ -413,7 +429,7 @@ func TestMercury_SetCurrentBlock(t *testing.T) { ds.chainHeadTracker = chainHeadTracker - obs := relaymercury.Observation{} + obs := relaymercuryv1.Observation{} ds.setCurrentBlock(context.Background(), &obs) assert.Equal(t, err, obs.CurrentBlockNum.Err) @@ -425,3 +441,23 @@ func TestMercury_SetCurrentBlock(t *testing.T) { headTracker.AssertExpectations(t) }) } + +var sampleFeedID = [32]uint8{28, 145, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114} + +func buildSampleV1Report() []byte { + feedID := sampleFeedID + timestamp := uint32(42) + bp := big.NewInt(242) + bid := big.NewInt(243) + ask := big.NewInt(244) + currentBlockNumber := uint64(143) + currentBlockHash := utils.NewHash() + currentBlockTimestamp := uint64(123) + validFromBlockNum := uint64(142) + + b, err := reportcodecv1.ReportTypes.Pack(feedID, timestamp, bp, bid, ask, currentBlockNumber, currentBlockHash, currentBlockTimestamp, validFromBlockNum) + if err != nil { + panic(err) + } + return b +} diff --git a/core/services/relay/evm/mercury/v1/reportcodec/report_codec.go b/core/services/relay/evm/mercury/v1/reportcodec/report_codec.go new file mode 100644 index 00000000000..a28186cce9c --- /dev/null +++ b/core/services/relay/evm/mercury/v1/reportcodec/report_codec.go @@ -0,0 +1,91 @@ +package reportcodec + +import ( + "errors" + "fmt" + "math" + + "github.com/ethereum/go-ethereum/common" + pkgerrors "github.com/pkg/errors" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + reportcodec "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v1" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" + reporttypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v1/types" +) + +// NOTE: +// This report codec is based on the original median evmreportcodec +// here: +// https://github.com/smartcontractkit/offchain-reporting/blob/master/lib/offchainreporting2/reportingplugin/median/evmreportcodec/reportcodec.go +var ReportTypes = reporttypes.GetSchema() +var maxReportLength = 32 * len(ReportTypes) // each arg is 256 bit EVM word + +var _ reportcodec.ReportCodec = &ReportCodec{} + +type ReportCodec struct { + logger logger.Logger + feedID utils.FeedID +} + +func NewReportCodec(feedID [32]byte, lggr logger.Logger) *ReportCodec { + return &ReportCodec{lggr, feedID} +} + +func (r *ReportCodec) BuildReport(rf reportcodec.ReportFields) (ocrtypes.Report, error) { + var merr error + if rf.BenchmarkPrice == nil { + merr = errors.Join(merr, errors.New("benchmarkPrice may not be nil")) + } + if rf.Bid == nil { + merr = errors.Join(merr, errors.New("bid may not be nil")) + } + if rf.Ask == nil { + merr = errors.Join(merr, errors.New("ask may not be nil")) + } + if len(rf.CurrentBlockHash) != 32 { + merr = errors.Join(merr, fmt.Errorf("invalid length for currentBlockHash, expected: 32, got: %d", len(rf.CurrentBlockHash))) + } + if merr != nil { + return nil, merr + } + var currentBlockHash common.Hash + copy(currentBlockHash[:], rf.CurrentBlockHash) + + reportBytes, err := ReportTypes.Pack(r.feedID, rf.Timestamp, rf.BenchmarkPrice, rf.Bid, rf.Ask, uint64(rf.CurrentBlockNum), currentBlockHash, uint64(rf.ValidFromBlockNum), rf.CurrentBlockTimestamp) + return ocrtypes.Report(reportBytes), pkgerrors.Wrap(err, "failed to pack report blob") +} + +// Maximum length in bytes of Report returned by BuildReport. Used for +// defending against spam attacks. +func (r *ReportCodec) MaxReportLength(n int) (int, error) { + return maxReportLength, nil +} + +func (r *ReportCodec) CurrentBlockNumFromReport(report ocrtypes.Report) (int64, error) { + decoded, err := r.Decode(report) + if err != nil { + return 0, err + } + if decoded.CurrentBlockNum > math.MaxInt64 { + return 0, fmt.Errorf("CurrentBlockNum=%d overflows max int64", decoded.CurrentBlockNum) + } + return int64(decoded.CurrentBlockNum), nil +} + +func (r *ReportCodec) ValidFromBlockNumFromReport(report ocrtypes.Report) (int64, error) { + decoded, err := r.Decode(report) + if err != nil { + return 0, err + } + if decoded.ValidFromBlockNum > math.MaxInt64 { + return 0, fmt.Errorf("ValidFromBlockNum=%d overflows max int64", decoded.ValidFromBlockNum) + } + return int64(decoded.ValidFromBlockNum), nil +} + +func (r *ReportCodec) Decode(report ocrtypes.Report) (*reporttypes.Report, error) { + return reporttypes.Decode(report) +} diff --git a/core/services/relay/evm/mercury/reportcodec/report_codec_test.go b/core/services/relay/evm/mercury/v1/reportcodec/report_codec_test.go similarity index 54% rename from core/services/relay/evm/mercury/reportcodec/report_codec_test.go rename to core/services/relay/evm/mercury/v1/reportcodec/report_codec_test.go index 757797807b9..6e6a58af4ca 100644 --- a/core/services/relay/evm/mercury/reportcodec/report_codec_test.go +++ b/core/services/relay/evm/mercury/v1/reportcodec/report_codec_test.go @@ -9,90 +9,45 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/libocr/commontypes" "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" + relaymercuryv1 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v1" "github.com/smartcontractkit/chainlink/v2/core/utils" ) var hash = hexutil.MustDecode("0x552c2cea3ab43bae137d89ee6142a01db3ae2b5678bc3c9bd5f509f537bea57b") -var paos = []relaymercury.ParsedAttributedObservation{ - { - Timestamp: uint32(42), - Observer: commontypes.OracleID(49), - - BenchmarkPrice: big.NewInt(43), - Bid: big.NewInt(44), - Ask: big.NewInt(45), - PricesValid: true, - - CurrentBlockNum: 48, - CurrentBlockHash: hash, - CurrentBlockTimestamp: uint64(123), - CurrentBlockValid: true, - }, - { - Timestamp: uint32(142), - Observer: commontypes.OracleID(149), - - BenchmarkPrice: big.NewInt(143), - Bid: big.NewInt(144), - Ask: big.NewInt(145), - PricesValid: true, - - CurrentBlockNum: 48, - CurrentBlockHash: hash, - CurrentBlockTimestamp: uint64(123), - CurrentBlockValid: true, - }, - { - Timestamp: uint32(242), - Observer: commontypes.OracleID(249), - - BenchmarkPrice: big.NewInt(243), - Bid: big.NewInt(244), - Ask: big.NewInt(245), - PricesValid: true, +func newValidReportFields() relaymercuryv1.ReportFields { + return relaymercuryv1.ReportFields{ + Timestamp: 242, + BenchmarkPrice: big.NewInt(243), + Bid: big.NewInt(244), + Ask: big.NewInt(245), CurrentBlockNum: 248, CurrentBlockHash: hash, - CurrentBlockTimestamp: uint64(789), - CurrentBlockValid: true, - }, - { - Timestamp: uint32(342), - Observer: commontypes.OracleID(250), - - BenchmarkPrice: big.NewInt(343), - Bid: big.NewInt(344), - Ask: big.NewInt(345), - PricesValid: true, - - CurrentBlockNum: 348, - CurrentBlockHash: hash, - CurrentBlockTimestamp: uint64(123456), - CurrentBlockValid: true, - }, + ValidFromBlockNum: 46, + CurrentBlockTimestamp: 123, + } } -func Test_ReportCodec_BuildReport(t *testing.T) { - r := EVMReportCodec{} +func Test_ReportCodec(t *testing.T) { + r := ReportCodec{} - f := 1 - - t.Run("BuildReport errors if observations are empty", func(t *testing.T) { - paos := []relaymercury.ParsedAttributedObservation{} - _, err := r.BuildReport(paos, f, 1) + t.Run("BuildReport errors on zero fields", func(t *testing.T) { + _, err := r.BuildReport(relaymercuryv1.ReportFields{}) require.Error(t, err) - assert.Contains(t, err.Error(), "cannot build report from empty attributed observation") + assert.Contains(t, err.Error(), "benchmarkPrice may not be nil") + assert.Contains(t, err.Error(), "bid may not be nil") + assert.Contains(t, err.Error(), "ask may not be nil") + assert.Contains(t, err.Error(), "invalid length for currentBlockHash, expected: 32, got: 0") }) t.Run("BuildReport constructs a report from observations", func(t *testing.T) { + rf := newValidReportFields() // only need to test happy path since validations are done in relaymercury - report, err := r.BuildReport(paos, f, 46) + report, err := r.BuildReport(rf) require.NoError(t, err) reportElems := make(map[string]interface{}) @@ -103,39 +58,73 @@ func Test_ReportCodec_BuildReport(t *testing.T) { assert.Equal(t, reportElems["benchmarkPrice"].(*big.Int).Int64(), int64(243)) assert.Equal(t, reportElems["bid"].(*big.Int).Int64(), int64(244)) assert.Equal(t, reportElems["ask"].(*big.Int).Int64(), int64(245)) - assert.Equal(t, reportElems["currentBlockNum"].(uint64), uint64(48)) + assert.Equal(t, reportElems["currentBlockNum"].(uint64), uint64(248)) assert.Equal(t, common.Hash(reportElems["currentBlockHash"].([32]byte)), common.BytesToHash(hash)) assert.Equal(t, reportElems["currentBlockTimestamp"].(uint64), uint64(123)) assert.Equal(t, reportElems["validFromBlockNum"].(uint64), uint64(46)) - assert.Equal(t, types.Report{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x55, 0x2c, 0x2c, 0xea, 0x3a, 0xb4, 0x3b, 0xae, 0x13, 0x7d, 0x89, 0xee, 0x61, 0x42, 0xa0, 0x1d, 0xb3, 0xae, 0x2b, 0x56, 0x78, 0xbc, 0x3c, 0x9b, 0xd5, 0xf5, 0x9, 0xf5, 0x37, 0xbe, 0xa5, 0x7b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7b}, report) + assert.Equal(t, types.Report{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf8, 0x55, 0x2c, 0x2c, 0xea, 0x3a, 0xb4, 0x3b, 0xae, 0x13, 0x7d, 0x89, 0xee, 0x61, 0x42, 0xa0, 0x1d, 0xb3, 0xae, 0x2b, 0x56, 0x78, 0xbc, 0x3c, 0x9b, 0xd5, 0xf5, 0x9, 0xf5, 0x37, 0xbe, 0xa5, 0x7b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7b}, report) + max, err := r.MaxReportLength(4) require.NoError(t, err) assert.LessOrEqual(t, len(report), max) + + t.Run("Decode decodes the report", func(t *testing.T) { + decoded, err := r.Decode(report) + require.NoError(t, err) + + require.NotNil(t, decoded) + + assert.Equal(t, uint32(242), decoded.ObservationsTimestamp) + assert.Equal(t, big.NewInt(243), decoded.BenchmarkPrice) + assert.Equal(t, big.NewInt(244), decoded.Bid) + assert.Equal(t, big.NewInt(245), decoded.Ask) + assert.Equal(t, uint64(248), decoded.CurrentBlockNum) + assert.Equal(t, [32]byte(common.BytesToHash(hash)), decoded.CurrentBlockHash) + assert.Equal(t, uint64(123), decoded.CurrentBlockTimestamp) + assert.Equal(t, uint64(46), decoded.ValidFromBlockNum) + }) }) -} -func Test_ReportCodec_MaxReportLength(t *testing.T) { - r := EVMReportCodec{} - n := len(paos) - report, err := r.BuildReport(paos, 1, 46) - require.NoError(t, err) + t.Run("Decode errors on invalid report", func(t *testing.T) { + _, err := r.Decode([]byte{1, 2, 3}) + assert.EqualError(t, err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32") - t.Run("MaxReportLength returns length of report", func(t *testing.T) { - max, err := r.MaxReportLength(n) - require.NoError(t, err) - assert.Equal(t, len(report), max) + longBad := make([]byte, 64) + for i := 0; i < len(longBad); i++ { + longBad[i] = byte(i) + } + _, err = r.Decode(longBad) + assert.EqualError(t, err, "failed to decode report: abi: improperly encoded uint32 value") }) } +func buildSampleReport(bn, validFromBn int64, feedID [32]byte) []byte { + timestamp := uint32(42) + bp := big.NewInt(242) + bid := big.NewInt(243) + ask := big.NewInt(244) + currentBlockNumber := uint64(bn) + currentBlockHash := utils.NewHash() + currentBlockTimestamp := uint64(123) + validFromBlockNum := uint64(validFromBn) + + b, err := ReportTypes.Pack(feedID, timestamp, bp, bid, ask, currentBlockNumber, currentBlockHash, validFromBlockNum, currentBlockTimestamp) + if err != nil { + panic(err) + } + return b +} + func Test_ReportCodec_CurrentBlockNumFromReport(t *testing.T) { - r := EVMReportCodec{} + r := ReportCodec{} + feedID := utils.NewHash() var validBn int64 = 42 var invalidBn int64 = -1 t.Run("CurrentBlockNumFromReport extracts the current block number from a valid report", func(t *testing.T) { - report := buildSampleReport(validBn) + report := buildSampleReport(validBn, 143, feedID) bn, err := r.CurrentBlockNumFromReport(report) require.NoError(t, err) @@ -143,29 +132,32 @@ func Test_ReportCodec_CurrentBlockNumFromReport(t *testing.T) { assert.Equal(t, validBn, bn) }) t.Run("CurrentBlockNumFromReport returns error if block num is too large", func(t *testing.T) { - report := buildSampleReport(invalidBn) + report := buildSampleReport(invalidBn, 143, feedID) _, err := r.CurrentBlockNumFromReport(report) require.Error(t, err) - assert.Contains(t, err.Error(), "blockNum overflows max int64, got: 18446744073709551615") + assert.Contains(t, err.Error(), "CurrentBlockNum=18446744073709551615 overflows max int64") }) } +func Test_ReportCodec_ValidFromBlockNumFromReport(t *testing.T) { + r := ReportCodec{} + feedID := utils.NewHash() -func buildSampleReport(bn int64) []byte { - feedID := [32]byte{'f', 'o', 'o'} - timestamp := uint32(42) - bp := big.NewInt(242) - bid := big.NewInt(243) - ask := big.NewInt(244) - currentBlockNumber := uint64(bn) - currentBlockHash := utils.NewHash() - currentBlockTimestamp := uint64(123) - validFromBlockNum := uint64(143) + t.Run("ValidFromBlockNumFromReport extracts the valid from block number from a valid report", func(t *testing.T) { + report := buildSampleReport(42, 999, feedID) - b, err := ReportTypes.Pack(feedID, timestamp, bp, bid, ask, currentBlockNumber, currentBlockHash, currentBlockTimestamp, validFromBlockNum) - if err != nil { - panic(err) - } - return b + bn, err := r.ValidFromBlockNumFromReport(report) + require.NoError(t, err) + + assert.Equal(t, int64(999), bn) + }) + t.Run("ValidFromBlockNumFromReport returns error if valid from block number is too large", func(t *testing.T) { + report := buildSampleReport(42, -1, feedID) + + _, err := r.ValidFromBlockNumFromReport(report) + require.Error(t, err) + + assert.Contains(t, err.Error(), "ValidFromBlockNum=18446744073709551615 overflows max int64") + }) } diff --git a/core/services/relay/evm/mercury/v1/types/types.go b/core/services/relay/evm/mercury/v1/types/types.go new file mode 100644 index 00000000000..709fd856a21 --- /dev/null +++ b/core/services/relay/evm/mercury/v1/types/types.go @@ -0,0 +1,56 @@ +package reporttypes + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" +) + +var schema = GetSchema() + +func GetSchema() abi.Arguments { + mustNewType := func(t string) abi.Type { + result, err := abi.NewType(t, "", []abi.ArgumentMarshaling{}) + if err != nil { + panic(fmt.Sprintf("Unexpected error during abi.NewType: %s", err)) + } + return result + } + return abi.Arguments([]abi.Argument{ + {Name: "feedId", Type: mustNewType("bytes32")}, + {Name: "observationsTimestamp", Type: mustNewType("uint32")}, + {Name: "benchmarkPrice", Type: mustNewType("int192")}, + {Name: "bid", Type: mustNewType("int192")}, + {Name: "ask", Type: mustNewType("int192")}, + {Name: "currentBlockNum", Type: mustNewType("uint64")}, + {Name: "currentBlockHash", Type: mustNewType("bytes32")}, + {Name: "validFromBlockNum", Type: mustNewType("uint64")}, + {Name: "currentBlockTimestamp", Type: mustNewType("uint64")}, + }) +} + +type Report struct { + FeedId [32]byte + ObservationsTimestamp uint32 + BenchmarkPrice *big.Int + Bid *big.Int + Ask *big.Int + CurrentBlockNum uint64 + CurrentBlockHash [32]byte + ValidFromBlockNum uint64 + CurrentBlockTimestamp uint64 +} + +// Decode is made available to external users (i.e. mercury server) +func Decode(report []byte) (*Report, error) { + values, err := schema.Unpack(report) + if err != nil { + return nil, fmt.Errorf("failed to decode report: %w", err) + } + decoded := new(Report) + if err = schema.Copy(decoded, values); err != nil { + return nil, fmt.Errorf("failed to copy report values to struct: %w", err) + } + return decoded, nil +} diff --git a/core/services/relay/evm/mercury/v2/data_source.go b/core/services/relay/evm/mercury/v2/data_source.go new file mode 100644 index 00000000000..bb9d72e35d9 --- /dev/null +++ b/core/services/relay/evm/mercury/v2/data_source.go @@ -0,0 +1,213 @@ +package mercury_v2 + +import ( + "context" + "fmt" + "math/big" + "sync" + + pkgerrors "github.com/pkg/errors" + + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" + relaymercuryv2 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v2" + + "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/pipeline" + mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +type Runner interface { + ExecuteRun(ctx context.Context, spec pipeline.Spec, vars pipeline.Vars, l logger.Logger) (run pipeline.Run, trrs pipeline.TaskRunResults, err error) +} + +type LatestReportFetcher interface { + LatestPrice(ctx context.Context, feedID [32]byte) (*big.Int, error) + LatestTimestamp(context.Context) (int64, error) +} + +type datasource struct { + pipelineRunner Runner + jb job.Job + spec pipeline.Spec + feedID mercuryutils.FeedID + lggr logger.Logger + runResults chan<- pipeline.Run + + fetcher LatestReportFetcher + linkFeedID mercuryutils.FeedID + nativeFeedID mercuryutils.FeedID + + mu sync.RWMutex + + chEnhancedTelem chan<- ocrcommon.EnhancedTelemetryMercuryData +} + +var _ relaymercuryv2.DataSource = &datasource{} + +func NewDataSource(pr pipeline.Runner, jb job.Job, spec pipeline.Spec, feedID mercuryutils.FeedID, lggr logger.Logger, rr chan pipeline.Run, enhancedTelemChan chan ocrcommon.EnhancedTelemetryMercuryData, fetcher LatestReportFetcher, linkFeedID, nativeFeedID mercuryutils.FeedID) *datasource { + return &datasource{pr, jb, spec, feedID, lggr, rr, fetcher, linkFeedID, nativeFeedID, sync.RWMutex{}, enhancedTelemChan} +} + +func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestamp, fetchMaxFinalizedTimestamp bool) (obs relaymercuryv2.Observation, err error) { + var wg sync.WaitGroup + ctx, cancel := context.WithCancel(ctx) + + if fetchMaxFinalizedTimestamp { + wg.Add(1) + go func() { + defer wg.Done() + obs.MaxFinalizedTimestamp.Val, obs.MaxFinalizedTimestamp.Err = ds.fetcher.LatestTimestamp(ctx) + }() + } + + wg.Add(1) + go func() { + defer wg.Done() + var trrs pipeline.TaskRunResults + var run pipeline.Run + run, trrs, err = ds.executeRun(ctx) + if err != nil { + cancel() + err = fmt.Errorf("Observe failed while executing run: %w", err) + return + } + select { + case ds.runResults <- run: + default: + ds.lggr.Warnf("unable to enqueue run save for job ID %d, buffer full", ds.spec.JobID) + } + + var parsed parseOutput + parsed, err = ds.parse(trrs) + if err != nil { + cancel() + // This is not expected under normal circumstances + ds.lggr.Errorw("Observe failed while parsing run results", "err", err) + err = fmt.Errorf("Observe failed while parsing run results: %w", err) + return + } + obs.BenchmarkPrice = parsed.benchmarkPrice + }() + + var isLink, isNative bool + if ds.feedID == ds.linkFeedID { + isLink = true + } else { + wg.Add(1) + go func() { + defer wg.Done() + obs.LinkPrice.Val, obs.LinkPrice.Err = ds.fetcher.LatestPrice(ctx, ds.linkFeedID) + if obs.LinkPrice.Val == nil && obs.LinkPrice.Err == nil { + ds.lggr.Warnw("Mercury server was missing LINK feed, falling back to max int192", "linkFeedID", ds.linkFeedID) + obs.LinkPrice.Val = relaymercury.MaxInt192 + } + }() + } + + if ds.feedID == ds.nativeFeedID { + isNative = true + } else { + wg.Add(1) + go func() { + defer wg.Done() + obs.NativePrice.Val, obs.NativePrice.Err = ds.fetcher.LatestPrice(ctx, ds.nativeFeedID) + if obs.NativePrice.Val == nil && obs.NativePrice.Err == nil { + ds.lggr.Warnw("Mercury server was missing native feed, falling back to max int192", "nativeFeedID", ds.nativeFeedID) + obs.NativePrice.Val = relaymercury.MaxInt192 + } + }() + } + + wg.Wait() + cancel() + + if isLink || isNative { + // run has now completed so it is safe to use err or benchmark price + if err != nil { + return + } + if isLink { + // This IS the LINK feed, use our observed price + obs.LinkPrice.Val, obs.LinkPrice.Err = obs.BenchmarkPrice.Val, obs.BenchmarkPrice.Err + } + if isNative { + // This IS the native feed, use our observed price + obs.NativePrice.Val, obs.NativePrice.Err = obs.BenchmarkPrice.Val, obs.BenchmarkPrice.Err + } + } + + // todo: implement telemetry - https://smartcontract-it.atlassian.net/browse/MERC-1388 + // if ocrcommon.ShouldCollectEnhancedTelemetryMercury(&ds.jb) { + // ocrcommon.EnqueueEnhancedTelem(ds.chEnhancedTelem, ocrcommon.EnhancedTelemetryMercuryData{ + // TaskRunResults: trrs, + // Observation: obs, + // RepTimestamp: repts, + // }) + // } + + return obs, err +} + +func toBigInt(val interface{}) (*big.Int, error) { + dec, err := utils.ToDecimal(val) + if err != nil { + return nil, err + } + return dec.BigInt(), nil +} + +type parseOutput struct { + benchmarkPrice relaymercury.ObsResult[*big.Int] +} + +func (ds *datasource) parse(trrs pipeline.TaskRunResults) (o parseOutput, merr error) { + var finaltrrs []pipeline.TaskRunResult + for _, trr := range trrs { + // only return terminal trrs from executeRun + if trr.IsTerminal() { + finaltrrs = append(finaltrrs, trr) + } + } + + if len(finaltrrs) != 1 { + return o, fmt.Errorf("invalid number of results, expected: 1, got: %d", len(finaltrrs)) + } + + return o, setBenchmarkPrice(&o, finaltrrs[0].Result) +} + +func setBenchmarkPrice(o *parseOutput, res pipeline.Result) error { + if res.Error != nil { + o.benchmarkPrice.Err = res.Error + return res.Error + } else if val, err := toBigInt(res.Value); err != nil { + return fmt.Errorf("failed to parse BenchmarkPrice: %w", err) + } else { + o.benchmarkPrice.Val = val + } + return nil +} + +// The context passed in here has a timeout of (ObservationTimeout + ObservationGracePeriod). +// Upon context cancellation, its expected that we return any usable values within ObservationGracePeriod. +func (ds *datasource) executeRun(ctx context.Context) (pipeline.Run, pipeline.TaskRunResults, error) { + vars := pipeline.NewVarsFrom(map[string]interface{}{ + "jb": map[string]interface{}{ + "databaseID": ds.jb.ID, + "externalJobID": ds.jb.ExternalJobID, + "name": ds.jb.Name.ValueOrZero(), + }, + }) + + run, trrs, err := ds.pipelineRunner.ExecuteRun(ctx, ds.spec, vars, ds.lggr) + if err != nil { + return pipeline.Run{}, nil, pkgerrors.Wrapf(err, "error executing run for spec ID %v", ds.spec.ID) + } + + return run, trrs, err +} diff --git a/core/services/relay/evm/mercury/v2/data_source_test.go b/core/services/relay/evm/mercury/v2/data_source_test.go new file mode 100644 index 00000000000..0d5d7b5895f --- /dev/null +++ b/core/services/relay/evm/mercury/v2/data_source_test.go @@ -0,0 +1,231 @@ +package mercury_v2 + +import ( + "context" + "math/big" + "testing" + + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + + relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" + + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "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" +) + +var _ relaymercury.MercuryServerFetcher = &mockFetcher{} + +type mockFetcher struct { + ts int64 + tsErr error + linkPrice *big.Int + linkPriceErr error + nativePrice *big.Int + nativePriceErr error +} + +var feedId utils.FeedID = [32]byte{1} +var linkFeedId utils.FeedID = [32]byte{2} +var nativeFeedId utils.FeedID = [32]byte{3} + +func (m *mockFetcher) FetchInitialMaxFinalizedBlockNumber(context.Context) (*int64, error) { + return nil, nil +} + +func (m *mockFetcher) LatestPrice(ctx context.Context, fId [32]byte) (*big.Int, error) { + if fId == linkFeedId { + return m.linkPrice, m.linkPriceErr + } else if fId == nativeFeedId { + return m.nativePrice, m.nativePriceErr + } + return nil, nil +} + +func (m *mockFetcher) LatestTimestamp(context.Context) (int64, error) { + return m.ts, m.tsErr +} + +func Test_Datasource(t *testing.T) { + ds := &datasource{lggr: logger.TestLogger(t)} + ctx := testutils.Context(t) + repts := ocrtypes.ReportTimestamp{} + + fetcher := &mockFetcher{} + ds.fetcher = fetcher + + goodTrrs := []pipeline.TaskRunResult{ + { + // bp + Result: pipeline.Result{Value: "122.345"}, + Task: &mercurymocks.MockTask{}, + }, + } + + ds.pipelineRunner = &mercurymocks.MockRunner{ + Trrs: goodTrrs, + } + + spec := pipeline.Spec{} + ds.spec = spec + + t.Run("when fetchMaxFinalizedTimestamp=true", func(t *testing.T) { + t.Run("if LatestTimestamp returns error", func(t *testing.T) { + fetcher.tsErr = errors.New("some error") + + obs, err := ds.Observe(ctx, repts, true) + assert.NoError(t, err) + + assert.EqualError(t, obs.MaxFinalizedTimestamp.Err, "some error") + assert.Zero(t, obs.MaxFinalizedTimestamp.Val) + }) + + t.Run("if LatestTimestamp succeeds", func(t *testing.T) { + fetcher.tsErr = nil + fetcher.ts = 123 + + obs, err := ds.Observe(ctx, repts, true) + assert.NoError(t, err) + + assert.Equal(t, int64(123), obs.MaxFinalizedTimestamp.Val) + assert.NoError(t, obs.MaxFinalizedTimestamp.Err) + }) + + t.Run("if LatestTimestamp succeeds but ts=0 (new feed)", func(t *testing.T) { + fetcher.tsErr = nil + fetcher.ts = 0 + + obs, err := ds.Observe(ctx, repts, true) + assert.NoError(t, err) + + assert.NoError(t, obs.MaxFinalizedTimestamp.Err) + assert.Zero(t, obs.MaxFinalizedTimestamp.Val) + }) + + t.Run("when run execution succeeded", func(t *testing.T) { + t.Run("when feedId=linkFeedID=nativeFeedId", func(t *testing.T) { + t.Cleanup(func() { + ds.feedID, ds.linkFeedID, ds.nativeFeedID = feedId, linkFeedId, nativeFeedId + }) + + ds.feedID, ds.linkFeedID, ds.nativeFeedID = feedId, feedId, feedId + + fetcher.ts = 123123 + fetcher.tsErr = nil + + obs, err := ds.Observe(ctx, repts, true) + assert.NoError(t, err) + + assert.Equal(t, big.NewInt(122), obs.BenchmarkPrice.Val) + assert.NoError(t, obs.BenchmarkPrice.Err) + assert.Equal(t, int64(123123), obs.MaxFinalizedTimestamp.Val) + assert.NoError(t, obs.MaxFinalizedTimestamp.Err) + assert.Equal(t, big.NewInt(122), obs.LinkPrice.Val) + assert.NoError(t, obs.LinkPrice.Err) + assert.Equal(t, big.NewInt(122), obs.NativePrice.Val) + assert.NoError(t, obs.NativePrice.Err) + }) + }) + }) + + t.Run("when fetchMaxFinalizedTimestamp=false", func(t *testing.T) { + t.Run("when run execution fails, returns error", func(t *testing.T) { + t.Cleanup(func() { + ds.pipelineRunner = &mercurymocks.MockRunner{ + Trrs: goodTrrs, + Err: nil, + } + }) + + ds.pipelineRunner = &mercurymocks.MockRunner{ + Trrs: goodTrrs, + Err: errors.New("run execution failed"), + } + + _, err := ds.Observe(ctx, repts, false) + assert.EqualError(t, err, "Observe failed while executing run: error executing run for spec ID 0: run execution failed") + }) + + t.Run("when parsing run results fails, return error", func(t *testing.T) { + t.Cleanup(func() { + runner := &mercurymocks.MockRunner{ + Trrs: goodTrrs, + Err: nil, + } + ds.pipelineRunner = runner + }) + + badTrrs := []pipeline.TaskRunResult{ + { + // benchmark price + Result: pipeline.Result{Error: errors.New("some error with bp")}, + Task: &mercurymocks.MockTask{}, + }, + } + + ds.pipelineRunner = &mercurymocks.MockRunner{ + Trrs: badTrrs, + Err: nil, + } + + _, err := ds.Observe(ctx, repts, false) + assert.EqualError(t, err, "Observe failed while parsing run results: some error with bp") + }) + + t.Run("when run execution succeeded", func(t *testing.T) { + t.Run("when feedId=linkFeedID=nativeFeedId", func(t *testing.T) { + t.Cleanup(func() { + ds.feedID, ds.linkFeedID, ds.nativeFeedID = feedId, linkFeedId, nativeFeedId + }) + + var feedId utils.FeedID = [32]byte{1} + ds.feedID, ds.linkFeedID, ds.nativeFeedID = feedId, feedId, feedId + + obs, err := ds.Observe(ctx, repts, false) + assert.NoError(t, err) + + assert.Equal(t, big.NewInt(122), obs.BenchmarkPrice.Val) + assert.NoError(t, obs.BenchmarkPrice.Err) + assert.Equal(t, int64(0), obs.MaxFinalizedTimestamp.Val) + assert.NoError(t, obs.MaxFinalizedTimestamp.Err) + assert.Equal(t, big.NewInt(122), obs.LinkPrice.Val) + assert.NoError(t, obs.LinkPrice.Err) + assert.Equal(t, big.NewInt(122), obs.NativePrice.Val) + assert.NoError(t, obs.NativePrice.Err) + }) + + t.Run("when fails to fetch linkPrice or nativePrice", func(t *testing.T) { + t.Cleanup(func() { + fetcher.linkPriceErr = nil + fetcher.nativePriceErr = nil + }) + + fetcher.linkPriceErr = errors.New("some error fetching link price") + fetcher.nativePriceErr = errors.New("some error fetching native price") + + obs, err := ds.Observe(ctx, repts, false) + assert.NoError(t, err) + + assert.Nil(t, obs.LinkPrice.Val) + assert.EqualError(t, obs.LinkPrice.Err, "some error fetching link price") + assert.Nil(t, obs.NativePrice.Val) + assert.EqualError(t, obs.NativePrice.Err, "some error fetching native price") + }) + + t.Run("when succeeds to fetch linkPrice or nativePrice but got nil (new feed)", func(t *testing.T) { + obs, err := ds.Observe(ctx, repts, false) + assert.NoError(t, err) + + assert.Equal(t, obs.LinkPrice.Val, relaymercury.MaxInt192) + assert.Nil(t, obs.LinkPrice.Err) + assert.Equal(t, obs.NativePrice.Val, relaymercury.MaxInt192) + assert.Nil(t, obs.NativePrice.Err) + }) + }) + }) +} diff --git a/core/services/relay/evm/mercury/v2/reportcodec/report_codec.go b/core/services/relay/evm/mercury/v2/reportcodec/report_codec.go new file mode 100644 index 00000000000..60dde81f1cb --- /dev/null +++ b/core/services/relay/evm/mercury/v2/reportcodec/report_codec.go @@ -0,0 +1,69 @@ +package reportcodec + +import ( + "errors" + "fmt" + "math/big" + + pkgerrors "github.com/pkg/errors" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + reportcodec "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v2" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" + reporttypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v2/types" +) + +var ReportTypes = reporttypes.GetSchema() +var maxReportLength = 32 * len(ReportTypes) // each arg is 256 bit EVM word +var zero = big.NewInt(0) + +var _ reportcodec.ReportCodec = &ReportCodec{} + +type ReportCodec struct { + logger logger.Logger + feedID utils.FeedID +} + +func NewReportCodec(feedID [32]byte, lggr logger.Logger) *ReportCodec { + return &ReportCodec{lggr, feedID} +} + +func (r *ReportCodec) BuildReport(rf reportcodec.ReportFields) (ocrtypes.Report, error) { + var merr error + if rf.BenchmarkPrice == nil { + merr = errors.Join(merr, errors.New("benchmarkPrice may not be nil")) + } + if rf.LinkFee == nil { + merr = errors.Join(merr, errors.New("linkFee may not be nil")) + } else if rf.LinkFee.Cmp(zero) < 0 { + merr = errors.Join(merr, fmt.Errorf("linkFee may not be negative (got: %s)", rf.LinkFee)) + } + if rf.NativeFee == nil { + merr = errors.Join(merr, errors.New("nativeFee may not be nil")) + } else if rf.NativeFee.Cmp(zero) < 0 { + merr = errors.Join(merr, fmt.Errorf("nativeFee may not be negative (got: %s)", rf.NativeFee)) + } + if merr != nil { + return nil, merr + } + reportBytes, err := ReportTypes.Pack(r.feedID, rf.ValidFromTimestamp, rf.Timestamp, rf.NativeFee, rf.LinkFee, rf.ExpiresAt, rf.BenchmarkPrice) + return ocrtypes.Report(reportBytes), pkgerrors.Wrap(err, "failed to pack report blob") +} + +func (r *ReportCodec) MaxReportLength(n int) (int, error) { + return maxReportLength, nil +} + +func (r *ReportCodec) ObservationTimestampFromReport(report ocrtypes.Report) (uint32, error) { + decoded, err := r.Decode(report) + if err != nil { + return 0, err + } + return decoded.ObservationsTimestamp, nil +} + +func (r *ReportCodec) Decode(report ocrtypes.Report) (*reporttypes.Report, error) { + return reporttypes.Decode(report) +} diff --git a/core/services/relay/evm/mercury/v2/reportcodec/report_codec_test.go b/core/services/relay/evm/mercury/v2/reportcodec/report_codec_test.go new file mode 100644 index 00000000000..c0c931dfe3a --- /dev/null +++ b/core/services/relay/evm/mercury/v2/reportcodec/report_codec_test.go @@ -0,0 +1,134 @@ +package reportcodec + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + relaymercuryv2 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v2" +) + +func newValidReportFields() relaymercuryv2.ReportFields { + return relaymercuryv2.ReportFields{ + Timestamp: 242, + BenchmarkPrice: big.NewInt(243), + ValidFromTimestamp: 123, + ExpiresAt: 20, + LinkFee: big.NewInt(456), + NativeFee: big.NewInt(457), + } +} + +func Test_ReportCodec_BuildReport(t *testing.T) { + r := ReportCodec{} + + t.Run("BuildReport errors on zero values", func(t *testing.T) { + _, err := r.BuildReport(relaymercuryv2.ReportFields{}) + require.Error(t, err) + assert.Contains(t, err.Error(), "benchmarkPrice may not be nil") + assert.Contains(t, err.Error(), "linkFee may not be nil") + assert.Contains(t, err.Error(), "nativeFee may not be nil") + }) + + t.Run("BuildReport constructs a report from observations", func(t *testing.T) { + rf := newValidReportFields() + // only need to test happy path since validations are done in relaymercury + + report, err := r.BuildReport(rf) + require.NoError(t, err) + + reportElems := make(map[string]interface{}) + err = ReportTypes.UnpackIntoMap(reportElems, report) + require.NoError(t, err) + + assert.Equal(t, int(reportElems["observationsTimestamp"].(uint32)), 242) + assert.Equal(t, reportElems["benchmarkPrice"].(*big.Int).Int64(), int64(243)) + assert.Equal(t, reportElems["validFromTimestamp"].(uint32), uint32(123)) + assert.Equal(t, reportElems["expiresAt"].(uint32), uint32(20)) + assert.Equal(t, reportElems["linkFee"].(*big.Int).Int64(), int64(456)) + assert.Equal(t, reportElems["nativeFee"].(*big.Int).Int64(), int64(457)) + + assert.Equal(t, types.Report{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xc9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf3}, report) + max, err := r.MaxReportLength(4) + require.NoError(t, err) + assert.LessOrEqual(t, len(report), max) + + t.Run("Decode decodes the report", func(t *testing.T) { + decoded, err := r.Decode(report) + require.NoError(t, err) + + require.NotNil(t, decoded) + + assert.Equal(t, uint32(242), decoded.ObservationsTimestamp) + assert.Equal(t, big.NewInt(243), decoded.BenchmarkPrice) + assert.Equal(t, uint32(123), decoded.ValidFromTimestamp) + assert.Equal(t, uint32(20), decoded.ExpiresAt) + assert.Equal(t, big.NewInt(456), decoded.LinkFee) + assert.Equal(t, big.NewInt(457), decoded.NativeFee) + }) + }) + + t.Run("errors on negative fee", func(t *testing.T) { + rf := newValidReportFields() + rf.LinkFee = big.NewInt(-1) + rf.NativeFee = big.NewInt(-1) + _, err := r.BuildReport(rf) + require.Error(t, err) + + assert.Contains(t, err.Error(), "linkFee may not be negative (got: -1)") + assert.Contains(t, err.Error(), "nativeFee may not be negative (got: -1)") + }) + + t.Run("Decode errors on invalid report", func(t *testing.T) { + _, err := r.Decode([]byte{1, 2, 3}) + assert.EqualError(t, err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32") + + longBad := make([]byte, 64) + for i := 0; i < len(longBad); i++ { + longBad[i] = byte(i) + } + _, err = r.Decode(longBad) + assert.EqualError(t, err, "failed to decode report: abi: improperly encoded uint32 value") + }) +} + +func buildSampleReport(ts int64) []byte { + feedID := [32]byte{'f', 'o', 'o'} + timestamp := uint32(ts) + bp := big.NewInt(242) + validFromTimestamp := uint32(123) + expiresAt := uint32(456) + linkFee := big.NewInt(3334455) + nativeFee := big.NewInt(556677) + + b, err := ReportTypes.Pack(feedID, validFromTimestamp, timestamp, nativeFee, linkFee, expiresAt, bp) + if err != nil { + panic(err) + } + return b +} + +func Test_ReportCodec_ObservationTimestampFromReport(t *testing.T) { + r := ReportCodec{} + + t.Run("ObservationTimestampFromReport extracts observation timestamp from a valid report", func(t *testing.T) { + report := buildSampleReport(123) + + ts, err := r.ObservationTimestampFromReport(report) + require.NoError(t, err) + + assert.Equal(t, ts, uint32(123)) + }) + t.Run("ObservationTimestampFromReport returns error when report is invalid", func(t *testing.T) { + report := []byte{1, 2, 3} + + _, err := r.ObservationTimestampFromReport(report) + require.Error(t, err) + + assert.EqualError(t, err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32") + }) +} diff --git a/core/services/relay/evm/mercury/v2/types/types.go b/core/services/relay/evm/mercury/v2/types/types.go new file mode 100644 index 00000000000..b09ee66f093 --- /dev/null +++ b/core/services/relay/evm/mercury/v2/types/types.go @@ -0,0 +1,52 @@ +package reporttypes + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" +) + +var schema = GetSchema() + +func GetSchema() abi.Arguments { + mustNewType := func(t string) abi.Type { + result, err := abi.NewType(t, "", []abi.ArgumentMarshaling{}) + if err != nil { + panic(fmt.Sprintf("Unexpected error during abi.NewType: %s", err)) + } + return result + } + return abi.Arguments([]abi.Argument{ + {Name: "feedId", Type: mustNewType("bytes32")}, + {Name: "validFromTimestamp", Type: mustNewType("uint32")}, + {Name: "observationsTimestamp", Type: mustNewType("uint32")}, + {Name: "nativeFee", Type: mustNewType("int192")}, + {Name: "linkFee", Type: mustNewType("int192")}, + {Name: "expiresAt", Type: mustNewType("uint32")}, + {Name: "benchmarkPrice", Type: mustNewType("int192")}, + }) +} + +type Report struct { + FeedId [32]byte + ObservationsTimestamp uint32 + BenchmarkPrice *big.Int + ValidFromTimestamp uint32 + ExpiresAt uint32 + LinkFee *big.Int + NativeFee *big.Int +} + +// Decode is made available to external users (i.e. mercury server) +func Decode(report []byte) (*Report, error) { + values, err := schema.Unpack(report) + if err != nil { + return nil, fmt.Errorf("failed to decode report: %w", err) + } + decoded := new(Report) + if err = schema.Copy(decoded, values); err != nil { + return nil, fmt.Errorf("failed to copy report values to struct: %w", err) + } + return decoded, nil +} diff --git a/core/services/relay/evm/mercury/v3/data_source.go b/core/services/relay/evm/mercury/v3/data_source.go new file mode 100644 index 00000000000..46dcf1fecdb --- /dev/null +++ b/core/services/relay/evm/mercury/v3/data_source.go @@ -0,0 +1,251 @@ +package mercury_v3 + +import ( + "context" + "errors" + "fmt" + "math/big" + "sync" + + pkgerrors "github.com/pkg/errors" + + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" + relaymercuryv3 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v3" + + "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/pipeline" + mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +type Runner interface { + ExecuteRun(ctx context.Context, spec pipeline.Spec, vars pipeline.Vars, l logger.Logger) (run pipeline.Run, trrs pipeline.TaskRunResults, err error) +} + +type LatestReportFetcher interface { + LatestPrice(ctx context.Context, feedID [32]byte) (*big.Int, error) + LatestTimestamp(context.Context) (int64, error) +} + +type datasource struct { + pipelineRunner Runner + jb job.Job + spec pipeline.Spec + feedID mercuryutils.FeedID + lggr logger.Logger + runResults chan<- pipeline.Run + + fetcher LatestReportFetcher + linkFeedID mercuryutils.FeedID + nativeFeedID mercuryutils.FeedID + + mu sync.RWMutex + + chEnhancedTelem chan<- ocrcommon.EnhancedTelemetryMercuryData +} + +var _ relaymercuryv3.DataSource = &datasource{} + +func NewDataSource(pr pipeline.Runner, jb job.Job, spec pipeline.Spec, feedID mercuryutils.FeedID, lggr logger.Logger, rr chan pipeline.Run, enhancedTelemChan chan ocrcommon.EnhancedTelemetryMercuryData, fetcher LatestReportFetcher, linkFeedID, nativeFeedID mercuryutils.FeedID) *datasource { + return &datasource{pr, jb, spec, feedID, lggr, rr, fetcher, linkFeedID, nativeFeedID, sync.RWMutex{}, enhancedTelemChan} +} + +func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestamp, fetchMaxFinalizedTimestamp bool) (obs relaymercuryv3.Observation, err error) { + var wg sync.WaitGroup + ctx, cancel := context.WithCancel(ctx) + + if fetchMaxFinalizedTimestamp { + wg.Add(1) + go func() { + defer wg.Done() + obs.MaxFinalizedTimestamp.Val, obs.MaxFinalizedTimestamp.Err = ds.fetcher.LatestTimestamp(ctx) + }() + } + + wg.Add(1) + go func() { + defer wg.Done() + var trrs pipeline.TaskRunResults + var run pipeline.Run + run, trrs, err = ds.executeRun(ctx) + if err != nil { + cancel() + err = fmt.Errorf("Observe failed while executing run: %w", err) + return + } + select { + case ds.runResults <- run: + default: + ds.lggr.Warnf("unable to enqueue run save for job ID %d, buffer full", ds.spec.JobID) + } + + var parsed parseOutput + parsed, err = ds.parse(trrs) + if err != nil { + cancel() + // This is not expected under normal circumstances + ds.lggr.Errorw("Observe failed while parsing run results", "err", err) + err = fmt.Errorf("Observe failed while parsing run results: %w", err) + return + } + obs.BenchmarkPrice = parsed.benchmarkPrice + obs.Bid = parsed.bid + obs.Ask = parsed.ask + }() + + var isLink, isNative bool + if ds.feedID == ds.linkFeedID { + isLink = true + } else { + wg.Add(1) + go func() { + defer wg.Done() + obs.LinkPrice.Val, obs.LinkPrice.Err = ds.fetcher.LatestPrice(ctx, ds.linkFeedID) + if obs.LinkPrice.Val == nil && obs.LinkPrice.Err == nil { + ds.lggr.Warnw("Mercury server was missing LINK feed, falling back to max int192", "linkFeedID", ds.linkFeedID) + obs.LinkPrice.Val = relaymercury.MaxInt192 + } + }() + } + + if ds.feedID == ds.nativeFeedID { + isNative = true + } else { + wg.Add(1) + go func() { + defer wg.Done() + obs.NativePrice.Val, obs.NativePrice.Err = ds.fetcher.LatestPrice(ctx, ds.nativeFeedID) + if obs.NativePrice.Val == nil && obs.NativePrice.Err == nil { + ds.lggr.Warnw("Mercury server was missing native feed, falling back to max int192", "nativeFeedID", ds.nativeFeedID) + obs.NativePrice.Val = relaymercury.MaxInt192 + } + }() + } + + wg.Wait() + cancel() + + if isLink || isNative { + // run has now completed so it is safe to use err or benchmark price + if err != nil { + return + } + if isLink { + // This IS the LINK feed, use our observed price + obs.LinkPrice.Val, obs.LinkPrice.Err = obs.BenchmarkPrice.Val, obs.BenchmarkPrice.Err + } + if isNative { + // This IS the native feed, use our observed price + obs.NativePrice.Val, obs.NativePrice.Err = obs.BenchmarkPrice.Val, obs.BenchmarkPrice.Err + } + } + + // todo: implement telemetry https://smartcontract-it.atlassian.net/browse/MERC-1388 + // if ocrcommon.ShouldCollectEnhancedTelemetryMercury(&ds.jb) { + // ocrcommon.EnqueueEnhancedTelem(ds.chEnhancedTelem, ocrcommon.EnhancedTelemetryMercuryData{ + // TaskRunResults: trrs, + // Observation: obs, + // RepTimestamp: repts, + // }) + // } + + cancel() + return obs, err +} + +func toBigInt(val interface{}) (*big.Int, error) { + dec, err := utils.ToDecimal(val) + if err != nil { + return nil, err + } + return dec.BigInt(), nil +} + +type parseOutput struct { + benchmarkPrice relaymercury.ObsResult[*big.Int] + bid relaymercury.ObsResult[*big.Int] + ask relaymercury.ObsResult[*big.Int] +} + +func (ds *datasource) parse(trrs pipeline.TaskRunResults) (o parseOutput, merr error) { + var finaltrrs []pipeline.TaskRunResult + for _, trr := range trrs { + // only return terminal trrs from executeRun + if trr.IsTerminal() { + finaltrrs = append(finaltrrs, trr) + } + } + + // pipeline.TaskRunResults comes ordered asc by index, this is guaranteed + // by the pipeline executor + if len(finaltrrs) != 3 { + return o, fmt.Errorf("invalid number of results, expected: 3, got: %d", len(finaltrrs)) + } + + merr = errors.Join( + setBenchmarkPrice(&o, finaltrrs[0].Result), + setBid(&o, finaltrrs[1].Result), + setAsk(&o, finaltrrs[2].Result), + ) + + return o, merr +} + +func setBenchmarkPrice(o *parseOutput, res pipeline.Result) error { + if res.Error != nil { + o.benchmarkPrice.Err = res.Error + return res.Error + } else if val, err := toBigInt(res.Value); err != nil { + return fmt.Errorf("failed to parse BenchmarkPrice: %w", err) + } else { + o.benchmarkPrice.Val = val + } + return nil +} + +func setBid(o *parseOutput, res pipeline.Result) error { + if res.Error != nil { + o.bid.Err = res.Error + return res.Error + } else if val, err := toBigInt(res.Value); err != nil { + return fmt.Errorf("failed to parse Bid: %w", err) + } else { + o.bid.Val = val + } + return nil +} + +func setAsk(o *parseOutput, res pipeline.Result) error { + if res.Error != nil { + o.ask.Err = res.Error + return res.Error + } else if val, err := toBigInt(res.Value); err != nil { + return fmt.Errorf("failed to parse Ask: %w", err) + } else { + o.ask.Val = val + } + return nil +} + +// The context passed in here has a timeout of (ObservationTimeout + ObservationGracePeriod). +// Upon context cancellation, its expected that we return any usable values within ObservationGracePeriod. +func (ds *datasource) executeRun(ctx context.Context) (pipeline.Run, pipeline.TaskRunResults, error) { + vars := pipeline.NewVarsFrom(map[string]interface{}{ + "jb": map[string]interface{}{ + "databaseID": ds.jb.ID, + "externalJobID": ds.jb.ExternalJobID, + "name": ds.jb.Name.ValueOrZero(), + }, + }) + + run, trrs, err := ds.pipelineRunner.ExecuteRun(ctx, ds.spec, vars, ds.lggr) + if err != nil { + return pipeline.Run{}, nil, pkgerrors.Wrapf(err, "error executing run for spec ID %v", ds.spec.ID) + } + + return run, trrs, 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 new file mode 100644 index 00000000000..7fc2e90193c --- /dev/null +++ b/core/services/relay/evm/mercury/v3/data_source_test.go @@ -0,0 +1,259 @@ +package mercury_v3 + +import ( + "context" + "math/big" + "testing" + + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + + relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" + + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "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" +) + +var _ relaymercury.MercuryServerFetcher = &mockFetcher{} + +type mockFetcher struct { + ts int64 + tsErr error + linkPrice *big.Int + linkPriceErr error + nativePrice *big.Int + nativePriceErr error +} + +var feedId utils.FeedID = [32]byte{1} +var linkFeedId utils.FeedID = [32]byte{2} +var nativeFeedId utils.FeedID = [32]byte{3} + +func (m *mockFetcher) FetchInitialMaxFinalizedBlockNumber(context.Context) (*int64, error) { + return nil, nil +} + +func (m *mockFetcher) LatestPrice(ctx context.Context, fId [32]byte) (*big.Int, error) { + if fId == linkFeedId { + return m.linkPrice, m.linkPriceErr + } else if fId == nativeFeedId { + return m.nativePrice, m.nativePriceErr + } + return nil, nil +} + +func (m *mockFetcher) LatestTimestamp(context.Context) (int64, error) { + return m.ts, m.tsErr +} + +func Test_Datasource(t *testing.T) { + ds := &datasource{lggr: logger.TestLogger(t)} + ctx := testutils.Context(t) + repts := ocrtypes.ReportTimestamp{} + + fetcher := &mockFetcher{} + ds.fetcher = fetcher + + goodTrrs := []pipeline.TaskRunResult{ + { + // bp + Result: pipeline.Result{Value: "122.345"}, + Task: &mercurymocks.MockTask{}, + }, + { + // bid + Result: pipeline.Result{Value: "121.993"}, + Task: &mercurymocks.MockTask{}, + }, + { + // ask + Result: pipeline.Result{Value: "123.111"}, + Task: &mercurymocks.MockTask{}, + }, + } + + ds.pipelineRunner = &mercurymocks.MockRunner{ + Trrs: goodTrrs, + } + + spec := pipeline.Spec{} + ds.spec = spec + + t.Run("when fetchMaxFinalizedTimestamp=true", func(t *testing.T) { + t.Run("if LatestTimestamp returns error", func(t *testing.T) { + fetcher.tsErr = errors.New("some error") + + obs, err := ds.Observe(ctx, repts, true) + assert.NoError(t, err) + + assert.EqualError(t, obs.MaxFinalizedTimestamp.Err, "some error") + assert.Zero(t, obs.MaxFinalizedTimestamp.Val) + }) + + t.Run("if LatestTimestamp succeeds", func(t *testing.T) { + fetcher.tsErr = nil + fetcher.ts = 123 + + obs, err := ds.Observe(ctx, repts, true) + assert.NoError(t, err) + + assert.Equal(t, int64(123), obs.MaxFinalizedTimestamp.Val) + assert.NoError(t, obs.MaxFinalizedTimestamp.Err) + }) + + t.Run("if LatestTimestamp succeeds but ts=0 (new feed)", func(t *testing.T) { + fetcher.tsErr = nil + fetcher.ts = 0 + + obs, err := ds.Observe(ctx, repts, true) + assert.NoError(t, err) + + assert.NoError(t, obs.MaxFinalizedTimestamp.Err) + assert.Zero(t, obs.MaxFinalizedTimestamp.Val) + }) + + t.Run("when run execution succeeded", func(t *testing.T) { + t.Run("when feedId=linkFeedID=nativeFeedId", func(t *testing.T) { + t.Cleanup(func() { + ds.feedID, ds.linkFeedID, ds.nativeFeedID = feedId, linkFeedId, nativeFeedId + }) + + ds.feedID, ds.linkFeedID, ds.nativeFeedID = feedId, feedId, feedId + + fetcher.ts = 123123 + fetcher.tsErr = nil + + obs, err := ds.Observe(ctx, repts, true) + assert.NoError(t, err) + + assert.Equal(t, big.NewInt(122), obs.BenchmarkPrice.Val) + assert.NoError(t, obs.BenchmarkPrice.Err) + assert.Equal(t, big.NewInt(121), obs.Bid.Val) + assert.NoError(t, obs.Bid.Err) + assert.Equal(t, big.NewInt(123), obs.Ask.Val) + assert.NoError(t, obs.Ask.Err) + assert.Equal(t, int64(123123), obs.MaxFinalizedTimestamp.Val) + assert.NoError(t, obs.MaxFinalizedTimestamp.Err) + assert.Equal(t, big.NewInt(122), obs.LinkPrice.Val) + assert.NoError(t, obs.LinkPrice.Err) + assert.Equal(t, big.NewInt(122), obs.NativePrice.Val) + assert.NoError(t, obs.NativePrice.Err) + }) + }) + }) + + t.Run("when fetchMaxFinalizedTimestamp=false", func(t *testing.T) { + t.Run("when run execution fails, returns error", func(t *testing.T) { + t.Cleanup(func() { + ds.pipelineRunner = &mercurymocks.MockRunner{ + Trrs: goodTrrs, + Err: nil, + } + }) + + ds.pipelineRunner = &mercurymocks.MockRunner{ + Trrs: goodTrrs, + Err: errors.New("run execution failed"), + } + + _, err := ds.Observe(ctx, repts, false) + assert.EqualError(t, err, "Observe failed while executing run: error executing run for spec ID 0: run execution failed") + }) + + t.Run("when parsing run results fails, return error", func(t *testing.T) { + t.Cleanup(func() { + runner := &mercurymocks.MockRunner{ + Trrs: goodTrrs, + Err: nil, + } + ds.pipelineRunner = runner + }) + + badTrrs := []pipeline.TaskRunResult{ + { + // benchmark price + Result: pipeline.Result{Value: "122.345"}, + Task: &mercurymocks.MockTask{}, + }, + { + // bid + Result: pipeline.Result{Value: "121.993"}, + Task: &mercurymocks.MockTask{}, + }, + { + // ask + Result: pipeline.Result{Error: errors.New("some error with ask")}, + Task: &mercurymocks.MockTask{}, + }, + } + + ds.pipelineRunner = &mercurymocks.MockRunner{ + Trrs: badTrrs, + Err: nil, + } + + _, err := ds.Observe(ctx, repts, false) + assert.EqualError(t, err, "Observe failed while parsing run results: some error with ask") + }) + + t.Run("when run execution succeeded", func(t *testing.T) { + t.Run("when feedId=linkFeedID=nativeFeedId", func(t *testing.T) { + t.Cleanup(func() { + ds.feedID, ds.linkFeedID, ds.nativeFeedID = feedId, linkFeedId, nativeFeedId + }) + + var feedId utils.FeedID = [32]byte{1} + ds.feedID, ds.linkFeedID, ds.nativeFeedID = feedId, feedId, feedId + + obs, err := ds.Observe(ctx, repts, false) + assert.NoError(t, err) + + assert.Equal(t, big.NewInt(122), obs.BenchmarkPrice.Val) + assert.NoError(t, obs.BenchmarkPrice.Err) + assert.Equal(t, big.NewInt(121), obs.Bid.Val) + assert.NoError(t, obs.Bid.Err) + assert.Equal(t, big.NewInt(123), obs.Ask.Val) + assert.NoError(t, obs.Ask.Err) + assert.Equal(t, int64(0), obs.MaxFinalizedTimestamp.Val) + assert.NoError(t, obs.MaxFinalizedTimestamp.Err) + assert.Equal(t, big.NewInt(122), obs.LinkPrice.Val) + assert.NoError(t, obs.LinkPrice.Err) + assert.Equal(t, big.NewInt(122), obs.NativePrice.Val) + assert.NoError(t, obs.NativePrice.Err) + }) + + t.Run("when fails to fetch linkPrice or nativePrice", func(t *testing.T) { + t.Cleanup(func() { + fetcher.linkPriceErr = nil + fetcher.nativePriceErr = nil + }) + + fetcher.linkPriceErr = errors.New("some error fetching link price") + fetcher.nativePriceErr = errors.New("some error fetching native price") + + obs, err := ds.Observe(ctx, repts, false) + assert.NoError(t, err) + + assert.Nil(t, obs.LinkPrice.Val) + assert.EqualError(t, obs.LinkPrice.Err, "some error fetching link price") + assert.Nil(t, obs.NativePrice.Val) + assert.EqualError(t, obs.NativePrice.Err, "some error fetching native price") + }) + + t.Run("when succeeds to fetch linkPrice or nativePrice but got nil (new feed)", func(t *testing.T) { + obs, err := ds.Observe(ctx, repts, false) + assert.NoError(t, err) + + assert.Equal(t, obs.LinkPrice.Val, relaymercury.MaxInt192) + assert.Nil(t, obs.LinkPrice.Err) + assert.Equal(t, obs.NativePrice.Val, relaymercury.MaxInt192) + assert.Nil(t, obs.NativePrice.Err) + }) + }) + }) +} diff --git a/core/services/relay/evm/mercury/v3/reportcodec/report_codec.go b/core/services/relay/evm/mercury/v3/reportcodec/report_codec.go new file mode 100644 index 00000000000..66995e74ea7 --- /dev/null +++ b/core/services/relay/evm/mercury/v3/reportcodec/report_codec.go @@ -0,0 +1,76 @@ +package reportcodec + +import ( + "errors" + "fmt" + + "math/big" + + pkgerrors "github.com/pkg/errors" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + reportcodec "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v3" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" + reporttypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/types" +) + +var ReportTypes = reporttypes.GetSchema() +var maxReportLength = 32 * len(ReportTypes) // each arg is 256 bit EVM word +var zero = big.NewInt(0) + +var _ reportcodec.ReportCodec = &ReportCodec{} + +type ReportCodec struct { + logger logger.Logger + feedID utils.FeedID +} + +func NewReportCodec(feedID [32]byte, lggr logger.Logger) *ReportCodec { + return &ReportCodec{lggr, feedID} +} + +func (r *ReportCodec) BuildReport(rf reportcodec.ReportFields) (ocrtypes.Report, error) { + var merr error + if rf.BenchmarkPrice == nil { + merr = errors.Join(merr, errors.New("benchmarkPrice may not be nil")) + } + if rf.Bid == nil { + merr = errors.Join(merr, errors.New("bid may not be nil")) + } + if rf.Ask == nil { + merr = errors.Join(merr, errors.New("ask may not be nil")) + } + if rf.LinkFee == nil { + merr = errors.Join(merr, errors.New("linkFee may not be nil")) + } else if rf.LinkFee.Cmp(zero) < 0 { + merr = errors.Join(merr, fmt.Errorf("linkFee may not be negative (got: %s)", rf.LinkFee)) + } + if rf.NativeFee == nil { + merr = errors.Join(merr, errors.New("nativeFee may not be nil")) + } else if rf.NativeFee.Cmp(zero) < 0 { + merr = errors.Join(merr, fmt.Errorf("nativeFee may not be negative (got: %s)", rf.NativeFee)) + } + if merr != nil { + return nil, merr + } + reportBytes, err := ReportTypes.Pack(r.feedID, rf.ValidFromTimestamp, rf.Timestamp, rf.NativeFee, rf.LinkFee, rf.ExpiresAt, rf.BenchmarkPrice, rf.Bid, rf.Ask) + return ocrtypes.Report(reportBytes), pkgerrors.Wrap(err, "failed to pack report blob") +} + +func (r *ReportCodec) MaxReportLength(n int) (int, error) { + return maxReportLength, nil +} + +func (r *ReportCodec) ObservationTimestampFromReport(report ocrtypes.Report) (uint32, error) { + decoded, err := r.Decode(report) + if err != nil { + return 0, err + } + return decoded.ObservationsTimestamp, nil +} + +func (r *ReportCodec) Decode(report ocrtypes.Report) (*reporttypes.Report, error) { + return reporttypes.Decode(report) +} diff --git a/core/services/relay/evm/mercury/v3/reportcodec/report_codec_test.go b/core/services/relay/evm/mercury/v3/reportcodec/report_codec_test.go new file mode 100644 index 00000000000..80cf4c9665b --- /dev/null +++ b/core/services/relay/evm/mercury/v3/reportcodec/report_codec_test.go @@ -0,0 +1,142 @@ +package reportcodec + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + relaymercuryv3 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v3" +) + +func newValidReportFields() relaymercuryv3.ReportFields { + return relaymercuryv3.ReportFields{ + Timestamp: 242, + BenchmarkPrice: big.NewInt(243), + Bid: big.NewInt(244), + Ask: big.NewInt(245), + ValidFromTimestamp: 123, + ExpiresAt: 20, + LinkFee: big.NewInt(456), + NativeFee: big.NewInt(457), + } +} + +func Test_ReportCodec_BuildReport(t *testing.T) { + r := ReportCodec{} + + t.Run("BuildReport errors on zero values", func(t *testing.T) { + _, err := r.BuildReport(relaymercuryv3.ReportFields{}) + require.Error(t, err) + assert.Contains(t, err.Error(), "benchmarkPrice may not be nil") + assert.Contains(t, err.Error(), "linkFee may not be nil") + assert.Contains(t, err.Error(), "nativeFee may not be nil") + }) + + t.Run("BuildReport constructs a report from observations", func(t *testing.T) { + rf := newValidReportFields() + // only need to test happy path since validations are done in relaymercury + + report, err := r.BuildReport(rf) + require.NoError(t, err) + + reportElems := make(map[string]interface{}) + err = ReportTypes.UnpackIntoMap(reportElems, report) + require.NoError(t, err) + + assert.Equal(t, int(reportElems["observationsTimestamp"].(uint32)), 242) + assert.Equal(t, reportElems["benchmarkPrice"].(*big.Int).Int64(), int64(243)) + assert.Equal(t, reportElems["bid"].(*big.Int).Int64(), int64(244)) + assert.Equal(t, reportElems["ask"].(*big.Int).Int64(), int64(245)) + assert.Equal(t, reportElems["validFromTimestamp"].(uint32), uint32(123)) + assert.Equal(t, reportElems["expiresAt"].(uint32), uint32(20)) + assert.Equal(t, reportElems["linkFee"].(*big.Int).Int64(), int64(456)) + assert.Equal(t, reportElems["nativeFee"].(*big.Int).Int64(), int64(457)) + + assert.Equal(t, types.Report{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xc9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf5}, report) + max, err := r.MaxReportLength(4) + require.NoError(t, err) + assert.LessOrEqual(t, len(report), max) + + t.Run("Decode decodes the report", func(t *testing.T) { + decoded, err := r.Decode(report) + require.NoError(t, err) + + require.NotNil(t, decoded) + + assert.Equal(t, uint32(242), decoded.ObservationsTimestamp) + assert.Equal(t, big.NewInt(243), decoded.BenchmarkPrice) + assert.Equal(t, big.NewInt(244), decoded.Bid) + assert.Equal(t, big.NewInt(245), decoded.Ask) + assert.Equal(t, uint32(123), decoded.ValidFromTimestamp) + assert.Equal(t, uint32(20), decoded.ExpiresAt) + assert.Equal(t, big.NewInt(456), decoded.LinkFee) + assert.Equal(t, big.NewInt(457), decoded.NativeFee) + }) + }) + + t.Run("errors on negative fee", func(t *testing.T) { + rf := newValidReportFields() + rf.LinkFee = big.NewInt(-1) + rf.NativeFee = big.NewInt(-1) + _, err := r.BuildReport(rf) + require.Error(t, err) + + assert.Contains(t, err.Error(), "linkFee may not be negative (got: -1)") + assert.Contains(t, err.Error(), "nativeFee may not be negative (got: -1)") + }) + + t.Run("Decode errors on invalid report", func(t *testing.T) { + _, err := r.Decode([]byte{1, 2, 3}) + assert.EqualError(t, err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32") + + longBad := make([]byte, 64) + for i := 0; i < len(longBad); i++ { + longBad[i] = byte(i) + } + _, err = r.Decode(longBad) + assert.EqualError(t, err, "failed to decode report: abi: improperly encoded uint32 value") + }) +} + +func buildSampleReport(ts int64) []byte { + feedID := [32]byte{'f', 'o', 'o'} + timestamp := uint32(ts) + bp := big.NewInt(242) + bid := big.NewInt(243) + ask := big.NewInt(244) + validFromTimestamp := uint32(123) + expiresAt := uint32(456) + linkFee := big.NewInt(3334455) + nativeFee := big.NewInt(556677) + + b, err := ReportTypes.Pack(feedID, validFromTimestamp, timestamp, nativeFee, linkFee, expiresAt, bp, bid, ask) + if err != nil { + panic(err) + } + return b +} + +func Test_ReportCodec_ObservationTimestampFromReport(t *testing.T) { + r := ReportCodec{} + + t.Run("ObservationTimestampFromReport extracts observation timestamp from a valid report", func(t *testing.T) { + report := buildSampleReport(123) + + ts, err := r.ObservationTimestampFromReport(report) + require.NoError(t, err) + + assert.Equal(t, ts, uint32(123)) + }) + t.Run("ObservationTimestampFromReport returns error when report is invalid", func(t *testing.T) { + report := []byte{1, 2, 3} + + _, err := r.ObservationTimestampFromReport(report) + require.Error(t, err) + + assert.EqualError(t, err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32") + }) +} diff --git a/core/services/relay/evm/mercury/v3/types/types.go b/core/services/relay/evm/mercury/v3/types/types.go new file mode 100644 index 00000000000..110315942d8 --- /dev/null +++ b/core/services/relay/evm/mercury/v3/types/types.go @@ -0,0 +1,56 @@ +package reporttypes + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" +) + +var schema = GetSchema() + +func GetSchema() abi.Arguments { + mustNewType := func(t string) abi.Type { + result, err := abi.NewType(t, "", []abi.ArgumentMarshaling{}) + if err != nil { + panic(fmt.Sprintf("Unexpected error during abi.NewType: %s", err)) + } + return result + } + return abi.Arguments([]abi.Argument{ + {Name: "feedId", Type: mustNewType("bytes32")}, + {Name: "validFromTimestamp", Type: mustNewType("uint32")}, + {Name: "observationsTimestamp", Type: mustNewType("uint32")}, + {Name: "nativeFee", Type: mustNewType("int192")}, + {Name: "linkFee", Type: mustNewType("int192")}, + {Name: "expiresAt", Type: mustNewType("uint32")}, + {Name: "benchmarkPrice", Type: mustNewType("int192")}, + {Name: "bid", Type: mustNewType("int192")}, + {Name: "ask", Type: mustNewType("int192")}, + }) +} + +type Report struct { + FeedId [32]byte + ObservationsTimestamp uint32 + BenchmarkPrice *big.Int + Bid *big.Int + Ask *big.Int + ValidFromTimestamp uint32 + ExpiresAt uint32 + LinkFee *big.Int + NativeFee *big.Int +} + +// Decode is made available to external users (i.e. mercury server) +func Decode(report []byte) (*Report, error) { + values, err := schema.Unpack(report) + if err != nil { + return nil, fmt.Errorf("failed to decode report: %w", err) + } + decoded := new(Report) + if err = schema.Copy(decoded, values); err != nil { + return nil, fmt.Errorf("failed to copy report values to struct: %w", err) + } + return decoded, nil +} diff --git a/core/services/relay/evm/mercury/wsrpc/client.go b/core/services/relay/evm/mercury/wsrpc/client.go index 5f3d05d0c0d..fb9a57d9a2d 100644 --- a/core/services/relay/evm/mercury/wsrpc/client.go +++ b/core/services/relay/evm/mercury/wsrpc/client.go @@ -238,7 +238,7 @@ func (w *client) Transmit(ctx context.Context, req *pb.TransmitRequest) (resp *p w.logger.Trace("Transmit") start := time.Now() if err = w.waitForReady(ctx); err != nil { - return nil, errors.Wrap(err, "Transmit failed") + return nil, errors.Wrap(err, "Transmit call failed") } resp, err = w.client.Transmit(ctx, req) if errors.Is(err, context.DeadlineExceeded) { @@ -272,10 +272,10 @@ func (w *client) Transmit(ctx context.Context, req *pb.TransmitRequest) (resp *p w.consecutiveTimeoutCnt.Store(0) } if err != nil { - w.logger.Warnw("Transmit failed", "err", err, "resp", resp) + w.logger.Warnw("Transmit call failed due to networking error", "err", err, "resp", resp) incRequestStatusMetric(statusFailed) } else { - w.logger.Debugw("Transmit succeeded", "resp", resp) + w.logger.Tracew("Transmit call succeeded", "resp", resp) incRequestStatusMetric(statusSuccess) setRequestLatencyMetric(float64(time.Since(start).Milliseconds())) } diff --git a/core/services/relay/evm/mercury_provider.go b/core/services/relay/evm/mercury_provider.go index 9f604234016..ee32b8d99be 100644 --- a/core/services/relay/evm/mercury_provider.go +++ b/core/services/relay/evm/mercury_provider.go @@ -5,6 +5,9 @@ import ( "errors" relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" + relaymercuryv1 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v1" + relaymercuryv2 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v2" + relaymercuryv3 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v3" relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "golang.org/x/exp/maps" @@ -19,7 +22,9 @@ var _ relaytypes.MercuryProvider = (*mercuryProvider)(nil) type mercuryProvider struct { configWatcher *configWatcher transmitter mercury.Transmitter - reportCodec relaymercury.ReportCodec + reportCodecV1 relaymercuryv1.ReportCodec + reportCodecV2 relaymercuryv2.ReportCodec + reportCodecV3 relaymercuryv3.ReportCodec logger logger.Logger ms services.MultiStart @@ -28,13 +33,17 @@ type mercuryProvider struct { func NewMercuryProvider( configWatcher *configWatcher, transmitter mercury.Transmitter, - reportCodec relaymercury.ReportCodec, + reportCodecV1 relaymercuryv1.ReportCodec, + reportCodecV2 relaymercuryv2.ReportCodec, + reportCodecV3 relaymercuryv3.ReportCodec, lggr logger.Logger, ) *mercuryProvider { return &mercuryProvider{ configWatcher, transmitter, - reportCodec, + reportCodecV1, + reportCodecV2, + reportCodecV3, lggr, services.MultiStart{}, } @@ -75,8 +84,16 @@ func (p *mercuryProvider) OnchainConfigCodec() relaymercury.OnchainConfigCodec { return relaymercury.StandardOnchainConfigCodec{} } -func (p *mercuryProvider) ReportCodec() relaymercury.ReportCodec { - return p.reportCodec +func (p *mercuryProvider) ReportCodecV1() relaymercuryv1.ReportCodec { + return p.reportCodecV1 +} + +func (p *mercuryProvider) ReportCodecV2() relaymercuryv2.ReportCodec { + return p.reportCodecV2 +} + +func (p *mercuryProvider) ReportCodecV3() relaymercuryv3.ReportCodec { + return p.reportCodecV3 } func (p *mercuryProvider) ContractTransmitter() relaymercury.Transmitter { diff --git a/core/chains/evm/mocks/chain_set.go b/core/services/relay/evm/mocks/loop_relay_adapter.go similarity index 52% rename from core/chains/evm/mocks/chain_set.go rename to core/services/relay/evm/mocks/loop_relay_adapter.go index 76366c9fb00..b0d9b7cf95e 100644 --- a/core/chains/evm/mocks/chain_set.go +++ b/core/services/relay/evm/mocks/loop_relay_adapter.go @@ -7,34 +7,34 @@ import ( big "math/big" evm "github.com/smartcontractkit/chainlink/v2/core/chains/evm" - evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - mock "github.com/stretchr/testify/mock" types "github.com/smartcontractkit/chainlink-relay/pkg/types" ) -// ChainSet is an autogenerated mock type for the ChainSet type -type ChainSet struct { +// LoopRelayAdapter is an autogenerated mock type for the LoopRelayAdapter type +type LoopRelayAdapter struct { mock.Mock } -// ChainCount provides a mock function with given fields: -func (_m *ChainSet) ChainCount() int { +// Chain provides a mock function with given fields: +func (_m *LoopRelayAdapter) Chain() evm.Chain { ret := _m.Called() - var r0 int - if rf, ok := ret.Get(0).(func() int); ok { + var r0 evm.Chain + if rf, ok := ret.Get(0).(func() evm.Chain); ok { r0 = rf() } else { - r0 = ret.Get(0).(int) + if ret.Get(0) != nil { + r0 = ret.Get(0).(evm.Chain) + } } return r0 } // ChainStatus provides a mock function with given fields: ctx, id -func (_m *ChainSet) ChainStatus(ctx context.Context, id string) (types.ChainStatus, error) { +func (_m *LoopRelayAdapter) ChainStatus(ctx context.Context, id string) (types.ChainStatus, error) { ret := _m.Called(ctx, id) var r0 types.ChainStatus @@ -58,7 +58,7 @@ func (_m *ChainSet) ChainStatus(ctx context.Context, id string) (types.ChainStat } // ChainStatuses provides a mock function with given fields: ctx, offset, limit -func (_m *ChainSet) ChainStatuses(ctx context.Context, offset int, limit int) ([]types.ChainStatus, int, error) { +func (_m *LoopRelayAdapter) ChainStatuses(ctx context.Context, offset int, limit int) ([]types.ChainStatus, int, error) { ret := _m.Called(ctx, offset, limit) var r0 []types.ChainStatus @@ -90,71 +90,83 @@ func (_m *ChainSet) ChainStatuses(ctx context.Context, offset int, limit int) ([ return r0, r1, r2 } -// Chains provides a mock function with given fields: -func (_m *ChainSet) Chains() []evm.Chain { +// Close provides a mock function with given fields: +func (_m *LoopRelayAdapter) Close() error { ret := _m.Called() - var r0 []evm.Chain - if rf, ok := ret.Get(0).(func() []evm.Chain); ok { + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { r0 = rf() } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]evm.Chain) - } + r0 = ret.Error(0) } return r0 } -// Close provides a mock function with given fields: -func (_m *ChainSet) Close() error { +// Default provides a mock function with given fields: +func (_m *LoopRelayAdapter) Default() bool { ret := _m.Called() - var r0 error - if rf, ok := ret.Get(0).(func() error); ok { + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { r0 = rf() } else { - r0 = ret.Error(0) + r0 = ret.Get(0).(bool) } return r0 } -// Configs provides a mock function with given fields: -func (_m *ChainSet) Configs() evmtypes.Configs { +// HealthReport provides a mock function with given fields: +func (_m *LoopRelayAdapter) HealthReport() map[string]error { ret := _m.Called() - var r0 evmtypes.Configs - if rf, ok := ret.Get(0).(func() evmtypes.Configs); ok { + var r0 map[string]error + if rf, ok := ret.Get(0).(func() map[string]error); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(evmtypes.Configs) + r0 = ret.Get(0).(map[string]error) } } return r0 } -// Default provides a mock function with given fields: -func (_m *ChainSet) Default() (evm.Chain, error) { +// Name provides a mock function with given fields: +func (_m *LoopRelayAdapter) Name() string { ret := _m.Called() - var r0 evm.Chain + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// NewConfigProvider provides a mock function with given fields: _a0, _a1 +func (_m *LoopRelayAdapter) NewConfigProvider(_a0 context.Context, _a1 types.RelayArgs) (types.ConfigProvider, error) { + ret := _m.Called(_a0, _a1) + + var r0 types.ConfigProvider var r1 error - if rf, ok := ret.Get(0).(func() (evm.Chain, error)); ok { - return rf() + if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs) (types.ConfigProvider, error)); ok { + return rf(_a0, _a1) } - if rf, ok := ret.Get(0).(func() evm.Chain); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs) types.ConfigProvider); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(evm.Chain) + r0 = ret.Get(0).(types.ConfigProvider) } } - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() + if rf, ok := ret.Get(1).(func(context.Context, types.RelayArgs) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -162,25 +174,25 @@ func (_m *ChainSet) Default() (evm.Chain, error) { return r0, r1 } -// Get provides a mock function with given fields: id -func (_m *ChainSet) Get(id *big.Int) (evm.Chain, error) { - ret := _m.Called(id) +// NewFunctionsProvider provides a mock function with given fields: _a0, _a1, _a2 +func (_m *LoopRelayAdapter) NewFunctionsProvider(_a0 context.Context, _a1 types.RelayArgs, _a2 types.PluginArgs) (types.FunctionsProvider, error) { + ret := _m.Called(_a0, _a1, _a2) - var r0 evm.Chain + var r0 types.FunctionsProvider var r1 error - if rf, ok := ret.Get(0).(func(*big.Int) (evm.Chain, error)); ok { - return rf(id) + if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) (types.FunctionsProvider, error)); ok { + return rf(_a0, _a1, _a2) } - if rf, ok := ret.Get(0).(func(*big.Int) evm.Chain); ok { - r0 = rf(id) + if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) types.FunctionsProvider); ok { + r0 = rf(_a0, _a1, _a2) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(evm.Chain) + r0 = ret.Get(0).(types.FunctionsProvider) } } - if rf, ok := ret.Get(1).(func(*big.Int) error); ok { - r1 = rf(id) + if rf, ok := ret.Get(1).(func(context.Context, types.RelayArgs, types.PluginArgs) error); ok { + r1 = rf(_a0, _a1, _a2) } else { r1 = ret.Error(1) } @@ -188,38 +200,60 @@ func (_m *ChainSet) Get(id *big.Int) (evm.Chain, error) { return r0, r1 } -// HealthReport provides a mock function with given fields: -func (_m *ChainSet) HealthReport() map[string]error { - ret := _m.Called() +// NewMedianProvider provides a mock function with given fields: _a0, _a1, _a2 +func (_m *LoopRelayAdapter) NewMedianProvider(_a0 context.Context, _a1 types.RelayArgs, _a2 types.PluginArgs) (types.MedianProvider, error) { + ret := _m.Called(_a0, _a1, _a2) - var r0 map[string]error - if rf, ok := ret.Get(0).(func() map[string]error); ok { - r0 = rf() + var r0 types.MedianProvider + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) (types.MedianProvider, error)); ok { + return rf(_a0, _a1, _a2) + } + if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) types.MedianProvider); ok { + r0 = rf(_a0, _a1, _a2) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(map[string]error) + r0 = ret.Get(0).(types.MedianProvider) } } - return r0 + if rf, ok := ret.Get(1).(func(context.Context, types.RelayArgs, types.PluginArgs) error); ok { + r1 = rf(_a0, _a1, _a2) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// Name provides a mock function with given fields: -func (_m *ChainSet) Name() string { - ret := _m.Called() +// NewMercuryProvider provides a mock function with given fields: _a0, _a1, _a2 +func (_m *LoopRelayAdapter) NewMercuryProvider(_a0 context.Context, _a1 types.RelayArgs, _a2 types.PluginArgs) (types.MercuryProvider, error) { + ret := _m.Called(_a0, _a1, _a2) - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() + var r0 types.MercuryProvider + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) (types.MercuryProvider, error)); ok { + return rf(_a0, _a1, _a2) + } + if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) types.MercuryProvider); ok { + r0 = rf(_a0, _a1, _a2) } else { - r0 = ret.Get(0).(string) + if ret.Get(0) != nil { + r0 = ret.Get(0).(types.MercuryProvider) + } } - return r0 + if rf, ok := ret.Get(1).(func(context.Context, types.RelayArgs, types.PluginArgs) error); ok { + r1 = rf(_a0, _a1, _a2) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // NodeStatuses provides a mock function with given fields: ctx, offset, limit, chainIDs -func (_m *ChainSet) NodeStatuses(ctx context.Context, offset int, limit int, chainIDs ...string) ([]types.NodeStatus, int, error) { +func (_m *LoopRelayAdapter) NodeStatuses(ctx context.Context, offset int, limit int, chainIDs ...string) ([]types.NodeStatus, int, error) { _va := make([]interface{}, len(chainIDs)) for _i := range chainIDs { _va[_i] = chainIDs[_i] @@ -259,7 +293,7 @@ func (_m *ChainSet) NodeStatuses(ctx context.Context, offset int, limit int, cha } // Ready provides a mock function with given fields: -func (_m *ChainSet) Ready() error { +func (_m *LoopRelayAdapter) Ready() error { ret := _m.Called() var r0 error @@ -273,7 +307,7 @@ func (_m *ChainSet) Ready() error { } // SendTx provides a mock function with given fields: ctx, chainID, from, to, amount, balanceCheck -func (_m *ChainSet) SendTx(ctx context.Context, chainID string, from string, to string, amount *big.Int, balanceCheck bool) error { +func (_m *LoopRelayAdapter) SendTx(ctx context.Context, chainID string, from string, to string, amount *big.Int, balanceCheck bool) error { ret := _m.Called(ctx, chainID, from, to, amount, balanceCheck) var r0 error @@ -287,7 +321,7 @@ func (_m *ChainSet) SendTx(ctx context.Context, chainID string, from string, to } // Start provides a mock function with given fields: _a0 -func (_m *ChainSet) Start(_a0 context.Context) error { +func (_m *LoopRelayAdapter) Start(_a0 context.Context) error { ret := _m.Called(_a0) var r0 error @@ -300,14 +334,14 @@ func (_m *ChainSet) Start(_a0 context.Context) error { return r0 } -type mockConstructorTestingTNewChainSet interface { +type mockConstructorTestingTNewLoopRelayAdapter interface { mock.TestingT Cleanup(func()) } -// NewChainSet creates a new instance of ChainSet. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewChainSet(t mockConstructorTestingTNewChainSet) *ChainSet { - mock := &ChainSet{} +// NewLoopRelayAdapter creates a new instance of LoopRelayAdapter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewLoopRelayAdapter(t mockConstructorTestingTNewLoopRelayAdapter) *LoopRelayAdapter { + mock := &LoopRelayAdapter{} mock.Mock.Test(t) t.Cleanup(func() { mock.AssertExpectations(t) }) diff --git a/core/services/relay/evm/ocr2keeper.go b/core/services/relay/evm/ocr2keeper.go index 3c6fee4f9af..c6f4f1ad395 100644 --- a/core/services/relay/evm/ocr2keeper.go +++ b/core/services/relay/evm/ocr2keeper.go @@ -1,6 +1,7 @@ package evm import ( + "context" "encoding/json" "fmt" "strings" @@ -10,6 +11,8 @@ import ( "github.com/pkg/errors" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/ocr2keepers/pkg/v3/plugin" "github.com/smartcontractkit/sqlx" relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types" @@ -83,6 +86,40 @@ func (r *ocr2keeperRelayer) NewOCR2KeeperProvider(rargs relaytypes.RelayArgs, pa }, nil } +type ocr3keeperProviderContractTransmitter struct { + contractTransmitter ocrtypes.ContractTransmitter +} + +var _ ocr3types.ContractTransmitter[plugin.AutomationReportInfo] = &ocr3keeperProviderContractTransmitter{} + +func NewKeepersOCR3ContractTransmitter(ocr2ContractTransmitter ocrtypes.ContractTransmitter) *ocr3keeperProviderContractTransmitter { + return &ocr3keeperProviderContractTransmitter{ocr2ContractTransmitter} +} + +func (t *ocr3keeperProviderContractTransmitter) Transmit( + ctx context.Context, + digest ocrtypes.ConfigDigest, + seqNr uint64, + reportWithInfo ocr3types.ReportWithInfo[plugin.AutomationReportInfo], + aoss []ocrtypes.AttributedOnchainSignature, +) error { + return t.contractTransmitter.Transmit( + ctx, + ocrtypes.ReportContext{ + ReportTimestamp: ocrtypes.ReportTimestamp{ + ConfigDigest: digest, + Epoch: uint32(seqNr), + }, + }, + reportWithInfo.Report, + aoss, + ) +} + +func (t *ocr3keeperProviderContractTransmitter) FromAccount() (ocrtypes.Account, error) { + return t.contractTransmitter.FromAccount() +} + type ocr2keeperProvider struct { *configWatcher contractTransmitter ContractTransmitter diff --git a/core/services/relay/evm/relayer_extender.go b/core/services/relay/evm/relayer_extender.go new file mode 100644 index 00000000000..cab804e5883 --- /dev/null +++ b/core/services/relay/evm/relayer_extender.go @@ -0,0 +1,437 @@ +package evm + +import ( + "context" + "fmt" + "math/big" + "sync" + + "github.com/pkg/errors" + "go.uber.org/multierr" + "golang.org/x/exp/maps" + + relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types" + + "github.com/smartcontractkit/chainlink/v2/core/chains" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm" + evmchain "github.com/smartcontractkit/chainlink/v2/core/chains/evm" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" +) + +// ErrNoChains indicates that no EVM chains have been started +var ErrNoChains = errors.New("no EVM chains loaded") + +var _ legacyChainSet = &chainSet{} + +type legacyChainSet interface { + services.ServiceCtx + chains.ChainStatuser + chains.NodesStatuser + + Get(id *big.Int) (evmchain.Chain, error) + + Default() (evmchain.Chain, error) + Chains() []evmchain.Chain + ChainCount() int + + Configs() evmtypes.Configs + + SendTx(ctx context.Context, chainID, from, to string, amount *big.Int, balanceCheck bool) error +} + +type EVMChainRelayerExtender interface { + relay.RelayerExt + Chain() evmchain.Chain + Default() bool +} + +type EVMChainRelayerExtenderSlicer interface { + Slice() []EVMChainRelayerExtender + Len() int + AppConfig() evmchain.AppConfig +} + +type ChainRelayerExtenders struct { + exts []EVMChainRelayerExtender + cfg evmchain.AppConfig +} + +var _ EVMChainRelayerExtenderSlicer = &ChainRelayerExtenders{} + +func NewLegacyChainsFromRelayerExtenders(exts EVMChainRelayerExtenderSlicer) (*evmchain.LegacyChains, error) { + + m := make(map[string]evmchain.Chain) + var dflt evmchain.Chain + for _, r := range exts.Slice() { + m[r.Chain().ID().String()] = r.Chain() + if r.Default() { + dflt = r.Chain() + } + } + l, err := evmchain.NewLegacyChains(exts.AppConfig(), m) + if err != nil { + return nil, err + } + if dflt != nil { + l.SetDefault(dflt) + } + return l, nil +} + +func newChainRelayerExtsFromSlice(exts []*ChainRelayerExt, appConfig evm.AppConfig) *ChainRelayerExtenders { + temp := make([]EVMChainRelayerExtender, len(exts)) + for i := range exts { + temp[i] = exts[i] + } + return &ChainRelayerExtenders{ + exts: temp, + cfg: appConfig, + } +} + +func (c *ChainRelayerExtenders) AppConfig() evmchain.AppConfig { + return c.cfg +} + +func (c *ChainRelayerExtenders) Slice() []EVMChainRelayerExtender { + return c.exts +} + +func (c *ChainRelayerExtenders) Len() int { + return len(c.exts) +} + +// implements OneChain +type ChainRelayerExt struct { + chain evmchain.Chain + // TODO remove this altogether. BFC-2440 + cs *chainSet + isDefault bool +} + +var _ EVMChainRelayerExtender = &ChainRelayerExt{} + +func (s *ChainRelayerExt) Chain() evmchain.Chain { + return s.chain +} + +func (s *ChainRelayerExt) Default() bool { + return s.isDefault +} + +var ErrCorruptEVMChain = errors.New("corrupt evm chain") + +func (s *ChainRelayerExt) Start(ctx context.Context) error { + if len(s.cs.chains) > 1 { + err := fmt.Errorf("%w: internal error more than one chain (%d)", ErrCorruptEVMChain, len(s.cs.chains)) + panic(err) + } + return s.cs.Start(ctx) +} + +func (s *ChainRelayerExt) Close() (err error) { + return s.cs.Close() +} + +func (s *ChainRelayerExt) Name() string { + // we set each private chainSet logger to contain the chain id + return s.cs.Name() +} + +func (s *ChainRelayerExt) HealthReport() map[string]error { + return s.cs.HealthReport() +} + +func (s *ChainRelayerExt) Ready() (err error) { + return s.cs.Ready() +} + +var ErrInconsistentChainRelayerExtender = errors.New("inconsistent evm chain relayer extender") + +func (s *ChainRelayerExt) ChainStatus(ctx context.Context, id string) (relaytypes.ChainStatus, error) { + // TODO BCF-2441: update relayer interface + // we need to implement the interface, but passing id doesn't really make sense because there is only + // one chain here. check the id here to provide clear error reporting. + if s.chain.ID().String() != id { + return relaytypes.ChainStatus{}, fmt.Errorf("%w: given id %q does not match expected id %q", ErrInconsistentChainRelayerExtender, id, s.chain.ID()) + } + return s.cs.ChainStatus(ctx, id) +} + +func (s *ChainRelayerExt) ChainStatuses(ctx context.Context, offset, limit int) ([]relaytypes.ChainStatus, int, error) { + stat, err := s.cs.ChainStatus(ctx, s.chain.ID().String()) + if err != nil { + return nil, -1, err + } + return []relaytypes.ChainStatus{stat}, 1, nil + +} + +func (s *ChainRelayerExt) NodeStatuses(ctx context.Context, offset, limit int, chainIDs ...string) (nodes []relaytypes.NodeStatus, count int, err error) { + if len(chainIDs) > 1 { + return nil, -1, fmt.Errorf("single chain chain set only support one chain id. got %v", chainIDs) + } + cid := chainIDs[0] + if cid != s.chain.ID().String() { + return nil, -1, fmt.Errorf("unknown chain id %s. expected %s", cid, s.chain.ID()) + } + return s.cs.NodeStatuses(ctx, offset, limit, chainIDs...) +} + +func (s *ChainRelayerExt) SendTx(ctx context.Context, chainID, from, to string, amount *big.Int, balanceCheck bool) error { + return s.cs.SendTx(ctx, chainID, from, to, amount, balanceCheck) +} + +type chainSet struct { + defaultID *big.Int + chains map[string]evmchain.Chain + startedChains []evmchain.Chain + chainsMu sync.RWMutex + logger logger.Logger + opts evmchain.ChainRelayExtenderConfig +} + +func (cll *chainSet) Start(ctx context.Context) error { + if !cll.opts.AppConfig.EVMEnabled() { + cll.logger.Warn("EVM is disabled, no EVM-based chains will be started") + return nil + } + if !cll.opts.AppConfig.EVMRPCEnabled() { + cll.logger.Warn("EVM RPC connections are disabled. Chainlink will not connect to any EVM RPC node.") + } + var ms services.MultiStart + for _, c := range cll.Chains() { + if err := ms.Start(ctx, c); err != nil { + return errors.Wrapf(err, "failed to start chain %q", c.ID().String()) + } + cll.startedChains = append(cll.startedChains, c) + } + evmChainIDs := make([]*big.Int, len(cll.startedChains)) + for i, c := range cll.startedChains { + evmChainIDs[i] = c.ID() + } + defChainID := "unspecified" + if cll.defaultID != nil { + defChainID = fmt.Sprintf("%q", cll.defaultID.String()) + } + cll.logger.Infow(fmt.Sprintf("EVM: Started %d/%d chains, default chain ID is %s", len(cll.startedChains), len(cll.Chains()), defChainID), "startedEvmChainIDs", evmChainIDs) + return nil +} + +func (cll *chainSet) Close() (err error) { + cll.logger.Debug("EVM: stopping") + for _, c := range cll.startedChains { + err = multierr.Combine(err, c.Close()) + } + return +} + +func (cll *chainSet) Name() string { + return cll.logger.Name() +} + +func (cll *chainSet) HealthReport() map[string]error { + report := map[string]error{} + for _, c := range cll.Chains() { + maps.Copy(report, c.HealthReport()) + } + return report +} + +func (cll *chainSet) Ready() (err error) { + for _, c := range cll.Chains() { + err = multierr.Combine(err, c.Ready()) + } + return +} + +func (cll *chainSet) Get(id *big.Int) (evmchain.Chain, error) { + if id == nil { + if cll.defaultID == nil { + cll.logger.Debug("Chain ID not specified, and default is nil") + return nil, errors.New("chain ID not specified, and default is nil") + } + cll.logger.Debugf("Chain ID not specified, using default: %s", cll.defaultID.String()) + return cll.Default() + } + return cll.get(id.String()) +} + +func (cll *chainSet) get(id string) (evmchain.Chain, error) { + cll.chainsMu.RLock() + defer cll.chainsMu.RUnlock() + c, exists := cll.chains[id] + if exists { + return c, nil + } + return nil, errors.Wrap(chains.ErrNotFound, fmt.Sprintf("failed to get chain with id %s", id)) +} + +func (cll *chainSet) ChainStatus(ctx context.Context, id string) (cfg relaytypes.ChainStatus, err error) { + var cs []relaytypes.ChainStatus + cs, _, err = cll.opts.EVMConfigs().Chains(0, -1, id) + if err != nil { + return + } + l := len(cs) + if l == 0 { + err = fmt.Errorf("chain %s: %w", id, chains.ErrNotFound) + return + } + if l > 1 { + err = fmt.Errorf("multiple chains found: %d", len(cs)) + return + } + cfg = cs[0] + return +} + +func (cll *chainSet) ChainStatuses(ctx context.Context, offset, limit int) ([]relaytypes.ChainStatus, int, error) { + return cll.opts.EVMConfigs().Chains(offset, limit) +} + +func (cll *chainSet) Default() (evmchain.Chain, error) { + cll.chainsMu.RLock() + length := len(cll.chains) + cll.chainsMu.RUnlock() + if length == 0 { + return nil, errors.Wrap(ErrNoChains, "cannot get default EVM chain; no EVM chains are available") + } + if cll.defaultID == nil { + // This is an invariant violation; if any chains are available then a + // default should _always_ have been set in the constructor + return nil, errors.New("no default chain ID specified") + } + + return cll.Get(cll.defaultID) +} + +func (cll *chainSet) Chains() (c []evmchain.Chain) { + cll.chainsMu.RLock() + defer cll.chainsMu.RUnlock() + for _, chain := range cll.chains { + c = append(c, chain) + } + return c +} + +func (cll *chainSet) ChainCount() int { + cll.chainsMu.RLock() + defer cll.chainsMu.RUnlock() + return len(cll.chains) +} + +func (cll *chainSet) Configs() evmtypes.Configs { + return cll.opts.EVMConfigs() +} + +func (cll *chainSet) NodeStatuses(ctx context.Context, offset, limit int, chainIDs ...string) (nodes []relaytypes.NodeStatus, count int, err error) { + nodes, count, err = cll.opts.EVMConfigs().NodeStatusesPaged(offset, limit, chainIDs...) + if err != nil { + err = errors.Wrap(err, "GetNodesForChain failed to load nodes from DB") + return + } + for i := range nodes { + cll.addStateToNode(&nodes[i]) + } + return +} + +func (cll *chainSet) addStateToNode(n *relaytypes.NodeStatus) { + cll.chainsMu.RLock() + chain, exists := cll.chains[n.ChainID] + cll.chainsMu.RUnlock() + if !exists { + // The EVM chain is disabled + n.State = "Disabled" + return + } + states := chain.Client().NodeStates() + if states == nil { + n.State = "Unknown" + return + } + state, exists := states[n.Name] + if exists { + n.State = state + return + } + // The node is in the DB and the chain is enabled but it's not running + n.State = "NotLoaded" +} + +func (cll *chainSet) SendTx(ctx context.Context, chainID, from, to string, amount *big.Int, balanceCheck bool) error { + chain, err := cll.get(chainID) + if err != nil { + return err + } + + return chain.SendTx(ctx, from, to, amount, balanceCheck) +} + +func NewChainRelayerExtenders(ctx context.Context, opts evmchain.ChainRelayExtenderConfig) (*ChainRelayerExtenders, error) { + if err := opts.Check(); err != nil { + return nil, err + } + evmConfigs := opts.AppConfig.EVMConfigs() + var enabled []*toml.EVMConfig + for i := range evmConfigs { + if evmConfigs[i].IsEnabled() { + enabled = append(enabled, evmConfigs[i]) + } + } + + defaultChainID := opts.AppConfig.DefaultChainID() + if defaultChainID == nil && len(enabled) >= 1 { + defaultChainID = enabled[0].ChainID.ToInt() + if len(enabled) > 1 { + opts.Logger.Debugf("Multiple chains present, default chain: %s", defaultChainID.String()) + } + } + + var result []*ChainRelayerExt + var err error + for i := range enabled { + + cid := enabled[i].ChainID.String() + privOpts := evmchain.ChainRelayExtenderConfig{ + Logger: opts.Logger.Named(cid), + RelayerConfig: opts.RelayerConfig, + DB: opts.DB, + KeyStore: opts.KeyStore, + } + cll := newChainSet(privOpts) + + cll.logger.Infow(fmt.Sprintf("Loading chain %s", cid), "evmChainID", cid) + chain, err2 := evmchain.NewTOMLChain(ctx, enabled[i], privOpts) + if err2 != nil { + err = multierr.Combine(err, err2) + continue + } + if _, exists := cll.chains[cid]; exists { + return nil, errors.Errorf("duplicate chain with ID %s", cid) + } + cll.chains[cid] = chain + + s := &ChainRelayerExt{ + chain: chain, + cs: cll, + isDefault: (cid == defaultChainID.String()), + } + result = append(result, s) + } + return newChainRelayerExtsFromSlice(result, opts.AppConfig), nil +} + +func newChainSet(opts evmchain.ChainRelayExtenderConfig) *chainSet { + return &chainSet{ + chains: make(map[string]evmchain.Chain), + startedChains: make([]evmchain.Chain, 0), + logger: opts.Logger.Named("ChainSet"), + opts: opts, + } +} diff --git a/core/services/relay/evm/relayer_extender_test.go b/core/services/relay/evm/relayer_extender_test.go new file mode 100644 index 00000000000..d4cbb1368c2 --- /dev/null +++ b/core/services/relay/evm/relayer_extender_test.go @@ -0,0 +1,89 @@ +package evm_test + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + evmclimocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + configtest "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest/v2" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +func TestChainRelayExtenders(t *testing.T) { + t.Parallel() + + newId := testutils.NewRandomEVMChainID() + cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { + one := uint32(1) + c.EVM[0].MinIncomingConfirmations = &one + t := true + c.EVM = append(c.EVM, &toml.EVMConfig{ChainID: utils.NewBig(newId), Enabled: &t, Chain: toml.Defaults(nil)}) + }) + db := pgtest.NewSqlxDB(t) + kst := cltest.NewKeyStore(t, db, cfg.Database()) + require.NoError(t, kst.Unlock(cltest.Password)) + + opts := evmtest.NewChainRelayExtOpts(t, evmtest.TestChainOpts{DB: db, KeyStore: kst.Eth(), GeneralConfig: cfg}) + opts.GenEthClient = func(*big.Int) evmclient.Client { + return cltest.NewEthMocksWithStartupAssertions(t) + } + relayExtenders, err := evmrelay.NewChainRelayerExtenders(testutils.Context(t), opts) + require.NoError(t, err) + + require.Equal(t, relayExtenders.Len(), 2) + relayExtendersInstances := relayExtenders.Slice() + for _, c := range relayExtendersInstances { + require.NoError(t, c.Start(testutils.Context(t))) + require.NoError(t, c.Ready()) + } + + require.NotEqual(t, relayExtendersInstances[0].Chain().ID().String(), relayExtendersInstances[1].Chain().ID().String()) + + for _, c := range relayExtendersInstances { + require.NoError(t, c.Close()) + } + + relayExtendersInstances[0].Chain().Client().(*evmclimocks.Client).AssertCalled(t, "Close") + relayExtendersInstances[1].Chain().Client().(*evmclimocks.Client).AssertCalled(t, "Close") + + assert.Error(t, relayExtendersInstances[0].Chain().Ready()) + assert.Error(t, relayExtendersInstances[1].Chain().Ready()) + + // test extender methods on single instance + relayExt := relayExtendersInstances[0] + s, err := relayExt.ChainStatus(testutils.Context(t), "not a chain") + assert.Error(t, err) + assert.Empty(t, s) + // the 0-th extender corresponds to the test fixture default chain + s, err = relayExt.ChainStatus(testutils.Context(t), cltest.FixtureChainID.String()) + assert.NotEmpty(t, s) + assert.NoError(t, err) + + stats, cnt, err := relayExt.ChainStatuses(testutils.Context(t), 0, 0) + assert.NoError(t, err) + assert.Len(t, stats, 1) + assert.Equal(t, 1, cnt) + + // test error conditions for NodeStatuses + nstats, cnt, err := relayExt.NodeStatuses(testutils.Context(t), 0, 0, cltest.FixtureChainID.String(), "error, only one chain supported") + assert.Error(t, err) + assert.Nil(t, nstats) + assert.Equal(t, -1, cnt) + + nstats, cnt, err = relayExt.NodeStatuses(testutils.Context(t), 0, 0, "not the chain id") + assert.Error(t, err) + assert.Nil(t, nstats) + assert.Equal(t, -1, cnt) + +} diff --git a/core/services/relay/evm/types/mocks/log_poller_wrapper.go b/core/services/relay/evm/types/mocks/log_poller_wrapper.go new file mode 100644 index 00000000000..a32df6500f3 --- /dev/null +++ b/core/services/relay/evm/types/mocks/log_poller_wrapper.go @@ -0,0 +1,142 @@ +// Code generated by mockery v2.28.1. DO NOT EDIT. + +package mocks + +import ( + context "context" + + types "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" + mock "github.com/stretchr/testify/mock" +) + +// LogPollerWrapper is an autogenerated mock type for the LogPollerWrapper type +type LogPollerWrapper struct { + mock.Mock +} + +// Close provides a mock function with given fields: +func (_m *LogPollerWrapper) Close() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// HealthReport provides a mock function with given fields: +func (_m *LogPollerWrapper) HealthReport() map[string]error { + ret := _m.Called() + + var r0 map[string]error + if rf, ok := ret.Get(0).(func() map[string]error); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string]error) + } + } + + return r0 +} + +// LatestEvents provides a mock function with given fields: +func (_m *LogPollerWrapper) LatestEvents() ([]types.OracleRequest, []types.OracleResponse, error) { + ret := _m.Called() + + var r0 []types.OracleRequest + var r1 []types.OracleResponse + var r2 error + if rf, ok := ret.Get(0).(func() ([]types.OracleRequest, []types.OracleResponse, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() []types.OracleRequest); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]types.OracleRequest) + } + } + + if rf, ok := ret.Get(1).(func() []types.OracleResponse); ok { + r1 = rf() + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).([]types.OracleResponse) + } + } + + if rf, ok := ret.Get(2).(func() error); ok { + r2 = rf() + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// Name provides a mock function with given fields: +func (_m *LogPollerWrapper) Name() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// Ready provides a mock function with given fields: +func (_m *LogPollerWrapper) Ready() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Start provides a mock function with given fields: _a0 +func (_m *LogPollerWrapper) Start(_a0 context.Context) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// SubscribeToUpdates provides a mock function with given fields: name, subscriber +func (_m *LogPollerWrapper) SubscribeToUpdates(name string, subscriber types.RouteUpdateSubscriber) { + _m.Called(name, subscriber) +} + +type mockConstructorTestingTNewLogPollerWrapper interface { + mock.TestingT + Cleanup(func()) +} + +// NewLogPollerWrapper creates a new instance of LogPollerWrapper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewLogPollerWrapper(t mockConstructorTestingTNewLogPollerWrapper) *LogPollerWrapper { + mock := &LogPollerWrapper{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/relay/evm/types/types.go b/core/services/relay/evm/types/types.go index 3047dd180aa..8671082db25 100644 --- a/core/services/relay/evm/types/types.go +++ b/core/services/relay/evm/types/types.go @@ -2,6 +2,9 @@ package types import ( "context" + "encoding/json" + "errors" + "fmt" "github.com/ethereum/go-ethereum/common" "github.com/lib/pq" @@ -10,6 +13,9 @@ import ( ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-relay/pkg/types" + relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types" + "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -25,6 +31,36 @@ type RelayConfig struct { FeedID *common.Hash `json:"feedID"` } +type RelayOpts struct { + // TODO BCF-2508 -- should anyone ever get the raw config bytes that are embedded in args? if not, + // make this private and wrap the arg fields with funcs on RelayOpts + relaytypes.RelayArgs + c *RelayConfig +} + +var ErrBadRelayConfig = errors.New("bad relay config") + +func NewRelayOpts(args types.RelayArgs) *RelayOpts { + return &RelayOpts{ + RelayArgs: args, + c: nil, // lazy initialization + } +} + +func (o *RelayOpts) RelayConfig() (RelayConfig, error) { + var empty RelayConfig + //TODO this should be done once and the error should be cached + if o.c == nil { + var c RelayConfig + err := json.Unmarshal(o.RelayArgs.RelayConfig, &c) + if err != nil { + return empty, fmt.Errorf("%w: failed to deserialize relay config: %w", ErrBadRelayConfig, err) + } + o.c = &c + } + return *o.c, nil +} + type ConfigPoller interface { ocrtypes.ContractConfigTracker @@ -32,3 +68,43 @@ type ConfigPoller interface { Close() error Replay(ctx context.Context, fromBlock int64) error } + +// TODO(FUN-668): Migrate this fully into relaytypes.FunctionsProvider +type FunctionsProvider interface { + relaytypes.FunctionsProvider + LogPollerWrapper() LogPollerWrapper +} + +type OracleRequest struct { + RequestId [32]byte + RequestingContract common.Address + RequestInitiator common.Address + SubscriptionId uint64 + SubscriptionOwner common.Address + Data []byte + DataVersion uint16 + Flags [32]byte + CallbackGasLimit uint64 + TxHash common.Hash + CoordinatorContract common.Address + OnchainMetadata []byte +} + +type OracleResponse struct { + RequestId [32]byte +} + +type RouteUpdateSubscriber interface { + UpdateRoutes(activeCoordinator common.Address, proposedCoordinator common.Address) error +} + +// A LogPoller wrapper that understands router proxy contracts +// +//go:generate mockery --quiet --name LogPollerWrapper --output ./mocks/ --case=underscore +type LogPollerWrapper interface { + relaytypes.Service + LatestEvents() ([]OracleRequest, []OracleResponse, error) + + // TODO (FUN-668): Remove from the LOOP interface and only use internally within the EVM relayer + SubscribeToUpdates(name string, subscriber RouteUpdateSubscriber) +} diff --git a/core/services/relay/relay.go b/core/services/relay/relay.go index 3028f59fb28..c6d3ab6a900 100644 --- a/core/services/relay/relay.go +++ b/core/services/relay/relay.go @@ -5,6 +5,8 @@ import ( "errors" "fmt" "math/big" + "regexp" + "strconv" "golang.org/x/exp/maps" @@ -28,6 +30,78 @@ var ( } ) +// ID uniquely identifies a relayer by network and chain id +type ID struct { + Network Network + ChainID ChainID +} + +func (i *ID) Name() string { + return fmt.Sprintf("%s.%s", i.Network, i.ChainID.String()) +} + +func (i *ID) String() string { + return i.Name() +} +func NewID(n Network, c ChainID) (ID, error) { + id := ID{Network: n, ChainID: c} + err := id.validate() + if err != nil { + return ID{}, err + } + return id, nil +} +func (i *ID) validate() error { + // the only validation is to ensure that EVM chain ids are compatible with int64 + if i.Network == EVM { + _, err := i.ChainID.Int64() + if err != nil { + return fmt.Errorf("RelayIdentifier invalid: EVM relayer must have integer-compatible chain ID: %w", err) + } + } + return nil +} + +var idRegex = regexp.MustCompile( + fmt.Sprintf("^((%s)|(%s)|(%s)|(%s))\\.", EVM, Cosmos, Solana, StarkNet), +) + +func (i *ID) UnmarshalString(s string) error { + idxs := idRegex.FindStringIndex(s) + if idxs == nil { + return fmt.Errorf("error unmarshaling Identifier. %q does not match expected pattern", s) + } + // ignore the `.` in the match by dropping last rune + network := s[idxs[0] : idxs[1]-1] + chainID := s[idxs[1]:] + newID := &ID{ChainID: ChainID(chainID)} + for n := range SupportedRelays { + if Network(network) == n { + newID.Network = n + break + } + } + if newID.Network == "" { + return fmt.Errorf("error unmarshaling identifier: did not find network in supported list %q", network) + } + i.ChainID = newID.ChainID + i.Network = newID.Network + return nil +} + +type ChainID string + +func (c ChainID) String() string { + return string(c) +} +func (c ChainID) Int64() (int64, error) { + i, err := strconv.Atoi(c.String()) + if err != nil { + return int64(0), err + } + return int64(i), nil +} + // RelayerExt is a subset of [loop.Relayer] for adapting [types.Relayer], typically with a ChainSet. See [relayerAdapter]. type RelayerExt interface { services.ServiceCtx @@ -65,6 +139,10 @@ func (r *relayerAdapter) NewMercuryProvider(ctx context.Context, rargs types.Rel return r.Relayer.NewMercuryProvider(rargs, pargs) } +func (r *relayerAdapter) NewFunctionsProvider(ctx context.Context, rargs types.RelayArgs, pargs types.PluginArgs) (types.FunctionsProvider, error) { + return r.Relayer.NewFunctionsProvider(rargs, pargs) +} + func (r *relayerAdapter) Start(ctx context.Context) error { var ms services.MultiStart return ms.Start(ctx, r.RelayerExt, r.Relayer) diff --git a/core/services/relay/relay_test.go b/core/services/relay/relay_test.go new file mode 100644 index 00000000000..0ed14b6c5b7 --- /dev/null +++ b/core/services/relay/relay_test.go @@ -0,0 +1,81 @@ +package relay + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestIdentifier_UnmarshalString(t *testing.T) { + type fields struct { + Network Network + ChainID ChainID + } + type args struct { + s string + } + tests := []struct { + name string + want fields + args args + wantErr bool + }{ + {name: "evm", + args: args{s: "evm.1"}, + wantErr: false, + want: fields{Network: EVM, ChainID: "1"}, + }, + {name: "bad network", + args: args{s: "notANetwork.1"}, + wantErr: true, + }, + {name: "bad pattern", + args: args{s: "evm_1"}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + i := &ID{} + err := i.UnmarshalString(tt.args.s) + if (err != nil) != tt.wantErr { + t.Errorf("Identifier.UnmarshalString() error = %v, wantErr %v", err, tt.wantErr) + } + assert.Equal(t, tt.want.Network, i.Network) + assert.Equal(t, tt.want.ChainID, i.ChainID) + }) + } +} + +func TestNewID(t *testing.T) { + type args struct { + n Network + c ChainID + } + tests := []struct { + name string + args args + want ID + wantErr bool + }{ + {name: "good evm", + args: args{n: EVM, c: "1"}, + want: ID{Network: EVM, ChainID: "1"}, + }, + {name: "bad evm", + args: args{n: EVM, c: "not a number"}, + want: ID{}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := NewID(tt.args.n, tt.args.c) + if (err != nil) != tt.wantErr { + t.Errorf("NewID() error = %v, wantErr %v", err, tt.wantErr) + return + } + assert.Equal(t, tt.want, got, "got id %v", got) + }) + } +} diff --git a/core/services/s4/envelope.go b/core/services/s4/envelope.go index 12435ecd8c5..07e4201341c 100644 --- a/core/services/s4/envelope.go +++ b/core/services/s4/envelope.go @@ -6,7 +6,7 @@ import ( "fmt" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/smartcontractkit/chainlink/v2/core/utils" ) // Envelope represents a JSON object that is signed for address verification. @@ -42,8 +42,7 @@ func (e Envelope) Sign(privateKey *ecdsa.PrivateKey) (signature []byte, err erro if err != nil { return nil, err } - hash := crypto.Keccak256Hash(js) - return crypto.Sign(hash[:], privateKey) + return utils.GenerateEthSignature(privateKey, js) } // GetSignerAddress verifies the signature and returns the signing address. @@ -55,12 +54,7 @@ func (e Envelope) GetSignerAddress(signature []byte) (address common.Address, er if err != nil { return common.Address{}, err } - hash := crypto.Keccak256Hash(js) - sigPublicKey, err := crypto.SigToPub(hash[:], signature) - if err != nil { - return common.Address{}, err - } - return crypto.PubkeyToAddress(*sigPublicKey), nil + return utils.GetSignersEthAddress(js, signature) } func (e Envelope) ToJson() ([]byte, error) { diff --git a/core/services/synchronization/telem/telem_automation_custom.pb.go b/core/services/synchronization/telem/telem_automation_custom.pb.go index 707a7a0c826..e88cb2f951a 100644 --- a/core/services/synchronization/telem/telem_automation_custom.pb.go +++ b/core/services/synchronization/telem/telem_automation_custom.pb.go @@ -25,10 +25,10 @@ type BlockNumber struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` - Timetsamp uint64 `protobuf:"varint,2,opt,name=timetsamp,proto3" json:"timetsamp,omitempty"` - BlockNumber uint64 `protobuf:"varint,3,opt,name=block_number,json=blockNumber,proto3" json:"block_number,omitempty"` - BlockHash string `protobuf:"bytes,4,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` + Timestamp uint64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + BlockNumber uint64 `protobuf:"varint,2,opt,name=block_number,json=blockNumber,proto3" json:"block_number,omitempty"` + BlockHash string `protobuf:"bytes,3,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` + ConfigDigest []byte `protobuf:"bytes,4,opt,name=config_digest,json=configDigest,proto3" json:"config_digest,omitempty"` } func (x *BlockNumber) Reset() { @@ -63,16 +63,9 @@ func (*BlockNumber) Descriptor() ([]byte, []int) { return file_telem_automation_custom_proto_rawDescGZIP(), []int{0} } -func (x *BlockNumber) GetNodeId() string { +func (x *BlockNumber) GetTimestamp() uint64 { if x != nil { - return x.NodeId - } - return "" -} - -func (x *BlockNumber) GetTimetsamp() uint64 { - if x != nil { - return x.Timetsamp + return x.Timestamp } return 0 } @@ -91,14 +84,21 @@ func (x *BlockNumber) GetBlockHash() string { return "" } +func (x *BlockNumber) GetConfigDigest() []byte { + if x != nil { + return x.ConfigDigest + } + return nil +} + type NodeVersion struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` - Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` - NodeVersion uint32 `protobuf:"varint,3,opt,name=node_version,json=nodeVersion,proto3" json:"node_version,omitempty"` + Timestamp uint64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + NodeVersion string `protobuf:"bytes,2,opt,name=node_version,json=nodeVersion,proto3" json:"node_version,omitempty"` + ConfigDigest []byte `protobuf:"bytes,3,opt,name=config_digest,json=configDigest,proto3" json:"config_digest,omitempty"` } func (x *NodeVersion) Reset() { @@ -133,53 +133,145 @@ func (*NodeVersion) Descriptor() ([]byte, []int) { return file_telem_automation_custom_proto_rawDescGZIP(), []int{1} } -func (x *NodeVersion) GetNodeId() string { +func (x *NodeVersion) GetTimestamp() uint64 { if x != nil { - return x.NodeId + return x.Timestamp } - return "" + return 0 } -func (x *NodeVersion) GetTimestamp() uint64 { +func (x *NodeVersion) GetNodeVersion() string { if x != nil { - return x.Timestamp + return x.NodeVersion } - return 0 + return "" } -func (x *NodeVersion) GetNodeVersion() uint32 { +func (x *NodeVersion) GetConfigDigest() []byte { if x != nil { + return x.ConfigDigest + } + return nil +} + +type AutomationTelemWrapper struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Msg: + // + // *AutomationTelemWrapper_BlockNumber + // *AutomationTelemWrapper_NodeVersion + Msg isAutomationTelemWrapper_Msg `protobuf_oneof:"msg"` +} + +func (x *AutomationTelemWrapper) Reset() { + *x = AutomationTelemWrapper{} + if protoimpl.UnsafeEnabled { + mi := &file_telem_automation_custom_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AutomationTelemWrapper) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AutomationTelemWrapper) ProtoMessage() {} + +func (x *AutomationTelemWrapper) ProtoReflect() protoreflect.Message { + mi := &file_telem_automation_custom_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AutomationTelemWrapper.ProtoReflect.Descriptor instead. +func (*AutomationTelemWrapper) Descriptor() ([]byte, []int) { + return file_telem_automation_custom_proto_rawDescGZIP(), []int{2} +} + +func (m *AutomationTelemWrapper) GetMsg() isAutomationTelemWrapper_Msg { + if m != nil { + return m.Msg + } + return nil +} + +func (x *AutomationTelemWrapper) GetBlockNumber() *BlockNumber { + if x, ok := x.GetMsg().(*AutomationTelemWrapper_BlockNumber); ok { + return x.BlockNumber + } + return nil +} + +func (x *AutomationTelemWrapper) GetNodeVersion() *NodeVersion { + if x, ok := x.GetMsg().(*AutomationTelemWrapper_NodeVersion); ok { return x.NodeVersion } - return 0 + return nil } +type isAutomationTelemWrapper_Msg interface { + isAutomationTelemWrapper_Msg() +} + +type AutomationTelemWrapper_BlockNumber struct { + BlockNumber *BlockNumber `protobuf:"bytes,1,opt,name=block_number,json=blockNumber,proto3,oneof"` +} + +type AutomationTelemWrapper_NodeVersion struct { + NodeVersion *NodeVersion `protobuf:"bytes,2,opt,name=node_version,json=nodeVersion,proto3,oneof"` +} + +func (*AutomationTelemWrapper_BlockNumber) isAutomationTelemWrapper_Msg() {} + +func (*AutomationTelemWrapper_NodeVersion) isAutomationTelemWrapper_Msg() {} + var File_telem_automation_custom_proto protoreflect.FileDescriptor var file_telem_automation_custom_proto_rawDesc = []byte{ 0x0a, 0x1d, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x5f, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x05, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x22, 0x86, 0x01, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, - 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x74, 0x73, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x74, 0x73, 0x61, 0x6d, 0x70, 0x12, 0x21, 0x0a, - 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x22, - 0x67, 0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x17, - 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x6e, 0x6f, 0x64, - 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x4e, 0x5a, 0x4c, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6d, 0x61, 0x72, 0x74, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x61, 0x63, 0x74, 0x6b, 0x69, 0x74, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x69, 0x6e, - 0x6b, 0x2f, 0x76, 0x32, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x2f, 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x05, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x22, 0x92, 0x01, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x22, 0x73, 0x0a, 0x0b, 0x4e, + 0x6f, 0x64, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x6f, 0x64, 0x65, + 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x6e, 0x6f, 0x64, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, + 0x22, 0x91, 0x01, 0x0a, 0x16, 0x41, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, + 0x65, 0x6c, 0x65, 0x6d, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x0c, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x0c, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x6d, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x00, + 0x52, 0x0b, 0x6e, 0x6f, 0x64, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x05, 0x0a, + 0x03, 0x6d, 0x73, 0x67, 0x42, 0x4e, 0x5a, 0x4c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x73, 0x6d, 0x61, 0x72, 0x74, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, + 0x6b, 0x69, 0x74, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x2f, 0x76, 0x32, + 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x73, + 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x74, + 0x65, 0x6c, 0x65, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -194,17 +286,20 @@ func file_telem_automation_custom_proto_rawDescGZIP() []byte { return file_telem_automation_custom_proto_rawDescData } -var file_telem_automation_custom_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_telem_automation_custom_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_telem_automation_custom_proto_goTypes = []interface{}{ - (*BlockNumber)(nil), // 0: telem.BlockNumber - (*NodeVersion)(nil), // 1: telem.NodeVersion + (*BlockNumber)(nil), // 0: telem.BlockNumber + (*NodeVersion)(nil), // 1: telem.NodeVersion + (*AutomationTelemWrapper)(nil), // 2: telem.AutomationTelemWrapper } var file_telem_automation_custom_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 0, // 0: telem.AutomationTelemWrapper.block_number:type_name -> telem.BlockNumber + 1, // 1: telem.AutomationTelemWrapper.node_version:type_name -> telem.NodeVersion + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } func init() { file_telem_automation_custom_proto_init() } @@ -237,6 +332,22 @@ func file_telem_automation_custom_proto_init() { return nil } } + file_telem_automation_custom_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AutomationTelemWrapper); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_telem_automation_custom_proto_msgTypes[2].OneofWrappers = []interface{}{ + (*AutomationTelemWrapper_BlockNumber)(nil), + (*AutomationTelemWrapper_NodeVersion)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -244,7 +355,7 @@ func file_telem_automation_custom_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_telem_automation_custom_proto_rawDesc, NumEnums: 0, - NumMessages: 2, + NumMessages: 3, NumExtensions: 0, NumServices: 0, }, diff --git a/core/services/synchronization/telem/telem_automation_custom.proto b/core/services/synchronization/telem/telem_automation_custom.proto index c83ca5bbf27..bded8e8b70a 100644 --- a/core/services/synchronization/telem/telem_automation_custom.proto +++ b/core/services/synchronization/telem/telem_automation_custom.proto @@ -5,16 +5,23 @@ option go_package = "github.com/smartcontractkit/chainlink/v2/core/services/sync package telem; message BlockNumber { - string node_id = 1; - uint64 timetsamp = 2; - uint64 block_number = 3; - string block_hash = 4; + uint64 timestamp = 1; + uint64 block_number = 2; + string block_hash = 3; + bytes config_digest = 4; } message NodeVersion { - string node_id = 1; - uint64 timestamp = 2; - uint32 node_version = 3; + uint64 timestamp = 1; + string node_version = 2; + bytes config_digest = 3; +} + +message AutomationTelemWrapper{ + oneof msg { + BlockNumber block_number = 1; + NodeVersion node_version = 2; + } } // // StreamsLookup contains the metadata about a mercury request diff --git a/core/services/vrf/delegate.go b/core/services/vrf/delegate.go index b3c3fb74da4..733c21b45a7 100644 --- a/core/services/vrf/delegate.go +++ b/core/services/vrf/delegate.go @@ -34,13 +34,13 @@ import ( ) type Delegate struct { - q pg.Q - pr pipeline.Runner - porm pipeline.ORM - ks keystore.Master - cc evm.ChainSet - lggr logger.Logger - mailMon *utils.MailboxMonitor + q pg.Q + pr pipeline.Runner + porm pipeline.ORM + ks keystore.Master + legacyChains evm.LegacyChainContainer + lggr logger.Logger + mailMon *utils.MailboxMonitor } func NewDelegate( @@ -48,18 +48,18 @@ func NewDelegate( ks keystore.Master, pr pipeline.Runner, porm pipeline.ORM, - chainSet evm.ChainSet, + legacyChains evm.LegacyChainContainer, lggr logger.Logger, cfg pg.QConfig, mailMon *utils.MailboxMonitor) *Delegate { return &Delegate{ - q: pg.NewQ(db, lggr, cfg), - ks: ks, - pr: pr, - porm: porm, - cc: chainSet, - lggr: lggr, - mailMon: mailMon, + q: pg.NewQ(db, lggr, cfg), + ks: ks, + pr: pr, + porm: porm, + legacyChains: legacyChains, + lggr: lggr, + mailMon: mailMon, } } @@ -73,7 +73,7 @@ func (d *Delegate) BeforeJobDeleted(spec job.Job) {} func (d *Delegate) OnDeleteJob(spec job.Job, q pg.Queryer) error { return nil } // ServicesForSpec satisfies the job.Delegate interface. -func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { +func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]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) } @@ -81,7 +81,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { if err != nil { return nil, err } - chain, err := d.cc.Get(jb.VRFSpec.EVMChainID.ToInt()) + chain, err := d.legacyChains.Get(jb.VRFSpec.EVMChainID.String()) if err != nil { return nil, err } @@ -126,10 +126,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { ) lV1 := l.Named("VRFListener") lV2 := l.Named("VRFListenerV2") - - if vrfOwner == nil { - lV2.Infow("Running without VRFOwnerAddress set on the spec") - } + lV2Plus := l.Named("VRFListenerV2Plus") for _, task := range pl.Tasks { if _, ok := task.(*pipeline.VRFTaskV2Plus); ok { @@ -144,7 +141,9 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { if err := CheckFromAddressMaxGasPrices(jb, chain.Config().EVM().GasEstimator().PriceMaxKey); err != nil { return nil, err } - + if vrfOwner != nil { + return nil, errors.New("VRF Owner is not supported for VRF V2 Plus") + } linkEthFeedAddress, err := coordinatorV2Plus.LINKETHFEED(nil) if err != nil { return nil, errors.Wrap(err, "LINKETHFEED") @@ -157,7 +156,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { return []job.ServiceCtx{v2.New( chain.Config().EVM(), chain.Config().EVM().GasEstimator(), - lV2, + lV2Plus, chain.Client(), chain.ID(), chain.LogBroadcaster(), @@ -173,7 +172,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { d.mailMon, utils.NewHighCapacityMailbox[log.Broadcast](), func() {}, - GetStartingResponseCountsV2(d.q, lV2, chainId.Uint64(), chain.Config().EVM().FinalityDepth()), + GetStartingResponseCountsV2(d.q, lV2Plus, chainId.Uint64(), chain.Config().EVM().FinalityDepth()), chain.HeadBroadcaster(), vrfcommon.NewLogDeduper(int(chain.Config().EVM().FinalityDepth())))}, nil } @@ -198,6 +197,9 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { if err != nil { return nil, errors.Wrap(err, "NewAggregatorV3Interface") } + if vrfOwner == nil { + lV2.Infow("Running without VRFOwnerAddress set on the spec") + } return []job.ServiceCtx{v2.New( chain.Config().EVM(), diff --git a/core/services/vrf/delegate_test.go b/core/services/vrf/delegate_test.go index 4b7f023b41a..dba1d818ed4 100644 --- a/core/services/vrf/delegate_test.go +++ b/core/services/vrf/delegate_test.go @@ -30,6 +30,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/vrfkey" "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" "github.com/smartcontractkit/chainlink/v2/core/services/srvctest" "github.com/smartcontractkit/chainlink/v2/core/services/vrf" @@ -49,18 +50,18 @@ import ( ) type vrfUniverse struct { - jrm job.ORM - pr pipeline.Runner - prm pipeline.ORM - lb *log_mocks.Broadcaster - ec *evmclimocks.Client - ks keystore.Master - vrfkey vrfkey.KeyV2 - submitter common.Address - txm *txmmocks.MockEvmTxManager - hb httypes.HeadBroadcaster - cc evm.ChainSet - cid big.Int + jrm job.ORM + pr pipeline.Runner + prm pipeline.ORM + lb *log_mocks.Broadcaster + ec *evmclimocks.Client + ks keystore.Master + vrfkey vrfkey.KeyV2 + submitter common.Address + txm *txmmocks.MockEvmTxManager + hb httypes.HeadBroadcaster + legacyChains evm.LegacyChainContainer + cid big.Int } func buildVrfUni(t *testing.T, db *sqlx.DB, cfg chainlink.GeneralConfig) vrfUniverse { @@ -77,10 +78,12 @@ func buildVrfUni(t *testing.T, db *sqlx.DB, cfg chainlink.GeneralConfig) vrfUniv btORM := bridges.NewORM(db, lggr, cfg.Database()) txm := txmmocks.NewMockEvmTxManager(t) ks := keystore.New(db, utils.FastScryptParams, lggr, cfg.Database()) - cc := evmtest.NewChainSet(t, evmtest.TestChainOpts{LogBroadcaster: lb, KeyStore: ks.Eth(), Client: ec, DB: db, GeneralConfig: cfg, TxManager: txm}) - jrm := job.NewORM(db, cc, prm, btORM, ks, lggr, cfg.Database()) + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{LogBroadcaster: lb, KeyStore: ks.Eth(), Client: ec, DB: db, GeneralConfig: cfg, TxManager: txm}) + legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) + require.NoError(t, err) + jrm := job.NewORM(db, legacyChains, prm, btORM, ks, lggr, cfg.Database()) t.Cleanup(func() { jrm.Close() }) - pr := pipeline.NewRunner(prm, btORM, cfg.JobPipeline(), cfg.WebServer(), cc, ks.Eth(), ks.VRF(), lggr, nil, nil) + pr := pipeline.NewRunner(prm, btORM, cfg.JobPipeline(), cfg.WebServer(), legacyChains, ks.Eth(), ks.VRF(), lggr, nil, nil) require.NoError(t, ks.Unlock(testutils.Password)) k, err := ks.Eth().Create(testutils.FixtureChainID) require.NoError(t, err) @@ -90,18 +93,18 @@ func buildVrfUni(t *testing.T, db *sqlx.DB, cfg chainlink.GeneralConfig) vrfUniv require.NoError(t, err) return vrfUniverse{ - jrm: jrm, - pr: pr, - prm: prm, - lb: lb, - ec: ec, - ks: ks, - vrfkey: vrfkey, - submitter: submitter, - txm: txm, - hb: hb, - cc: cc, - cid: *ec.ConfiguredChainID(), + jrm: jrm, + pr: pr, + prm: prm, + lb: lb, + ec: ec, + ks: ks, + vrfkey: vrfkey, + submitter: submitter, + txm: txm, + hb: hb, + legacyChains: legacyChains, + cid: *ec.ConfiguredChainID(), } } @@ -149,7 +152,7 @@ func setup(t *testing.T) (vrfUniverse, *v1.Listener, job.Job) { vuni.ks, vuni.pr, vuni.prm, - vuni.cc, + vuni.legacyChains, logger.TestLogger(t), cfg.Database(), mailMon) @@ -673,3 +676,37 @@ func Test_FromAddressMaxGasPricesAllEqual(t *testing.T) { assert.False(tt, vrf.FromAddressMaxGasPricesAllEqual(jb, cfg.PriceMaxKey)) }) } + +func Test_VRFV2PlusServiceFailsWhenVRFOwnerProvided(t *testing.T) { + db := pgtest.NewSqlxDB(t) + cfg := configtest.NewTestGeneralConfig(t) + vuni := buildVrfUni(t, db, cfg) + + mailMon := srvctest.Start(t, utils.NewMailboxMonitor(t.Name())) + + vd := vrf.NewDelegate( + db, + vuni.ks, + vuni.pr, + vuni.prm, + vuni.legacyChains, + logger.TestLogger(t), + cfg.Database(), + mailMon) + chain, err := vuni.legacyChains.Get(testutils.FixtureChainID.String()) + require.NoError(t, err) + vs := testspecs.GenerateVRFSpec(testspecs.VRFSpecParams{ + VRFVersion: vrfcommon.V2Plus, + PublicKey: vuni.vrfkey.PublicKey.String(), + FromAddresses: []string{string(vuni.submitter.Hex())}, + GasLanePrice: chain.Config().EVM().GasEstimator().PriceMax(), + }) + toml := "vrfOwnerAddress=\"0xF62fEFb54a0af9D32CDF0Db21C52710844c7eddb\"\n" + vs.Toml() + jb, err := vrfcommon.ValidatedVRFSpec(toml) + require.NoError(t, err) + err = vuni.jrm.CreateJob(&jb) + require.NoError(t, err) + _, err = vd.ServicesForSpec(jb) + require.Error(t, err) + require.Equal(t, "VRF Owner is not supported for VRF V2 Plus", err.Error()) +} diff --git a/core/services/vrf/v1/integration_test.go b/core/services/vrf/v1/integration_test.go index d0c87c9cc99..42b709e298c 100644 --- a/core/services/vrf/v1/integration_test.go +++ b/core/services/vrf/v1/integration_test.go @@ -89,6 +89,10 @@ func TestIntegration_VRF_JPV2(t *testing.T) { assert.NotNil(t, 0, runs[0].Outputs.Val) assert.NotNil(t, 0, runs[1].Outputs.Val) + // stop jobs as to not cause a race condition in geth simulated backend + // between job creating new tx and fulfillment logs polling below + require.NoError(t, app.JobSpawner().DeleteJob(jb.ID)) + // Ensure the eth transaction gets confirmed on chain. gomega.NewWithT(t).Eventually(func() bool { orm := txmgr.NewTxStore(app.GetSqlxDB(), app.GetLogger(), app.GetConfig().Database()) @@ -142,12 +146,12 @@ func TestIntegration_VRF_WithBHS(t *testing.T) { sendingKeys := []string{key.Address.String()} // Create BHS Job and start it - _ = vrftesthelpers.CreateAndStartBHSJob(t, sendingKeys, app, cu.BHSContractAddress.String(), - cu.RootContractAddress.String(), "", "") + bhsJob := vrftesthelpers.CreateAndStartBHSJob(t, sendingKeys, app, cu.BHSContractAddress.String(), + cu.RootContractAddress.String(), "", "", "", 0, 200) // Ensure log poller is ready and has all logs. - require.NoError(t, app.Chains.EVM.Chains()[0].LogPoller().Ready()) - require.NoError(t, app.Chains.EVM.Chains()[0].LogPoller().Replay(testutils.Context(t), 1)) + require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Ready()) + require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Replay(testutils.Context(t), 1)) // Create a VRF request _, err := cu.ConsumerContract.TestRequestRandomness(cu.Carol, @@ -200,6 +204,11 @@ func TestIntegration_VRF_WithBHS(t *testing.T) { assert.Equal(t, 4, len(runs[0].PipelineTaskRuns)) assert.NotNil(t, 0, runs[0].Outputs.Val) + // stop jobs as to not cause a race condition in geth simulated backend + // between job creating new tx and fulfillment logs polling below + require.NoError(t, app.JobSpawner().DeleteJob(jb.ID)) + require.NoError(t, app.JobSpawner().DeleteJob(bhsJob.ID)) + // Ensure the eth transaction gets confirmed on chain. gomega.NewWithT(t).Eventually(func() bool { orm := txmgr.NewTxStore(app.GetSqlxDB(), app.GetLogger(), app.GetConfig().Database()) diff --git a/core/services/vrf/v2/coordinator_v2x_interface.go b/core/services/vrf/v2/coordinator_v2x_interface.go index 9535c501260..8e2942ea927 100644 --- a/core/services/vrf/v2/coordinator_v2x_interface.go +++ b/core/services/vrf/v2/coordinator_v2x_interface.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/pkg/errors" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" @@ -21,11 +22,6 @@ var ( _ CoordinatorV2_X = (*coordinatorV2Plus)(nil) ) -var ( - _ CoordinatorV2_X = (*coordinatorV2)(nil) - _ CoordinatorV2_X = (*coordinatorV2Plus)(nil) -) - // CoordinatorV2_X is an interface that allows us to use the same code for // both the V2 and V2Plus coordinators. type CoordinatorV2_X interface { @@ -43,11 +39,13 @@ type CoordinatorV2_X interface { RegisterProvingKey(opts *bind.TransactOpts, oracle common.Address, publicProvingKey [2]*big.Int) (*types.Transaction, error) FilterSubscriptionCreated(opts *bind.FilterOpts, subID []*big.Int) (SubscriptionCreatedIterator, error) FilterRandomWordsRequested(opts *bind.FilterOpts, keyHash [][32]byte, subID []*big.Int, sender []common.Address) (RandomWordsRequestedIterator, error) - FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestID []*big.Int) (RandomWordsFulfilledIterator, error) + FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestID []*big.Int, subID []*big.Int) (RandomWordsFulfilledIterator, error) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) RemoveConsumer(opts *bind.TransactOpts, subID *big.Int, consumer common.Address) (*types.Transaction, error) CancelSubscription(opts *bind.TransactOpts, subID *big.Int, to common.Address) (*types.Transaction, error) GetCommitment(opts *bind.CallOpts, requestID *big.Int) ([32]byte, error) + Migrate(opts *bind.TransactOpts, subID *big.Int, newCoordinator common.Address) (*types.Transaction, error) + FundSubscriptionWithEth(opts *bind.TransactOpts, subID *big.Int, amount *big.Int) (*types.Transaction, error) } type coordinatorV2 struct { @@ -144,7 +142,7 @@ func (c *coordinatorV2) FilterRandomWordsRequested(opts *bind.FilterOpts, keyHas return NewV2RandomWordsRequestedIterator(it), nil } -func (c *coordinatorV2) FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestID []*big.Int) (RandomWordsFulfilledIterator, error) { +func (c *coordinatorV2) FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestID []*big.Int, subID []*big.Int) (RandomWordsFulfilledIterator, error) { it, err := c.coordinator.FilterRandomWordsFulfilled(opts, requestID) if err != nil { return nil, err @@ -168,6 +166,14 @@ func (c *coordinatorV2) GetCommitment(opts *bind.CallOpts, requestID *big.Int) ( return c.coordinator.GetCommitment(opts, requestID) } +func (c *coordinatorV2) Migrate(opts *bind.TransactOpts, subID *big.Int, newCoordinator common.Address) (*types.Transaction, error) { + panic("migrate not implemented for v2") +} + +func (c *coordinatorV2) FundSubscriptionWithEth(opts *bind.TransactOpts, subID *big.Int, amount *big.Int) (*types.Transaction, error) { + panic("fund subscription with Eth not implemented for v2") +} + type coordinatorV2Plus struct { vrfVersion vrfcommon.Version coordinator *vrf_coordinator_v2plus.VRFCoordinatorV2Plus @@ -274,8 +280,8 @@ func (c *coordinatorV2Plus) FilterRandomWordsRequested(opts *bind.FilterOpts, ke return NewV2PlusRandomWordsRequestedIterator(it), nil } -func (c *coordinatorV2Plus) FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestID []*big.Int) (RandomWordsFulfilledIterator, error) { - it, err := c.coordinator.FilterRandomWordsFulfilled(opts, requestID) +func (c *coordinatorV2Plus) FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestID []*big.Int, subID []*big.Int) (RandomWordsFulfilledIterator, error) { + it, err := c.coordinator.FilterRandomWordsFulfilled(opts, requestID, subID) if err != nil { return nil, err } @@ -298,6 +304,19 @@ func (c *coordinatorV2Plus) GetCommitment(opts *bind.CallOpts, requestID *big.In return c.coordinator.SRequestCommitments(opts, requestID) } +func (c *coordinatorV2Plus) Migrate(opts *bind.TransactOpts, subID *big.Int, newCoordinator common.Address) (*types.Transaction, error) { + return c.coordinator.Migrate(opts, subID, newCoordinator) +} + +func (c *coordinatorV2Plus) FundSubscriptionWithEth(opts *bind.TransactOpts, subID *big.Int, amount *big.Int) (*types.Transaction, error) { + if opts == nil { + return nil, errors.New("*bind.TransactOpts cannot be nil") + } + o := *opts + o.Value = amount + return c.coordinator.FundSubscriptionWithEth(&o, subID) +} + var ( _ RandomWordsRequestedIterator = (*v2RandomWordsRequestedIterator)(nil) _ RandomWordsRequestedIterator = (*v2PlusRandomWordsRequestedIterator)(nil) @@ -568,7 +587,7 @@ var ( type RandomWordsFulfilled interface { RequestID() *big.Int Success() bool - NativePayment() bool + SubID() *big.Int Payment() *big.Int Raw() types.Log } @@ -597,6 +616,10 @@ func (rwf *v2RandomWordsFulfilled) NativePayment() bool { return false } +func (rwf *v2RandomWordsFulfilled) SubID() *big.Int { + panic("VRF V2 RandomWordsFulfilled does not implement SubID") +} + func (rwf *v2RandomWordsFulfilled) Payment() *big.Int { return rwf.event.Payment } @@ -625,12 +648,8 @@ func (rwf *v2PlusRandomWordsFulfilled) Success() bool { return rwf.event.Success } -func (rwf *v2PlusRandomWordsFulfilled) NativePayment() bool { - nativePayment, err := extraargs.FromExtraArgsV1(rwf.event.ExtraArgs) - if err != nil { - panic(err) - } - return nativePayment +func (rwf *v2PlusRandomWordsFulfilled) SubID() *big.Int { + return rwf.event.SubID } func (rwf *v2PlusRandomWordsFulfilled) Payment() *big.Int { diff --git a/core/services/vrf/v2/integration_helpers_test.go b/core/services/vrf/v2/integration_helpers_test.go index 4f99b00cd16..43ca198334d 100644 --- a/core/services/vrf/v2/integration_helpers_test.go +++ b/core/services/vrf/v2/integration_helpers_test.go @@ -51,10 +51,12 @@ func testSingleConsumerHappyPath( batchCoordinatorAddress common.Address, vrfOwnerAddress *common.Address, vrfVersion vrfcommon.Version, + nativePayment bool, assertions ...func( t *testing.T, coordinator v22.CoordinatorV2_X, - rwfe v22.RandomWordsFulfilled), + rwfe v22.RandomWordsFulfilled, + subID *big.Int), ) { key1 := cltest.MustGenerateRandomKey(t) key2 := cltest.MustGenerateRandomKey(t) @@ -74,7 +76,7 @@ func testSingleConsumerHappyPath( app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, uni.backend, ownerKey, key1, key2) // Create a subscription and fund with 5 LINK. - subID := subscribeAndAssertSubscriptionCreatedEvent(t, consumerContract, consumer, consumerContractAddress, big.NewInt(5e18), coordinator, uni.backend) + subID := subscribeAndAssertSubscriptionCreatedEvent(t, consumerContract, consumer, consumerContractAddress, big.NewInt(5e18), coordinator, uni.backend, nativePayment) // Fund gas lanes. sendEth(t, ownerKey, uni.backend, key1.Address, 10) @@ -98,7 +100,7 @@ func testSingleConsumerHappyPath( // Make the first randomness request. numWords := uint32(20) - requestID1, _ := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, 500_000, coordinator, uni.backend) + requestID1, _ := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, 500_000, coordinator, uni.backend, nativePayment) // Wait for fulfillment to be queued. gomega.NewGomegaWithT(t).Eventually(func() bool { @@ -116,13 +118,13 @@ func testSingleConsumerHappyPath( // In particular: // * success should be true // * payment should be exactly the amount specified as the premium in the coordinator fee config - rwfe := assertRandomWordsFulfilled(t, requestID1, true, coordinator) + rwfe := assertRandomWordsFulfilled(t, requestID1, true, coordinator, nativePayment) if len(assertions) > 0 { - assertions[0](t, coordinator, rwfe) + assertions[0](t, coordinator, rwfe, subID) } // Make the second randomness request and assert fulfillment is successful - requestID2, _ := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, 500_000, coordinator, uni.backend) + 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() @@ -136,9 +138,9 @@ func testSingleConsumerHappyPath( // In particular: // * success should be true // * payment should be exactly the amount specified as the premium in the coordinator fee config - rwfe = assertRandomWordsFulfilled(t, requestID2, true, coordinator) + rwfe = assertRandomWordsFulfilled(t, requestID2, true, coordinator, nativePayment) if len(assertions) > 0 { - assertions[0](t, coordinator, rwfe) + assertions[0](t, coordinator, rwfe, subID) } // Assert correct number of random words sent by coordinator. @@ -168,6 +170,7 @@ func testMultipleConsumersNeedBHS( batchCoordinatorAddress common.Address, vrfOwnerAddress *common.Address, vrfVersion vrfcommon.Version, + nativePayment bool, assertions ...func( t *testing.T, coordinator v22.CoordinatorV2_X, @@ -178,14 +181,12 @@ func testMultipleConsumersNeedBHS( sendEth(t, ownerKey, uni.backend, vrfKey.Address, 10) // generate n BHS keys to make sure BHS job rotates sending keys - var bhsKeys []ethkey.KeyV2 var bhsKeyAddresses []string var keySpecificOverrides []toml.KeySpecific var keys []interface{} gasLanePriceWei := assets.GWei(10) for i := 0; i < nConsumers; i++ { bhsKey := cltest.MustGenerateRandomKey(t) - bhsKeys = append(bhsKeys, bhsKey) bhsKeyAddresses = append(bhsKeyAddresses, bhsKey.Address.String()) keys = append(keys, bhsKey) keySpecificOverrides = append(keySpecificOverrides, toml.KeySpecific{ @@ -239,18 +240,18 @@ func testMultipleConsumersNeedBHS( _ = vrftesthelpers.CreateAndStartBHSJob( t, bhsKeyAddresses, app, uni.bhsContractAddress.String(), "", - v2CoordinatorAddress, v2PlusCoordinatorAddress) + v2CoordinatorAddress, v2PlusCoordinatorAddress, "", 0, 200) // Ensure log poller is ready and has all logs. - require.NoError(t, app.Chains.EVM.Chains()[0].LogPoller().Ready()) - require.NoError(t, app.Chains.EVM.Chains()[0].LogPoller().Replay(testutils.Context(t), 1)) + require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Ready()) + require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Replay(testutils.Context(t), 1)) for i := 0; i < nConsumers; i++ { consumer := consumers[i] consumerContract := consumerContracts[i] // Create a subscription and fund with 0 LINK. - _, subID := subscribeVRF(t, consumer, consumerContract, coordinator, uni.backend, new(big.Int)) + _, subID := subscribeVRF(t, consumer, consumerContract, coordinator, uni.backend, new(big.Int), nativePayment) if vrfVersion == vrfcommon.V2 { require.Equal(t, uint64(i+1), subID.Uint64()) } @@ -258,7 +259,7 @@ func testMultipleConsumersNeedBHS( // Make the randomness request. It will not yet succeed since it is underfunded. numWords := uint32(20) - requestID, requestBlock := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, 500_000, coordinator, uni.backend) + requestID, requestBlock := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, 500_000, coordinator, uni.backend, nativePayment) // Wait 101 blocks. for i := 0; i < 100; i++ { @@ -272,8 +273,7 @@ func testMultipleConsumersNeedBHS( } // Fund the subscription - _, err := consumerContract.TopUpSubscription(consumer, big.NewInt(5e18 /* 5 LINK */)) - require.NoError(t, err) + topUpSubscription(t, consumer, consumerContract, uni.backend, big.NewInt(5e18 /* 5 LINK */), nativePayment) // Wait for fulfillment to be queued. gomega.NewGomegaWithT(t).Eventually(func() bool { @@ -286,7 +286,7 @@ func testMultipleConsumersNeedBHS( mine(t, requestID, subID, uni.backend, db, vrfVersion) - rwfe := assertRandomWordsFulfilled(t, requestID, true, coordinator) + rwfe := assertRandomWordsFulfilled(t, requestID, true, coordinator, nativePayment) if len(assertions) > 0 { assertions[0](t, coordinator, rwfe) } @@ -294,11 +294,159 @@ func testMultipleConsumersNeedBHS( // Assert correct number of random words sent by coordinator. assertNumRandomWords(t, consumerContract, numWords) } +} - for i := 0; i < len(bhsKeys); i++ { - n, err := uni.backend.PendingNonceAt(testutils.Context(t), bhsKeys[i].Address) - require.NoError(t, err) - require.EqualValues(t, 1, n) +func testMultipleConsumersNeedTrustedBHS( + t *testing.T, + ownerKey ethkey.KeyV2, + uni coordinatorV2PlusUniverse, + consumers []*bind.TransactOpts, + consumerContracts []vrftesthelpers.VRFConsumerContract, + consumerContractAddresses []common.Address, + coordinator v22.CoordinatorV2_X, + coordinatorAddress common.Address, + batchCoordinatorAddress common.Address, + vrfVersion vrfcommon.Version, + nativePayment bool, + addedDelay bool, + assertions ...func( + t *testing.T, + coordinator v22.CoordinatorV2_X, + rwfe v22.RandomWordsFulfilled), +) { + nConsumers := len(consumers) + vrfKey := cltest.MustGenerateRandomKey(t) + sendEth(t, ownerKey, uni.backend, vrfKey.Address, 10) + + // generate n BHS keys to make sure BHS job rotates sending keys + var bhsKeyAddresses []common.Address + var bhsKeyAddressesStrings []string + var keySpecificOverrides []toml.KeySpecific + var keys []interface{} + gasLanePriceWei := assets.GWei(10) + for i := 0; i < nConsumers; i++ { + bhsKey := cltest.MustGenerateRandomKey(t) + bhsKeyAddressesStrings = append(bhsKeyAddressesStrings, bhsKey.Address.String()) + bhsKeyAddresses = append(bhsKeyAddresses, bhsKey.Address) + keys = append(keys, bhsKey) + keySpecificOverrides = append(keySpecificOverrides, toml.KeySpecific{ + Key: ptr(bhsKey.EIP55Address), + GasEstimator: toml.KeySpecificGasEstimator{PriceMax: gasLanePriceWei}, + }) + sendEth(t, ownerKey, uni.backend, bhsKey.Address, 10) + } + keySpecificOverrides = append(keySpecificOverrides, toml.KeySpecific{ + // Gas lane. + Key: ptr(vrfKey.EIP55Address), + GasEstimator: toml.KeySpecificGasEstimator{PriceMax: gasLanePriceWei}, + }) + + // Whitelist vrf key for trusted BHS. + _, err := uni.trustedBhsContract.SetWhitelist(uni.neil, bhsKeyAddresses) + require.NoError(t, err) + uni.backend.Commit() + + config, db := heavyweight.FullTestDBV2(t, "vrfv2_needs_trusted_blockhash_store", func(c *chainlink.Config, s *chainlink.Secrets) { + simulatedOverrides(t, assets.GWei(10), keySpecificOverrides...)(c, s) + c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) + c.Feature.LogPoller = ptr(true) + c.EVM[0].FinalityDepth = ptr[uint32](2) + c.EVM[0].LogPollInterval = models.MustNewDuration(time.Second) + }) + keys = append(keys, ownerKey, vrfKey) + app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, uni.backend, keys...) + require.NoError(t, app.Start(testutils.Context(t))) + + // Create VRF job. + vrfJobs := createVRFJobs( + t, + [][]ethkey.KeyV2{{vrfKey}}, + app, + coordinator, + coordinatorAddress, + batchCoordinatorAddress, + uni.coordinatorV2UniverseCommon, + nil, + vrfVersion, + false, + gasLanePriceWei) + keyHash := vrfJobs[0].VRFSpec.PublicKey.MustHash() + + var ( + v2CoordinatorAddress string + v2PlusCoordinatorAddress string + ) + + if vrfVersion == vrfcommon.V2 { + v2CoordinatorAddress = coordinatorAddress.String() + } else if vrfVersion == vrfcommon.V2Plus { + v2PlusCoordinatorAddress = coordinatorAddress.String() + } + + _ = vrftesthelpers.CreateAndStartBHSJob( + t, bhsKeyAddressesStrings, app, "", "", + v2CoordinatorAddress, v2PlusCoordinatorAddress, uni.trustedBhsContractAddress.String(), 20, 1000) + + // 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)) + + for i := 0; i < nConsumers; i++ { + consumer := consumers[i] + consumerContract := consumerContracts[i] + + // Create a subscription and fund with 0 LINK. + _, subID := subscribeVRF(t, consumer, consumerContract, coordinator, uni.backend, new(big.Int), nativePayment) + if vrfVersion == vrfcommon.V2 { + require.Equal(t, uint64(i+1), subID.Uint64()) + } + + // Make the randomness request. It will not yet succeed since it is underfunded. + numWords := uint32(20) + + requestID, requestBlock := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, 500_000, coordinator, uni.backend, nativePayment) + + // Wait 101 blocks. + for i := 0; i < 100; i++ { + uni.backend.Commit() + } + + // For an added delay, we even go beyond the EVM lookback limit. This is not a problem in a trusted BHS setup. + if addedDelay { + for i := 0; i < 300; i++ { + uni.backend.Commit() + } + } + + verifyBlockhashStoredTrusted(t, uni, requestBlock) + + // Wait another 160 blocks so that the request is outside of the 256 block window + for i := 0; i < 160; i++ { + uni.backend.Commit() + } + + // Fund the subscription + topUpSubscription(t, consumer, consumerContract, uni.backend, big.NewInt(5e18 /* 5 LINK */), nativePayment) + + // Wait for fulfillment to be queued. + gomega.NewGomegaWithT(t).Eventually(func() bool { + uni.backend.Commit() + runs, err := app.PipelineORM().GetAllRuns() + require.NoError(t, err) + t.Log("runs", len(runs)) + return len(runs) == 1 + }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue()) + + mine(t, requestID, subID, uni.backend, db, vrfVersion) + + rwfe := assertRandomWordsFulfilled(t, requestID, true, coordinator, nativePayment) + if len(assertions) > 0 { + assertions[0](t, coordinator, rwfe) + } + + // Assert correct number of random words sent by coordinator. + assertNumRandomWords(t, consumerContract, numWords) } } @@ -328,6 +476,32 @@ func verifyBlockhashStored( }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue()) } +func verifyBlockhashStoredTrusted( + t *testing.T, + uni coordinatorV2PlusUniverse, + requestBlock uint64, +) { + // Wait for the blockhash to be stored + gomega.NewGomegaWithT(t).Eventually(func() bool { + uni.backend.Commit() + callOpts := &bind.CallOpts{ + Pending: false, + From: common.Address{}, + BlockNumber: nil, + Context: nil, + } + _, err := uni.trustedBhsContract.GetBlockhash(callOpts, big.NewInt(int64(requestBlock))) + if err == nil { + return true + } else if strings.Contains(err.Error(), "execution reverted") { + return false + } else { + t.Fatal(err) + return false + } + }, time.Second*300, time.Second).Should(gomega.BeTrue()) +} + func testSingleConsumerHappyPathBatchFulfillment( t *testing.T, ownerKey ethkey.KeyV2, @@ -342,10 +516,12 @@ func testSingleConsumerHappyPathBatchFulfillment( numRequests int, bigGasCallback bool, vrfVersion vrfcommon.Version, + nativePayment bool, assertions ...func( t *testing.T, coordinator v22.CoordinatorV2_X, - rwfe v22.RandomWordsFulfilled), + rwfe v22.RandomWordsFulfilled, + subID *big.Int), ) { key1 := cltest.MustGenerateRandomKey(t) gasLanePriceWei := assets.GWei(10) @@ -361,7 +537,7 @@ func testSingleConsumerHappyPathBatchFulfillment( app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, uni.backend, ownerKey, key1) // Create a subscription and fund with 5 LINK. - subID := subscribeAndAssertSubscriptionCreatedEvent(t, consumerContract, consumer, consumerContractAddress, big.NewInt(5e18), coordinator, uni.backend) + subID := subscribeAndAssertSubscriptionCreatedEvent(t, consumerContract, consumer, consumerContractAddress, big.NewInt(5e18), coordinator, uni.backend, nativePayment) // Fund gas lane. sendEth(t, ownerKey, uni.backend, key1.Address, 10) @@ -386,14 +562,14 @@ func testSingleConsumerHappyPathBatchFulfillment( numWords := uint32(2) var reqIDs []*big.Int for i := 0; i < numRequests; i++ { - requestID, _ := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, 500_000, coordinator, uni.backend) + requestID, _ := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, 500_000, coordinator, uni.backend, nativePayment) reqIDs = append(reqIDs, requestID) } if bigGasCallback { // Make one randomness request with the max callback gas limit. // It should live in a batch on it's own. - requestID, _ := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, 2_500_000, coordinator, uni.backend) + requestID, _ := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, 2_500_000, coordinator, uni.backend, nativePayment) reqIDs = append(reqIDs, requestID) } @@ -417,12 +593,12 @@ func testSingleConsumerHappyPathBatchFulfillment( // contract is written. var rwfe v22.RandomWordsFulfilled if i == (len(reqIDs) - 1) { - rwfe = assertRandomWordsFulfilled(t, requestID, true, coordinator) + rwfe = assertRandomWordsFulfilled(t, requestID, true, coordinator, nativePayment) } else { - rwfe = assertRandomWordsFulfilled(t, requestID, false, coordinator) + rwfe = assertRandomWordsFulfilled(t, requestID, false, coordinator, nativePayment) } if len(assertions) > 0 { - assertions[0](t, coordinator, rwfe) + assertions[0](t, coordinator, rwfe, subID) } } @@ -444,6 +620,7 @@ func testSingleConsumerNeedsTopUp( initialFundingAmount *big.Int, topUpAmount *big.Int, vrfVersion vrfcommon.Version, + nativePayment bool, assertions ...func( t *testing.T, coordinator v22.CoordinatorV2_X, @@ -462,7 +639,7 @@ func testSingleConsumerNeedsTopUp( app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, uni.backend, ownerKey, key) // Create and fund a subscription - subID := subscribeAndAssertSubscriptionCreatedEvent(t, consumerContract, consumer, consumerContractAddress, initialFundingAmount, coordinator, uni.backend) + subID := subscribeAndAssertSubscriptionCreatedEvent(t, consumerContract, consumer, consumerContractAddress, initialFundingAmount, coordinator, uni.backend, nativePayment) // Fund expensive gas lane. sendEth(t, ownerKey, uni.backend, key.Address, 10) @@ -484,7 +661,7 @@ func testSingleConsumerNeedsTopUp( keyHash := jbs[0].VRFSpec.PublicKey.MustHash() numWords := uint32(20) - requestID, _ := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, 500_000, coordinator, uni.backend) + requestID, _ := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, 500_000, coordinator, uni.backend, nativePayment) // Fulfillment will not be enqueued because subscriber doesn't have enough LINK. gomega.NewGomegaWithT(t).Consistently(func() bool { @@ -496,8 +673,8 @@ func testSingleConsumerNeedsTopUp( }, 5*time.Second, 1*time.Second).Should(gomega.BeTrue()) // Top up subscription with enough LINK to see the job through. - _, err := consumerContract.TopUpSubscription(consumer, topUpAmount) - require.NoError(t, err) + topUpSubscription(t, consumer, consumerContract, uni.backend, topUpAmount, nativePayment) + uni.backend.Commit() // Wait for fulfillment to go through. gomega.NewWithT(t).Eventually(func() bool { @@ -513,7 +690,7 @@ func testSingleConsumerNeedsTopUp( mine(t, requestID, subID, uni.backend, db, vrfVersion) // Assert the state of the RandomWordsFulfilled event. - rwfe := assertRandomWordsFulfilled(t, requestID, true, coordinator) + rwfe := assertRandomWordsFulfilled(t, requestID, true, coordinator, nativePayment) if len(assertions) > 0 { assertions[0](t, coordinator, rwfe) } @@ -538,6 +715,7 @@ func testBlockHeaderFeeder( batchCoordinatorAddress common.Address, vrfOwnerAddress *common.Address, vrfVersion vrfcommon.Version, + nativePayment bool, assertions ...func( t *testing.T, coordinator v22.CoordinatorV2_X, @@ -597,15 +775,15 @@ func testBlockHeaderFeeder( v2coordinatorAddress, v2plusCoordinatorAddress) // Ensure log poller is ready and has all logs. - require.NoError(t, app.Chains.EVM.Chains()[0].LogPoller().Ready()) - require.NoError(t, app.Chains.EVM.Chains()[0].LogPoller().Replay(testutils.Context(t), 1)) + require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Ready()) + require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Replay(testutils.Context(t), 1)) for i := 0; i < nConsumers; i++ { consumer := consumers[i] consumerContract := consumerContracts[i] // Create a subscription and fund with 0 LINK. - _, subID := subscribeVRF(t, consumer, consumerContract, coordinator, uni.backend, new(big.Int)) + _, subID := subscribeVRF(t, consumer, consumerContract, coordinator, uni.backend, new(big.Int), nativePayment) if vrfVersion == vrfcommon.V2 { require.Equal(t, uint64(i+1), subID.Uint64()) } @@ -613,7 +791,7 @@ func testBlockHeaderFeeder( // Make the randomness request. It will not yet succeed since it is underfunded. numWords := uint32(20) - requestID, requestBlock := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, 500_000, coordinator, uni.backend) + requestID, requestBlock := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, 500_000, coordinator, uni.backend, nativePayment) // Wait 256 blocks. for i := 0; i < 256; i++ { @@ -622,8 +800,7 @@ func testBlockHeaderFeeder( verifyBlockhashStored(t, uni, requestBlock) // Fund the subscription - _, err := consumerContract.TopUpSubscription(consumer, big.NewInt(5e18 /* 5 LINK */)) - require.NoError(t, err) + topUpSubscription(t, consumer, consumerContract, uni.backend, big.NewInt(5e18), nativePayment) // Wait for fulfillment to be queued. gomega.NewGomegaWithT(t).Eventually(func() bool { @@ -636,7 +813,7 @@ func testBlockHeaderFeeder( mine(t, requestID, subID, uni.backend, db, vrfVersion) - rwfe := assertRandomWordsFulfilled(t, requestID, true, coordinator) + rwfe := assertRandomWordsFulfilled(t, requestID, true, coordinator, nativePayment) if len(assertions) > 0 { assertions[0](t, coordinator, rwfe) } @@ -843,7 +1020,7 @@ func testSingleConsumerForcedFulfillment( // In this particular case: // * success should be true // * payment should be zero (forced fulfillment) - rwfe := assertRandomWordsFulfilled(t, requestID, true, coordinator) + rwfe := assertRandomWordsFulfilled(t, requestID, true, coordinator, false) require.Equal(t, "0", rwfe.Payment().String()) // Check that the RandomWordsForced event is emitted correctly. @@ -868,6 +1045,7 @@ func testSingleConsumerEIP150( batchCoordinatorAddress common.Address, batchEnabled bool, vrfVersion vrfcommon.Version, + nativePayment bool, ) { callBackGasLimit := int64(2_500_000) // base callback gas. eip150Fee := callBackGasLimit / 64 // premium needed for callWithExactGas @@ -891,7 +1069,7 @@ func testSingleConsumerEIP150( consumerContractAddress := uni.consumerContractAddresses[0] // Create a subscription and fund with 500 LINK. subAmount := big.NewInt(1).Mul(big.NewInt(5e18), big.NewInt(100)) - subID := subscribeAndAssertSubscriptionCreatedEvent(t, consumerContract, consumer, consumerContractAddress, subAmount, uni.rootContract, uni.backend) + subID := subscribeAndAssertSubscriptionCreatedEvent(t, consumerContract, consumer, consumerContractAddress, subAmount, uni.rootContract, uni.backend, nativePayment) // Fund gas lane. sendEth(t, ownerKey, uni.backend, key1.Address, 10) @@ -914,7 +1092,7 @@ func testSingleConsumerEIP150( // Make the first randomness request. numWords := uint32(1) - requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, uint32(callBackGasLimit), uni.rootContract, uni.backend) + requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, uint32(callBackGasLimit), uni.rootContract, uni.backend, nativePayment) // Wait for simulation to pass. gomega.NewGomegaWithT(t).Eventually(func() bool { @@ -935,6 +1113,7 @@ func testSingleConsumerEIP150Revert( batchCoordinatorAddress common.Address, batchEnabled bool, vrfVersion vrfcommon.Version, + nativePayment bool, ) { callBackGasLimit := int64(2_500_000) // base callback gas. eip150Fee := int64(0) // no premium given for callWithExactGas @@ -958,7 +1137,7 @@ func testSingleConsumerEIP150Revert( consumerContractAddress := uni.consumerContractAddresses[0] // Create a subscription and fund with 500 LINK. subAmount := big.NewInt(1).Mul(big.NewInt(5e18), big.NewInt(100)) - subID := subscribeAndAssertSubscriptionCreatedEvent(t, consumerContract, consumer, consumerContractAddress, subAmount, uni.rootContract, uni.backend) + subID := subscribeAndAssertSubscriptionCreatedEvent(t, consumerContract, consumer, consumerContractAddress, subAmount, uni.rootContract, uni.backend, nativePayment) // Fund gas lane. sendEth(t, ownerKey, uni.backend, key1.Address, 10) @@ -981,7 +1160,7 @@ func testSingleConsumerEIP150Revert( // Make the first randomness request. numWords := uint32(1) - requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, uint32(callBackGasLimit), uni.rootContract, uni.backend) + requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, uint32(callBackGasLimit), uni.rootContract, uni.backend, nativePayment) // Simulation should not pass. gomega.NewGomegaWithT(t).Consistently(func() bool { @@ -1002,6 +1181,7 @@ func testSingleConsumerBigGasCallbackSandwich( batchCoordinatorAddress common.Address, batchEnabled bool, vrfVersion vrfcommon.Version, + nativePayment bool, ) { key1 := cltest.MustGenerateRandomKey(t) gasLanePriceWei := assets.GWei(100) @@ -1019,7 +1199,7 @@ func testSingleConsumerBigGasCallbackSandwich( consumerContract := uni.consumerContracts[0] consumerContractAddress := uni.consumerContractAddresses[0] - subID := subscribeAndAssertSubscriptionCreatedEvent(t, consumerContract, consumer, consumerContractAddress, assets.Ether(2).ToInt(), uni.rootContract, uni.backend) + subID := subscribeAndAssertSubscriptionCreatedEvent(t, consumerContract, consumer, consumerContractAddress, assets.Ether(2).ToInt(), uni.rootContract, uni.backend, nativePayment) // Fund gas lane. sendEth(t, ownerKey, uni.backend, key1.Address, 10) @@ -1045,7 +1225,7 @@ func testSingleConsumerBigGasCallbackSandwich( reqIDs := []*big.Int{} callbackGasLimits := []uint32{2_500_000, 50_000, 1_500_000} for _, limit := range callbackGasLimits { - requestID, _ := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, limit, uni.rootContract, uni.backend) + requestID, _ := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, limit, uni.rootContract, uni.backend, nativePayment) reqIDs = append(reqIDs, requestID) uni.backend.Commit() } @@ -1078,7 +1258,7 @@ func testSingleConsumerBigGasCallbackSandwich( mine(t, reqIDs[1], subID, uni.backend, db, vrfVersion) // Assert the random word was fulfilled - assertRandomWordsFulfilled(t, reqIDs[1], false, uni.rootContract) + assertRandomWordsFulfilled(t, reqIDs[1], false, uni.rootContract, nativePayment) // Assert that we've still only completed 1 run before adding new requests. runs, err = app.PipelineORM().GetAllRuns() @@ -1088,7 +1268,7 @@ func testSingleConsumerBigGasCallbackSandwich( // Make some randomness requests, each one block apart, this time without a low-gas request present in the callbackGasLimit slice. callbackGasLimits = []uint32{2_500_000, 2_500_000, 2_500_000} for _, limit := range callbackGasLimits { - _, _ = requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, limit, uni.rootContract, uni.backend) + _, _ = requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, limit, uni.rootContract, uni.backend, nativePayment) uni.backend.Commit() } @@ -1111,6 +1291,7 @@ func testSingleConsumerMultipleGasLanes( batchCoordinatorAddress common.Address, batchEnabled bool, vrfVersion vrfcommon.Version, + nativePayment bool, ) { cheapKey := cltest.MustGenerateRandomKey(t) expensiveKey := cltest.MustGenerateRandomKey(t) @@ -1136,7 +1317,7 @@ func testSingleConsumerMultipleGasLanes( consumerContractAddress := uni.consumerContractAddresses[0] // Create a subscription and fund with 5 LINK. - subID := subscribeAndAssertSubscriptionCreatedEvent(t, consumerContract, consumer, consumerContractAddress, big.NewInt(5e18), uni.rootContract, uni.backend) + subID := subscribeAndAssertSubscriptionCreatedEvent(t, consumerContract, consumer, consumerContractAddress, big.NewInt(5e18), uni.rootContract, uni.backend, nativePayment) // Fund gas lanes. sendEth(t, ownerKey, uni.backend, cheapKey.Address, 10) @@ -1161,7 +1342,7 @@ func testSingleConsumerMultipleGasLanes( numWords := uint32(20) cheapRequestID, _ := - requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, cheapHash, subID, numWords, 500_000, uni.rootContract, uni.backend) + requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, cheapHash, subID, numWords, 500_000, uni.rootContract, uni.backend, nativePayment) // Wait for fulfillment to be queued for cheap key hash. gomega.NewGomegaWithT(t).Eventually(func() bool { @@ -1176,12 +1357,12 @@ func testSingleConsumerMultipleGasLanes( mine(t, cheapRequestID, subID, uni.backend, db, vrfVersion) // Assert correct state of RandomWordsFulfilled event. - assertRandomWordsFulfilled(t, cheapRequestID, true, uni.rootContract) + assertRandomWordsFulfilled(t, cheapRequestID, true, uni.rootContract, nativePayment) // Assert correct number of random words sent by coordinator. assertNumRandomWords(t, consumerContract, numWords) - expensiveRequestID, _ := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, expensiveHash, subID, numWords, 500_000, uni.rootContract, uni.backend) + expensiveRequestID, _ := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, expensiveHash, subID, numWords, 500_000, uni.rootContract, uni.backend, nativePayment) // We should not have any new fulfillments until a top up. gomega.NewWithT(t).Consistently(func() bool { @@ -1193,8 +1374,7 @@ func testSingleConsumerMultipleGasLanes( }, 5*time.Second, 1*time.Second).Should(gomega.BeTrue()) // Top up subscription with enough LINK to see the job through. 100 LINK should do the trick. - _, err := consumerContract.TopUpSubscription(consumer, decimal.RequireFromString("100e18").BigInt()) - require.NoError(t, err) + topUpSubscription(t, consumer, consumerContract, uni.backend, decimal.RequireFromString("100e18").BigInt(), nativePayment) // Wait for fulfillment to be queued for expensive key hash. gomega.NewGomegaWithT(t).Eventually(func() bool { @@ -1209,12 +1389,23 @@ func testSingleConsumerMultipleGasLanes( mine(t, expensiveRequestID, subID, uni.backend, db, vrfVersion) // Assert correct state of RandomWordsFulfilled event. - assertRandomWordsFulfilled(t, expensiveRequestID, true, uni.rootContract) + assertRandomWordsFulfilled(t, expensiveRequestID, true, uni.rootContract, nativePayment) // Assert correct number of random words sent by coordinator. assertNumRandomWords(t, consumerContract, numWords) } +func topUpSubscription(t *testing.T, consumer *bind.TransactOpts, consumerContract vrftesthelpers.VRFConsumerContract, backend *backends.SimulatedBackend, fundingAmount *big.Int, nativePayment bool) { + if nativePayment { + _, err := consumerContract.TopUpSubscriptionNative(consumer, fundingAmount) + require.NoError(t, err) + } else { + _, err := consumerContract.TopUpSubscription(consumer, fundingAmount) + require.NoError(t, err) + } + backend.Commit() +} + func testSingleConsumerAlwaysRevertingCallbackStillFulfilled( t *testing.T, ownerKey ethkey.KeyV2, @@ -1222,6 +1413,7 @@ func testSingleConsumerAlwaysRevertingCallbackStillFulfilled( batchCoordinatorAddress common.Address, batchEnabled bool, vrfVersion vrfcommon.Version, + nativePayment bool, ) { key := cltest.MustGenerateRandomKey(t) gasLanePriceWei := assets.GWei(10) @@ -1239,7 +1431,7 @@ func testSingleConsumerAlwaysRevertingCallbackStillFulfilled( consumerContractAddress := uni.revertingConsumerContractAddress // Create a subscription and fund with 5 LINK. - subID := subscribeAndAssertSubscriptionCreatedEvent(t, consumerContract, consumer, consumerContractAddress, big.NewInt(5e18), uni.rootContract, uni.backend) + subID := subscribeAndAssertSubscriptionCreatedEvent(t, consumerContract, consumer, consumerContractAddress, big.NewInt(5e18), uni.rootContract, uni.backend, nativePayment) // Fund gas lane. sendEth(t, ownerKey, uni.backend, key.Address, 10) @@ -1262,7 +1454,7 @@ func testSingleConsumerAlwaysRevertingCallbackStillFulfilled( // Make the randomness request. numWords := uint32(20) - requestID, _ := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, 500_000, uni.rootContract, uni.backend) + requestID, _ := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, 500_000, uni.rootContract, uni.backend, nativePayment) // Wait for fulfillment to be queued. gomega.NewGomegaWithT(t).Eventually(func() bool { @@ -1277,7 +1469,7 @@ func testSingleConsumerAlwaysRevertingCallbackStillFulfilled( mine(t, requestID, subID, uni.backend, db, vrfVersion) // Assert correct state of RandomWordsFulfilled event. - assertRandomWordsFulfilled(t, requestID, false, uni.rootContract) + assertRandomWordsFulfilled(t, requestID, false, uni.rootContract, nativePayment) t.Log("Done!") } @@ -1288,6 +1480,7 @@ func testConsumerProxyHappyPath( batchCoordinatorAddress common.Address, batchEnabled bool, vrfVersion vrfcommon.Version, + nativePayment bool, ) { key1 := cltest.MustGenerateRandomKey(t) key2 := cltest.MustGenerateRandomKey(t) @@ -1311,7 +1504,7 @@ func testConsumerProxyHappyPath( // Create a subscription and fund with 5 LINK. subID := subscribeAndAssertSubscriptionCreatedEvent( t, consumerContract, consumerOwner, consumerContractAddress, - assets.Ether(5).ToInt(), uni.rootContract, uni.backend) + assets.Ether(5).ToInt(), uni.rootContract, uni.backend, nativePayment) // Create gas lane. sendEth(t, ownerKey, uni.backend, key1.Address, 10) @@ -1336,7 +1529,7 @@ func testConsumerProxyHappyPath( // Make the first randomness request. numWords := uint32(20) requestID1, _ := requestRandomnessAndAssertRandomWordsRequestedEvent( - t, consumerContract, consumerOwner, keyHash, subID, numWords, 750_000, uni.rootContract, uni.backend) + t, consumerContract, consumerOwner, keyHash, subID, numWords, 750_000, uni.rootContract, uni.backend, nativePayment) // Wait for fulfillment to be queued. gomega.NewGomegaWithT(t).Eventually(func() bool { @@ -1351,7 +1544,7 @@ func testConsumerProxyHappyPath( mine(t, requestID1, subID, uni.backend, db, vrfVersion) // Assert correct state of RandomWordsFulfilled event. - assertRandomWordsFulfilled(t, requestID1, true, uni.rootContract) + assertRandomWordsFulfilled(t, requestID1, true, uni.rootContract, nativePayment) // Gas available will be around 724,385, which means that 750,000 - 724,385 = 25,615 gas was used. // This is ~20k more than what the non-proxied consumer uses. @@ -1362,7 +1555,7 @@ func testConsumerProxyHappyPath( // Make the second randomness request and assert fulfillment is successful requestID2, _ := requestRandomnessAndAssertRandomWordsRequestedEvent( - t, consumerContract, consumerOwner, keyHash, subID, numWords, 750_000, uni.rootContract, uni.backend) + 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() @@ -1371,7 +1564,7 @@ func testConsumerProxyHappyPath( return len(runs) == 2 }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue()) mine(t, requestID2, subID, uni.backend, db, vrfVersion) - assertRandomWordsFulfilled(t, requestID2, true, uni.rootContract) + assertRandomWordsFulfilled(t, requestID2, true, uni.rootContract, nativePayment) // Assert correct number of random words sent by coordinator. assertNumRandomWords(t, consumerContract, numWords) @@ -1488,14 +1681,14 @@ func testMaliciousConsumer( }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue()) // The fulfillment tx should succeed - ch, err := app.GetChains().EVM.Default() + ch, err := app.GetRelayers().LegacyEVMChains().Default() require.NoError(t, err) r, err := ch.Client().TransactionReceipt(testutils.Context(t), attempts[0].Hash) require.NoError(t, err) require.Equal(t, uint64(1), r.Status) // The user callback should have errored - it, err := uni.rootContract.FilterRandomWordsFulfilled(nil, nil) + it, err := uni.rootContract.FilterRandomWordsFulfilled(nil, nil, nil) require.NoError(t, err) var fulfillments []v22.RandomWordsFulfilled for it.Next() { diff --git a/core/services/vrf/v2/integration_v2_plus_test.go b/core/services/vrf/v2/integration_v2_plus_test.go index 96873be43d1..4e1cf62d01d 100644 --- a/core/services/vrf/v2/integration_v2_plus_test.go +++ b/core/services/vrf/v2/integration_v2_plus_test.go @@ -4,6 +4,7 @@ import ( "math/big" "strings" "testing" + "time" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -12,18 +13,22 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/onsi/gomega" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/assets" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/batch_blockhash_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/batch_vrf_coordinator_v2plus" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/blockhash_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_v3_aggregator_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/trusted_blockhash_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_consumer_v2_plus_upgradeable_example" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_consumer_v2_upgradeable_example" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_plus_v2_example" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_malicious_consumer_v2_plus" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_single_consumer" @@ -33,9 +38,12 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_consumer_example" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_reverting_example" "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" configtest "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest/v2" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "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/signatures/secp256k1" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/extraargs" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/proof" @@ -50,9 +58,13 @@ type coordinatorV2PlusUniverse struct { submanager *bind.TransactOpts // Subscription owner batchCoordinatorContract *batch_vrf_coordinator_v2plus.BatchVRFCoordinatorV2Plus batchCoordinatorContractAddress common.Address + migrationTestCoordinator *vrf_coordinator_v2_plus_v2_example.VRFCoordinatorV2PlusV2Example + migrationTestCoordinatorAddress common.Address + trustedBhsContract *trusted_blockhash_store.TrustedBlockhashStore + trustedBhsContractAddress common.Address } -func newVRFCoordinatorV2PlusUniverse(t *testing.T, key ethkey.KeyV2, numConsumers int) coordinatorV2PlusUniverse { +func newVRFCoordinatorV2PlusUniverse(t *testing.T, key ethkey.KeyV2, numConsumers int, trusting bool) coordinatorV2PlusUniverse { testutils.SkipShort(t, "VRFCoordinatorV2Universe") oracleTransactor, err := bind.NewKeyedTransactorWithChainID(key.ToEcdsaPrivKey(), testutils.SimulatedChainID) require.NoError(t, err) @@ -110,22 +122,35 @@ func newVRFCoordinatorV2PlusUniverse(t *testing.T, key ethkey.KeyV2, numConsumer bhsAddress, _, bhsContract, err := blockhash_store.DeployBlockhashStore(neil, backend) require.NoError(t, err, "failed to deploy BlockhashStore contract to simulated ethereum blockchain") + // Deploy trusted BHS + trustedBHSAddress, _, trustedBhsContract, err := trusted_blockhash_store.DeployTrustedBlockhashStore(neil, backend, []common.Address{}) + require.NoError(t, err, "failed to deploy trusted BlockhashStore contract to simulated ethereum blockchain") + // Deploy batch blockhash store batchBHSAddress, _, batchBHSContract, err := batch_blockhash_store.DeployBatchBlockhashStore(neil, backend, bhsAddress) require.NoError(t, err, "failed to deploy BatchBlockhashStore contract to simulated ethereum blockchain") // Deploy VRF V2plus coordinator + var bhsAddr = bhsAddress + if trusting { + bhsAddr = trustedBHSAddress + } coordinatorAddress, _, coordinatorContract, err := vrf_coordinator_v2plus.DeployVRFCoordinatorV2Plus( - neil, backend, bhsAddress) + neil, backend, bhsAddr) require.NoError(t, err, "failed to deploy VRFCoordinatorV2 contract to simulated ethereum blockchain") backend.Commit() - _, err = coordinatorContract.SetLINK(neil, linkAddress) + _, err = coordinatorContract.SetLINKAndLINKETHFeed(neil, linkAddress, linkEthFeed) + require.NoError(t, err) + backend.Commit() + + migrationTestCoordinatorAddress, _, migrationTestCoordinator, err := vrf_coordinator_v2_plus_v2_example.DeployVRFCoordinatorV2PlusV2Example( + neil, backend, linkAddress, coordinatorAddress) require.NoError(t, err) backend.Commit() - _, err = coordinatorContract.SetLinkEthFeed(neil, linkEthFeed) + _, err = coordinatorContract.RegisterMigratableCoordinator(neil, migrationTestCoordinatorAddress) require.NoError(t, err) backend.Commit() @@ -271,73 +296,169 @@ func newVRFCoordinatorV2PlusUniverse(t *testing.T, key ethkey.KeyV2, numConsumer batchCoordinatorContract: batchCoordinatorContract, batchCoordinatorContractAddress: batchCoordinatorAddress, submanager: submanager, + migrationTestCoordinator: migrationTestCoordinator, + migrationTestCoordinatorAddress: migrationTestCoordinatorAddress, + trustedBhsContract: trustedBhsContract, + trustedBhsContractAddress: trustedBHSAddress, } } func TestVRFV2PlusIntegration_SingleConsumer_HappyPath_BatchFulfillment(t *testing.T) { t.Parallel() ownerKey := cltest.MustGenerateRandomKey(t) - uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1) - testSingleConsumerHappyPathBatchFulfillment( - t, - ownerKey, - uni.coordinatorV2UniverseCommon, - uni.vrfConsumers[0], - uni.consumerContracts[0], - uni.consumerContractAddresses[0], - uni.rootContract, - uni.rootContractAddress, - uni.batchCoordinatorContractAddress, - nil, - 5, // number of requests to send - false, // don't send big callback - vrfcommon.V2Plus, - ) + uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1, false) + t.Run("link payment", func(tt *testing.T) { + testSingleConsumerHappyPathBatchFulfillment( + t, + ownerKey, + uni.coordinatorV2UniverseCommon, + uni.vrfConsumers[0], + uni.consumerContracts[0], + uni.consumerContractAddresses[0], + uni.rootContract, + uni.rootContractAddress, + uni.batchCoordinatorContractAddress, + nil, + 5, // number of requests to send + false, // don't send big callback + vrfcommon.V2Plus, + false, + func(t *testing.T, coordinator v22.CoordinatorV2_X, rwfe v22.RandomWordsFulfilled, expectedSubID *big.Int) { + _, err := coordinator.GetSubscription(nil, rwfe.SubID()) + require.NoError(t, err) + require.Equal(t, expectedSubID, rwfe.SubID()) + }, + ) + }) + + t.Run("native payment", func(tt *testing.T) { + testSingleConsumerHappyPathBatchFulfillment( + t, + ownerKey, + uni.coordinatorV2UniverseCommon, + uni.vrfConsumers[0], + uni.consumerContracts[0], + uni.consumerContractAddresses[0], + uni.rootContract, + uni.rootContractAddress, + uni.batchCoordinatorContractAddress, + nil, + 5, // number of requests to send + false, // don't send big callback + vrfcommon.V2Plus, + true, + func(t *testing.T, coordinator v22.CoordinatorV2_X, rwfe v22.RandomWordsFulfilled, expectedSubID *big.Int) { + _, err := coordinator.GetSubscription(nil, rwfe.SubID()) + require.NoError(t, err) + require.Equal(t, expectedSubID, rwfe.SubID()) + }, + ) + }) } func TestVRFV2PlusIntegration_SingleConsumer_HappyPath_BatchFulfillment_BigGasCallback(t *testing.T) { t.Parallel() ownerKey := cltest.MustGenerateRandomKey(t) - uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1) - testSingleConsumerHappyPathBatchFulfillment( - t, - ownerKey, - uni.coordinatorV2UniverseCommon, - uni.vrfConsumers[0], - uni.consumerContracts[0], - uni.consumerContractAddresses[0], - uni.rootContract, - uni.rootContractAddress, - uni.batchCoordinatorContractAddress, - nil, - 5, // number of requests to send - true, // send big callback - vrfcommon.V2Plus, - ) + uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1, false) + t.Run("link payment", func(tt *testing.T) { + testSingleConsumerHappyPathBatchFulfillment( + t, + ownerKey, + uni.coordinatorV2UniverseCommon, + uni.vrfConsumers[0], + uni.consumerContracts[0], + uni.consumerContractAddresses[0], + uni.rootContract, + uni.rootContractAddress, + uni.batchCoordinatorContractAddress, + nil, + 5, // number of requests to send + true, // send big callback + vrfcommon.V2Plus, + false, + func(t *testing.T, coordinator v22.CoordinatorV2_X, rwfe v22.RandomWordsFulfilled, expectedSubID *big.Int) { + _, err := coordinator.GetSubscription(nil, rwfe.SubID()) + require.NoError(t, err) + require.Equal(t, expectedSubID, rwfe.SubID()) + }, + ) + }) + + t.Run("native payment", func(tt *testing.T) { + testSingleConsumerHappyPathBatchFulfillment( + t, + ownerKey, + uni.coordinatorV2UniverseCommon, + uni.vrfConsumers[0], + uni.consumerContracts[0], + uni.consumerContractAddresses[0], + uni.rootContract, + uni.rootContractAddress, + uni.batchCoordinatorContractAddress, + nil, + 5, // number of requests to send + true, // send big callback + vrfcommon.V2Plus, + true, + func(t *testing.T, coordinator v22.CoordinatorV2_X, rwfe v22.RandomWordsFulfilled, expectedSubID *big.Int) { + _, err := coordinator.GetSubscription(nil, rwfe.SubID()) + require.NoError(t, err) + require.Equal(t, expectedSubID, rwfe.SubID()) + }, + ) + }) } func TestVRFV2PlusIntegration_SingleConsumer_HappyPath(t *testing.T) { t.Parallel() ownerKey := cltest.MustGenerateRandomKey(t) - uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1) - testSingleConsumerHappyPath( - t, - ownerKey, - uni.coordinatorV2UniverseCommon, - uni.vrfConsumers[0], - uni.consumerContracts[0], - uni.consumerContractAddresses[0], - uni.rootContract, - uni.rootContractAddress, - uni.batchCoordinatorContractAddress, - nil, - vrfcommon.V2Plus) + uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1, false) + t.Run("link payment", func(tt *testing.T) { + testSingleConsumerHappyPath( + t, + ownerKey, + uni.coordinatorV2UniverseCommon, + uni.vrfConsumers[0], + uni.consumerContracts[0], + uni.consumerContractAddresses[0], + uni.rootContract, + uni.rootContractAddress, + uni.batchCoordinatorContractAddress, + nil, + vrfcommon.V2Plus, + false, + func(t *testing.T, coordinator v22.CoordinatorV2_X, rwfe v22.RandomWordsFulfilled, expectedSubID *big.Int) { + _, err := coordinator.GetSubscription(nil, rwfe.SubID()) + require.NoError(t, err) + require.Equal(t, expectedSubID, rwfe.SubID()) + }) + }) + t.Run("native payment", func(tt *testing.T) { + testSingleConsumerHappyPath( + t, + ownerKey, + uni.coordinatorV2UniverseCommon, + uni.vrfConsumers[0], + uni.consumerContracts[0], + uni.consumerContractAddresses[0], + uni.rootContract, + uni.rootContractAddress, + uni.batchCoordinatorContractAddress, + nil, + vrfcommon.V2Plus, + true, + func(t *testing.T, coordinator v22.CoordinatorV2_X, rwfe v22.RandomWordsFulfilled, expectedSubID *big.Int) { + _, err := coordinator.GetSubscription(nil, rwfe.SubID()) + require.NoError(t, err) + require.Equal(t, expectedSubID, rwfe.SubID()) + }) + }) } func TestVRFV2PlusIntegration_SingleConsumer_EOA_Request(t *testing.T) { t.Parallel() ownerKey := cltest.MustGenerateRandomKey(t) - uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1) + uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1, false) testEoa( t, ownerKey, @@ -352,7 +473,7 @@ func TestVRFV2PlusIntegration_SingleConsumer_EOA_Request(t *testing.T) { func TestVRFV2PlusIntegration_SingleConsumer_EOA_Request_Batching_Enabled(t *testing.T) { t.Parallel() ownerKey := cltest.MustGenerateRandomKey(t) - uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1) + uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1, false) testEoa( t, ownerKey, @@ -367,7 +488,7 @@ func TestVRFV2PlusIntegration_SingleConsumer_EOA_Request_Batching_Enabled(t *tes func TestVRFV2PlusIntegration_SingleConsumer_EIP150_HappyPath(t *testing.T) { t.Parallel() ownerKey := cltest.MustGenerateRandomKey(t) - uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1) + uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1, false) testSingleConsumerEIP150( t, ownerKey, @@ -375,13 +496,14 @@ func TestVRFV2PlusIntegration_SingleConsumer_EIP150_HappyPath(t *testing.T) { uni.batchCoordinatorContractAddress, false, vrfcommon.V2Plus, + false, ) } func TestVRFV2PlusIntegration_SingleConsumer_EIP150_Revert(t *testing.T) { t.Parallel() ownerKey := cltest.MustGenerateRandomKey(t) - uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1) + uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1, false) testSingleConsumerEIP150Revert( t, ownerKey, @@ -389,69 +511,131 @@ func TestVRFV2PlusIntegration_SingleConsumer_EIP150_Revert(t *testing.T) { uni.batchCoordinatorContractAddress, false, vrfcommon.V2Plus, + false, ) } func TestVRFV2PlusIntegration_SingleConsumer_NeedsBlockhashStore(t *testing.T) { t.Parallel() ownerKey := cltest.MustGenerateRandomKey(t) - uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 2) - testMultipleConsumersNeedBHS( - t, - ownerKey, - uni.coordinatorV2UniverseCommon, - uni.vrfConsumers, - uni.consumerContracts, - uni.consumerContractAddresses, - uni.rootContract, - uni.rootContractAddress, - uni.batchCoordinatorContractAddress, - nil, - vrfcommon.V2Plus) + uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 2, false) + t.Run("link payment", func(tt *testing.T) { + testMultipleConsumersNeedBHS( + t, + ownerKey, + uni.coordinatorV2UniverseCommon, + uni.vrfConsumers, + uni.consumerContracts, + uni.consumerContractAddresses, + uni.rootContract, + uni.rootContractAddress, + uni.batchCoordinatorContractAddress, + nil, + vrfcommon.V2Plus, + false, + ) + }) + t.Run("native payment", func(tt *testing.T) { + testMultipleConsumersNeedBHS( + t, + ownerKey, + uni.coordinatorV2UniverseCommon, + uni.vrfConsumers, + uni.consumerContracts, + uni.consumerContractAddresses, + uni.rootContract, + uni.rootContractAddress, + uni.batchCoordinatorContractAddress, + nil, + vrfcommon.V2Plus, + true, + ) + }) } func TestVRFV2PlusIntegration_SingleConsumer_BlockHeaderFeeder(t *testing.T) { t.Parallel() ownerKey := cltest.MustGenerateRandomKey(t) - uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1) - testBlockHeaderFeeder( - t, - ownerKey, - uni.coordinatorV2UniverseCommon, - uni.vrfConsumers, - uni.consumerContracts, - uni.consumerContractAddresses, - uni.rootContract, - uni.rootContractAddress, - uni.batchCoordinatorContractAddress, - nil, - vrfcommon.V2Plus) + uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1, false) + t.Run("link payment", func(tt *testing.T) { + testBlockHeaderFeeder( + t, + ownerKey, + uni.coordinatorV2UniverseCommon, + uni.vrfConsumers, + uni.consumerContracts, + uni.consumerContractAddresses, + uni.rootContract, + uni.rootContractAddress, + uni.batchCoordinatorContractAddress, + nil, + vrfcommon.V2Plus, + false, + ) + }) + t.Run("native payment", func(tt *testing.T) { + testBlockHeaderFeeder( + t, + ownerKey, + uni.coordinatorV2UniverseCommon, + uni.vrfConsumers, + uni.consumerContracts, + uni.consumerContractAddresses, + uni.rootContract, + uni.rootContractAddress, + uni.batchCoordinatorContractAddress, + nil, + vrfcommon.V2Plus, + true, + ) + }) } func TestVRFV2PlusIntegration_SingleConsumer_NeedsTopUp(t *testing.T) { t.Parallel() ownerKey := cltest.MustGenerateRandomKey(t) - uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1) - testSingleConsumerNeedsTopUp( - t, - ownerKey, - uni.coordinatorV2UniverseCommon, - uni.vrfConsumers[0], - uni.consumerContracts[0], - uni.consumerContractAddresses[0], - uni.rootContract, - uni.rootContractAddress, - uni.batchCoordinatorContractAddress, - nil, - assets.Ether(1).ToInt(), // initial funding of 1 LINK - assets.Ether(100).ToInt(), // top up of 100 LINK - vrfcommon.V2Plus, - ) + uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1, false) + t.Run("link payment", func(tt *testing.T) { + testSingleConsumerNeedsTopUp( + t, + ownerKey, + uni.coordinatorV2UniverseCommon, + uni.vrfConsumers[0], + uni.consumerContracts[0], + uni.consumerContractAddresses[0], + uni.rootContract, + uni.rootContractAddress, + uni.batchCoordinatorContractAddress, + nil, + assets.Ether(1).ToInt(), // initial funding of 1 LINK + assets.Ether(100).ToInt(), // top up of 100 LINK + vrfcommon.V2Plus, + false, + ) + }) + t.Run("native payment", func(tt *testing.T) { + testSingleConsumerNeedsTopUp( + t, + ownerKey, + uni.coordinatorV2UniverseCommon, + uni.vrfConsumers[0], + uni.consumerContracts[0], + uni.consumerContractAddresses[0], + uni.rootContract, + uni.rootContractAddress, + uni.batchCoordinatorContractAddress, + nil, + big.NewInt(1e17), // initial funding of 0.1 ETH + assets.Ether(100).ToInt(), // top up of 100 ETH + vrfcommon.V2Plus, + true, + ) + }) } func TestVRFV2PlusIntegration_SingleConsumer_BigGasCallback_Sandwich(t *testing.T) { ownerKey := cltest.MustGenerateRandomKey(t) - uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1) + uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1, false) testSingleConsumerBigGasCallbackSandwich( t, ownerKey, @@ -459,12 +643,13 @@ func TestVRFV2PlusIntegration_SingleConsumer_BigGasCallback_Sandwich(t *testing. uni.batchCoordinatorContractAddress, false, vrfcommon.V2Plus, + false, ) } func TestVRFV2PlusIntegration_SingleConsumer_MultipleGasLanes(t *testing.T) { ownerKey := cltest.MustGenerateRandomKey(t) - uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1) + uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1, false) testSingleConsumerMultipleGasLanes( t, ownerKey, @@ -472,12 +657,13 @@ func TestVRFV2PlusIntegration_SingleConsumer_MultipleGasLanes(t *testing.T) { uni.batchCoordinatorContractAddress, false, vrfcommon.V2Plus, + false, ) } func TestVRFV2PlusIntegration_SingleConsumer_AlwaysRevertingCallback_StillFulfilled(t *testing.T) { ownerKey := cltest.MustGenerateRandomKey(t) - uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 0) + uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 0, false) testSingleConsumerAlwaysRevertingCallbackStillFulfilled( t, ownerKey, @@ -485,12 +671,13 @@ func TestVRFV2PlusIntegration_SingleConsumer_AlwaysRevertingCallback_StillFulfil uni.batchCoordinatorContractAddress, false, vrfcommon.V2Plus, + false, ) } func TestVRFV2PlusIntegration_ConsumerProxy_HappyPath(t *testing.T) { ownerKey := cltest.MustGenerateRandomKey(t) - uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 0) + uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 0, false) testConsumerProxyHappyPath( t, ownerKey, @@ -498,12 +685,13 @@ func TestVRFV2PlusIntegration_ConsumerProxy_HappyPath(t *testing.T) { uni.batchCoordinatorContractAddress, false, vrfcommon.V2Plus, + false, ) } func TestVRFV2PlusIntegration_ConsumerProxy_CoordinatorZeroAddress(t *testing.T) { ownerKey := cltest.MustGenerateRandomKey(t) - uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 0) + uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 0, false) testConsumerProxyCoordinatorZeroAddress(t, uni.coordinatorV2UniverseCommon) } @@ -519,6 +707,12 @@ func TestVRFV2PlusIntegration_ExternalOwnerConsumerExample(t *testing.T) { owner, backend) require.NoError(t, err) backend.Commit() + // Deploy feed + linkEthFeed, _, _, err := + mock_v3_aggregator_contract.DeployMockV3AggregatorContract( + owner, backend, 18, vrftesthelpers.WeiPerUnitLink.BigInt()) // 0.01 eth per link + require.NoError(t, err) + backend.Commit() coordinatorAddress, _, coordinator, err := vrf_coordinator_v2plus.DeployVRFCoordinatorV2Plus( owner, backend, common.Address{}) //bhs not needed for this test @@ -529,7 +723,7 @@ func TestVRFV2PlusIntegration_ExternalOwnerConsumerExample(t *testing.T) { }) require.NoError(t, err) backend.Commit() - _, err = coordinator.SetLINK(owner, linkAddress) + _, err = coordinator.SetLINKAndLINKETHFeed(owner, linkAddress, linkEthFeed) require.NoError(t, err) backend.Commit() consumerAddress, _, consumer, err := vrf_v2plus_sub_owner.DeployVRFV2PlusExternalSubOwnerExample(owner, backend, coordinatorAddress, linkAddress) @@ -583,12 +777,18 @@ func TestVRFV2PlusIntegration_SimpleConsumerExample(t *testing.T) { owner, backend) require.NoError(t, err) backend.Commit() + // Deploy feed + linkEthFeed, _, _, err := + mock_v3_aggregator_contract.DeployMockV3AggregatorContract( + owner, backend, 18, vrftesthelpers.WeiPerUnitLink.BigInt()) // 0.01 eth per link + require.NoError(t, err) + backend.Commit() coordinatorAddress, _, coordinator, err := vrf_coordinator_v2plus.DeployVRFCoordinatorV2Plus( owner, backend, common.Address{}) // bhs not needed for this test require.NoError(t, err) backend.Commit() - _, err = coordinator.SetLINK(owner, linkAddress) + _, err = coordinator.SetLINKAndLINKETHFeed(owner, linkAddress, linkEthFeed) require.NoError(t, err) backend.Commit() consumerAddress, _, consumer, err := vrf_v2plus_single_consumer.DeployVRFV2PlusSingleConsumerExample(owner, backend, coordinatorAddress, linkAddress, 1, 1, 1, [32]byte{}, false) @@ -618,7 +818,7 @@ func TestVRFV2PlusIntegration_SimpleConsumerExample(t *testing.T) { func TestVRFV2PlusIntegration_TestMaliciousConsumer(t *testing.T) { t.Parallel() key := cltest.MustGenerateRandomKey(t) - uni := newVRFCoordinatorV2PlusUniverse(t, key, 1) + uni := newVRFCoordinatorV2PlusUniverse(t, key, 1, false) testMaliciousConsumer( t, key, @@ -631,7 +831,7 @@ func TestVRFV2PlusIntegration_TestMaliciousConsumer(t *testing.T) { func TestVRFV2PlusIntegration_RequestCost(t *testing.T) { key := cltest.MustGenerateRandomKey(t) - uni := newVRFCoordinatorV2PlusUniverse(t, key, 1) + uni := newVRFCoordinatorV2PlusUniverse(t, key, 1, false) cfg := configtest.NewGeneralConfigSimulated(t, nil) app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, cfg, uni.backend, key) @@ -654,6 +854,9 @@ func TestVRFV2PlusIntegration_RequestCost(t *testing.T) { big.NewInt(1000000000000000000)) // 0.1 LINK require.NoError(tt, err) uni.backend.Commit() + _, err = carolContract.TopUpSubscriptionNative(carol, + big.NewInt(2000000000000000000)) // 0.2 ETH + uni.backend.Commit() // Ensure even with large number of consumers its still cheap var addrs []common.Address for i := 0; i < 99; i++ { @@ -661,12 +864,17 @@ func TestVRFV2PlusIntegration_RequestCost(t *testing.T) { } _, err = carolContract.UpdateSubscription(carol, addrs) require.NoError(tt, err) - estimate := estimateGas(tt, uni.backend, common.Address{}, + linkEstimate := estimateGas(tt, uni.backend, common.Address{}, carolContractAddress, uni.consumerABI, "requestRandomWords", uint32(10000), uint16(2), uint32(1), vrfkey.PublicKey.MustHash(), false) - tt.Log("gas estimate of non-proxied requestRandomWords:", estimate) - assert.Less(tt, estimate, uint64(127_000), + tt.Log("gas estimate of non-proxied requestRandomWords with LINK payment:", linkEstimate) + nativeEstimate := estimateGas(tt, uni.backend, common.Address{}, + carolContractAddress, uni.consumerABI, + "requestRandomWords", uint32(10000), uint16(2), uint32(1), + vrfkey.PublicKey.MustHash(), false) + tt.Log("gas estimate of non-proxied requestRandomWords with Native payment:", nativeEstimate) + assert.Less(tt, nativeEstimate, uint64(127_000), "requestRandomWords tx gas cost more than expected") }) @@ -703,7 +911,7 @@ func TestVRFV2PlusIntegration_RequestCost(t *testing.T) { func TestVRFV2PlusIntegration_MaxConsumersCost(t *testing.T) { key := cltest.MustGenerateRandomKey(t) - uni := newVRFCoordinatorV2PlusUniverse(t, key, 1) + uni := newVRFCoordinatorV2PlusUniverse(t, key, 1, false) carol := uni.vrfConsumers[0] carolContract := uni.consumerContracts[0] carolContractAddress := uni.consumerContractAddresses[0] @@ -736,9 +944,54 @@ func TestVRFV2PlusIntegration_MaxConsumersCost(t *testing.T) { assert.Less(t, estimate, uint64(100000)) } +func requestAndEstimateFulfillmentCost( + t *testing.T, + subID *big.Int, + consumer *bind.TransactOpts, + vrfkey vrfkey.KeyV2, + minConfs uint16, + gas uint32, + numWords uint32, + consumerContract vrftesthelpers.VRFConsumerContract, + consumerContractAddress common.Address, + uni coordinatorV2UniverseCommon, + app *cltest.TestApplication, + nativePayment bool, + lowerBound, upperBound uint64, +) { + _, err := consumerContract.RequestRandomness(consumer, vrfkey.PublicKey.MustHash(), subID, minConfs, gas, numWords, nativePayment) + require.NoError(t, err) + for i := 0; i < int(minConfs); i++ { + uni.backend.Commit() + } + + requestLog := FindLatestRandomnessRequestedLog(t, uni.rootContract, vrfkey.PublicKey.MustHash()) + s, err := proof.BigToSeed(requestLog.PreSeed()) + require.NoError(t, err) + extraArgs, err := extraargs.ExtraArgsV1(nativePayment) + require.NoError(t, err) + proof, rc, err := proof.GenerateProofResponseV2Plus(app.GetKeyStore().VRF(), vrfkey.ID(), proof.PreSeedDataV2Plus{ + PreSeed: s, + BlockHash: requestLog.Raw().BlockHash, + BlockNum: requestLog.Raw().BlockNumber, + SubId: subID, + CallbackGasLimit: gas, + NumWords: numWords, + Sender: consumerContractAddress, + ExtraArgs: extraArgs, + }) + require.NoError(t, err) + gasEstimate := estimateGas(t, uni.backend, common.Address{}, + uni.rootContractAddress, uni.coordinatorABI, + "fulfillRandomWords", proof, rc) + t.Log("consumer fulfillment gas estimate:", gasEstimate) + assert.Greater(t, gasEstimate, lowerBound) + assert.Less(t, gasEstimate, upperBound) +} + func TestVRFV2PlusIntegration_FulfillmentCost(t *testing.T) { key := cltest.MustGenerateRandomKey(t) - uni := newVRFCoordinatorV2PlusUniverse(t, key, 1) + uni := newVRFCoordinatorV2PlusUniverse(t, key, 1, false) cfg := configtest.NewGeneralConfigSimulated(t, nil) app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, cfg, uni.backend, key) @@ -753,10 +1006,6 @@ func TestVRFV2PlusIntegration_FulfillmentCost(t *testing.T) { require.NoError(t, err) uni.backend.Commit() - var ( - nonProxiedConsumerGasEstimate uint64 - proxiedConsumerGasEstimate uint64 - ) t.Run("non-proxied consumer", func(tt *testing.T) { carol := uni.vrfConsumers[0] carolContract := uni.consumerContracts[0] @@ -766,41 +1015,51 @@ func TestVRFV2PlusIntegration_FulfillmentCost(t *testing.T) { big.NewInt(1000000000000000000)) // 0.1 LINK require.NoError(tt, err) uni.backend.Commit() - subId, err := carolContract.SSubId(nil) + subID, err := carolContract.SSubId(nil) + require.NoError(tt, err) + _, err = carolContract.TopUpSubscriptionNative(carol, + big.NewInt(2000000000000000000)) // 0.2 ETH require.NoError(tt, err) - gasRequested := 50_000 nw := 1 requestedIncomingConfs := 3 - _, err = carolContract.RequestRandomness(carol, vrfkey.PublicKey.MustHash(), subId, uint16(requestedIncomingConfs), uint32(gasRequested), uint32(nw), false) - require.NoError(t, err) - for i := 0; i < requestedIncomingConfs; i++ { - uni.backend.Commit() - } + t.Run("native payment", func(tt *testing.T) { + requestAndEstimateFulfillmentCost( + t, + subID, + carol, + vrfkey, + uint16(requestedIncomingConfs), + uint32(gasRequested), + uint32(nw), + carolContract, + carolContractAddress, + uni.coordinatorV2UniverseCommon, + app, + true, + 120_000, + 500_000, + ) + }) - requestLog := FindLatestRandomnessRequestedLog(tt, uni.rootContract, vrfkey.PublicKey.MustHash()) - s, err := proof.BigToSeed(requestLog.PreSeed()) - require.NoError(t, err) - extraArgs, err := extraargs.ExtraArgsV1(false) - require.NoError(t, err) - proof, rc, err := proof.GenerateProofResponseV2Plus(app.GetKeyStore().VRF(), vrfkey.ID(), proof.PreSeedDataV2Plus{ - PreSeed: s, - BlockHash: requestLog.Raw().BlockHash, - BlockNum: requestLog.Raw().BlockNumber, - SubId: subId, - CallbackGasLimit: uint32(gasRequested), - NumWords: uint32(nw), - Sender: carolContractAddress, - ExtraArgs: extraArgs, + t.Run("link payment", func(tt *testing.T) { + requestAndEstimateFulfillmentCost( + t, + subID, + carol, + vrfkey, + uint16(requestedIncomingConfs), + uint32(gasRequested), + uint32(nw), + carolContract, + carolContractAddress, + uni.coordinatorV2UniverseCommon, + app, + false, + 120_000, + 500_000, + ) }) - require.NoError(tt, err) - nonProxiedConsumerGasEstimate = estimateGas(tt, uni.backend, common.Address{}, - uni.rootContractAddress, uni.coordinatorABI, - "fulfillRandomWords", proof, rc) - t.Log("non-proxied consumer fulfillment gas estimate:", nonProxiedConsumerGasEstimate) - // Establish very rough bounds on fulfillment cost - assert.Greater(tt, nonProxiedConsumerGasEstimate, uint64(120_000)) - assert.Less(tt, nonProxiedConsumerGasEstimate, uint64(500_000)) }) t.Run("proxied consumer", func(tt *testing.T) { @@ -811,41 +1070,27 @@ func TestVRFV2PlusIntegration_FulfillmentCost(t *testing.T) { _, err = consumerContract.CreateSubscriptionAndFund(consumerOwner, assets.Ether(5).ToInt()) require.NoError(t, err) uni.backend.Commit() - subId, err := consumerContract.SSubId(nil) + subID, err := consumerContract.SSubId(nil) require.NoError(t, err) gasRequested := 50_000 nw := 1 requestedIncomingConfs := 3 - _, err = consumerContract.RequestRandomness(consumerOwner, vrfkey.PublicKey.MustHash(), subId, uint16(requestedIncomingConfs), uint32(gasRequested), uint32(nw), false) - require.NoError(t, err) - for i := 0; i < requestedIncomingConfs; i++ { - uni.backend.Commit() - } - - requestLog := FindLatestRandomnessRequestedLog(t, uni.rootContract, vrfkey.PublicKey.MustHash()) - require.Equal(tt, subId, requestLog.SubID()) - s, err := proof.BigToSeed(requestLog.PreSeed()) - require.NoError(t, err) - extraArgs, err := extraargs.ExtraArgsV1(false) - require.NoError(t, err) - proof, rc, err := proof.GenerateProofResponseV2Plus(app.GetKeyStore().VRF(), vrfkey.ID(), proof.PreSeedDataV2Plus{ - PreSeed: s, - BlockHash: requestLog.Raw().BlockHash, - BlockNum: requestLog.Raw().BlockNumber, - SubId: subId, - CallbackGasLimit: uint32(gasRequested), - NumWords: uint32(nw), - Sender: consumerContractAddress, - ExtraArgs: extraArgs, - }) - require.NoError(t, err) - proxiedConsumerGasEstimate = estimateGas(t, uni.backend, common.Address{}, - uni.rootContractAddress, uni.coordinatorABI, - "fulfillRandomWords", proof, rc) - t.Log("proxied consumer fulfillment gas estimate", proxiedConsumerGasEstimate) - // Establish very rough bounds on fulfillment cost - assert.Greater(t, proxiedConsumerGasEstimate, uint64(120_000)) - assert.Less(t, proxiedConsumerGasEstimate, uint64(500_000)) + requestAndEstimateFulfillmentCost( + t, + subID, + consumerOwner, + vrfkey, + uint16(requestedIncomingConfs), + uint32(gasRequested), + uint32(nw), + consumerContract, + consumerContractAddress, + uni.coordinatorV2UniverseCommon, + app, + false, + 120_000, + 500_000, + ) }) } @@ -857,3 +1102,247 @@ func AssertEthBalances(t *testing.T, backend *backends.SimulatedBackend, address assert.Equal(t, balances[i].String(), b.String(), "invalid balance for %v", a) } } + +func setupSubscriptionAndFund( + t *testing.T, + uni coordinatorV2UniverseCommon, + consumer *bind.TransactOpts, + consumerContract vrftesthelpers.VRFConsumerContract, + consumerAddress common.Address, + linkAmount *big.Int, + nativeAmount *big.Int) *big.Int { + _, err := uni.rootContract.CreateSubscription(consumer) + require.NoError(t, err) + uni.backend.Commit() + + iter, err := uni.rootContract.FilterSubscriptionCreated(nil, nil) + require.NoError(t, err) + require.True(t, iter.Next(), "could not find SubscriptionCreated event for subID") + subID := iter.Event().SubID() + + _, err = consumerContract.SetSubID(consumer, subID) + require.NoError(t, err) + + _, err = uni.rootContract.AddConsumer(consumer, subID, consumerAddress) + require.NoError(t, err, "failed to add consumer") + uni.backend.Commit() + + b, err := utils.ABIEncode(`[{"type":"uint256"}]`, subID) + require.NoError(t, err) + _, err = uni.linkContract.TransferAndCall( + uni.sergey, uni.rootContractAddress, linkAmount, b) + require.NoError(t, err, "failed to fund sub") + uni.backend.Commit() + + _, err = uni.rootContract.FundSubscriptionWithEth(consumer, subID, nativeAmount) + require.NoError(t, err, "failed to fund sub with native") + uni.backend.Commit() + + return subID +} + +func TestVRFV2PlusIntegration_Migration(t *testing.T) { + t.Parallel() + ownerKey := cltest.MustGenerateRandomKey(t) + uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1, false) + key1 := cltest.MustGenerateRandomKey(t) + gasLanePriceWei := assets.GWei(10) + config, db := heavyweight.FullTestDBV2(t, "vrfv2plus_migration", func(c *chainlink.Config, s *chainlink.Secrets) { + simulatedOverrides(t, assets.GWei(10), toml.KeySpecific{ + // Gas lane. + Key: ptr(key1.EIP55Address), + GasEstimator: toml.KeySpecificGasEstimator{PriceMax: gasLanePriceWei}, + })(c, s) + c.EVM[0].GasEstimator.LimitDefault = ptr[uint32](5_000_000) + c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) + }) + app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, uni.backend, ownerKey, key1) + + // Create a subscription and fund with 5 LINK. + consumerContract := uni.consumerContracts[0] + consumer := uni.vrfConsumers[0] + consumerAddress := uni.consumerContractAddresses[0] + + subID := setupSubscriptionAndFund( + t, + uni.coordinatorV2UniverseCommon, + consumer, + consumerContract, + consumerAddress, + new(big.Int).SetUint64(5e18), + new(big.Int).SetUint64(3e18), + ) + + // Fund gas lane. + sendEth(t, ownerKey, uni.backend, key1.Address, 10) + require.NoError(t, app.Start(testutils.Context(t))) + + // Create VRF job using key1 and key2 on the same gas lane. + jbs := createVRFJobs( + t, + [][]ethkey.KeyV2{{key1}}, + app, + uni.rootContract, + uni.rootContractAddress, + uni.batchCoordinatorContractAddress, + uni.coordinatorV2UniverseCommon, + nil, + vrfcommon.V2Plus, + false, + gasLanePriceWei) + keyHash := jbs[0].VRFSpec.PublicKey.MustHash() + + // Make some randomness requests. + numWords := uint32(2) + + requestID, _ := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, 500_000, uni.rootContract, uni.backend, false) + + // Wait for fulfillment to be queued. + gomega.NewGomegaWithT(t).Eventually(func() bool { + uni.backend.Commit() + runs, err := app.PipelineORM().GetAllRuns() + require.NoError(t, err) + t.Log("runs", len(runs)) + return len(runs) == 1 + }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue()) + + mine(t, requestID, subID, uni.backend, db, vrfcommon.V2Plus) + assertRandomWordsFulfilled(t, requestID, true, uni.rootContract, false) + + // Assert correct number of random words sent by coordinator. + assertNumRandomWords(t, consumerContract, numWords) + + rw, err := consumerContract.SRandomWords(nil, big.NewInt(0)) + require.NoError(t, err) + + subV1, err := uni.rootContract.GetSubscription(nil, subID) + require.NoError(t, err) + + _, err = uni.rootContract.Migrate(consumer, subID, uni.migrationTestCoordinatorAddress) + require.NoError(t, err) + uni.backend.Commit() + + subV2, err := uni.migrationTestCoordinator.GetSubscription(nil, subID) + require.NoError(t, err) + + totalLinkBalance, err := uni.migrationTestCoordinator.STotalLinkBalance(nil) + require.NoError(t, err) + totalNativeBalance, err := uni.migrationTestCoordinator.STotalNativeBalance(nil) + require.NoError(t, err) + linkContractBalance, err := uni.linkContract.BalanceOf(nil, uni.migrationTestCoordinatorAddress) + require.NoError(t, err) + balance, err := uni.backend.BalanceAt(testutils.Context(t), uni.migrationTestCoordinatorAddress, nil) + require.NoError(t, err) + + require.Equal(t, subV1.Balance(), totalLinkBalance) + require.Equal(t, subV1.EthBalance(), totalNativeBalance) + require.Equal(t, subV1.Balance(), linkContractBalance) + require.Equal(t, subV1.EthBalance(), balance) + + require.Equal(t, subV1.Balance(), subV2.LinkBalance) + require.Equal(t, subV1.EthBalance(), subV2.NativeBalance) + require.Equal(t, subV1.Owner(), subV2.Owner) + require.Equal(t, len(subV1.Consumers()), len(subV2.Consumers)) + for i, c := range subV1.Consumers() { + require.Equal(t, c, subV2.Consumers[i]) + } + + minRequestConfirmations := uint16(2) + requestID2, rw2 := requestRandomnessAndValidate( + t, + consumer, + consumerContract, + keyHash, + subID, + minRequestConfirmations, + 50_000, + numWords, + uni, + true, + ) + require.NotEqual(t, requestID, requestID2) + require.NotEqual(t, rw, rw2) + requestID3, rw3 := requestRandomnessAndValidate( + t, + consumer, + consumerContract, + keyHash, + subID, + minRequestConfirmations, + 50_000, + numWords, + uni, + false, + ) + require.NotEqual(t, requestID2, requestID3) + require.NotEqual(t, rw2, rw3) +} + +func requestRandomnessAndValidate(t *testing.T, + consumer *bind.TransactOpts, + consumerContract vrftesthelpers.VRFConsumerContract, + keyHash common.Hash, + subID *big.Int, + minConfs uint16, + gas, numWords uint32, + uni coordinatorV2PlusUniverse, + nativePayment bool) (*big.Int, *big.Int) { + _, err := consumerContract.RequestRandomness( + consumer, + keyHash, + subID, + minConfs, + gas, + numWords, + nativePayment, // test link payment works after migration + ) + require.NoError(t, err) + uni.backend.Commit() + + requestID, err := consumerContract.SRequestId(nil) + require.NoError(t, err) + + _, err = uni.migrationTestCoordinator.FulfillRandomWords(uni.neil, requestID) + require.NoError(t, err) + uni.backend.Commit() + + rw, err := consumerContract.SRandomWords(nil, big.NewInt(0)) + require.NoError(t, err) + + return requestID, rw +} + +func TestVRFV2PlusIntegration_CancelSubscription(t *testing.T) { + key := cltest.MustGenerateRandomKey(t) + uni := newVRFCoordinatorV2PlusUniverse(t, key, 1, false) + consumer := uni.vrfConsumers[0] + consumerContract := uni.consumerContracts[0] + consumerContractAddress := uni.consumerContractAddresses[0] + linkAmount := new(big.Int).SetUint64(5e18) + nativeAmount := new(big.Int).SetUint64(3e18) + subID := setupSubscriptionAndFund( + t, + uni.coordinatorV2UniverseCommon, + consumer, + consumerContract, + consumerContractAddress, + linkAmount, + nativeAmount, + ) + + linkBalanceBeforeCancel, err := uni.linkContract.BalanceOf(nil, uni.neil.From) + require.NoError(t, err) + nativeBalanceBeforeCancel, err := uni.backend.BalanceAt(testutils.Context(t), uni.neil.From, nil) + require.NoError(t, err) + + // non-owner cannot cancel subscription + _, err = uni.rootContract.CancelSubscription(uni.neil, subID, consumer.From) + require.Error(t, err) + + _, err = uni.rootContract.CancelSubscription(consumer, subID, uni.neil.From) + require.NoError(t, err) + uni.backend.Commit() + + AssertLinkBalance(t, uni.linkContract, uni.neil.From, linkBalanceBeforeCancel.Add(linkBalanceBeforeCancel, linkAmount)) + AssertNativeBalance(t, uni.backend, uni.neil.From, nativeBalanceBeforeCancel.Add(nativeBalanceBeforeCancel, nativeAmount)) +} diff --git a/core/services/vrf/v2/integration_v2_test.go b/core/services/vrf/v2/integration_v2_test.go index ce5e5999c34..6ae1cb020a5 100644 --- a/core/services/vrf/v2/integration_v2_test.go +++ b/core/services/vrf/v2/integration_v2_test.go @@ -224,6 +224,7 @@ func newVRFCoordinatorV2Universe(t *testing.T, key ethkey.KeyV2, numConsumers in // Deploy old VRF v2 coordinator from bytecode err, oldRootContractAddress, oldRootContract := deployOldCoordinator( t, linkAddress, bhsAddress, linkEthFeed, backend, neil) + require.NoError(t, err) // Deploy the VRFOwner contract, which will own the VRF coordinator // in some tests. @@ -477,9 +478,15 @@ func subscribeVRF( consumerContract vrftesthelpers.VRFConsumerContract, coordinator v22.CoordinatorV2_X, backend *backends.SimulatedBackend, - fundingJuels *big.Int, + fundingAmount *big.Int, + nativePayment bool, ) (v22.Subscription, *big.Int) { - _, err := consumerContract.CreateSubscriptionAndFund(author, fundingJuels) + var err error + if nativePayment { + _, err = consumerContract.CreateSubscriptionAndFundNative(author, fundingAmount) + } else { + _, err = consumerContract.CreateSubscriptionAndFund(author, fundingAmount) + } require.NoError(t, err) backend.Commit() @@ -488,6 +495,13 @@ func subscribeVRF( sub, err := coordinator.GetSubscription(nil, subID) require.NoError(t, err) + + if nativePayment { + require.Equal(t, fundingAmount.String(), sub.EthBalance().String()) + } else { + require.Equal(t, fundingAmount.String(), sub.Balance().String()) + } + return sub, subID } @@ -635,6 +649,7 @@ func requestRandomnessAndAssertRandomWordsRequestedEvent( cbGasLimit uint32, coordinator v22.CoordinatorV2_X, backend *backends.SimulatedBackend, + nativePayment bool, ) (requestID *big.Int, requestBlockNumber uint64) { minRequestConfirmations := uint16(2) _, err := vrfConsumerHandle.RequestRandomness( @@ -644,7 +659,7 @@ func requestRandomnessAndAssertRandomWordsRequestedEvent( minRequestConfirmations, cbGasLimit, numWords, - false, + nativePayment, ) require.NoError(t, err) backend.Commit() @@ -667,6 +682,7 @@ func requestRandomnessAndAssertRandomWordsRequestedEvent( require.Equal(t, cbGasLimit, event.CallbackGasLimit(), "callback gas limit of event and of request not equal") require.Equal(t, minRequestConfirmations, event.MinimumRequestConfirmations(), "min request confirmations of event and of request not equal") require.Equal(t, numWords, event.NumWords(), "num words of event and of request not equal") + require.Equal(t, nativePayment, event.NativePayment()) return requestID, event.Raw().BlockNumber } @@ -679,13 +695,13 @@ func subscribeAndAssertSubscriptionCreatedEvent( vrfConsumerHandle vrftesthelpers.VRFConsumerContract, consumerOwner *bind.TransactOpts, consumerContractAddress common.Address, - fundingJuels *big.Int, + fundingAmount *big.Int, coordinator v22.CoordinatorV2_X, backend *backends.SimulatedBackend, + nativePayment bool, ) *big.Int { // Create a subscription and fund with LINK. - sub, subID := subscribeVRF(t, consumerOwner, vrfConsumerHandle, coordinator, backend, fundingJuels) - require.Equal(t, fundingJuels.String(), sub.Balance().String()) + _, subID := subscribeVRF(t, consumerOwner, vrfConsumerHandle, coordinator, backend, fundingAmount, nativePayment) // Assert the subscription event in the coordinator contract. iter, err := coordinator.FilterSubscriptionCreated(nil, []*big.Int{subID}) @@ -708,13 +724,14 @@ func assertRandomWordsFulfilled( requestID *big.Int, expectedSuccess bool, coordinator v22.CoordinatorV2_X, + nativePayment bool, ) (rwfe v22.RandomWordsFulfilled) { // Check many times in case there are delays processing the event // this could happen occasionally and cause flaky tests. numChecks := 3 found := false for i := 0; i < numChecks; i++ { - filter, err := coordinator.FilterRandomWordsFulfilled(nil, []*big.Int{requestID}) + filter, err := coordinator.FilterRandomWordsFulfilled(nil, []*big.Int{requestID}, nil) require.NoError(t, err) for filter.Next() { require.Equal(t, expectedSuccess, filter.Event().Success(), "fulfillment event success not correct, expected: %+v, actual: %+v", expectedSuccess, filter.Event().Success()) @@ -853,6 +870,7 @@ func TestVRFV2Integration_SingleConsumer_HappyPath_BatchFulfillment(t *testing.T 5, // number of requests to send false, // don't send big callback vrfcommon.V2, + false, ) } @@ -874,6 +892,7 @@ func TestVRFV2Integration_SingleConsumer_HappyPath_BatchFulfillment_BigGasCallba 5, // number of requests to send true, // send big callback vrfcommon.V2, + false, ) } @@ -893,6 +912,12 @@ func TestVRFV2Integration_SingleConsumer_HappyPath(t *testing.T) { uni.batchCoordinatorContractAddress, ptr(uni.vrfOwnerAddress), vrfcommon.V2, + false, + func(t *testing.T, coordinator v22.CoordinatorV2_X, rwfe v22.RandomWordsFulfilled, expectedSubID *big.Int) { + require.PanicsWithValue(t, "VRF V2 RandomWordsFulfilled does not implement SubID", func() { + rwfe.SubID() + }) + }, ) } @@ -1052,6 +1077,7 @@ func TestVRFV2Integration_SingleConsumer_EIP150_HappyPath(t *testing.T) { uni.batchCoordinatorContractAddress, false, vrfcommon.V2, + false, ) } @@ -1066,6 +1092,7 @@ func TestVRFV2Integration_SingleConsumer_EIP150_Revert(t *testing.T) { uni.batchCoordinatorContractAddress, false, vrfcommon.V2, + false, ) } @@ -1165,7 +1192,7 @@ func TestVRFV2Integration_SingleConsumer_Wrapper(t *testing.T) { mine(t, requestID, new(big.Int).SetUint64(wrapperSubID), uni.backend, db, vrfcommon.V2) // Assert correct state of RandomWordsFulfilled event. - assertRandomWordsFulfilled(t, requestID, true, uni.rootContract) + assertRandomWordsFulfilled(t, requestID, true, uni.rootContract, false) t.Log("Done!") } @@ -1245,7 +1272,7 @@ func TestVRFV2Integration_Wrapper_High_Gas(t *testing.T) { mine(t, requestID, new(big.Int).SetUint64(wrapperSubID), uni.backend, db, vrfcommon.V2) // Assert correct state of RandomWordsFulfilled event. - assertRandomWordsFulfilled(t, requestID, true, uni.rootContract) + assertRandomWordsFulfilled(t, requestID, true, uni.rootContract, false) t.Log("Done!") } @@ -1266,6 +1293,47 @@ func TestVRFV2Integration_SingleConsumer_NeedsBlockhashStore(t *testing.T) { uni.batchCoordinatorContractAddress, ptr(uni.vrfOwnerAddress), vrfcommon.V2, + false, + ) +} + +func TestVRFV2Integration_SingleConsumer_NeedsTrustedBlockhashStore(t *testing.T) { + t.Parallel() + ownerKey := cltest.MustGenerateRandomKey(t) + uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 2, true) + testMultipleConsumersNeedTrustedBHS( + t, + ownerKey, + uni, + uni.vrfConsumers, + uni.consumerContracts, + uni.consumerContractAddresses, + uni.rootContract, + uni.rootContractAddress, + uni.batchCoordinatorContractAddress, + vrfcommon.V2Plus, + false, + false, + ) +} + +func TestVRFV2Integration_SingleConsumer_NeedsTrustedBlockhashStore_AfterDelay(t *testing.T) { + t.Parallel() + ownerKey := cltest.MustGenerateRandomKey(t) + uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 2, true) + testMultipleConsumersNeedTrustedBHS( + t, + ownerKey, + uni, + uni.vrfConsumers, + uni.consumerContracts, + uni.consumerContractAddresses, + uni.rootContract, + uni.rootContractAddress, + uni.batchCoordinatorContractAddress, + vrfcommon.V2Plus, + false, + true, ) } @@ -1285,6 +1353,7 @@ func TestVRFV2Integration_SingleConsumer_BlockHeaderFeeder(t *testing.T) { uni.batchCoordinatorContractAddress, ptr(uni.vrfOwnerAddress), vrfcommon.V2, + false, ) } @@ -1306,6 +1375,7 @@ func TestVRFV2Integration_SingleConsumer_NeedsTopUp(t *testing.T) { assets.Ether(1).ToInt(), // initial funding of 1 LINK assets.Ether(100).ToInt(), // top up of 100 LINK vrfcommon.V2, + false, ) } @@ -1319,6 +1389,7 @@ func TestVRFV2Integration_SingleConsumer_BigGasCallback_Sandwich(t *testing.T) { uni.batchCoordinatorContractAddress, false, vrfcommon.V2, + false, ) } @@ -1332,6 +1403,7 @@ func TestVRFV2Integration_SingleConsumer_MultipleGasLanes(t *testing.T) { uni.batchCoordinatorContractAddress, false, vrfcommon.V2, + false, ) } @@ -1345,6 +1417,7 @@ func TestVRFV2Integration_SingleConsumer_AlwaysRevertingCallback_StillFulfilled( uni.batchCoordinatorContractAddress, false, vrfcommon.V2, + false, ) } @@ -1358,6 +1431,7 @@ func TestVRFV2Integration_ConsumerProxy_HappyPath(t *testing.T) { uni.batchCoordinatorContractAddress, false, vrfcommon.V2, + false, ) } @@ -1603,7 +1677,7 @@ func TestIntegrationVRFV2(t *testing.T) { // Wait for the request to be fulfilled on-chain. var rf []v22.RandomWordsFulfilled gomega.NewWithT(t).Eventually(func() bool { - rfIterator, err2 := uni.rootContract.FilterRandomWordsFulfilled(nil, nil) + rfIterator, err2 := uni.rootContract.FilterRandomWordsFulfilled(nil, nil, nil) require.NoError(t, err2, "failed to logs") uni.backend.Commit() for rfIterator.Next() { @@ -1678,7 +1752,7 @@ func TestIntegrationVRFV2(t *testing.T) { }) // We should see the response count present - chain, err := app.Chains.EVM.Get(big.NewInt(1337)) + chain, err := app.GetRelayers().LegacyEVMChains().Get(big.NewInt(1337).String()) require.NoError(t, err) q := pg.NewQ(app.GetSqlxDB(), app.Logger, app.Config.Database()) @@ -2123,12 +2197,22 @@ func FindLatestRandomnessRequestedLog(t *testing.T, return rf[latest] } +func AssertLinkBalance(t *testing.T, linkContract *link_token_interface.LinkToken, address common.Address, balance *big.Int) { + b, err := linkContract.BalanceOf(nil, address) + require.NoError(t, err) + assert.Equal(t, balance.String(), b.String(), "invalid balance for %v", address) +} + +func AssertNativeBalance(t *testing.T, backend *backends.SimulatedBackend, address common.Address, balance *big.Int) { + b, err := backend.BalanceAt(testutils.Context(t), address, nil) + require.NoError(t, err) + assert.Equal(t, balance.String(), b.String(), "invalid balance for %v", address) +} + func AssertLinkBalances(t *testing.T, linkContract *link_token_interface.LinkToken, addresses []common.Address, balances []*big.Int) { require.Equal(t, len(addresses), len(balances)) for i, a := range addresses { - b, err := linkContract.BalanceOf(nil, a) - require.NoError(t, err) - assert.Equal(t, balances[i].String(), b.String(), "invalid balance for %v", a) + AssertLinkBalance(t, linkContract, a, balances[i]) } } diff --git a/core/services/vrf/v2/listener_v2.go b/core/services/vrf/v2/listener_v2.go index 37267742c85..9b643d4f571 100644 --- a/core/services/vrf/v2/listener_v2.go +++ b/core/services/vrf/v2/listener_v2.go @@ -54,9 +54,6 @@ var ( batchCoordinatorV2ABI = evmtypes.MustGetABI(batch_vrf_coordinator_v2.BatchVRFCoordinatorV2ABI) batchCoordinatorV2PlusABI = evmtypes.MustGetABI(batch_vrf_coordinator_v2plus.BatchVRFCoordinatorV2PlusABI) vrfOwnerABI = evmtypes.MustGetABI(vrf_owner.VRFOwnerMetaData.ABI) - // RandomWordsRequestedV2PlusABI is the ABI of the RandomWordsRequested event - // for V2Plus. - RandomWordsRequestedV2PlusABI = coordinatorV2PlusABI.Events["RandomWordsRequested"].Sig ) const ( @@ -97,6 +94,8 @@ const ( AND CAST(meta->>'GlobalSubId' AS NUMERIC) = $2 AND state IN ('unconfirmed', 'unstarted', 'in_progress') GROUP BY meta->>'GlobalSubId'` + + CouldNotDetermineIfLogConsumedMsg = "Could not determine if log was already consumed" ) type errPossiblyInsufficientFunds struct{} @@ -235,7 +234,7 @@ type listenerV2 struct { // Wait group to wait on all goroutines to shut down. wg *sync.WaitGroup - // aggregator client to get link/eth feed prices from chain. + // aggregator client to get link/eth feed prices from chain. Can be nil for VRF V2 plus aggregator aggregator_v3_interface.AggregatorV3InterfaceInterface // deduper prevents processing duplicate requests from the log broadcaster. @@ -389,8 +388,8 @@ func (lsn *listenerV2) pruneConfirmedRequestCounts() { // Determine a set of logs that are confirmed // and the subscription has sufficient balance to fulfill, // given a eth call with the max gas price. -// Note we have to consider the pending reqs already in the txm as already "spent" link, -// using a max link consumed in their metadata. +// Note we have to consider the pending reqs already in the txm as already "spent" link or native, +// using a max link or max native consumed in their metadata. // A user will need a minBalance capable of fulfilling a single req at the max gas price or nothing will happen. // This is acceptable as users can choose different keyhashes which have different max gas prices. // Other variables which can change the bill amount between our eth call simulation and tx execution: @@ -604,6 +603,7 @@ func (lsn *listenerV2) processRequestsPerSubBatchHelper( startBalanceNoReserved *big.Int, reqs []pendingRequest, subIsActive bool, + nativePayment bool, ) (processed map[string]struct{}) { start := time.Now() processed = make(map[string]struct{}) @@ -631,6 +631,7 @@ func (lsn *listenerV2) processRequestsPerSubBatchHelper( "startBalanceNoReserved", startBalanceNoReserved.String(), "batchMaxGas", batchMaxGas, "subIsActive", subIsActive, + "nativePayment", nativePayment, ) defer func() { @@ -736,7 +737,7 @@ func (lsn *listenerV2) processRequestsPerSubBatchHelper( } if startBalanceNoReserved.Cmp(p.fundsNeeded) < 0 && errors.Is(p.err, errPossiblyInsufficientFunds{}) { - ll.Infow("Insufficient link balance to fulfill a request based on estimate, breaking", "err", p.err) + ll.Infow("Insufficient balance to fulfill a request based on estimate, breaking", "err", p.err) outOfBalance = true // break out of this inner loop to process the currently constructed batch @@ -834,11 +835,11 @@ func (lsn *listenerV2) processRequestsPerSubBatch( wg.Add(2) go func() { defer wg.Done() - nativeProcessed = lsn.processRequestsPerSubBatchHelper(ctx, subID, startEthBalance, startBalanceNoReserveEth, nativeRequests, subIsActive) + nativeProcessed = lsn.processRequestsPerSubBatchHelper(ctx, subID, startEthBalance, startBalanceNoReserveEth, nativeRequests, subIsActive, true) }() go func() { defer wg.Done() - linkProcessed = lsn.processRequestsPerSubBatchHelper(ctx, subID, startLinkBalance, startBalanceNoReserveLink, linkRequests, subIsActive) + linkProcessed = lsn.processRequestsPerSubBatchHelper(ctx, subID, startLinkBalance, startBalanceNoReserveLink, linkRequests, subIsActive, false) }() wg.Wait() // combine the processed link and native requests into the processed map @@ -958,6 +959,7 @@ func (lsn *listenerV2) processRequestsPerSubHelper( startBalanceNoReserved *big.Int, reqs []pendingRequest, subIsActive bool, + nativePayment bool, ) (processed map[string]struct{}) { start := time.Now() processed = make(map[string]struct{}) @@ -968,6 +970,7 @@ func (lsn *listenerV2) processRequestsPerSubHelper( "startBalance", startBalance.String(), "startBalanceNoReserved", startBalanceNoReserved.String(), "subIsActive", subIsActive, + "nativePayment", nativePayment, ) defer func() { @@ -1061,7 +1064,7 @@ func (lsn *listenerV2) processRequestsPerSubHelper( } if startBalanceNoReserved.Cmp(p.fundsNeeded) < 0 { - ll.Infow("Insufficient link balance to fulfill a request based on estimate, returning", "err", p.err) + ll.Infow("Insufficient balance to fulfill a request based on estimate, returning", "err", p.err) return processed } @@ -1082,7 +1085,7 @@ func (lsn *listenerV2) processRequestsPerSubHelper( if startBalanceNoReserved.Cmp(p.maxFee) < 0 { // Insufficient funds, have to wait for a user top up. Leave it unprocessed for now - ll.Infow("Insufficient link balance to fulfill a request, returning") + ll.Infow("Insufficient balance to fulfill a request, returning") return processed } @@ -1214,7 +1217,8 @@ func (lsn *listenerV2) processRequestsPerSub( startEthBalance, startBalanceNoReserveEth, nativeRequests, - subIsActive) + subIsActive, + true) }() go func() { defer wg.Done() @@ -1224,7 +1228,8 @@ func (lsn *listenerV2) processRequestsPerSub( startLinkBalance, startBalanceNoReserveLink, linkRequests, - subIsActive) + subIsActive, + false) }() wg.Wait() // combine the native and link processed requests into the processed map @@ -1570,7 +1575,27 @@ func (lsn *listenerV2) handleLog(lb log.Broadcast, minConfs uint32) { lsn.l.Debugw("Received fulfilled log", "reqID", v.RequestId, "success", v.Success) consumed, err := lsn.logBroadcaster.WasAlreadyConsumed(lb) if err != nil { - lsn.l.Errorw("Could not determine if log was already consumed", "err", err, "txHash", lb.RawLog().TxHash) + lsn.l.Errorw(CouldNotDetermineIfLogConsumedMsg, "err", err, "txHash", lb.RawLog().TxHash) + return + } else if consumed { + return + } + lsn.respCountMu.Lock() + lsn.respCount[v.RequestId.String()]++ + lsn.respCountMu.Unlock() + lsn.blockNumberToReqID.Insert(fulfilledReqV2{ + blockNumber: v.Raw.BlockNumber, + reqID: v.RequestId.String(), + }) + lsn.markLogAsConsumed(lb) + return + } + + if v, ok := lb.DecodedLog().(*vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsFulfilled); ok { + lsn.l.Debugw("Received fulfilled log", "reqID", v.RequestId, "success", v.Success) + consumed, err := lsn.logBroadcaster.WasAlreadyConsumed(lb) + if err != nil { + lsn.l.Errorw(CouldNotDetermineIfLogConsumedMsg, "err", err, "txHash", lb.RawLog().TxHash) return } else if consumed { return @@ -1591,7 +1616,7 @@ func (lsn *listenerV2) handleLog(lb log.Broadcast, minConfs uint32) { lsn.l.Errorw("Failed to parse log", "err", err, "txHash", lb.RawLog().TxHash) consumed, err := lsn.logBroadcaster.WasAlreadyConsumed(lb) if err != nil { - lsn.l.Errorw("Could not determine if log was already consumed", "err", err, "txHash", lb.RawLog().TxHash) + lsn.l.Errorw(CouldNotDetermineIfLogConsumedMsg, "err", err, "txHash", lb.RawLog().TxHash) return } else if consumed { return @@ -1670,7 +1695,7 @@ func uniqueReqs(reqs []pendingRequest) int { } // GasProofVerification is an upper limit on the gas used for verifying the VRF proof on-chain. -// It can be used to estimate the amount of LINK needed to fulfill a request. +// It can be used to estimate the amount of LINK or native needed to fulfill a request. const GasProofVerification uint32 = 200_000 // EstimateFeeJuels estimates the amount of link needed to fulfill a request diff --git a/core/services/vrf/v2/listener_v2_test.go b/core/services/vrf/v2/listener_v2_test.go index cf18f74134d..dd63ec8208e 100644 --- a/core/services/vrf/v2/listener_v2_test.go +++ b/core/services/vrf/v2/listener_v2_test.go @@ -2,6 +2,7 @@ package v2 import ( "math/big" + "sync" "testing" "time" @@ -10,15 +11,19 @@ import ( "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/theodesp/go-heaps/pairing" "github.com/smartcontractkit/sqlx" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon" txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" txmgrtypes "github.com/smartcontractkit/chainlink/v2/common/txmgr/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -418,3 +423,73 @@ func TestListener_Backoff(t *testing.T) { }) } } + +func TestListener_handleLog(tt *testing.T) { + lb := mocks.NewBroadcaster(tt) + chainID := int64(2) + minConfs := uint32(3) + blockNumber := uint64(5) + requestID := int64(6) + tt.Run("v2", func(t *testing.T) { + j, err := vrfcommon.ValidatedVRFSpec(testspecs.GenerateVRFSpec(testspecs.VRFSpecParams{ + VRFVersion: vrfcommon.V2, + RequestedConfsDelay: 10, + FromAddresses: []string{"0xF2982b7Ef6E3D8BB738f8Ea20502229781f6Ad97"}, + }).Toml()) + require.NoError(t, err) + fulfilledLog := vrf_coordinator_v2.VRFCoordinatorV2RandomWordsFulfilled{ + RequestId: big.NewInt(requestID), + Raw: types.Log{BlockNumber: blockNumber}, + } + log := log.NewLogBroadcast(types.Log{}, *big.NewInt(chainID), &fulfilledLog) + lb.On("WasAlreadyConsumed", log).Return(false, nil).Once() + lb.On("MarkConsumed", log).Return(nil).Once() + defer lb.AssertExpectations(t) + listener := &listenerV2{ + respCount: map[string]uint64{}, + job: j, + blockNumberToReqID: pairing.New(), + latestHeadMu: sync.RWMutex{}, + logBroadcaster: lb, + l: logger.TestLogger(t), + } + listener.handleLog(log, minConfs) + require.Equal(t, listener.respCount[fulfilledLog.RequestId.String()], uint64(1)) + req, ok := listener.blockNumberToReqID.FindMin().(fulfilledReqV2) + require.True(t, ok) + require.Equal(t, req.blockNumber, blockNumber) + require.Equal(t, req.reqID, "6") + }) + + tt.Run("v2 plus", func(t *testing.T) { + j, err := vrfcommon.ValidatedVRFSpec(testspecs.GenerateVRFSpec(testspecs.VRFSpecParams{ + VRFVersion: vrfcommon.V2Plus, + RequestedConfsDelay: 10, + FromAddresses: []string{"0xF2982b7Ef6E3D8BB738f8Ea20502229781f6Ad97"}, + }).Toml()) + require.NoError(t, err) + fulfilledLog := vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsFulfilled{ + RequestId: big.NewInt(requestID), + Raw: types.Log{BlockNumber: blockNumber}, + } + log := log.NewLogBroadcast(types.Log{}, *big.NewInt(chainID), &fulfilledLog) + lb.On("WasAlreadyConsumed", log).Return(false, nil).Once() + lb.On("MarkConsumed", log).Return(nil).Once() + defer lb.AssertExpectations(t) + listener := &listenerV2{ + respCount: map[string]uint64{}, + job: j, + blockNumberToReqID: pairing.New(), + latestHeadMu: sync.RWMutex{}, + logBroadcaster: lb, + l: logger.TestLogger(t), + } + listener.handleLog(log, minConfs) + require.Equal(t, listener.respCount[fulfilledLog.RequestId.String()], uint64(1)) + req, ok := listener.blockNumberToReqID.FindMin().(fulfilledReqV2) + require.True(t, ok) + require.Equal(t, req.blockNumber, blockNumber) + require.Equal(t, req.reqID, "6") + }) + +} diff --git a/core/services/vrf/v2/listener_v2_types_test.go b/core/services/vrf/v2/listener_v2_types_test.go index 2e27980dd41..11bb7c98769 100644 --- a/core/services/vrf/v2/listener_v2_types_test.go +++ b/core/services/vrf/v2/listener_v2_types_test.go @@ -10,6 +10,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log/mocks" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon" @@ -54,3 +55,43 @@ func Test_BatchFulfillments_AddRun(t *testing.T) { }, fromAddress) require.Len(t, bfs.fulfillments, 2) } + +func Test_BatchFulfillments_AddRun_V2Plus(t *testing.T) { + batchLimit := uint32(2500) + bfs := newBatchFulfillments(batchLimit, vrfcommon.V2Plus) + fromAddress := testutils.NewAddress() + for i := 0; i < 4; i++ { + bfs.addRun(vrfPipelineResult{ + gasLimit: 500, + req: pendingRequest{ + req: NewV2PlusRandomWordsRequested(&vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsRequested{ + RequestId: big.NewInt(1), + Raw: types.Log{ + TxHash: common.HexToHash("0xd8d7ecc4800d25fa53ce0372f13a416d98907a7ef3d8d3bdd79cf4fe75529c65"), + }, + }), + lb: mocks.NewBroadcast(t), + }, + run: pipeline.NewRun(pipeline.Spec{}, pipeline.Vars{}), + }, fromAddress) + require.Len(t, bfs.fulfillments, 1) + } + + require.Equal(t, uint32(2000), bfs.fulfillments[0].totalGasLimit) + + // This addition should create and add a new batch + bfs.addRun(vrfPipelineResult{ + gasLimit: 500, + req: pendingRequest{ + req: NewV2PlusRandomWordsRequested(&vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsRequested{ + RequestId: big.NewInt(1), + Raw: types.Log{ + TxHash: common.HexToHash("0xd8d7ecc4800d25fa53ce0372f13a416d98907a7ef3d8d3bdd79cf4fe75529c65"), + }, + }), + lb: mocks.NewBroadcast(t), + }, + run: pipeline.NewRun(pipeline.Spec{}, pipeline.Vars{}), + }, fromAddress) + require.Len(t, bfs.fulfillments, 2) +} diff --git a/core/services/vrf/vrftesthelpers/consumer_v2.go b/core/services/vrf/vrftesthelpers/consumer_v2.go index 5d647ec3abb..ec3d727f7ab 100644 --- a/core/services/vrf/vrftesthelpers/consumer_v2.go +++ b/core/services/vrf/vrftesthelpers/consumer_v2.go @@ -25,13 +25,16 @@ var ( // the example contracts used for the integration tests. type VRFConsumerContract interface { CreateSubscriptionAndFund(opts *bind.TransactOpts, fundingJuels *big.Int) (*gethtypes.Transaction, error) + CreateSubscriptionAndFundNative(opts *bind.TransactOpts, fundingAmount *big.Int) (*gethtypes.Transaction, error) SSubId(opts *bind.CallOpts) (*big.Int, error) SRequestId(opts *bind.CallOpts) (*big.Int, error) RequestRandomness(opts *bind.TransactOpts, keyHash [32]byte, subID *big.Int, minReqConfs uint16, callbackGasLimit uint32, numWords uint32, payInEth bool) (*gethtypes.Transaction, error) SRandomWords(opts *bind.CallOpts, randomwordIdx *big.Int) (*big.Int, error) TopUpSubscription(opts *bind.TransactOpts, amount *big.Int) (*gethtypes.Transaction, error) + TopUpSubscriptionNative(opts *bind.TransactOpts, amount *big.Int) (*gethtypes.Transaction, error) SGasAvailable(opts *bind.CallOpts) (*big.Int, error) UpdateSubscription(opts *bind.TransactOpts, consumers []common.Address) (*gethtypes.Transaction, error) + SetSubID(opts *bind.TransactOpts, subID *big.Int) (*gethtypes.Transaction, error) } type ConsumerType string @@ -298,3 +301,30 @@ func (c *vrfConsumerContract) UpdateSubscription(opts *bind.TransactOpts, consum } return nil, errors.New("UpdateSubscription is not supported") } + +func (c *vrfConsumerContract) SetSubID(opts *bind.TransactOpts, subID *big.Int) (*gethtypes.Transaction, error) { + if c.consumerType == VRFV2PlusConsumer { + return c.vrfV2PlusConsumer.SetSubId(opts, subID) + } + return nil, errors.New("SetSubID is not supported") +} + +func (c *vrfConsumerContract) CreateSubscriptionAndFundNative(opts *bind.TransactOpts, fundingAmount *big.Int) (*gethtypes.Transaction, error) { + if c.consumerType == VRFV2PlusConsumer { + // copy object to not mutate original opts + o := *opts + o.Value = fundingAmount + return c.vrfV2PlusConsumer.CreateSubscriptionAndFundNative(&o) + } + return nil, errors.New("CreateSubscriptionAndFundNative is not supported") +} + +func (c *vrfConsumerContract) TopUpSubscriptionNative(opts *bind.TransactOpts, amount *big.Int) (*gethtypes.Transaction, error) { + if c.consumerType == VRFV2PlusConsumer { + // copy object to not mutate original opts + o := *opts + o.Value = amount + return c.vrfV2PlusConsumer.TopUpSubscriptionNative(&o) + } + return nil, errors.New("TopUpSubscriptionNative is not supported") +} diff --git a/core/services/vrf/vrftesthelpers/helpers.go b/core/services/vrf/vrftesthelpers/helpers.go index 883fdd7403c..d40e2bc747f 100644 --- a/core/services/vrf/vrftesthelpers/helpers.go +++ b/core/services/vrf/vrftesthelpers/helpers.go @@ -50,21 +50,24 @@ func CreateAndStartBHSJob( fromAddresses []string, app *cltest.TestApplication, bhsAddress, coordinatorV1Address, coordinatorV2Address, coordinatorV2PlusAddress string, + trustedBlockhashStoreAddress string, trustedBlockhashStoreBatchSize int32, lookback int, ) job.Job { jid := uuid.New() s := testspecs.GenerateBlockhashStoreSpec(testspecs.BlockhashStoreSpecParams{ - JobID: jid.String(), - Name: "blockhash-store", - CoordinatorV1Address: coordinatorV1Address, - CoordinatorV2Address: coordinatorV2Address, - CoordinatorV2PlusAddress: coordinatorV2PlusAddress, - WaitBlocks: 100, - LookbackBlocks: 200, - BlockhashStoreAddress: bhsAddress, - PollPeriod: time.Second, - RunTimeout: 100 * time.Millisecond, - EVMChainID: 1337, - FromAddresses: fromAddresses, + JobID: jid.String(), + Name: "blockhash-store", + CoordinatorV1Address: coordinatorV1Address, + CoordinatorV2Address: coordinatorV2Address, + CoordinatorV2PlusAddress: coordinatorV2PlusAddress, + WaitBlocks: 100, + LookbackBlocks: lookback, + BlockhashStoreAddress: bhsAddress, + TrustedBlockhashStoreAddress: trustedBlockhashStoreAddress, + TrustedBlockhashStoreBatchSize: trustedBlockhashStoreBatchSize, + PollPeriod: time.Second, + RunTimeout: 100 * time.Millisecond, + EVMChainID: 1337, + FromAddresses: fromAddresses, }) jb, err := blockhashstore.ValidatedSpec(s.Toml()) require.NoError(t, err) diff --git a/core/services/webhook/delegate.go b/core/services/webhook/delegate.go index 67b535a59d3..e373ff8087a 100644 --- a/core/services/webhook/delegate.go +++ b/core/services/webhook/delegate.go @@ -69,7 +69,7 @@ func (d *Delegate) BeforeJobDeleted(spec job.Job) { func (d *Delegate) OnDeleteJob(jb job.Job, q pg.Queryer) error { return nil } // ServicesForSpec satisfies the job.Delegate interface. -func (d *Delegate) ServicesForSpec(spec job.Job) ([]job.ServiceCtx, error) { +func (d *Delegate) ServicesForSpec(spec job.Job, qopts ...pg.QOpt) ([]job.ServiceCtx, error) { service := &pseudoService{ spec: spec, webhookJobRunner: d.webhookJobRunner, diff --git a/core/store/migrate/migrate.go b/core/store/migrate/migrate.go index e94cfbf8fba..97714b68bef 100644 --- a/core/store/migrate/migrate.go +++ b/core/store/migrate/migrate.go @@ -19,7 +19,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/store/migrate/migrations" // Invoke init() functions within migrations pkg. ) -//go:embed migrations/*.sql +//go:embed migrations/*.sql migrations/*.go var embedMigrations embed.FS const MIGRATIONS_DIR string = "migrations" diff --git a/core/store/migrate/migrations/0036_external_job_id.go b/core/store/migrate/migrations/0036_external_job_id.go index 47c0fa51b49..82f26206d88 100644 --- a/core/store/migrate/migrations/0036_external_job_id.go +++ b/core/store/migrate/migrations/0036_external_job_id.go @@ -1,6 +1,7 @@ package migrations import ( + "context" "database/sql" "fmt" @@ -10,7 +11,7 @@ import ( ) func init() { - goose.AddMigration(Up36, Down36) + goose.AddMigrationContext(Up36, Down36) } const ( @@ -35,9 +36,9 @@ const ( ) // nolint -func Up36(tx *sql.Tx) error { +func Up36(ctx context.Context, tx *sql.Tx) error { // Add the external ID column and remove type specific ones. - if _, err := tx.Exec(up36_1); err != nil { + if _, err := tx.ExecContext(ctx, up36_1); err != nil { return err } @@ -45,7 +46,7 @@ func Up36(tx *sql.Tx) error { // We do this to avoid using the uuid postgres extension. var jobIDs []int32 txx := sqlx.NewTx(tx, "postgres") - if err := txx.Select(&jobIDs, "SELECT id FROM jobs"); err != nil { + if err := txx.SelectContext(ctx, &jobIDs, "SELECT id FROM jobs"); err != nil { return err } if len(jobIDs) != 0 { @@ -58,22 +59,22 @@ func Up36(tx *sql.Tx) error { } } stmt += ` AS vals(external_job_id, id) WHERE vals.id = j.id` - if _, err := tx.Exec(stmt); err != nil { + if _, err := tx.ExecContext(ctx, stmt); err != nil { return err } } // Add constraints on the external_job_id. - if _, err := tx.Exec(up36_2); err != nil { + if _, err := tx.ExecContext(ctx, up36_2); err != nil { return err } return nil } // nolint -func Down36(tx *sql.Tx) error { - if _, err := tx.Exec(down36); err != nil { +func Down36(ctx context.Context, tx *sql.Tx) error { + if _, err := tx.ExecContext(ctx, down36); err != nil { return err } return nil diff --git a/core/store/migrate/migrations/0054_remove_legacy_pipeline.go b/core/store/migrate/migrations/0054_remove_legacy_pipeline.go index 3db2f19c6c6..924d32308b8 100644 --- a/core/store/migrate/migrations/0054_remove_legacy_pipeline.go +++ b/core/store/migrate/migrations/0054_remove_legacy_pipeline.go @@ -1,6 +1,7 @@ package migrations import ( + "context" "database/sql" "github.com/pkg/errors" @@ -28,26 +29,26 @@ ALTER TABLE job_spec_errors_v2 RENAME TO job_spec_errors; ` func init() { - goose.AddMigration(Up54, Down54) + goose.AddMigrationContext(Up54, Down54) } // nolint -func Up54(tx *sql.Tx) error { +func Up54(ctx context.Context, tx *sql.Tx) error { if err := CheckNoLegacyJobs(tx); err != nil { return err } - if _, err := tx.Exec(up54); err != nil { + if _, err := tx.ExecContext(ctx, up54); err != nil { return err } return nil } // nolint -func Down54(tx *sql.Tx) error { +func Down54(ctx context.Context, tx *sql.Tx) error { return errors.New("irreversible migration") } -// CheckNoLegacyJobs ensures that there are are no legacy job specs +// CheckNoLegacyJobs ensures that there are no legacy job specs func CheckNoLegacyJobs(tx *sql.Tx) error { var count int if err := tx.QueryRow(`SELECT COUNT(*) FROM job_specs WHERE deleted_at IS NULL`).Scan(&count); err != nil { diff --git a/core/store/migrate/migrations/0056_multichain.go b/core/store/migrate/migrations/0056_multichain.go index 419dacc9f52..128e7be5407 100644 --- a/core/store/migrate/migrations/0056_multichain.go +++ b/core/store/migrate/migrations/0056_multichain.go @@ -1,6 +1,7 @@ package migrations import ( + "context" "database/sql" "fmt" "log" @@ -12,7 +13,7 @@ import ( ) func init() { - goose.AddMigration(Up56, Down56) + goose.AddMigrationContext(Up56, Down56) } const up56 = ` @@ -48,8 +49,8 @@ DROP TABLE evm_chains; ` // nolint -func Up56(tx *sql.Tx) error { - if _, err := tx.Exec(up56); err != nil { +func Up56(ctx context.Context, tx *sql.Tx) error { + if _, err := tx.ExecContext(ctx, up56); err != nil { return err } evmDisabled := os.Getenv("EVM_ENABLED") == "false" @@ -67,7 +68,7 @@ func Up56(tx *sql.Tx) error { if !ok { panic(fmt.Sprintf("ETH_CHAIN_ID was invalid, expected a number, got: %s", chainIDStr)) } - _, err := tx.Exec("INSERT INTO evm_chains (id, created_at, updated_at) VALUES ($1, NOW(), NOW());", chainID.String()) + _, err := tx.ExecContext(ctx, "INSERT INTO evm_chains (id, created_at, updated_at) VALUES ($1, NOW(), NOW());", chainID.String()) return err } } @@ -75,8 +76,8 @@ func Up56(tx *sql.Tx) error { } // nolint -func Down56(tx *sql.Tx) error { - _, err := tx.Exec(down56) +func Down56(ctx context.Context, tx *sql.Tx) error { + _, err := tx.ExecContext(ctx, down56) if err != nil { return err } diff --git a/core/store/migrate/migrations/0182_nullable_feed_id.sql b/core/store/migrate/migrations/0182_nullable_feed_id.sql index f7d3dbf131e..94b2e201b76 100644 --- a/core/store/migrate/migrations/0182_nullable_feed_id.sql +++ b/core/store/migrate/migrations/0182_nullable_feed_id.sql @@ -1,6 +1,6 @@ -- +goose Up ALTER TABLE ocr2_oracle_specs ALTER COLUMN feed_id DROP NOT NULL, ALTER COLUMN feed_id SET DEFAULT NULL; -UPDATE ocr2_oracle_specs SET feed_id=NULL WHERE feed_id='\x0000000000000000000000000000000000000000000000000000000000000000' +UPDATE ocr2_oracle_specs SET feed_id=NULL WHERE feed_id='\x0000000000000000000000000000000000000000000000000000000000000000'; -- +goose Down UPDATE ocr2_oracle_specs SET feed_id='\x0000000000000000000000000000000000000000000000000000000000000000' WHERE feed_id IS NULL; diff --git a/core/store/migrate/migrations/0186_create_feed_latest_reports.sql b/core/store/migrate/migrations/0186_create_feed_latest_reports.sql new file mode 100644 index 00000000000..9d90562fb94 --- /dev/null +++ b/core/store/migrate/migrations/0186_create_feed_latest_reports.sql @@ -0,0 +1,13 @@ +-- +goose Up + +CREATE TABLE feed_latest_reports ( + feed_id BYTEA PRIMARY KEY CHECK (octet_length(feed_id) = 32), + report BYTEA NOT NULL, + epoch BIGINT NOT NULL, + round INT NOT NULL, + updated_at TIMESTAMPTZ NOT NULL +); + +-- +goose Down + +DROP TABLE feed_latest_reports; diff --git a/core/store/migrate/migrations/0187_trusted_bhs_vrfv2plus.sql b/core/store/migrate/migrations/0187_trusted_bhs_vrfv2plus.sql new file mode 100644 index 00000000000..288e5e00a85 --- /dev/null +++ b/core/store/migrate/migrations/0187_trusted_bhs_vrfv2plus.sql @@ -0,0 +1,10 @@ +-- +goose Up +ALTER TABLE blockhash_store_specs + ADD COLUMN IF NOT EXISTS "trusted_blockhash_store_address" bytea + CHECK (octet_length(trusted_blockhash_store_address) = 20); + +ALTER TABLE blockhash_store_specs + ADD COLUMN IF NOT EXISTS "trusted_blockhash_store_batch_size" integer DEFAULT 0; +-- +goose Down +ALTER TABLE blockhash_store_specs DROP COLUMN "trusted_blockhash_store_address"; +ALTER TABLE blockhash_store_specs DROP COLUMN "trusted_blockhash_store_batch_size"; \ No newline at end of file diff --git a/core/store/migrate/migrations/0188_nullable_feed_id_fix.sql b/core/store/migrate/migrations/0188_nullable_feed_id_fix.sql new file mode 100644 index 00000000000..572f8da6279 --- /dev/null +++ b/core/store/migrate/migrations/0188_nullable_feed_id_fix.sql @@ -0,0 +1,9 @@ +-- +goose Up +UPDATE ocr2_oracle_specs +SET feed_id=NULL +WHERE feed_id = '\x0000000000000000000000000000000000000000000000000000000000000000'; + +-- +goose Down +UPDATE ocr2_oracle_specs +SET feed_id='\x0000000000000000000000000000000000000000000000000000000000000000' +WHERE feed_id IS NULL; diff --git a/core/store/models/cosmos/common.go b/core/store/models/cosmos/common.go index 8143b899cf0..1bf896eb8c2 100644 --- a/core/store/models/cosmos/common.go +++ b/core/store/models/cosmos/common.go @@ -8,5 +8,6 @@ type SendRequest struct { FromAddress sdk.AccAddress `json:"from"` Amount sdk.Dec `json:"amount"` CosmosChainID string `json:"cosmosChainID"` + Token string `json:"token"` AllowHigherAmounts bool `json:"allowHigherAmounts"` } diff --git a/core/testdata/cosmos/my_first_contract.wasm b/core/testdata/cosmos/my_first_contract.wasm index 60742583752..e89b47b3938 100644 Binary files a/core/testdata/cosmos/my_first_contract.wasm and b/core/testdata/cosmos/my_first_contract.wasm differ diff --git a/core/testdata/testspecs/v2_specs.go b/core/testdata/testspecs/v2_specs.go index 923afa5a740..4c44f3b9c5e 100644 --- a/core/testdata/testspecs/v2_specs.go +++ b/core/testdata/testspecs/v2_specs.go @@ -11,6 +11,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/assets" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon" "github.com/smartcontractkit/chainlink/v2/core/services/webhook" + "github.com/smartcontractkit/chainlink/v2/core/utils" ) var ( @@ -585,18 +586,20 @@ ds -> ds_parse -> ds_multiply; // BlockhashStoreSpecParams defines params for building a blockhash store job spec. type BlockhashStoreSpecParams struct { - JobID string - Name string - CoordinatorV1Address string - CoordinatorV2Address string - CoordinatorV2PlusAddress string - WaitBlocks int - LookbackBlocks int - BlockhashStoreAddress string - PollPeriod time.Duration - RunTimeout time.Duration - EVMChainID int64 - FromAddresses []string + JobID string + Name string + CoordinatorV1Address string + CoordinatorV2Address string + CoordinatorV2PlusAddress string + WaitBlocks int + LookbackBlocks int + BlockhashStoreAddress string + TrustedBlockhashStoreAddress string + TrustedBlockhashStoreBatchSize int32 + PollPeriod time.Duration + RunTimeout time.Duration + EVMChainID int64 + FromAddresses []string } // BlockhashStoreSpec defines a blockhash store job spec. @@ -632,6 +635,14 @@ func GenerateBlockhashStoreSpec(params BlockhashStoreSpecParams) BlockhashStoreS params.CoordinatorV2PlusAddress = "0x92B5e28Ac583812874e4271380c7d070C5FB6E6b" } + if params.TrustedBlockhashStoreAddress == "" { + params.TrustedBlockhashStoreAddress = utils.ZeroAddress.Hex() + } + + if params.TrustedBlockhashStoreBatchSize == 0 { + params.TrustedBlockhashStoreBatchSize = 20 + } + if params.WaitBlocks == 0 { params.WaitBlocks = 100 } @@ -673,6 +684,8 @@ coordinatorV2PlusAddress = "%s" waitBlocks = %d lookbackBlocks = %d blockhashStoreAddress = "%s" +trustedBlockhashStoreAddress = "%s" +trustedBlockhashStoreBatchSize = %d pollPeriod = "%s" runTimeout = "%s" evmChainID = "%d" @@ -680,7 +693,7 @@ fromAddresses = %s ` toml := fmt.Sprintf(template, params.Name, params.CoordinatorV1Address, params.CoordinatorV2Address, params.CoordinatorV2PlusAddress, params.WaitBlocks, params.LookbackBlocks, - params.BlockhashStoreAddress, params.PollPeriod.String(), params.RunTimeout.String(), + params.BlockhashStoreAddress, params.TrustedBlockhashStoreAddress, params.TrustedBlockhashStoreBatchSize, params.PollPeriod.String(), params.RunTimeout.String(), params.EVMChainID, formattedFromAddresses) return BlockhashStoreSpec{BlockhashStoreSpecParams: params, toml: toml} diff --git a/core/utils/eth_signatures.go b/core/utils/eth_signatures.go new file mode 100644 index 00000000000..688d67108a6 --- /dev/null +++ b/core/utils/eth_signatures.go @@ -0,0 +1,47 @@ +package utils + +import ( + "crypto/ecdsa" + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/pkg/errors" +) + +const EthSignedMessagePrefix = "\x19Ethereum Signed Message:\n" + +func GetSignersEthAddress(msg []byte, sig []byte) (recoveredAddr common.Address, err error) { + if len(sig) != 65 { + return recoveredAddr, errors.New("invalid signature: signature length must be 65 bytes") + } + + // Adjust the V component of the signature in case it uses 27 or 28 instead of 0 or 1 + if sig[64] == 27 || sig[64] == 28 { + sig[64] -= 27 + } + if sig[64] != 0 && sig[64] != 1 { + return recoveredAddr, errors.New("invalid signature: invalid V component") + } + + prefixedMsg := fmt.Sprintf("%s%d%s", EthSignedMessagePrefix, len(msg), msg) + hash := crypto.Keccak256Hash([]byte(prefixedMsg)) + + sigPublicKey, err := crypto.SigToPub(hash[:], sig) + if err != nil { + return recoveredAddr, err + } + + recoveredAddr = crypto.PubkeyToAddress(*sigPublicKey) + return recoveredAddr, nil +} + +func GenerateEthPrefixedMsgHash(msg []byte) (hash common.Hash) { + prefixedMsg := fmt.Sprintf("%s%d%s", EthSignedMessagePrefix, len(msg), msg) + return crypto.Keccak256Hash([]byte(prefixedMsg)) +} + +func GenerateEthSignature(privateKey *ecdsa.PrivateKey, msg []byte) (signature []byte, err error) { + hash := GenerateEthPrefixedMsgHash(msg) + return crypto.Sign(hash[:], privateKey) +} diff --git a/core/utils/eth_signatures_test.go b/core/utils/eth_signatures_test.go new file mode 100644 index 00000000000..85b94500d68 --- /dev/null +++ b/core/utils/eth_signatures_test.go @@ -0,0 +1,53 @@ +package utils + +import ( + "testing" + + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGetSignersEthAddress_Success(t *testing.T) { + privateKey, err := crypto.GenerateKey() + require.NoError(t, err) + address := crypto.PubkeyToAddress(privateKey.PublicKey) + + msg := []byte("test message") + sig, err := GenerateEthSignature(privateKey, msg) + assert.NoError(t, err) + + recoveredAddress, err := GetSignersEthAddress(msg, sig) + assert.NoError(t, err) + assert.Equal(t, address, recoveredAddress) +} + +func TestGetSignersEthAddress_InvalidSignatureLength(t *testing.T) { + msg := []byte("test message") + sig := []byte("invalid signature length") + _, err := GetSignersEthAddress(msg, sig) + assert.EqualError(t, err, "invalid signature: signature length must be 65 bytes") +} + +func TestGenerateEthPrefixedMsgHash(t *testing.T) { + msg := []byte("test message") + expectedPrefix := "\x19Ethereum Signed Message:\n" + expectedHash := crypto.Keccak256Hash([]byte(expectedPrefix + "12" + string(msg))) + + hash := GenerateEthPrefixedMsgHash(msg) + assert.Equal(t, expectedHash, hash) +} + +func TestGenerateEthSignature(t *testing.T) { + privateKey, err := crypto.GenerateKey() + assert.NoError(t, err) + + msg := []byte("test message") + signature, err := GenerateEthSignature(privateKey, msg) + assert.NoError(t, err) + assert.Len(t, signature, 65) + + recoveredPub, err := crypto.SigToPub(GenerateEthPrefixedMsgHash(msg).Bytes(), signature) + assert.NoError(t, err) + assert.Equal(t, privateKey.PublicKey, *recoveredPub) +} diff --git a/core/utils/hash.go b/core/utils/hash.go new file mode 100644 index 00000000000..bcae823770e --- /dev/null +++ b/core/utils/hash.go @@ -0,0 +1,40 @@ +package utils + +import ( + "encoding/hex" + "fmt" + "strings" + + "github.com/pkg/errors" +) + +// Hash is a simplified version of go-ethereum's common.Hash to avoid +// go-ethereum dependency +// It represents a 32 byte fixed size array that marshals/unmarshals assuming a +// 0x prefix +type Hash [32]byte + +// Hex converts a hash to a hex string. +func (h Hash) Hex() string { return fmt.Sprintf("0x%s", hex.EncodeToString(h[:])) } + +// String implements the stringer interface and is used also by the logger when +// doing full logging into a file. +func (h Hash) String() string { + return h.Hex() +} + +// UnmarshalText parses a hash in hex syntax. +func (h *Hash) UnmarshalText(input []byte) error { + if !strings.HasPrefix(string(input), "0x") { + return errors.New("hash: expected a hex string starting with '0x'") + } + phex := new(PlainHexBytes) + if err := phex.UnmarshalText(input[2:]); err != nil { + return fmt.Errorf("hash: %w", err) + } + if len(*phex) != 32 { + return fmt.Errorf("hash: expected 32-byte sequence, got %d bytes", len(*phex)) + } + copy((*h)[:], (*phex)) + return nil +} diff --git a/core/utils/hash_test.go b/core/utils/hash_test.go new file mode 100644 index 00000000000..07ab11f96d1 --- /dev/null +++ b/core/utils/hash_test.go @@ -0,0 +1,65 @@ +package utils + +import ( + "encoding/json" + "strings" + "testing" +) + +func Test_Hash_UnmarshalText(t *testing.T) { + var tests = []struct { + Prefix string + Size int + Error string + }{ + {"", 62, "hash: expected a hex string starting with '0x'"}, + {"0x", 66, "hash: expected 32-byte sequence, got 33 bytes"}, + {"0x", 63, "hash: UnmarshalText failed: odd length"}, + {"0x", 0, "hash: expected 32-byte sequence, got 0 bytes"}, + {"0x", 64, ""}, + {"0X", 64, "hash: expected a hex string starting with '0x'"}, + } + for _, test := range tests { + input := test.Prefix + strings.Repeat("0", test.Size) + v := new(Hash) + err := v.UnmarshalText([]byte(input)) + if err == nil { + if test.Error != "" { + t.Errorf("%s: error mismatch: have nil, want %q", input, test.Error) + } + } else { + if err.Error() != test.Error { + t.Errorf("%s: error mismatch: have %q, want %q", input, err, test.Error) + } + } + } +} + +func Test_Hash_UnmarshalJSON(t *testing.T) { + var tests = []struct { + Prefix string + Size int + Error string + }{ + {"", 62, "hash: expected a hex string starting with '0x'"}, + {"0x", 66, "hash: expected 32-byte sequence, got 33 bytes"}, + {"0x", 63, "hash: UnmarshalText failed: odd length"}, + {"0x", 0, "hash: expected 32-byte sequence, got 0 bytes"}, + {"0x", 64, ""}, + {"0X", 64, "hash: expected a hex string starting with '0x'"}, + } + for _, test := range tests { + input := `"` + test.Prefix + strings.Repeat("0", test.Size) + `"` + var v Hash + err := json.Unmarshal([]byte(input), &v) + if err == nil { + if test.Error != "" { + t.Errorf("%s: error mismatch: have nil, want %q", input, test.Error) + } + } else { + if err.Error() != test.Error { + t.Errorf("%s: error mismatch: have %q, want %q", input, err, test.Error) + } + } + } +} diff --git a/core/web/chains_controller.go b/core/web/chains_controller.go index ffeafbf3f8d..c11d457c49c 100644 --- a/core/web/chains_controller.go +++ b/core/web/chains_controller.go @@ -9,9 +9,10 @@ import ( "github.com/smartcontractkit/chainlink-relay/pkg/types" - "github.com/smartcontractkit/chainlink/v2/core/chains" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/logger/audit" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) type ChainsController interface { @@ -22,8 +23,9 @@ type ChainsController interface { } type chainsController[R jsonapi.EntityNamer] struct { + network relay.Network resourceName string - chainSet chains.Chains + chainStats chainlink.ChainStatuser errNotEnabled error newResource func(types.ChainStatus) R lggr logger.Logger @@ -39,11 +41,12 @@ func (e errChainDisabled) Error() string { return fmt.Sprintf("%s is disabled: Set %s=true to enable", e.name, e.tomlKey) } -func newChainsController[R jsonapi.EntityNamer](prefix string, chainSet chains.Chains, errNotEnabled error, +func newChainsController[R jsonapi.EntityNamer](network relay.Network, chainStats chainlink.ChainsNodesStatuser, errNotEnabled error, newResource func(types.ChainStatus) R, lggr logger.Logger, auditLogger audit.AuditLogger) *chainsController[R] { return &chainsController[R]{ - resourceName: prefix + "_chain", - chainSet: chainSet, + network: network, + resourceName: string(network) + "_chain", + chainStats: chainStats, errNotEnabled: errNotEnabled, newResource: newResource, lggr: lggr, @@ -52,11 +55,11 @@ func newChainsController[R jsonapi.EntityNamer](prefix string, chainSet chains.C } func (cc *chainsController[R]) Index(c *gin.Context, size, page, offset int) { - if cc.chainSet == nil { + if cc.chainStats == nil { jsonAPIError(c, http.StatusBadRequest, cc.errNotEnabled) return } - chains, count, err := cc.chainSet.ChainStatuses(c, offset, size) + chains, count, err := cc.chainStats.ChainStatuses(c, offset, size) if err != nil { jsonAPIError(c, http.StatusBadRequest, err) @@ -72,11 +75,12 @@ func (cc *chainsController[R]) Index(c *gin.Context, size, page, offset int) { } func (cc *chainsController[R]) Show(c *gin.Context) { - if cc.chainSet == nil { + if cc.chainStats == nil { jsonAPIError(c, http.StatusBadRequest, cc.errNotEnabled) return } - chain, err := cc.chainSet.ChainStatus(c, c.Param("ID")) + relayID := relay.ID{Network: cc.network, ChainID: relay.ChainID(c.Param("ID"))} + chain, err := cc.chainStats.ChainStatus(c, relayID) if err != nil { jsonAPIError(c, http.StatusBadRequest, err) return diff --git a/core/web/common.go b/core/web/common.go index 4204709b2f7..1afc1636ba5 100644 --- a/core/web/common.go +++ b/core/web/common.go @@ -14,23 +14,25 @@ var ( ErrMultipleChains = errors.New("more than one chain available, you must specify evmChainID parameter") ) -func getChain(cs evm.ChainSet, chainIDstr string) (chain evm.Chain, err error) { +func getChain(legacyChains evm.LegacyChainContainer, chainIDstr string) (chain evm.Chain, err error) { + if legacyChains.Len() > 1 { + return nil, ErrMultipleChains + } + if chainIDstr != "" && chainIDstr != "" { - chainID, ok := big.NewInt(0).SetString(chainIDstr, 10) + // evm keys are expected to be parsable as a big int + _, ok := big.NewInt(0).SetString(chainIDstr, 10) if !ok { return nil, ErrInvalidChainID } - chain, err = cs.Get(chainID) + chain, err = legacyChains.Get(chainIDstr) if err != nil { return nil, ErrMissingChainID } return chain, nil } - if cs.ChainCount() > 1 { - return nil, ErrMultipleChains - } - chain, err = cs.Default() + chain, err = legacyChains.Default() if err != nil { return nil, err } diff --git a/core/web/cosmos_chains_controller.go b/core/web/cosmos_chains_controller.go index 251ebb4b954..20a0738c5eb 100644 --- a/core/web/cosmos_chains_controller.go +++ b/core/web/cosmos_chains_controller.go @@ -2,10 +2,16 @@ package web import ( "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) func NewCosmosChainsController(app chainlink.Application) ChainsController { return newChainsController[presenters.CosmosChainResource]( - "cosmos", app.GetChains().Cosmos, ErrCosmosNotEnabled, presenters.NewCosmosChainResource, app.GetLogger(), app.GetAuditLogger()) + relay.Cosmos, + app.GetRelayers().List(chainlink.FilterRelayersByType(relay.Cosmos)), + ErrCosmosNotEnabled, + presenters.NewCosmosChainResource, + app.GetLogger(), + app.GetAuditLogger()) } diff --git a/core/web/cosmos_chains_controller_test.go b/core/web/cosmos_chains_controller_test.go index d8389cbb21e..f670076d748 100644 --- a/core/web/cosmos_chains_controller_test.go +++ b/core/web/cosmos_chains_controller_test.go @@ -43,11 +43,12 @@ func Test_CosmosChainsController_Show(t *testing.T) { Enabled: true, Config: `ChainID = 'Chainlink-12' Enabled = true +Bech32Prefix = 'wasm' BlockRate = '6s' BlocksUntilTxTimeout = 30 ConfirmPollPeriod = '1s' FallbackGasPrice = '9.999' -FCDURL = '' +FeeToken = 'ucosm' GasLimitMultiplier = '1.55555' MaxMsgsPerBatch = 100 OCR2CachePollPeriod = '4s' @@ -106,14 +107,15 @@ func Test_CosmosChainsController_Index(t *testing.T) { t.Parallel() chainA := &cosmos.CosmosConfig{ - ChainID: ptr(cosmostest.RandomChainID()), + ChainID: ptr("a" + cosmostest.RandomChainID()), Enabled: ptr(true), Chain: coscfg.Chain{ FallbackGasPrice: ptr(decimal.RequireFromString("9.999")), }, } + chainB := &cosmos.CosmosConfig{ - ChainID: ptr(cosmostest.RandomChainID()), + ChainID: ptr("b" + cosmostest.RandomChainID()), Enabled: ptr(true), Chain: coscfg.Chain{ GasLimitMultiplier: ptr(decimal.RequireFromString("1.55555")), @@ -164,6 +166,7 @@ func Test_CosmosChainsController_Index(t *testing.T) { tomlB, err := chainB.TOMLString() require.NoError(t, err) assert.Equal(t, tomlB, chains[0].Config) + } type TestCosmosChainsController struct { diff --git a/core/web/cosmos_nodes_controller.go b/core/web/cosmos_nodes_controller.go index 2a1a65cafe2..756d1ded741 100644 --- a/core/web/cosmos_nodes_controller.go +++ b/core/web/cosmos_nodes_controller.go @@ -2,6 +2,7 @@ package web import ( "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) @@ -10,6 +11,6 @@ var ErrCosmosNotEnabled = errChainDisabled{name: "Cosmos", tomlKey: "Cosmos.Enab func NewCosmosNodesController(app chainlink.Application) NodesController { return newNodesController[presenters.CosmosNodeResource]( - app.GetChains().Cosmos, ErrCosmosNotEnabled, presenters.NewCosmosNodeResource, app.GetAuditLogger(), + app.GetRelayers().List(chainlink.FilterRelayersByType(relay.Cosmos)), ErrCosmosNotEnabled, presenters.NewCosmosNodeResource, app.GetAuditLogger(), ) } diff --git a/core/web/cosmos_transfer_controller.go b/core/web/cosmos_transfer_controller.go index 63769b36326..2409a05e6a4 100644 --- a/core/web/cosmos_transfer_controller.go +++ b/core/web/cosmos_transfer_controller.go @@ -26,9 +26,9 @@ type CosmosTransfersController struct { App chainlink.Application } -// Create sends Atom and other native coins from the Chainlink's account to a specified address. +// Create sends native coins from the Chainlink's account to a specified address. func (tc *CosmosTransfersController) Create(c *gin.Context) { - cosmosChains := tc.App.GetChains().Cosmos + cosmosChains := tc.App.GetRelayers().LegacyCosmosChains() if cosmosChains == nil { jsonAPIError(c, http.StatusBadRequest, ErrCosmosNotEnabled) return @@ -43,7 +43,9 @@ func (tc *CosmosTransfersController) Create(c *gin.Context) { jsonAPIError(c, http.StatusBadRequest, errors.New("missing cosmosChainID")) return } - chain, err := cosmosChains.Chain(c.Request.Context(), tr.CosmosChainID) + // TODO what about ctx in Get? ctx was used here but not in ETH calls. maybe better to make the interface require ctx and + // put in TODOs in ETH... + chain, err := cosmosChains.Get(tr.CosmosChainID) //cosmosChains.Chain(c.Request.Context(), tr.CosmosChainID) if errors.Is(err, cosmos.ErrChainIDInvalid) || errors.Is(err, cosmos.ErrChainIDEmpty) { jsonAPIError(c, http.StatusBadRequest, err) return @@ -56,10 +58,9 @@ func (tc *CosmosTransfersController) Create(c *gin.Context) { jsonAPIError(c, http.StatusUnprocessableEntity, errors.Errorf("withdrawal source address is missing: %v", tr.FromAddress)) return } - - coin, err := denom.ConvertDecCoinToDenom(sdk.NewDecCoinFromDec("atom", tr.Amount), "uatom") + coin, err := denom.ConvertDecCoinToDenom(sdk.NewDecCoinFromDec(tr.Token, tr.Amount), chain.Config().FeeToken()) if err != nil { - jsonAPIError(c, http.StatusBadRequest, errors.Errorf("unable to convert to uatom: %v", err)) + jsonAPIError(c, http.StatusBadRequest, errors.Errorf("unable to convert %s to %s: %v", tr.Token, chain.Config().FeeToken(), err)) return } else if !coin.Amount.IsPositive() { jsonAPIError(c, http.StatusBadRequest, errors.Errorf("amount must be greater than zero: %s", coin.Amount)) @@ -116,17 +117,8 @@ func (tc *CosmosTransfersController) Create(c *gin.Context) { } // cosmosValidateBalance validates that fromAddr's balance can cover coin, including fees at gasPrice. -// Note: This is currently limited to uatom only, for both gasPrice and coin. func cosmosValidateBalance(reader client.Reader, gasPrice sdk.DecCoin, fromAddr sdk.AccAddress, coin sdk.Coin) error { - const denom = "uatom" - if gasPrice.Denom != denom { - return errors.Errorf("unsupported gas price denom: %s", gasPrice.Denom) - } - if coin.Denom != denom { - return errors.Errorf("unsupported coin denom: %s", gasPrice.Denom) - } - - balance, err := reader.Balance(fromAddr, denom) + balance, err := reader.Balance(fromAddr, coin.GetDenom()) if err != nil { return err } diff --git a/core/web/eth_keys_controller.go b/core/web/eth_keys_controller.go index f37254c6ba2..f708f8634ec 100644 --- a/core/web/eth_keys_controller.go +++ b/core/web/eth_keys_controller.go @@ -17,6 +17,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/utils" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" @@ -124,7 +125,7 @@ func (ekc *ETHKeysController) Create(c *gin.Context) { ethKeyStore := ekc.app.GetKeyStore().Eth() cid := c.Query("evmChainID") - chain, ok := ekc.getChain(c, ekc.app.GetChains().EVM, cid) + chain, ok := ekc.getChain(c, cid) if !ok { return } @@ -210,7 +211,7 @@ func (ekc *ETHKeysController) Import(c *gin.Context) { } oldPassword := c.Query("oldpassword") cid := c.Query("evmChainID") - chain, ok := ekc.getChain(c, ekc.app.GetChains().EVM, cid) + chain, ok := ekc.getChain(c, cid) if !ok { return } @@ -271,7 +272,7 @@ func (ekc *ETHKeysController) Chain(c *gin.Context) { address := common.HexToAddress((keyID)) cid := c.Query("evmChainID") - chain, ok := ekc.getChain(c, ekc.app.GetChains().EVM, cid) + chain, ok := ekc.getChain(c, cid) if !ok { return } @@ -356,9 +357,9 @@ func (ekc *ETHKeysController) setEthBalance(bal *big.Int) presenters.NewETHKeyOp // queries the EthClient for the ETH balance at the address associated with state func (ekc *ETHKeysController) getEthBalance(ctx context.Context, state ethkey.State) *big.Int { chainID := state.EVMChainID.ToInt() - chain, err := ekc.app.GetChains().EVM.Get(chainID) + chain, err := ekc.app.GetRelayers().LegacyEVMChains().Get(chainID.String()) if err != nil { - if !errors.Is(errors.Cause(err), evm.ErrNoChains) { + if !errors.Is(errors.Cause(err), evmrelay.ErrNoChains) { ekc.lggr.Errorw("Failed to get EVM Chain", "chainID", chainID, "address", state.Address, "err", err) } return nil @@ -383,9 +384,9 @@ func (ekc *ETHKeysController) setLinkBalance(bal *assets.Link) presenters.NewETH func (ekc *ETHKeysController) getLinkBalance(ctx context.Context, state ethkey.State) *assets.Link { var bal *assets.Link chainID := state.EVMChainID.ToInt() - chain, err := ekc.app.GetChains().EVM.Get(chainID) + chain, err := ekc.app.GetRelayers().LegacyEVMChains().Get(chainID.String()) if err != nil { - if !errors.Is(errors.Cause(err), evm.ErrNoChains) { + if !errors.Is(errors.Cause(err), evmrelay.ErrNoChains) { ekc.lggr.Errorw("Failed to get EVM Chain", "chainID", chainID, "err", err) } } else { @@ -409,9 +410,9 @@ func (ekc *ETHKeysController) setKeyMaxGasPriceWei(price *assets.Wei) presenters func (ekc *ETHKeysController) getKeyMaxGasPriceWei(state ethkey.State, keyAddress common.Address) *assets.Wei { var price *assets.Wei chainID := state.EVMChainID.ToInt() - chain, err := ekc.app.GetChains().EVM.Get(chainID) + chain, err := ekc.app.GetRelayers().LegacyEVMChains().Get(chainID.String()) if err != nil { - if !errors.Is(errors.Cause(err), evm.ErrNoChains) { + if !errors.Is(errors.Cause(err), evmrelay.ErrNoChains) { ekc.lggr.Errorw("Failed to get EVM Chain", "chainID", chainID, "err", err) } } else { @@ -422,13 +423,10 @@ func (ekc *ETHKeysController) getKeyMaxGasPriceWei(state ethkey.State, keyAddres // getChain is a convenience wrapper to retrieve a chain for a given request // and call the corresponding API response error function for 400, 404 and 500 results -func (ekc *ETHKeysController) getChain(c *gin.Context, cs evm.ChainSet, chainIDstr string) (chain evm.Chain, ok bool) { - chain, err := getChain(ekc.app.GetChains().EVM, chainIDstr) +func (ekc *ETHKeysController) getChain(c *gin.Context, chainIDstr string) (chain evm.Chain, ok bool) { + chain, err := getChain(ekc.app.GetRelayers().LegacyEVMChains(), chainIDstr) if err != nil { - if errors.Is(err, ErrInvalidChainID) { - jsonAPIError(c, http.StatusBadRequest, err) - return nil, false - } else if errors.Is(err, ErrMultipleChains) { + if errors.Is(err, ErrInvalidChainID) || errors.Is(err, ErrMultipleChains) { jsonAPIError(c, http.StatusBadRequest, err) return nil, false } else if errors.Is(err, ErrMissingChainID) { diff --git a/core/web/eth_keys_controller_test.go b/core/web/eth_keys_controller_test.go index aa676cc1731..0ef01257e17 100644 --- a/core/web/eth_keys_controller_test.go +++ b/core/web/eth_keys_controller_test.go @@ -393,7 +393,7 @@ func TestETHKeysController_ChainSuccess_ResetWithAbandon(t *testing.T) { require.NoError(t, app.Start(testutils.Context(t))) - chain := app.GetChains().EVM.Chains()[0] + chain := app.GetRelayers().LegacyEVMChains().Slice()[0] subject := uuid.New() strategy := commontxmmocks.NewTxStrategy(t) strategy.On("Subject").Return(uuid.NullUUID{UUID: subject, Valid: true}) diff --git a/core/web/evm_chains_controller.go b/core/web/evm_chains_controller.go index 9be243f9331..45b4964c215 100644 --- a/core/web/evm_chains_controller.go +++ b/core/web/evm_chains_controller.go @@ -2,6 +2,7 @@ package web import ( "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) @@ -9,5 +10,10 @@ var ErrEVMNotEnabled = errChainDisabled{name: "EVM", tomlKey: "EVM.Enabled"} func NewEVMChainsController(app chainlink.Application) ChainsController { return newChainsController[presenters.EVMChainResource]( - "evm", app.GetChains().EVM, ErrEVMNotEnabled, presenters.NewEVMChainResource, app.GetLogger(), app.GetAuditLogger()) + relay.EVM, + app.GetRelayers().List(chainlink.FilterRelayersByType(relay.EVM)), + ErrEVMNotEnabled, + presenters.NewEVMChainResource, + app.GetLogger(), + app.GetAuditLogger()) } diff --git a/core/web/evm_chains_controller_test.go b/core/web/evm_chains_controller_test.go index 553bdae937b..6c779868d1b 100644 --- a/core/web/evm_chains_controller_test.go +++ b/core/web/evm_chains_controller_test.go @@ -2,7 +2,9 @@ package web_test import ( "fmt" + "math/big" "net/http" + "sort" "testing" "github.com/manyminds/api2go/jsonapi" @@ -101,10 +103,17 @@ func Test_EVMChainsController_Show(t *testing.T) { func Test_EVMChainsController_Index(t *testing.T) { t.Parallel() - newChains := evmcfg.EVMConfigs{ - {ChainID: utils.NewBig(testutils.NewRandomEVMChainID()), Chain: evmcfg.Defaults(nil)}, + // sort test chain ids to make expected comparison easy + chainIDs := []*big.Int{testutils.NewRandomEVMChainID(), testutils.NewRandomEVMChainID(), testutils.NewRandomEVMChainID()} + sort.Slice(chainIDs, func(i, j int) bool { + + return chainIDs[i].String() < chainIDs[j].String() + }) + + configuredChains := evmcfg.EVMConfigs{ + {ChainID: utils.NewBig(chainIDs[0]), Chain: evmcfg.Defaults(nil)}, { - ChainID: utils.NewBig(testutils.NewRandomEVMChainID()), + ChainID: utils.NewBig(chainIDs[1]), Chain: evmcfg.Defaults(nil, &evmcfg.Chain{ RPCBlockQueryDelay: ptr[uint16](13), GasEstimator: evmcfg.GasEstimator{ @@ -117,7 +126,7 @@ func Test_EVMChainsController_Index(t *testing.T) { }), }, { - ChainID: utils.NewBig(testutils.NewRandomEVMChainID()), + ChainID: utils.NewBig(chainIDs[2]), Chain: evmcfg.Defaults(nil, &evmcfg.Chain{ RPCBlockQueryDelay: ptr[uint16](5), GasEstimator: evmcfg.GasEstimator{ @@ -131,8 +140,9 @@ func Test_EVMChainsController_Index(t *testing.T) { }, } + assert.Len(t, configuredChains, 3) controller := setupEVMChainsControllerTest(t, configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM = append(c.EVM, newChains...) + c.EVM = append(c.EVM, configuredChains...) })) badResp, cleanup := controller.client.Get("/v2/chains/evm?size=asd") @@ -147,37 +157,40 @@ func Test_EVMChainsController_Index(t *testing.T) { metaCount, err := cltest.ParseJSONAPIResponseMetaCount(body) require.NoError(t, err) - require.Equal(t, 1+len(newChains), metaCount) + require.Equal(t, 1+len(configuredChains), metaCount) var links jsonapi.Links - var chains []presenters.EVMChainResource - err = web.ParsePaginatedResponse(body, &chains, &links) + var gotChains []presenters.EVMChainResource + err = web.ParsePaginatedResponse(body, &gotChains, &links) assert.NoError(t, err) assert.NotEmpty(t, links["next"].Href) assert.Empty(t, links["prev"].Href) assert.Len(t, links, 1) - assert.Equal(t, newChains[1].ChainID.String(), chains[2].ID) - toml, err := newChains[1].TOMLString() + // the difference in index value here seems to be due to the fact + // that cltest always has a default EVM chain, which is the off-by-one + // in the indices + assert.Equal(t, gotChains[2].ID, configuredChains[1].ChainID.String()) + toml, err := configuredChains[1].TOMLString() require.NoError(t, err) - assert.Equal(t, toml, chains[2].Config) + assert.Equal(t, toml, gotChains[2].Config) resp, cleanup = controller.client.Get(links["next"].Href) t.Cleanup(cleanup) require.Equal(t, http.StatusOK, resp.StatusCode) - chains = []presenters.EVMChainResource{} - err = web.ParsePaginatedResponse(cltest.ParseResponseBody(t, resp), &chains, &links) + gotChains = []presenters.EVMChainResource{} + err = web.ParsePaginatedResponse(cltest.ParseResponseBody(t, resp), &gotChains, &links) assert.NoError(t, err) assert.Empty(t, links["next"].Href) assert.NotEmpty(t, links["prev"].Href) assert.Len(t, links, 1) - assert.Equal(t, newChains[2].ChainID.String(), chains[0].ID) - toml, err = newChains[2].TOMLString() + assert.Equal(t, gotChains[0].ID, configuredChains[2].ChainID.String()) + toml, err = configuredChains[2].TOMLString() require.NoError(t, err) - assert.Equal(t, toml, chains[0].Config) + assert.Equal(t, toml, gotChains[0].Config) } type TestEVMChainsController struct { diff --git a/core/web/evm_forwarders_controller.go b/core/web/evm_forwarders_controller.go index b848c327647..6228723506d 100644 --- a/core/web/evm_forwarders_controller.go +++ b/core/web/evm_forwarders_controller.go @@ -80,7 +80,7 @@ func (cc *EVMForwardersController) Delete(c *gin.Context) { } filterCleanup := func(tx pg.Queryer, evmChainID int64, addr common.Address) error { - chain, err2 := cc.App.GetChains().EVM.Get(big.NewInt(evmChainID)) + chain, err2 := cc.App.GetRelayers().LegacyEVMChains().Get(big.NewInt(evmChainID).String()) if err2 != nil { // If the chain id doesn't even exist, or logpoller is disabled, then there isn't any filter to clean up. Returning an error // here could be dangerous as it would make it impossible to delete a forwarder with an invalid chain id @@ -91,7 +91,7 @@ func (cc *EVMForwardersController) Delete(c *gin.Context) { // handle same as non-existent chain id return nil } - return chain.LogPoller().UnregisterFilter(forwarders.FilterName(addr), tx) + return chain.LogPoller().UnregisterFilter(forwarders.FilterName(addr), pg.WithQueryer(tx)) } orm := forwarders.NewORM(cc.App.GetSqlxDB(), cc.App.GetLogger(), cc.App.GetConfig().Database()) diff --git a/core/web/evm_forwarders_controller_test.go b/core/web/evm_forwarders_controller_test.go index 212105252c4..705fce05c02 100644 --- a/core/web/evm_forwarders_controller_test.go +++ b/core/web/evm_forwarders_controller_test.go @@ -69,7 +69,7 @@ func Test_EVMForwardersController_Track(t *testing.T) { assert.Equal(t, resource.Address, address) - require.Len(t, controller.app.Chains.EVM.Chains(), 1) + require.Len(t, controller.app.GetRelayers().LegacyEVMChains().Slice(), 1) resp, cleanup = controller.client.Delete("/v2/nodes/evm/forwarders/" + resource.ID) t.Cleanup(cleanup) diff --git a/core/web/evm_nodes_controller.go b/core/web/evm_nodes_controller.go index dda551fba5b..aba0faca8e8 100644 --- a/core/web/evm_nodes_controller.go +++ b/core/web/evm_nodes_controller.go @@ -2,10 +2,11 @@ package web import ( "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) func NewEVMNodesController(app chainlink.Application) NodesController { return newNodesController[presenters.EVMNodeResource]( - app.GetChains().EVM, ErrEVMNotEnabled, presenters.NewEVMNodeResource, app.GetAuditLogger()) + app.GetRelayers().List(chainlink.FilterRelayersByType(relay.EVM)), ErrEVMNotEnabled, presenters.NewEVMNodeResource, app.GetAuditLogger()) } diff --git a/core/web/evm_transfer_controller.go b/core/web/evm_transfer_controller.go index e5ceded58d4..a42ab923c90 100644 --- a/core/web/evm_transfer_controller.go +++ b/core/web/evm_transfer_controller.go @@ -33,7 +33,7 @@ func (tc *EVMTransfersController) Create(c *gin.Context) { return } - chain, err := getChain(tc.App.GetChains().EVM, tr.EVMChainID.String()) + chain, err := getChain(tc.App.GetRelayers().LegacyEVMChains(), tr.EVMChainID.String()) switch err { case ErrInvalidChainID, ErrMultipleChains, ErrMissingChainID: jsonAPIError(c, http.StatusUnprocessableEntity, err) diff --git a/core/web/jobs_controller.go b/core/web/jobs_controller.go index e82a3e1ab05..4c8a77d370e 100644 --- a/core/web/jobs_controller.go +++ b/core/web/jobs_controller.go @@ -113,7 +113,7 @@ func (jc *JobsController) Create(c *gin.Context) { defer cancel() err = jc.App.AddJobV2(ctx, &jb) if err != nil { - if errors.Is(errors.Cause(err), job.ErrNoSuchKeyBundle) || errors.As(err, &keystore.KeyNotFoundError{}) || errors.Is(errors.Cause(err), job.ErrNoSuchTransmitterKey) { + if errors.Is(errors.Cause(err), job.ErrNoSuchKeyBundle) || errors.As(err, &keystore.KeyNotFoundError{}) || errors.Is(errors.Cause(err), job.ErrNoSuchTransmitterKey) || errors.Is(errors.Cause(err), job.ErrNoSuchSendingKey) { jsonAPIError(c, http.StatusBadRequest, err) return } @@ -201,7 +201,7 @@ func (jc *JobsController) Update(c *gin.Context) { err = jc.App.AddJobV2(ctx, &jb) if err != nil { - if errors.Is(errors.Cause(err), job.ErrNoSuchKeyBundle) || errors.As(err, &keystore.KeyNotFoundError{}) || errors.Is(errors.Cause(err), job.ErrNoSuchTransmitterKey) { + if errors.Is(errors.Cause(err), job.ErrNoSuchKeyBundle) || errors.As(err, &keystore.KeyNotFoundError{}) || errors.Is(errors.Cause(err), job.ErrNoSuchTransmitterKey) || errors.Is(errors.Cause(err), job.ErrNoSuchSendingKey) { jsonAPIError(c, http.StatusBadRequest, err) return } @@ -221,7 +221,7 @@ func (jc *JobsController) validateJobSpec(tomlString string) (jb job.Job, status config := jc.App.GetConfig() switch jobType { case job.OffchainReporting: - jb, err = ocr.ValidatedOracleSpecToml(jc.App.GetChains().EVM, tomlString) + jb, err = ocr.ValidatedOracleSpecToml(jc.App.GetRelayers().LegacyEVMChains(), tomlString) if !config.OCR().Enabled() { return jb, http.StatusNotImplemented, errors.New("The Offchain Reporting feature is disabled by configuration") } diff --git a/core/web/loader/loader_test.go b/core/web/loader/loader_test.go index 0567ab5188b..d5123053cf2 100644 --- a/core/web/loader/loader_test.go +++ b/core/web/loader/loader_test.go @@ -2,6 +2,7 @@ package loader import ( "database/sql" + "math/big" "testing" "github.com/google/uuid" @@ -14,18 +15,18 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" - evmmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtxmgrmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr/mocks" coremocks "github.com/smartcontractkit/chainlink/v2/core/internal/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" - "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + chainlinkmocks "github.com/smartcontractkit/chainlink/v2/core/services/chainlink/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/feeds" feedsMocks "github.com/smartcontractkit/chainlink/v2/core/services/feeds/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/job" jobORMMocks "github.com/smartcontractkit/chainlink/v2/core/services/job/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -64,32 +65,35 @@ func TestLoader_Chains(t *testing.T) { func TestLoader_Nodes(t *testing.T) { t.Parallel() - evmChainSet := evmmocks.NewChainSet(t) app := coremocks.NewApplication(t) ctx := InjectDataloader(testutils.Context(t), app) - node1 := relaytypes.NodeStatus{ - Name: "test-node-1", - ChainID: "1", - } - node2 := relaytypes.NodeStatus{ - Name: "test-node-1", - ChainID: "2", - } + chainID1, chainID2, notAnID := big.NewInt(1), big.NewInt(2), big.NewInt(3) + relayID1 := relay.ID{Network: relay.EVM, ChainID: relay.ChainID(chainID1.String())} + relayID2 := relay.ID{Network: relay.EVM, ChainID: relay.ChainID(chainID2.String())} + notARelayID := relay.ID{Network: relay.EVM, ChainID: relay.ChainID(notAnID.String())} - evmChainSet.On("NodeStatuses", mock.Anything, mock.Anything, mock.Anything, "2", "1", "3").Return([]relaytypes.NodeStatus{ - node1, node2, + genNodeStat := func(id string) relaytypes.NodeStatus { + return relaytypes.NodeStatus{ + Name: "test-node-" + id, + ChainID: id, + } + } + rcInterops := chainlinkmocks.NewRelayerChainInteroperators(t) + rcInterops.On("NodeStatuses", mock.Anything, 0, -1, + relayID2.String(), relayID1.String(), notARelayID.String()).Return([]relaytypes.NodeStatus{ + genNodeStat(chainID2.String()), genNodeStat(chainID1.String()), }, 2, nil) - app.On("GetChains").Return(chainlink.Chains{EVM: evmChainSet}) + app.On("GetRelayers").Return(rcInterops) batcher := nodeBatcher{app} - keys := dataloader.NewKeysFromStrings([]string{"2", "1", "3"}) + keys := dataloader.NewKeysFromStrings([]string{chainID2.String(), chainID1.String(), notAnID.String()}) found := batcher.loadByChainIDs(ctx, keys) require.Len(t, found, 3) - assert.Equal(t, []relaytypes.NodeStatus{node2}, found[0].Data) - assert.Equal(t, []relaytypes.NodeStatus{node1}, found[1].Data) + assert.Equal(t, []relaytypes.NodeStatus{genNodeStat(chainID2.String())}, found[0].Data) + assert.Equal(t, []relaytypes.NodeStatus{genNodeStat(chainID1.String())}, found[1].Data) assert.Equal(t, []relaytypes.NodeStatus{}, found[2].Data) } diff --git a/core/web/loader/node.go b/core/web/loader/node.go index e0b1d6711e8..fb0c58d1f2c 100644 --- a/core/web/loader/node.go +++ b/core/web/loader/node.go @@ -8,6 +8,7 @@ import ( "github.com/smartcontractkit/chainlink-relay/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) type nodeBatcher struct { @@ -18,20 +19,22 @@ func (b *nodeBatcher) loadByChainIDs(ctx context.Context, keys dataloader.Keys) // Create a map for remembering the order of keys passed in keyOrder := make(map[string]int, len(keys)) // Collect the keys to search for - var ids []string + // note backward compatibility -- this only ever supported evm chains + var evmrelayIdStrs []string + for ix, key := range keys { - ids = append(ids, key.String()) + rid := relay.ID{Network: relay.EVM, ChainID: relay.ChainID(key.String())} + evmrelayIdStrs = append(evmrelayIdStrs, rid.String()) keyOrder[key.String()] = ix } - nodes, _, err := b.app.GetChains().EVM.NodeStatuses(ctx, 0, -1, ids...) + allNodes, _, err := b.app.GetRelayers().NodeStatuses(ctx, 0, -1, evmrelayIdStrs...) if err != nil { return []*dataloader.Result{{Data: nil, Error: err}} } - // Generate a map of nodes to chainIDs nodesForChain := map[string][]types.NodeStatus{} - for _, n := range nodes { + for _, n := range allNodes { nodesForChain[n.ChainID] = append(nodesForChain[n.ChainID], n) } diff --git a/core/web/nodes_controller.go b/core/web/nodes_controller.go index da5fcd05b2d..e65f3e68a8a 100644 --- a/core/web/nodes_controller.go +++ b/core/web/nodes_controller.go @@ -18,14 +18,14 @@ type NodesController interface { } type nodesController[R jsonapi.EntityNamer] struct { - nodeSet chains.Nodes + nodeSet chains.NodesStatuser errNotEnabled error newResource func(status types.NodeStatus) R auditLogger audit.AuditLogger } func newNodesController[R jsonapi.EntityNamer]( - nodeSet chains.Nodes, + nodeSet chains.NodesStatuser, errNotEnabled error, newResource func(status types.NodeStatus) R, auditLogger audit.AuditLogger, diff --git a/core/web/presenters/job.go b/core/web/presenters/job.go index 571a6509680..01e01c9fa1e 100644 --- a/core/web/presenters/job.go +++ b/core/web/presenters/job.go @@ -325,33 +325,37 @@ func NewVRFSpec(spec *job.VRFSpec) *VRFSpec { // BlockhashStoreSpec defines the job parameters for a blockhash store feeder job. type BlockhashStoreSpec struct { - CoordinatorV1Address *ethkey.EIP55Address `json:"coordinatorV1Address"` - CoordinatorV2Address *ethkey.EIP55Address `json:"coordinatorV2Address"` - CoordinatorV2PlusAddress *ethkey.EIP55Address `json:"coordinatorV2PlusAddress"` - WaitBlocks int32 `json:"waitBlocks"` - LookbackBlocks int32 `json:"lookbackBlocks"` - BlockhashStoreAddress ethkey.EIP55Address `json:"blockhashStoreAddress"` - PollPeriod time.Duration `json:"pollPeriod"` - RunTimeout time.Duration `json:"runTimeout"` - EVMChainID *utils.Big `json:"evmChainID"` - FromAddresses []ethkey.EIP55Address `json:"fromAddresses"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + CoordinatorV1Address *ethkey.EIP55Address `json:"coordinatorV1Address"` + CoordinatorV2Address *ethkey.EIP55Address `json:"coordinatorV2Address"` + CoordinatorV2PlusAddress *ethkey.EIP55Address `json:"coordinatorV2PlusAddress"` + WaitBlocks int32 `json:"waitBlocks"` + LookbackBlocks int32 `json:"lookbackBlocks"` + BlockhashStoreAddress ethkey.EIP55Address `json:"blockhashStoreAddress"` + TrustedBlockhashStoreAddress *ethkey.EIP55Address `json:"trustedBlockhashStoreAddress"` + TrustedBlockhashStoreBatchSize int32 `json:"trustedBlockhashStoreBatchSize"` + PollPeriod time.Duration `json:"pollPeriod"` + RunTimeout time.Duration `json:"runTimeout"` + EVMChainID *utils.Big `json:"evmChainID"` + FromAddresses []ethkey.EIP55Address `json:"fromAddresses"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` } // NewBlockhashStoreSpec creates a new BlockhashStoreSpec for the given parameters. func NewBlockhashStoreSpec(spec *job.BlockhashStoreSpec) *BlockhashStoreSpec { return &BlockhashStoreSpec{ - CoordinatorV1Address: spec.CoordinatorV1Address, - CoordinatorV2Address: spec.CoordinatorV2Address, - CoordinatorV2PlusAddress: spec.CoordinatorV2PlusAddress, - WaitBlocks: spec.WaitBlocks, - LookbackBlocks: spec.LookbackBlocks, - BlockhashStoreAddress: spec.BlockhashStoreAddress, - PollPeriod: spec.PollPeriod, - RunTimeout: spec.RunTimeout, - EVMChainID: spec.EVMChainID, - FromAddresses: spec.FromAddresses, + CoordinatorV1Address: spec.CoordinatorV1Address, + CoordinatorV2Address: spec.CoordinatorV2Address, + CoordinatorV2PlusAddress: spec.CoordinatorV2PlusAddress, + WaitBlocks: spec.WaitBlocks, + LookbackBlocks: spec.LookbackBlocks, + BlockhashStoreAddress: spec.BlockhashStoreAddress, + TrustedBlockhashStoreAddress: spec.TrustedBlockhashStoreAddress, + TrustedBlockhashStoreBatchSize: spec.TrustedBlockhashStoreBatchSize, + PollPeriod: spec.PollPeriod, + RunTimeout: spec.RunTimeout, + EVMChainID: spec.EVMChainID, + FromAddresses: spec.FromAddresses, } } diff --git a/core/web/presenters/job_test.go b/core/web/presenters/job_test.go index 3e8f4176a17..a069a3e1ba5 100644 --- a/core/web/presenters/job_test.go +++ b/core/web/presenters/job_test.go @@ -53,6 +53,10 @@ func TestJob(t *testing.T) { batchBHSAddress, err := ethkey.NewEIP55Address("0xF6bB415b033D19EFf24A872a4785c6e1C4426103") require.NoError(t, err) + trustedBlockhashStoreAddress, err := ethkey.NewEIP55Address("0x0ad9FE7a58216242a8475ca92F222b0640E26B63") + require.NoError(t, err) + trustedBlockhashStoreBatchSize := int32(20) + var specGasLimit uint32 = 1000 testCases := []struct { @@ -472,17 +476,19 @@ func TestJob(t *testing.T) { job: job.Job{ ID: 1, BlockhashStoreSpec: &job.BlockhashStoreSpec{ - ID: 1, - CoordinatorV1Address: &v1CoordAddress, - CoordinatorV2Address: &v2CoordAddress, - CoordinatorV2PlusAddress: &v2PlusCoordAddress, - WaitBlocks: 123, - LookbackBlocks: 223, - BlockhashStoreAddress: contractAddress, - PollPeriod: 25 * time.Second, - RunTimeout: 10 * time.Second, - EVMChainID: utils.NewBigI(4), - FromAddresses: []ethkey.EIP55Address{fromAddress}, + ID: 1, + CoordinatorV1Address: &v1CoordAddress, + CoordinatorV2Address: &v2CoordAddress, + CoordinatorV2PlusAddress: &v2PlusCoordAddress, + WaitBlocks: 123, + LookbackBlocks: 223, + BlockhashStoreAddress: contractAddress, + PollPeriod: 25 * time.Second, + RunTimeout: 10 * time.Second, + EVMChainID: utils.NewBigI(4), + FromAddresses: []ethkey.EIP55Address{fromAddress}, + TrustedBlockhashStoreAddress: &trustedBlockhashStoreAddress, + TrustedBlockhashStoreBatchSize: trustedBlockhashStoreBatchSize, }, PipelineSpec: &pipeline.Spec{ ID: 1, @@ -521,6 +527,8 @@ func TestJob(t *testing.T) { "waitBlocks": 123, "lookbackBlocks": 223, "blockhashStoreAddress": "0x9E40733cC9df84636505f4e6Db28DCa0dC5D1bba", + "trustedBlockhashStoreAddress": "0x0ad9FE7a58216242a8475ca92F222b0640E26B63", + "trustedBlockhashStoreBatchSize": 20, "pollPeriod": 25000000000, "runTimeout": 10000000000, "evmChainID": "4", diff --git a/core/web/replay_controller.go b/core/web/replay_controller.go index 6809f1852ed..47c3e2dc522 100644 --- a/core/web/replay_controller.go +++ b/core/web/replay_controller.go @@ -46,7 +46,7 @@ func (bdc *ReplayController) ReplayFromBlock(c *gin.Context) { return } - chain, err := getChain(bdc.App.GetChains().EVM, c.Query("evmChainID")) + chain, err := getChain(bdc.App.GetRelayers().LegacyEVMChains(), c.Query("evmChainID")) switch err { case ErrInvalidChainID, ErrMultipleChains, ErrMissingChainID: jsonAPIError(c, http.StatusUnprocessableEntity, err) diff --git a/core/web/resolver/config_test.go b/core/web/resolver/config_test.go index c86fdb9a759..a04b3fa2484 100644 --- a/core/web/resolver/config_test.go +++ b/core/web/resolver/config_test.go @@ -52,7 +52,7 @@ func TestResolver_ConfigV2(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { opts := chainlink.GeneralConfigOpts{ - ConfigStrings: []string{configFull}, + ConfigStrings: []string{configFull}, SecretsStrings: []string{}, } cfg, err := opts.New() @@ -67,7 +67,7 @@ func TestResolver_ConfigV2(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { opts := chainlink.GeneralConfigOpts{ - ConfigStrings: []string{configMulti}, + ConfigStrings: []string{configMulti}, SecretsStrings: []string{}, } cfg, err := opts.New() diff --git a/core/web/resolver/eth_key_test.go b/core/web/resolver/eth_key_test.go index 3f49815548c..0df24ef9ff1 100644 --- a/core/web/resolver/eth_key_test.go +++ b/core/web/resolver/eth_key_test.go @@ -8,14 +8,17 @@ import ( gqlerrors "github.com/graph-gophers/graphql-go/errors" "github.com/pkg/errors" "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config" mocks2 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" - "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + configtest "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest/v2" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -86,6 +89,11 @@ func TestResolver_ETHKeys(t *testing.T) { chainID := *utils.NewBigI(12) linkAddr := common.HexToAddress("0x5431F5F973781809D18643b87B44921b11355d81") + cfg := configtest.NewGeneralConfig(t, nil) + m := map[string]evm.Chain{states[0].EVMChainID.String(): f.Mocks.chain} + legacyEVMChains, err := evm.NewLegacyChains(cfg, m) + require.NoError(t, err) + f.Mocks.ethKs.On("GetStatesForKeys", keys).Return(states, nil) f.Mocks.ethKs.On("Get", keys[0].Address.Hex()).Return(keys[0], nil) f.Mocks.ethKs.On("GetAll").Return(keys, nil) @@ -94,35 +102,37 @@ func TestResolver_ETHKeys(t *testing.T) { f.Mocks.balM.On("GetEthBalance", address).Return(assets.NewEth(1)) f.Mocks.chain.On("BalanceMonitor").Return(f.Mocks.balM) f.Mocks.chain.On("Config").Return(f.Mocks.scfg) - f.Mocks.chainSet.On("Get", states[0].EVMChainID.ToInt()).Return(f.Mocks.chain, nil) + f.Mocks.relayerChainInterops.On("LegacyEVMChains").Return(legacyEVMChains) f.Mocks.evmORM.PutChains(toml.EVMConfig{ChainID: &chainID}) f.Mocks.keystore.On("Eth").Return(f.Mocks.ethKs) f.App.On("GetKeyStore").Return(f.Mocks.keystore) f.App.On("EVMORM").Return(f.Mocks.evmORM) - f.App.On("GetChains").Return(chainlink.Chains{EVM: f.Mocks.chainSet}) + f.App.On("GetRelayers").Return(f.Mocks.relayerChainInterops) + f.Mocks.scfg.On("EVM").Return(&evmMockConfig) }, query: query, result: ` - { - "ethKeys": { - "results": [ - { - "address": "0x5431F5F973781809D18643b87B44921b11355d81", - "isDisabled": false, - "ethBalance": "0.000000000000000001", - "linkBalance": "12", - "maxGasPriceWei": "1", - "createdAt": "2021-01-01T00:00:00Z", - "updatedAt": "2021-01-01T00:00:00Z", - "chain": { - "id": "12" - } + { + "ethKeys": { + "results": [ + { + "address": "0x5431F5F973781809D18643b87B44921b11355d81", + "isDisabled": false, + "ethBalance": "0.000000000000000001", + "linkBalance": "12", + "maxGasPriceWei": "1", + "createdAt": "2021-01-01T00:00:00Z", + "updatedAt": "2021-01-01T00:00:00Z", + "chain": { + "id": "12" + } + } + ] } - ] - } - }`, + }`, }, + { name: "success with no chains", authenticated: true, @@ -137,38 +147,39 @@ func TestResolver_ETHKeys(t *testing.T) { }, } chainID := *utils.NewBigI(12) - + f.Mocks.legacyEVMChains.On("Get", states[0].EVMChainID.String()).Return(nil, evmrelay.ErrNoChains) f.Mocks.ethKs.On("GetStatesForKeys", keys).Return(states, nil) f.Mocks.ethKs.On("Get", keys[0].Address.Hex()).Return(keys[0], nil) f.Mocks.ethKs.On("GetAll").Return(keys, nil) - f.Mocks.chainSet.On("Get", states[0].EVMChainID.ToInt()).Return(f.Mocks.chain, evm.ErrNoChains) + f.Mocks.relayerChainInterops.On("LegacyEVMChains").Return(f.Mocks.legacyEVMChains) f.Mocks.evmORM.PutChains(toml.EVMConfig{ChainID: &chainID}) f.Mocks.keystore.On("Eth").Return(f.Mocks.ethKs) f.App.On("GetKeyStore").Return(f.Mocks.keystore) f.App.On("EVMORM").Return(f.Mocks.evmORM) - f.App.On("GetChains").Return(chainlink.Chains{EVM: f.Mocks.chainSet}) + f.App.On("GetRelayers").Return(f.Mocks.relayerChainInterops) }, query: query, result: ` - { - "ethKeys": { - "results": [ { - "address": "0x5431F5F973781809D18643b87B44921b11355d81", - "isDisabled": false, - "ethBalance": null, - "linkBalance": null, - "maxGasPriceWei": null, - "createdAt": "2021-01-01T00:00:00Z", - "updatedAt": "2021-01-01T00:00:00Z", - "chain": { - "id": "12" + "ethKeys": { + "results": [ + { + "address": "0x5431F5F973781809D18643b87B44921b11355d81", + "isDisabled": false, + "ethBalance": null, + "linkBalance": null, + "maxGasPriceWei": null, + "createdAt": "2021-01-01T00:00:00Z", + "updatedAt": "2021-01-01T00:00:00Z", + "chain": { + "id": "12" + } + } + ] } - } - ] - } - }`, + }`, }, + { name: "generic error on GetAll()", authenticated: true, @@ -239,6 +250,7 @@ func TestResolver_ETHKeys(t *testing.T) { }, }, }, + { name: "Empty set on #chainSet.Get()", authenticated: true, @@ -257,17 +269,18 @@ func TestResolver_ETHKeys(t *testing.T) { f.Mocks.ethKs.On("Get", keys[0].Address.Hex()).Return(ethkey.KeyV2{}, nil) f.Mocks.ethKs.On("GetAll").Return(keys, nil) f.Mocks.keystore.On("Eth").Return(f.Mocks.ethKs) - f.Mocks.chainSet.On("Get", states[0].EVMChainID.ToInt()).Return(f.Mocks.chain, gError) + f.Mocks.legacyEVMChains.On("Get", states[0].EVMChainID.String()).Return(f.Mocks.chain, gError) + f.Mocks.relayerChainInterops.On("LegacyEVMChains").Return(f.Mocks.legacyEVMChains) + f.App.On("GetRelayers").Return(f.Mocks.relayerChainInterops) f.App.On("GetKeyStore").Return(f.Mocks.keystore) - f.App.On("GetChains").Return(chainlink.Chains{EVM: f.Mocks.chainSet}) }, query: query, result: ` - { - "ethKeys": { - "results": [] - } - }`, + { + "ethKeys": { + "results": [] + } + }`, }, { name: "generic error on GetLINKBalance()", @@ -290,37 +303,38 @@ func TestResolver_ETHKeys(t *testing.T) { f.Mocks.ethKs.On("GetAll").Return(keys, nil) f.Mocks.keystore.On("Eth").Return(f.Mocks.ethKs) f.Mocks.ethClient.On("LINKBalance", mock.Anything, address, linkAddr).Return(assets.NewLinkFromJuels(12), gError) - f.Mocks.chainSet.On("Get", states[0].EVMChainID.ToInt()).Return(f.Mocks.chain, nil) + f.Mocks.legacyEVMChains.On("Get", states[0].EVMChainID.String()).Return(f.Mocks.chain, nil) + f.Mocks.relayerChainInterops.On("LegacyEVMChains").Return(f.Mocks.legacyEVMChains) f.Mocks.chain.On("Client").Return(f.Mocks.ethClient) f.Mocks.balM.On("GetEthBalance", address).Return(assets.NewEth(1)) f.Mocks.chain.On("BalanceMonitor").Return(f.Mocks.balM) f.App.On("GetKeyStore").Return(f.Mocks.keystore) - f.App.On("GetChains").Return(chainlink.Chains{EVM: f.Mocks.chainSet}) f.Mocks.chain.On("Config").Return(f.Mocks.scfg) f.Mocks.evmORM.PutChains(toml.EVMConfig{ChainID: &chainID}) + f.App.On("GetRelayers").Return(f.Mocks.relayerChainInterops) f.App.On("EVMORM").Return(f.Mocks.evmORM) f.Mocks.scfg.On("EVM").Return(&evmMockConfig) }, query: query, result: ` - { - "ethKeys": { - "results": [ - { - "address": "0x5431F5F973781809D18643b87B44921b11355d81", - "isDisabled": false, - "ethBalance": "0.000000000000000001", - "linkBalance": null, - "maxGasPriceWei": "1", - "createdAt": "2021-01-01T00:00:00Z", - "updatedAt": "2021-01-01T00:00:00Z", - "chain": { - "id": "12" - } + { + "ethKeys": { + "results": [ + { + "address": "0x5431F5F973781809D18643b87B44921b11355d81", + "isDisabled": false, + "ethBalance": "0.000000000000000001", + "linkBalance": null, + "maxGasPriceWei": "1", + "createdAt": "2021-01-01T00:00:00Z", + "updatedAt": "2021-01-01T00:00:00Z", + "chain": { + "id": "12" + } + } + ] } - ] - } - }`, + }`, }, { name: "success with no eth balance", @@ -345,34 +359,35 @@ func TestResolver_ETHKeys(t *testing.T) { f.Mocks.chain.On("Client").Return(f.Mocks.ethClient) f.Mocks.chain.On("BalanceMonitor").Return(nil) f.Mocks.chain.On("Config").Return(f.Mocks.scfg) - f.Mocks.chainSet.On("Get", states[0].EVMChainID.ToInt()).Return(f.Mocks.chain, nil) + f.Mocks.legacyEVMChains.On("Get", states[0].EVMChainID.String()).Return(f.Mocks.chain, nil) + f.Mocks.relayerChainInterops.On("LegacyEVMChains").Return(f.Mocks.legacyEVMChains) f.Mocks.evmORM.PutChains(toml.EVMConfig{ChainID: &chainID}) f.Mocks.keystore.On("Eth").Return(f.Mocks.ethKs) f.App.On("GetKeyStore").Return(f.Mocks.keystore) f.App.On("EVMORM").Return(f.Mocks.evmORM) - f.App.On("GetChains").Return(chainlink.Chains{EVM: f.Mocks.chainSet}) + f.App.On("GetRelayers").Return(f.Mocks.relayerChainInterops) f.Mocks.scfg.On("EVM").Return(&evmMockConfig) }, query: query, result: ` - { - "ethKeys": { - "results": [ - { - "address": "0x5431F5F973781809D18643b87B44921b11355d81", - "isDisabled": false, - "ethBalance": null, - "linkBalance": "12", - "maxGasPriceWei": "1", - "createdAt": "2021-01-01T00:00:00Z", - "updatedAt": "2021-01-01T00:00:00Z", - "chain": { - "id": "12" - } + { + "ethKeys": { + "results": [ + { + "address": "0x5431F5F973781809D18643b87B44921b11355d81", + "isDisabled": false, + "ethBalance": null, + "linkBalance": "12", + "maxGasPriceWei": "1", + "createdAt": "2021-01-01T00:00:00Z", + "updatedAt": "2021-01-01T00:00:00Z", + "chain": { + "id": "12" + } + } + ] } - ] - } - }`, + }`, }, } diff --git a/core/web/resolver/job_test.go b/core/web/resolver/job_test.go index 8a34b5a4ffc..7d73d7d0d2a 100644 --- a/core/web/resolver/job_test.go +++ b/core/web/resolver/job_test.go @@ -13,6 +13,7 @@ import ( "github.com/stretchr/testify/mock" "gopkg.in/guregu/null.v4" + "github.com/smartcontractkit/chainlink/v2/core/chains" clnull "github.com/smartcontractkit/chainlink/v2/core/null" "github.com/smartcontractkit/chainlink/v2/core/services/directrequest" "github.com/smartcontractkit/chainlink/v2/core/services/job" @@ -171,6 +172,32 @@ func TestResolver_Job(t *testing.T) { } } ` + exampleJobResult = ` + { + "job": { + "id": "1", + "createdAt": "2021-01-01T00:00:00Z", + "externalJobID": "00000000-0000-0000-0000-000000000001", + "gasLimit": 123, + "maxTaskDuration": "1s", + "name": "job1", + "schemaVersion": 1, + "spec": { + "__typename": "OCRSpec" + }, + "runs": { + "__typename": "JobRunsPayload", + "results": [{ + "id": "200" + }], + "metadata": { + "total": 1 + } + }, + "observationSource": "ds1 [type=bridge name=voter_turnout];" + } + } + ` ) testCases := []GQLTestCase{ @@ -204,33 +231,8 @@ func TestResolver_Job(t *testing.T) { On("CountPipelineRunsByJobID", int32(1)). Return(int32(1), nil) }, - query: query, - result: ` - { - "job": { - "id": "1", - "createdAt": "2021-01-01T00:00:00Z", - "externalJobID": "00000000-0000-0000-0000-000000000001", - "gasLimit": 123, - "maxTaskDuration": "1s", - "name": "job1", - "schemaVersion": 1, - "spec": { - "__typename": "OCRSpec" - }, - "runs": { - "__typename": "JobRunsPayload", - "results": [{ - "id": "200" - }], - "metadata": { - "total": 1 - } - }, - "observationSource": "ds1 [type=bridge name=voter_turnout];" - } - } - `, + query: query, + result: exampleJobResult, }, { name: "not found", @@ -249,6 +251,38 @@ func TestResolver_Job(t *testing.T) { } `, }, + { + name: "show job when chainID is disabled", + authenticated: true, + before: func(f *gqlTestFramework) { + f.App.On("JobORM").Return(f.Mocks.jobORM) + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{ + ID: 1, + Name: null.StringFrom("job1"), + SchemaVersion: 1, + GasLimit: clnull.Uint32From(123), + MaxTaskDuration: models.Interval(1 * time.Second), + ExternalJobID: externalJobID, + CreatedAt: f.Timestamp(), + Type: job.OffchainReporting, + OCROracleSpec: &job.OCROracleSpec{}, + PipelineSpec: &pipeline.Spec{ + DotDagSource: "ds1 [type=bridge name=voter_turnout];", + }, + }, chains.ErrNoSuchChainID) + f.Mocks.jobORM. + On("FindPipelineRunIDsByJobID", int32(1), 0, 50). + Return([]int64{200}, nil) + f.Mocks.jobORM. + On("FindPipelineRunsByIDs", []int64{200}). + Return([]pipeline.Run{{ID: 200}}, nil) + f.Mocks.jobORM. + On("CountPipelineRunsByJobID", int32(1)). + Return(int32(1), nil) + }, + query: query, + result: exampleJobResult, + }, } RunGQLTests(t, testCases) diff --git a/core/web/resolver/mutation.go b/core/web/resolver/mutation.go index dfb4b9f85be..5af263d9395 100644 --- a/core/web/resolver/mutation.go +++ b/core/web/resolver/mutation.go @@ -1011,7 +1011,7 @@ func (r *Resolver) CreateJob(ctx context.Context, args struct { config := r.App.GetConfig() switch jbt { case job.OffchainReporting: - jb, err = ocr.ValidatedOracleSpecToml(r.App.GetChains().EVM, args.Input.TOML) + jb, err = ocr.ValidatedOracleSpecToml(r.App.GetRelayers().LegacyEVMChains(), args.Input.TOML) if !config.OCR().Enabled() { return nil, errors.New("The Offchain Reporting feature is disabled by configuration") } diff --git a/core/web/resolver/node_test.go b/core/web/resolver/node_test.go index 1bb381731d6..e949a67a85b 100644 --- a/core/web/resolver/node_test.go +++ b/core/web/resolver/node_test.go @@ -8,9 +8,7 @@ import ( "github.com/stretchr/testify/mock" "github.com/smartcontractkit/chainlink-relay/pkg/types" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" - "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/store/models" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -45,8 +43,8 @@ func TestResolver_Nodes(t *testing.T) { name: "success", authenticated: true, before: func(f *gqlTestFramework) { - f.App.On("GetChains").Return(chainlink.Chains{EVM: f.Mocks.chainSet}) - f.Mocks.chainSet.On("NodeStatuses", mock.Anything, PageDefaultOffset, PageDefaultLimit).Return([]types.NodeStatus{ + f.App.On("GetRelayers").Return(f.Mocks.relayerChainInterops) + f.Mocks.relayerChainInterops.On("NodeStatuses", mock.Anything, PageDefaultOffset, PageDefaultLimit).Return([]types.NodeStatus{ { Name: "node-name", ChainID: chainID.String(), @@ -55,6 +53,7 @@ func TestResolver_Nodes(t *testing.T) { }, 1, nil) f.App.On("EVMORM").Return(f.Mocks.evmORM) f.Mocks.evmORM.PutChains(toml.EVMConfig{ChainID: &chainID}) + }, query: query, result: ` @@ -77,8 +76,8 @@ func TestResolver_Nodes(t *testing.T) { name: "generic error", authenticated: true, before: func(f *gqlTestFramework) { - f.Mocks.chainSet.On("NodeStatuses", mock.Anything, PageDefaultOffset, PageDefaultLimit).Return([]types.NodeStatus{}, 0, gError) - f.App.On("GetChains").Return(chainlink.Chains{EVM: f.Mocks.chainSet}) + f.Mocks.relayerChainInterops.On("NodeStatuses", mock.Anything, PageDefaultOffset, PageDefaultLimit).Return([]types.NodeStatus{}, 0, gError) + f.App.On("GetRelayers").Return(f.Mocks.relayerChainInterops) }, query: query, result: `null`, diff --git a/core/web/resolver/query.go b/core/web/resolver/query.go index 802e33be6bf..22b95a2d2ef 100644 --- a/core/web/resolver/query.go +++ b/core/web/resolver/query.go @@ -11,12 +11,11 @@ import ( "github.com/pkg/errors" "github.com/smartcontractkit/chainlink-relay/pkg/types" - "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/chains" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/vrfkey" + evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/utils/stringutils" ) @@ -154,7 +153,11 @@ func (r *Resolver) Job(ctx context.Context, args struct{ ID graphql.ID }) (*JobP if err != nil { if errors.Is(err, sql.ErrNoRows) { return NewJobPayload(r.App, nil, err), nil + } + //We still need to show the job in UI/CLI even if the chain id is disabled + if errors.Is(err, chains.ErrNoSuchChainID) { + return NewJobPayload(r.App, &j, err), nil } return nil, err @@ -223,10 +226,13 @@ func (r *Resolver) Node(ctx context.Context, args struct{ ID graphql.ID }) (*Nod if err := authenticateUser(ctx); err != nil { return nil, err } - + r.App.GetLogger().Debug("resolver Node args %v", args) name := string(args.ID) + r.App.GetLogger().Debug("resolver Node name %s", name) node, err := r.App.EVMORM().NodeStatus(name) if err != nil { + r.App.GetLogger().Errorw("resolver getting node status", "err", err) + if errors.Is(err, chains.ErrNotFound) { npr, warn := NewNodePayloadResolver(nil, err) if warn != nil { @@ -326,13 +332,15 @@ func (r *Resolver) Nodes(ctx context.Context, args struct { offset := pageOffset(args.Offset) limit := pageLimit(args.Limit) + r.App.GetLogger().Debugw("resolver Nodes query", "offset", offset, "limit", limit) + allNodes, total, err := r.App.GetRelayers().NodeStatuses(ctx, offset, limit) + r.App.GetLogger().Debugw("resolver Nodes query result", "nodes", allNodes, "total", total, "err", err) - nodes, count, err := r.App.GetChains().EVM.NodeStatuses(ctx, offset, limit) if err != nil { + r.App.GetLogger().Errorw("Error creating get nodes status from app", "err", err) return nil, err } - - npr, warn := NewNodesPayload(nodes, int32(count)) + npr, warn := NewNodesPayload(allNodes, int32(total)) if warn != nil { r.App.GetLogger().Warnw("Error creating NodesPayloadResolver", "err", warn) } @@ -407,8 +415,8 @@ func (r *Resolver) ETHKeys(ctx context.Context) (*ETHKeysPayloadResolver, error) return nil, err } - chain, err := r.App.GetChains().EVM.Get(state.EVMChainID.ToInt()) - if errors.Is(errors.Cause(err), evm.ErrNoChains) { + chain, err := r.App.GetRelayers().LegacyEVMChains().Get(state.EVMChainID.String()) + if errors.Is(errors.Cause(err), evmrelay.ErrNoChains) { ethKeys = append(ethKeys, ETHKey{ addr: k.EIP55Address, state: state, diff --git a/core/web/resolver/resolver_test.go b/core/web/resolver/resolver_test.go index c628a020052..d0523d6b968 100644 --- a/core/web/resolver/resolver_test.go +++ b/core/web/resolver/resolver_test.go @@ -18,6 +18,7 @@ import ( coremocks "github.com/smartcontractkit/chainlink/v2/core/internal/mocks" "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/logger/audit" chainlinkMocks "github.com/smartcontractkit/chainlink/v2/core/services/chainlink/mocks" feedsMocks "github.com/smartcontractkit/chainlink/v2/core/services/feeds/mocks" @@ -33,29 +34,30 @@ import ( ) type mocks struct { - bridgeORM *bridgeORMMocks.ORM - evmORM *evmtest.TestConfigs - jobORM *jobORMMocks.ORM - sessionsORM *sessionsMocks.ORM - pipelineORM *pipelineMocks.ORM - feedsSvc *feedsMocks.Service - cfg *chainlinkMocks.GeneralConfig - scfg *evmConfigMocks.ChainScopedConfig - ocr *keystoreMocks.OCR - ocr2 *keystoreMocks.OCR2 - csa *keystoreMocks.CSA - keystore *keystoreMocks.Master - ethKs *keystoreMocks.Eth - p2p *keystoreMocks.P2P - vrf *keystoreMocks.VRF - solana *keystoreMocks.Solana - chain *evmORMMocks.Chain - chainSet *evmORMMocks.ChainSet - ethClient *evmClientMocks.Client - eIMgr *webhookmocks.ExternalInitiatorManager - balM *evmORMMocks.BalanceMonitor - txmStore *evmtxmgrmocks.EvmTxStore - auditLogger *audit.AuditLoggerService + bridgeORM *bridgeORMMocks.ORM + evmORM *evmtest.TestConfigs + jobORM *jobORMMocks.ORM + sessionsORM *sessionsMocks.ORM + pipelineORM *pipelineMocks.ORM + feedsSvc *feedsMocks.Service + cfg *chainlinkMocks.GeneralConfig + scfg *evmConfigMocks.ChainScopedConfig + ocr *keystoreMocks.OCR + ocr2 *keystoreMocks.OCR2 + csa *keystoreMocks.CSA + keystore *keystoreMocks.Master + ethKs *keystoreMocks.Eth + p2p *keystoreMocks.P2P + vrf *keystoreMocks.VRF + solana *keystoreMocks.Solana + chain *evmORMMocks.Chain + legacyEVMChains *evmORMMocks.LegacyChainContainer + relayerChainInterops *chainlinkMocks.RelayerChainInteroperators + ethClient *evmClientMocks.Client + eIMgr *webhookmocks.ExternalInitiatorManager + balM *evmORMMocks.BalanceMonitor + txmStore *evmtxmgrmocks.EvmTxStore + auditLogger *audit.AuditLoggerService } // gqlTestFramework is a framework wrapper containing the objects needed to run @@ -63,7 +65,7 @@ type mocks struct { type gqlTestFramework struct { t *testing.T - // The mocked chainlf.Mocks.chainSetink.Application + // The mocked chainlink.Application App *coremocks.Application // The root GQL schema @@ -91,32 +93,35 @@ func setupFramework(t *testing.T) *gqlTestFramework { // Setup mocks // Note - If you add a new mock make sure you assert it's expectation below. m := &mocks{ - bridgeORM: bridgeORMMocks.NewORM(t), - evmORM: evmtest.NewTestConfigs(), - jobORM: jobORMMocks.NewORM(t), - feedsSvc: feedsMocks.NewService(t), - sessionsORM: sessionsMocks.NewORM(t), - pipelineORM: pipelineMocks.NewORM(t), - cfg: chainlinkMocks.NewGeneralConfig(t), - scfg: evmConfigMocks.NewChainScopedConfig(t), - ocr: keystoreMocks.NewOCR(t), - ocr2: keystoreMocks.NewOCR2(t), - csa: keystoreMocks.NewCSA(t), - keystore: keystoreMocks.NewMaster(t), - ethKs: keystoreMocks.NewEth(t), - p2p: keystoreMocks.NewP2P(t), - vrf: keystoreMocks.NewVRF(t), - solana: keystoreMocks.NewSolana(t), - chain: evmORMMocks.NewChain(t), - chainSet: evmORMMocks.NewChainSet(t), - ethClient: evmClientMocks.NewClient(t), - eIMgr: webhookmocks.NewExternalInitiatorManager(t), - balM: evmORMMocks.NewBalanceMonitor(t), - txmStore: evmtxmgrmocks.NewEvmTxStore(t), - auditLogger: &audit.AuditLoggerService{}, + bridgeORM: bridgeORMMocks.NewORM(t), + evmORM: evmtest.NewTestConfigs(), + jobORM: jobORMMocks.NewORM(t), + feedsSvc: feedsMocks.NewService(t), + sessionsORM: sessionsMocks.NewORM(t), + pipelineORM: pipelineMocks.NewORM(t), + cfg: chainlinkMocks.NewGeneralConfig(t), + scfg: evmConfigMocks.NewChainScopedConfig(t), + ocr: keystoreMocks.NewOCR(t), + ocr2: keystoreMocks.NewOCR2(t), + csa: keystoreMocks.NewCSA(t), + keystore: keystoreMocks.NewMaster(t), + ethKs: keystoreMocks.NewEth(t), + p2p: keystoreMocks.NewP2P(t), + vrf: keystoreMocks.NewVRF(t), + solana: keystoreMocks.NewSolana(t), + chain: evmORMMocks.NewChain(t), + legacyEVMChains: evmORMMocks.NewLegacyChainContainer(t), + relayerChainInterops: chainlinkMocks.NewRelayerChainInteroperators(t), + ethClient: evmClientMocks.NewClient(t), + eIMgr: webhookmocks.NewExternalInitiatorManager(t), + balM: evmORMMocks.NewBalanceMonitor(t), + txmStore: evmtxmgrmocks.NewEvmTxStore(t), + auditLogger: &audit.AuditLoggerService{}, } + lggr := logger.TestLogger(t) app.Mock.On("GetAuditLogger", mock.Anything, mock.Anything).Return(audit.NoopLogger).Maybe() + app.Mock.On("GetLogger").Return(lggr).Maybe() f := &gqlTestFramework{ t: t, diff --git a/core/web/resolver/spec.go b/core/web/resolver/spec.go index abcb468e1a7..fa3e5a14fa0 100644 --- a/core/web/resolver/spec.go +++ b/core/web/resolver/spec.go @@ -799,6 +799,20 @@ func (b *BlockhashStoreSpecResolver) BlockhashStoreAddress() string { return b.spec.BlockhashStoreAddress.String() } +// TrustedBlockhashStoreAddress returns the address of the job's TrustedBlockhashStoreAddress, if any. +func (b *BlockhashStoreSpecResolver) TrustedBlockhashStoreAddress() *string { + if b.spec.TrustedBlockhashStoreAddress == nil { + return nil + } + addr := b.spec.TrustedBlockhashStoreAddress.String() + return &addr +} + +// BatchBlockhashStoreAddress returns the job's BatchBlockhashStoreAddress param. +func (b *BlockhashStoreSpecResolver) TrustedBlockhashStoreBatchSize() int32 { + return b.spec.TrustedBlockhashStoreBatchSize +} + // PollPeriod return's the job's PollPeriod param. func (b *BlockhashStoreSpecResolver) PollPeriod() string { return b.spec.PollPeriod.String() diff --git a/core/web/resolver/spec_test.go b/core/web/resolver/spec_test.go index f3686774f13..8c6dadc880e 100644 --- a/core/web/resolver/spec_test.go +++ b/core/web/resolver/spec_test.go @@ -755,6 +755,10 @@ func TestResolver_BlockhashStoreSpec(t *testing.T) { blockhashStoreAddress, err := ethkey.NewEIP55Address("0xb26A6829D454336818477B946f03Fb21c9706f3A") require.NoError(t, err) + trustedBlockhashStoreAddress, err := ethkey.NewEIP55Address("0x0ad9FE7a58216242a8475ca92F222b0640E26B63") + require.NoError(t, err) + trustedBlockhashStoreBatchSize := int32(20) + testCases := []GQLTestCase{ { name: "blockhash store spec", @@ -764,17 +768,19 @@ func TestResolver_BlockhashStoreSpec(t *testing.T) { f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{ Type: job.BlockhashStore, BlockhashStoreSpec: &job.BlockhashStoreSpec{ - CoordinatorV1Address: &coordinatorV1Address, - CoordinatorV2Address: &coordinatorV2Address, - CoordinatorV2PlusAddress: &coordinatorV2PlusAddress, - CreatedAt: f.Timestamp(), - EVMChainID: utils.NewBigI(42), - FromAddresses: []ethkey.EIP55Address{fromAddress1, fromAddress2}, - PollPeriod: 1 * time.Minute, - RunTimeout: 37 * time.Second, - WaitBlocks: 100, - LookbackBlocks: 200, - BlockhashStoreAddress: blockhashStoreAddress, + CoordinatorV1Address: &coordinatorV1Address, + CoordinatorV2Address: &coordinatorV2Address, + CoordinatorV2PlusAddress: &coordinatorV2PlusAddress, + CreatedAt: f.Timestamp(), + EVMChainID: utils.NewBigI(42), + FromAddresses: []ethkey.EIP55Address{fromAddress1, fromAddress2}, + PollPeriod: 1 * time.Minute, + RunTimeout: 37 * time.Second, + WaitBlocks: 100, + LookbackBlocks: 200, + BlockhashStoreAddress: blockhashStoreAddress, + TrustedBlockhashStoreAddress: &trustedBlockhashStoreAddress, + TrustedBlockhashStoreBatchSize: trustedBlockhashStoreBatchSize, }, }, nil) }, @@ -796,6 +802,8 @@ func TestResolver_BlockhashStoreSpec(t *testing.T) { waitBlocks lookbackBlocks blockhashStoreAddress + trustedBlockhashStoreAddress + trustedBlockhashStoreBatchSize } } } @@ -817,7 +825,9 @@ func TestResolver_BlockhashStoreSpec(t *testing.T) { "runTimeout": "37s", "waitBlocks": 100, "lookbackBlocks": 200, - "blockhashStoreAddress": "0xb26A6829D454336818477B946f03Fb21c9706f3A" + "blockhashStoreAddress": "0xb26A6829D454336818477B946f03Fb21c9706f3A", + "trustedBlockhashStoreAddress": "0x0ad9FE7a58216242a8475ca92F222b0640E26B63", + "trustedBlockhashStoreBatchSize": 20 } } } diff --git a/core/web/resolver/testdata/config-empty-effective.toml b/core/web/resolver/testdata/config-empty-effective.toml index 65c5511c581..8c3eef53f6a 100644 --- a/core/web/resolver/testdata/config-empty-effective.toml +++ b/core/web/resolver/testdata/config-empty-effective.toml @@ -118,6 +118,7 @@ ContractTransmitterTransmitTimeout = '10s' DatabaseTimeout = '10s' KeyBundleID = '0000000000000000000000000000000000000000000000000000000000000000' CaptureEATelemetry = false +CaptureAutomationCustomTelemetry = false DefaultTransactionQueueDepth = 1 SimulateTransactions = false TraceLogging = false diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index c746bcfa900..96f24b1955c 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -118,6 +118,7 @@ ContractTransmitterTransmitTimeout = '1m0s' DatabaseTimeout = '8s' KeyBundleID = '7a5f66bbe6594259325bf2b4f5b1a9c900000000000000000000000000000000' CaptureEATelemetry = false +CaptureAutomationCustomTelemetry = false DefaultTransactionQueueDepth = 1 SimulateTransactions = false TraceLogging = false @@ -318,11 +319,12 @@ SendOnly = true [[Cosmos]] ChainID = 'Malaga-420' Enabled = true +Bech32Prefix = 'wasm' BlockRate = '1m0s' BlocksUntilTxTimeout = 12 ConfirmPollPeriod = '1s' FallbackGasPrice = '0.001' -FCDURL = 'http://cosmos.com' +FeeToken = 'ucosm' GasLimitMultiplier = '1.2' MaxMsgsPerBatch = 17 OCR2CachePollPeriod = '1m0s' diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index 73a0d5867a3..d6b38349b83 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -118,6 +118,7 @@ ContractTransmitterTransmitTimeout = '10s' DatabaseTimeout = '20s' KeyBundleID = '0000000000000000000000000000000000000000000000000000000000000000' CaptureEATelemetry = false +CaptureAutomationCustomTelemetry = false DefaultTransactionQueueDepth = 1 SimulateTransactions = false TraceLogging = false @@ -450,11 +451,12 @@ WSURL = 'wss://web.socket/test/bar' [[Cosmos]] ChainID = 'Ibiza-808' +Bech32Prefix = 'wasm' BlockRate = '6s' BlocksUntilTxTimeout = 30 ConfirmPollPeriod = '1s' FallbackGasPrice = '0.015' -FCDURL = '' +FeeToken = 'ucosm' GasLimitMultiplier = '1.5' MaxMsgsPerBatch = 13 OCR2CachePollPeriod = '4s' @@ -467,11 +469,12 @@ TendermintURL = 'http://columbus.cosmos.com' [[Cosmos]] ChainID = 'Malaga-420' +Bech32Prefix = 'wasm' BlockRate = '6s' BlocksUntilTxTimeout = 20 ConfirmPollPeriod = '1s' FallbackGasPrice = '0.015' -FCDURL = '' +FeeToken = 'ucosm' GasLimitMultiplier = '1.5' MaxMsgsPerBatch = 100 OCR2CachePollPeriod = '4s' diff --git a/core/web/resolver/testdata/config-multi-chain.toml b/core/web/resolver/testdata/config-multi-chain.toml index 53425dd1afe..eee786e69bf 100644 --- a/core/web/resolver/testdata/config-multi-chain.toml +++ b/core/web/resolver/testdata/config-multi-chain.toml @@ -71,6 +71,8 @@ WSURL = 'wss://web.socket/test/bar' [[Cosmos]] ChainID = 'Ibiza-808' +Bech32Prefix = 'wasm' +FeeToken = 'ucosm' MaxMsgsPerBatch = 13 [[Cosmos.Nodes]] @@ -79,7 +81,9 @@ TendermintURL = 'http://columbus.cosmos.com' [[Cosmos]] ChainID = 'Malaga-420' +Bech32Prefix = 'wasm' BlocksUntilTxTimeout = 20 +FeeToken = 'ucosm' [[Cosmos.Nodes]] Name = 'secondary' diff --git a/core/web/schema/type/spec.graphql b/core/web/schema/type/spec.graphql index 636c9d0fc2c..c92a1dd1ea9 100644 --- a/core/web/schema/type/spec.graphql +++ b/core/web/schema/type/spec.graphql @@ -126,6 +126,8 @@ type BlockhashStoreSpec { waitBlocks: Int! lookbackBlocks: Int! blockhashStoreAddress: String! + trustedBlockhashStoreAddress: String + trustedBlockhashStoreBatchSize: Int! pollPeriod: String! runTimeout: String! evmChainID: String diff --git a/core/web/solana_chains_controller.go b/core/web/solana_chains_controller.go index 5c6e1854ec4..8e2d4393a5f 100644 --- a/core/web/solana_chains_controller.go +++ b/core/web/solana_chains_controller.go @@ -2,10 +2,16 @@ package web import ( "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) func NewSolanaChainsController(app chainlink.Application) ChainsController { - return newChainsController("solana", app.GetChains().Solana, ErrSolanaNotEnabled, - presenters.NewSolanaChainResource, app.GetLogger(), app.GetAuditLogger()) + return newChainsController( + relay.Solana, + app.GetRelayers().List(chainlink.FilterRelayersByType(relay.Solana)), + ErrSolanaNotEnabled, + presenters.NewSolanaChainResource, + app.GetLogger(), + app.GetAuditLogger()) } diff --git a/core/web/solana_chains_controller_test.go b/core/web/solana_chains_controller_test.go index 5f2c00540d0..e6055840804 100644 --- a/core/web/solana_chains_controller_test.go +++ b/core/web/solana_chains_controller_test.go @@ -8,11 +8,12 @@ import ( "time" "github.com/manyminds/api2go/jsonapi" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-relay/pkg/types" "github.com/smartcontractkit/chainlink-relay/pkg/utils" "github.com/smartcontractkit/chainlink-solana/pkg/solana/config" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/chains/solana" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" diff --git a/core/web/solana_nodes_controller.go b/core/web/solana_nodes_controller.go index 350da7152e3..1c12418a5b2 100644 --- a/core/web/solana_nodes_controller.go +++ b/core/web/solana_nodes_controller.go @@ -2,6 +2,7 @@ package web import ( "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) @@ -10,5 +11,5 @@ var ErrSolanaNotEnabled = errChainDisabled{name: "Solana", tomlKey: "Solana.Enab func NewSolanaNodesController(app chainlink.Application) NodesController { return newNodesController[presenters.SolanaNodeResource]( - app.GetChains().Solana, ErrSolanaNotEnabled, presenters.NewSolanaNodeResource, app.GetAuditLogger()) + app.GetRelayers().List(chainlink.FilterRelayersByType(relay.Solana)), ErrSolanaNotEnabled, presenters.NewSolanaNodeResource, app.GetAuditLogger()) } diff --git a/core/web/solana_transfer_controller.go b/core/web/solana_transfer_controller.go index 5180a9d42c7..8238f775626 100644 --- a/core/web/solana_transfer_controller.go +++ b/core/web/solana_transfer_controller.go @@ -11,6 +11,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains" "github.com/smartcontractkit/chainlink/v2/core/logger/audit" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" solanamodels "github.com/smartcontractkit/chainlink/v2/core/store/models/solana" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) @@ -22,8 +23,8 @@ type SolanaTransfersController struct { // Create sends SOL and other native coins from the Chainlink's account to a specified address. func (tc *SolanaTransfersController) Create(c *gin.Context) { - relayer := tc.App.GetChains().Solana - if relayer == nil { + relayers := tc.App.GetRelayers().List(chainlink.FilterRelayersByType(relay.Solana)) + if relayers == nil { jsonAPIError(c, http.StatusBadRequest, ErrSolanaNotEnabled) return } @@ -47,7 +48,20 @@ func (tc *SolanaTransfersController) Create(c *gin.Context) { } amount := new(big.Int).SetUint64(tr.Amount) - err := relayer.SendTx(c, tr.SolanaChainID, tr.From.String(), tr.To.String(), amount, !tr.AllowHigherAmounts) + relayerID := relay.ID{Network: relay.Solana, ChainID: relay.ChainID(tr.SolanaChainID)} + relayer, err := relayers.Get(relayerID) + if err != nil { + if errors.Is(err, chainlink.ErrNoSuchRelayer) { + jsonAPIError(c, http.StatusBadRequest, err) + return + } else { + jsonAPIError(c, http.StatusInternalServerError, err) + return + } + } + // note the [loop.Relayer] API is in intermediate state. we found the relayer above; we should not need to pass + // the chain id here + err = relayer.SendTx(c, tr.SolanaChainID, tr.From.String(), tr.To.String(), amount, !tr.AllowHigherAmounts) if err != nil { switch err { case chains.ErrNotFound, chains.ErrChainIDEmpty: diff --git a/core/web/starknet_chains_controller.go b/core/web/starknet_chains_controller.go index 7b5baee95e8..414e17d9823 100644 --- a/core/web/starknet_chains_controller.go +++ b/core/web/starknet_chains_controller.go @@ -2,10 +2,16 @@ package web import ( "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) func NewStarkNetChainsController(app chainlink.Application) ChainsController { - return newChainsController("starknet", app.GetChains().StarkNet, ErrStarkNetNotEnabled, - presenters.NewStarkNetChainResource, app.GetLogger(), app.GetAuditLogger()) + return newChainsController( + relay.StarkNet, + app.GetRelayers().List(chainlink.FilterRelayersByType(relay.StarkNet)), + ErrStarkNetNotEnabled, + presenters.NewStarkNetChainResource, + app.GetLogger(), + app.GetAuditLogger()) } diff --git a/core/web/starknet_nodes_controller.go b/core/web/starknet_nodes_controller.go index 23cf27cee15..5c6e5c4d575 100644 --- a/core/web/starknet_nodes_controller.go +++ b/core/web/starknet_nodes_controller.go @@ -2,6 +2,7 @@ package web import ( "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) @@ -10,5 +11,5 @@ var ErrStarkNetNotEnabled = errChainDisabled{name: "StarkNet", tomlKey: "Starkne func NewStarkNetNodesController(app chainlink.Application) NodesController { return newNodesController[presenters.StarkNetNodeResource]( - app.GetChains().StarkNet, ErrStarkNetNotEnabled, presenters.NewStarkNetNodeResource, app.GetAuditLogger()) + app.GetRelayers().List(chainlink.FilterRelayersByType(relay.StarkNet)), ErrStarkNetNotEnabled, presenters.NewStarkNetNodeResource, app.GetAuditLogger()) } diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 2f787e14b2f..a5c31a8b4d7 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -9,8 +9,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [dev] +... + +## 2.5.0 - 2023-09-13 + +### Upcoming Required Configuration Change + +- Starting in 2.6.0, chainlink nodes will no longer allow insecure configuration for production builds. Any TOML configuration that sets the following line will fail validation checks in `node start` or `node validate`: + +``` +AllowSimplePasswords=true +``` + +- To migrate on production builds, update the database password set in Database.URL to be 16 - 50 characters without leading or trailing whitespace. URI parsing rules apply to the chosen password - refer to [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) for special character escape rules. + +### Added + +- Various Functions improvements + ## 2.4.0 - 2023-08-21 ### Fixed diff --git a/docs/CONFIG.md b/docs/CONFIG.md index e466473ee68..efbe9cbbf01 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -730,6 +730,7 @@ ContractTransmitterTransmitTimeout = '10s' # Default DatabaseTimeout = '10s' # Default KeyBundleID = '7a5f66bbe6594259325bf2b4f5b1a9c900000000000000000000000000000000' # Example CaptureEATelemetry = false # Default +CaptureAutomationCustomTelemetry = false # Default DefaultTransactionQueueDepth = 1 # Default SimulateTransactions = false # Default TraceLogging = false # Default @@ -824,6 +825,12 @@ CaptureEATelemetry = false # Default ``` CaptureEATelemetry toggles collecting extra information from External Adaptares +### CaptureAutomationCustomTelemetry +```toml +CaptureAutomationCustomTelemetry = false # Default +``` +CaptureAutomationCustomTelemetry toggles collecting automation specific telemetry + ### DefaultTransactionQueueDepth ```toml DefaultTransactionQueueDepth = 1 # Default @@ -2284,6 +2291,84 @@ GasLimit = 5300000

+
BSC Testnet (97)

+ +```toml +AutoCreateKey = true +BlockBackfillDepth = 10 +BlockBackfillSkip = false +FinalityDepth = 50 +FinalityTagEnabled = false +LinkContractAddress = '0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06' +LogBackfillBatchSize = 1000 +LogPollInterval = '3s' +LogKeepBlocksDepth = 100000 +MinIncomingConfirmations = 3 +MinContractPayment = '0.00001 link' +NonceAutoSync = true +NoNewHeadsThreshold = '30s' +RPCDefaultBatchSize = 250 +RPCBlockQueryDelay = 2 + +[Transactions] +ForwardersEnabled = false +MaxInFlight = 16 +MaxQueued = 250 +ReaperInterval = '1h0m0s' +ReaperThreshold = '168h0m0s' +ResendAfterThreshold = '1m0s' + +[BalanceMonitor] +Enabled = true + +[GasEstimator] +Mode = 'BlockHistory' +PriceDefault = '5 gwei' +PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +PriceMin = '1 gwei' +LimitDefault = 500000 +LimitMax = 500000 +LimitMultiplier = '1' +LimitTransfer = 21000 +BumpMin = '5 gwei' +BumpPercent = 20 +BumpThreshold = 5 +EIP1559DynamicFees = false +FeeCapDefault = '100 gwei' +TipCapDefault = '1 wei' +TipCapMin = '1 wei' + +[GasEstimator.BlockHistory] +BatchSize = 25 +BlockHistorySize = 24 +CheckInclusionBlocks = 12 +CheckInclusionPercentile = 90 +TransactionPercentile = 60 + +[HeadTracker] +HistoryDepth = 100 +MaxBufferSize = 3 +SamplingInterval = '1s' + +[NodePool] +PollFailureThreshold = 5 +PollInterval = '10s' +SelectionMode = 'HighestHead' +SyncThreshold = 10 + +[OCR] +ContractConfirmations = 4 +ContractTransmitterTransmitTimeout = '2s' +DatabaseTimeout = '2s' +ObservationGracePeriod = '500ms' + +[OCR2] +[OCR2.Automation] +GasLimit = 5300000 +``` + +

+
xDai Mainnet (100)

```toml @@ -3924,6 +4009,160 @@ GasLimit = 5300000

+
Scroll Sepolia (534351)

+ +```toml +AutoCreateKey = true +BlockBackfillDepth = 10 +BlockBackfillSkip = false +FinalityDepth = 1 +FinalityTagEnabled = false +LogBackfillBatchSize = 1000 +LogPollInterval = '30s' +LogKeepBlocksDepth = 100000 +MinIncomingConfirmations = 1 +MinContractPayment = '0.00001 link' +NonceAutoSync = true +NoNewHeadsThreshold = '0s' +RPCDefaultBatchSize = 250 +RPCBlockQueryDelay = 1 + +[Transactions] +ForwardersEnabled = false +MaxInFlight = 16 +MaxQueued = 250 +ReaperInterval = '1h0m0s' +ReaperThreshold = '168h0m0s' +ResendAfterThreshold = '2m0s' + +[BalanceMonitor] +Enabled = true + +[GasEstimator] +Mode = 'L2Suggested' +PriceDefault = '20 gwei' +PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +PriceMin = '0' +LimitDefault = 500000 +LimitMax = 500000 +LimitMultiplier = '1' +LimitTransfer = 21000 +BumpMin = '5 gwei' +BumpPercent = 20 +BumpThreshold = 0 +EIP1559DynamicFees = false +FeeCapDefault = '100 gwei' +TipCapDefault = '1 wei' +TipCapMin = '1 wei' + +[GasEstimator.BlockHistory] +BatchSize = 25 +BlockHistorySize = 0 +CheckInclusionBlocks = 12 +CheckInclusionPercentile = 90 +TransactionPercentile = 60 + +[HeadTracker] +HistoryDepth = 50 +MaxBufferSize = 3 +SamplingInterval = '1s' + +[NodePool] +PollFailureThreshold = 5 +PollInterval = '10s' +SelectionMode = 'HighestHead' +SyncThreshold = 5 + +[OCR] +ContractConfirmations = 1 +ContractTransmitterTransmitTimeout = '10s' +DatabaseTimeout = '10s' +ObservationGracePeriod = '1s' + +[OCR2] +[OCR2.Automation] +GasLimit = 5300000 +``` + +

+ +
Scroll Mainnet (534352)

+ +```toml +AutoCreateKey = true +BlockBackfillDepth = 10 +BlockBackfillSkip = false +FinalityDepth = 1 +FinalityTagEnabled = false +LogBackfillBatchSize = 1000 +LogPollInterval = '30s' +LogKeepBlocksDepth = 100000 +MinIncomingConfirmations = 1 +MinContractPayment = '0.00001 link' +NonceAutoSync = true +NoNewHeadsThreshold = '0s' +RPCDefaultBatchSize = 250 +RPCBlockQueryDelay = 1 + +[Transactions] +ForwardersEnabled = false +MaxInFlight = 16 +MaxQueued = 250 +ReaperInterval = '1h0m0s' +ReaperThreshold = '168h0m0s' +ResendAfterThreshold = '2m0s' + +[BalanceMonitor] +Enabled = true + +[GasEstimator] +Mode = 'L2Suggested' +PriceDefault = '20 gwei' +PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +PriceMin = '0' +LimitDefault = 500000 +LimitMax = 500000 +LimitMultiplier = '1' +LimitTransfer = 21000 +BumpMin = '5 gwei' +BumpPercent = 20 +BumpThreshold = 0 +EIP1559DynamicFees = false +FeeCapDefault = '100 gwei' +TipCapDefault = '1 wei' +TipCapMin = '1 wei' + +[GasEstimator.BlockHistory] +BatchSize = 25 +BlockHistorySize = 0 +CheckInclusionBlocks = 12 +CheckInclusionPercentile = 90 +TransactionPercentile = 60 + +[HeadTracker] +HistoryDepth = 50 +MaxBufferSize = 3 +SamplingInterval = '1s' + +[NodePool] +PollFailureThreshold = 5 +PollInterval = '10s' +SelectionMode = 'HighestHead' +SyncThreshold = 5 + +[OCR] +ContractConfirmations = 1 +ContractTransmitterTransmitTimeout = '10s' +DatabaseTimeout = '10s' +ObservationGracePeriod = '1s' + +[OCR2] +[OCR2.Automation] +GasLimit = 5300000 +``` + +

+
Ethereum Sepolia (11155111)

```toml @@ -4896,11 +5135,12 @@ GasLimit controls the gas limit for transmit transactions from ocr2automation jo [[Cosmos]] ChainID = 'Malaga-420' # Example Enabled = true # Default +Bech32Prefix = 'wasm' # Default BlockRate = '6s' # Default BlocksUntilTxTimeout = 30 # Default ConfirmPollPeriod = '1s' # Default FallbackGasPrice = '0.015' # Default -FCDURL = 'http://cosmos.com' # Example +FeeToken = 'ucosm' # Default GasLimitMultiplier = '1.5' # Default MaxMsgsPerBatch = 100 # Default OCR2CachePollPeriod = '4s' # Default @@ -4921,6 +5161,12 @@ Enabled = true # Default ``` Enabled enables this chain. +### Bech32Prefix +```toml +Bech32Prefix = 'wasm' # Default +``` +Bech32Prefix is the human-readable prefix for addresses on this Cosmos chain. See https://docs.cosmos.network/v0.47/spec/addresses/bech32. + ### BlockRate ```toml BlockRate = '6s' # Default @@ -4945,11 +5191,11 @@ FallbackGasPrice = '0.015' # Default ``` FallbackGasPrice sets a fallback gas price to use when the estimator is not available. -### FCDURL +### FeeToken ```toml -FCDURL = 'http://cosmos.com' # Example +FeeToken = 'ucosm' # Default ``` -FCDURL sets the FCD (Full Client Daemon) URL. +FeeToken is the token denomination which is being used to pay gas fees on this chain. ### GasLimitMultiplier ```toml diff --git a/go.mod b/go.mod index 3b7b8eb010b..e6afe0f8d18 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,6 @@ require ( github.com/cometbft/cometbft v0.37.2 github.com/cosmos/cosmos-sdk v0.47.4 github.com/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e - github.com/deckarep/golang-set/v2 v2.3.0 github.com/ethereum/go-ethereum v1.12.0 github.com/fatih/color v1.15.0 github.com/fxamacker/cbor/v2 v2.4.0 @@ -52,9 +51,9 @@ require ( github.com/onsi/gomega v1.27.8 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pelletier/go-toml v1.9.5 - github.com/pelletier/go-toml/v2 v2.0.8 + github.com/pelletier/go-toml/v2 v2.0.9 github.com/pkg/errors v0.9.1 - github.com/pressly/goose/v3 v3.5.3 + github.com/pressly/goose/v3 v3.15.0 github.com/prometheus/client_golang v1.16.0 github.com/prometheus/client_model v0.4.0 github.com/prometheus/common v0.44.0 @@ -66,16 +65,16 @@ require ( github.com/shirou/gopsutil/v3 v3.22.12 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230725012331-9007d9fb0d7b - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230620171700-bbcb3a99b7d3 - github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230612131011-369bfb503592 - github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230622060316-7ce48476dd7d - github.com/smartcontractkit/libocr v0.0.0-20230724105022-c5e49b4195ac - github.com/smartcontractkit/ocr2keepers v1.0.0-alpha.0 - github.com/smartcontractkit/ocr2vrf v0.0.0-20230616201444-d8b4222aff3c + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230824124058-9b063c470048 // TODO: update when https://github.com/smartcontractkit/chainlink-cosmos/pull/356 is merged + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230824125819-215fd09979a2 + github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230802143301-165000751a85 + github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230802150127-d2c95679d61a + github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 + github.com/smartcontractkit/ocr2keepers v0.7.17 + github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb - github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230616141813-ca0ecf03ca5c - github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230625174811-4934857d1c4a + github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230823081604-f2a0e6b108bb + github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230823081604-f2a0e6b108bb github.com/smartcontractkit/wsrpc v0.7.2 github.com/spf13/cast v1.5.1 github.com/stretchr/testify v1.8.4 @@ -85,7 +84,7 @@ require ( github.com/ulule/limiter/v3 v3.11.2 github.com/umbracle/ethgo v0.1.3 github.com/unrolled/secure v1.13.0 - github.com/urfave/cli v1.22.13 + github.com/urfave/cli v1.22.14 go.dedis.ch/fixbuf v1.0.3 go.dedis.ch/kyber/v3 v3.1.0 go.uber.org/multierr v1.11.0 @@ -115,12 +114,10 @@ require ( filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect - github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect github.com/CosmWasm/wasmvm v1.2.4 // indirect github.com/DataDog/zstd v1.5.2 // indirect github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect github.com/VictoriaMetrics/fastcache v1.10.0 // indirect github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect github.com/armon/go-metrics v0.4.1 // indirect @@ -154,6 +151,7 @@ require ( github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect + github.com/deckarep/golang-set/v2 v2.3.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 // indirect github.com/dgraph-io/badger/v2 v2.2007.4 // indirect @@ -216,7 +214,7 @@ require ( github.com/huandu/skiplist v1.2.0 // indirect github.com/huandu/xstrings v1.4.0 // indirect github.com/huin/goupnp v1.0.3 // indirect - github.com/imdario/mergo v0.3.15 // indirect + github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/go-cid v0.0.7 // indirect github.com/ipfs/go-datastore v0.4.5 // indirect @@ -235,7 +233,7 @@ require ( github.com/jmhodges/levigo v1.0.0 // indirect github.com/jmoiron/sqlx v1.3.5 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.16.3 // indirect + github.com/klauspost/compress v1.16.7 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/koron/go-ssdp v0.0.2 // indirect github.com/kr/pretty v0.3.1 // indirect @@ -302,10 +300,9 @@ require ( github.com/multiformats/go-multihash v0.0.14 // indirect github.com/multiformats/go-multistream v0.2.0 // indirect github.com/multiformats/go-varint v0.0.6 // indirect + github.com/mwitkow/grpc-proxy v0.0.0-20230212185441-f345521cb9c9 // indirect github.com/oklog/run v1.1.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc3 // indirect - github.com/opencontainers/runc v1.1.7 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect @@ -380,5 +377,8 @@ replace ( github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 // until merged upstream: https://github.com/hashicorp/go-plugin/pull/257 - github.com/hashicorp/go-plugin => github.com/jmank88/go-plugin v0.0.0-20230604120638-7bb12ec27e75 + github.com/hashicorp/go-plugin => github.com/smartcontractkit/go-plugin v0.0.0-20230605132010-0f4d515d1472 + + // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 + github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f ) diff --git a/go.sum b/go.sum index 69c185326cb..589d6cece36 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,3 @@ -bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -71,20 +70,13 @@ github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI= github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE= github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0= -github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= -github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= -github.com/ClickHouse/clickhouse-go v1.5.4/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= github.com/CosmWasm/wasmd v0.40.1 h1:LxbO78t/6S8TkeQlUrJ0m5O87HtAwLx4RGHq3rdrOEU= @@ -108,11 +100,8 @@ github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0 github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= -github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.5 h1:zl/OfRA6nftbBK9qTohYBJ5xvw6C/oNKizR7cZGl3cI= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= @@ -158,8 +147,6 @@ github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1U github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= @@ -184,7 +171,6 @@ github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= @@ -194,7 +180,6 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= @@ -202,11 +187,9 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -234,10 +217,7 @@ github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0 github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= -github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= -github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.2.2/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk= -github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= +github.com/containerd/continuity v0.4.1 h1:wQnVrjIyQ8vhU2sgOiL5T07jo+ouqc2bnKsv5/EqGhU= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -247,7 +227,6 @@ github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmf github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= @@ -271,17 +250,14 @@ github.com/cosmos/ledger-cosmos-go v0.12.1 h1:sMBxza5p/rNK/06nBSNmsI/WDqI0pVJFVN github.com/cosmos/ledger-cosmos-go v0.12.1/go.mod h1:dhO6kj+Y+AHIOgAe4L9HL/6NDdyyth4q238I9yFpD2g= github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzUGSKFTcM= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creachadair/taskgroup v0.4.2 h1:jsBLdAJE42asreGss2xZGZ8fJra7WtwnHWeJFxv2Li8= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= -github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= @@ -299,7 +275,6 @@ github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5il github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= -github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/dfuse-io/logging v0.0.0-20201110202154-26697de88c79/go.mod h1:V+ED4kT/t/lKtH99JQmKIb0v9WL3VaYkJ36CfHlVECI= github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 h1:CuJS05R9jmNlUK8GOxrEELPbfXm0EuGh/30LjkjN5vo= @@ -320,14 +295,9 @@ github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUn github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/cli v20.10.11+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= @@ -361,7 +331,6 @@ github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlK github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 h1:u/UEqS66A5ckRmS4yNpjmVH56sVtS/RfclBAYocb4as= github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -442,9 +411,8 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91 github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= @@ -462,7 +430,6 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= @@ -475,8 +442,6 @@ github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= -github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+wXQnTPR4KqTKDgJukSZ6amVRtWMPEjE6sQoK8= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= @@ -510,6 +475,7 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= @@ -573,7 +539,6 @@ github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9S github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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= @@ -690,9 +655,8 @@ github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:q github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= -github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -811,13 +775,10 @@ github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0 github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= -github.com/jmank88/go-plugin v0.0.0-20230604120638-7bb12ec27e75 h1:KYTOmcwuezD27O7vNF15lj8H7imCBMXCq1RzCdj4e3A= -github.com/jmank88/go-plugin v0.0.0-20230604120638-7bb12ec27e75/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= -github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= @@ -841,7 +802,6 @@ github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2 github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= @@ -850,8 +810,8 @@ github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0 github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= -github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= @@ -883,12 +843,10 @@ github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a/go.mod h1:U2L/ github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= @@ -1107,8 +1065,6 @@ github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f h1:tVvGiZQFjOXP+9YyGqSA6jE55x1XVxmoPYudncxrZ8U= github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f/go.mod h1:Z60vy0EZVSu0bOugCHdcN5ZxFMKSpjRgsnh0XKPFqqk= -github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= -github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -1135,9 +1091,7 @@ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.10/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -1176,15 +1130,12 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4 github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= -github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -1192,7 +1143,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 h1:mPMvm6X6tf4w8y7j9YIt6V9jfWhL6QlbEc7CCmeQlWk= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1/go.mod h1:ye2e/VUEtE2BHE+G/QcKkcLQVAEJoYRFj5VUOQatCRE= github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= @@ -1202,7 +1152,6 @@ github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjW github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= @@ -1294,23 +1243,15 @@ github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAl github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ= -github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8= -github.com/opencontainers/image-spec v1.1.0-rc3/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= -github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= +github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= github.com/opencontainers/runc v1.1.7 h1:y2EZDS8sNng4Ksf0GUYNhKbTShZJPJg1FiXJNH/uoCk= -github.com/opencontainers/runc v1.1.7/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50= -github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= -github.com/ory/dockertest/v3 v3.8.1/go.mod h1:wSRQ3wmkz+uSARYMk7kVJFDBGm8x5gSxIhI7NDc+BAQ= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -1320,15 +1261,13 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= -github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= -github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0= +github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 h1:hDSdbBuw3Lefr6R18ax0tZ2BJeNB3NehB3trOwYBsdU= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -1341,8 +1280,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/pressly/goose/v3 v3.5.3 h1:lIQIIXVbdO2RuQtJBS1e7MZjKEk0demVWt6i0YPiOrg= -github.com/pressly/goose/v3 v3.5.3/go.mod h1:IL4NNMdXx9O6hHpGbNB5l1hkVe/Avoz4gBDE5g7rQNg= +github.com/pressly/goose/v3 v3.15.0 h1:6tY5aDqFknY6VZkorFGgZtWygodZQxfmmEF4rqyJW9k= +github.com/pressly/goose/v3 v3.15.0/go.mod h1:LlIo3zGccjb/YUgG+Svdb9Er14vefRdlDI7URCDrwYo= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= @@ -1380,8 +1319,7 @@ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqn github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= -github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= -github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -1414,7 +1352,6 @@ github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtm github.com/scylladb/go-reflectx v1.0.1 h1:b917wZM7189pZdlND9PbIJ6NQxfDPfBvUaQ7cjj1iZQ= github.com/scylladb/go-reflectx v1.0.1/go.mod h1:rWnOfDIRWBGN0miMLIcoPt/Dhi2doCMZqwMCJ3KupFc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= @@ -1428,32 +1365,34 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumvbfM1u/etVq42Afwq/jtNSBSOA8n5jntnNPo= github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230725012331-9007d9fb0d7b h1:vh4N/K+TMG8oV7L2i4U8q5aMjlVgf5M8TAZJCsXUh4U= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230725012331-9007d9fb0d7b/go.mod h1:TtLMvOtGV9hwNg59iJj+Sa0vL0Kq3o3eF+6uSIRixDc= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230620171700-bbcb3a99b7d3 h1:rlNWHk15A2im/e9U95q4AkHZk5Wbc77lpx6ys4kUyCE= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230620171700-bbcb3a99b7d3/go.mod h1:MfZBUifutkv3aK7abyw5YmTJbqt8iFwcQDFikrxC/uI= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230612131011-369bfb503592 h1:3Ul/LkULxrolCVguHUFnWJamgUDsSGISlm/DzclstmE= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230612131011-369bfb503592/go.mod h1:km46XAo6xebV4Q+WyRFfo3E2t80YqTkegJM4FEfo5/Y= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230622060316-7ce48476dd7d h1:4jSCp6i/p/EIaAkYQDxPK8nXDuv0fBXzKIcVYzetCoI= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230622060316-7ce48476dd7d/go.mod h1:AW1rNDx4YN0VJzM1OrZtsOV9ORdcqcSFtsOQO3GeOQo= -github.com/smartcontractkit/libocr v0.0.0-20230724105022-c5e49b4195ac h1:ugouvLyN5D2AeztWrByENx08cx0phkxxvfP+AkBv3NI= -github.com/smartcontractkit/libocr v0.0.0-20230724105022-c5e49b4195ac/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= -github.com/smartcontractkit/ocr2keepers v1.0.0-alpha.0 h1:zkXsh4MAARNXqUlsMPBzVtFVV7SN93SxQ3KfCicnans= -github.com/smartcontractkit/ocr2keepers v1.0.0-alpha.0/go.mod h1:13Q6zuYWLByKXzzcSoi7L01bT8OzxM//XgMZQeCZVP0= -github.com/smartcontractkit/ocr2vrf v0.0.0-20230616201444-d8b4222aff3c h1:BX1ibMdGE2QdD8rJEI5nxE4jA6v2bf7LULrSbDrNM+A= -github.com/smartcontractkit/ocr2vrf v0.0.0-20230616201444-d8b4222aff3c/go.mod h1:AT1OrDDOCd8vzmMsCnA70N+tZdq9AbdZAiAw+gQq260= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230824124058-9b063c470048 h1:OHj8qzXajBAIT9TBnHN5LVGoCxvso/4JgCeg/l76Tgk= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230824124058-9b063c470048/go.mod h1:xMwqRdj5vqYhCJXgKVqvyAwdcqM6ZAEhnwEQ4Khsop8= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230824125819-215fd09979a2 h1:z9PIgm0klhunwPy+KZYR4E9vCpjgJaMOyQRLCYgfoLk= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230824125819-215fd09979a2/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230802143301-165000751a85 h1:/fm02hYSUdhbSh7xPn7os9yHj7dnl8aLs2+nFXPiB4g= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230802143301-165000751a85/go.mod h1:H3/j2l84FsxYevCLNERdVasI7FVr+t2mkpv+BCJLSVw= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230802150127-d2c95679d61a h1:b3rjvZLpTV45TmCV+ALX+EDDslf91pnDUugP54Lu9FA= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230802150127-d2c95679d61a/go.mod h1:LL+FLf10gOUHrF3aUsRGEZlT/w8DaW5T/eEo/54W68c= +github.com/smartcontractkit/go-plugin v0.0.0-20230605132010-0f4d515d1472 h1:x3kNwgFlDmbE/n0gTSRMt9GBDfsfGrs4X9b9arPZtFI= +github.com/smartcontractkit/go-plugin v0.0.0-20230605132010-0f4d515d1472/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0= +github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= +github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= +github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 h1:rzbqGoScs9VHGnyCKF7AoQEuUfwJnzcKmGIfaczeanA= +github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= +github.com/smartcontractkit/ocr2keepers v0.7.17 h1:847GG2SHyHIPc3yu+dhB+1HfeLRhSjyiKnhw3umpoJw= +github.com/smartcontractkit/ocr2keepers v0.7.17/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= +github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 h1:NwC3SOc25noBTe1KUQjt45fyTIuInhoE2UfgcHAdihM= +github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687/go.mod h1:YYZq52t4wcHoMQeITksYsorD+tZcOyuVU5+lvot3VFM= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb h1:OMaBUb4X9IFPLbGbCHsMU+kw/BPCrewaVwWGIBc0I4A= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb/go.mod h1:HNUu4cJekUdsJbwRBCiOybtkPJEfGRELQPe2tkoDEyk= -github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230616141813-ca0ecf03ca5c h1:B7jWegIHCHXY32qWGwlNalrJYSz4uZh5zAgd2rQ3Iyc= -github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230616141813-ca0ecf03ca5c/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= -github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230625174811-4934857d1c4a h1:/ZJnNxcdJ75yDJHnKMjd3G9oZ6lcQRvFUdmiR2DPAgQ= -github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230625174811-4934857d1c4a/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw= +github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230823081604-f2a0e6b108bb h1:xNLGJcARfz9HCUKla6wH0gmwsG1/FTAWWeOplW2J72A= +github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230823081604-f2a0e6b108bb/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= +github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230823081604-f2a0e6b108bb h1:jyhgdafuZsex+kEHDIgq8o8wuVoPTr9wsGmuBtcFbEk= +github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230823081604-f2a0e6b108bb/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/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -1510,13 +1449,11 @@ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1F github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= @@ -1547,7 +1484,6 @@ github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+F github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= @@ -1569,9 +1505,8 @@ github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 h1:10Nbw6cACsnQm7 github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722/go.mod h1:c8J0h9aULj2i3umrfyestM6jCq0LK0U6ly6bWy96nd4= github.com/unrolled/secure v1.13.0 h1:sdr3Phw2+f8Px8HE5sd1EHdj1aV3yUwed/uZXChLFsk= github.com/unrolled/secure v1.13.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.13 h1:wsLILXG8qCJNse/qAgLNf23737Cx05GflHg/PJGe1Ok= -github.com/urfave/cli v1.22.13/go.mod h1:VufqObjsMTF2BBwKawpx9R8eAneNEWhoO0yx8Vd+FkE= +github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= +github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bCzK15ozrqo2sZxkh0FHynJZOTVoV6Q= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= @@ -1581,8 +1516,6 @@ github.com/valyala/fastjson v1.4.1/go.mod h1:nV6MsjxL2IMJQUoHDIrjEI7oLyeqK6aBD7E github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= -github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= -github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= @@ -1609,13 +1542,11 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= @@ -1709,7 +1640,6 @@ golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= @@ -1719,7 +1649,6 @@ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220210151621-f4118a5b28e2/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= @@ -1761,7 +1690,6 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1812,15 +1740,13 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -1875,7 +1801,6 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1887,10 +1812,8 @@ golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1907,36 +1830,31 @@ golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210629170331-7dc0b73dc9fb/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1999,7 +1917,6 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -2041,7 +1958,6 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -2051,7 +1967,6 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4f 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.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= @@ -2138,6 +2053,7 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 h1:Au6te5hbKUV8pIYWHqOUZ1pva5qK/rwbIhoXEUB9Lu8= google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y= @@ -2167,6 +2083,7 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI= @@ -2233,8 +2150,6 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -2243,134 +2158,17 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= -lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI= -lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= -modernc.org/cc/v3 v3.33.6/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.33.9/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.33.11/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.34.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.4/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.5/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.7/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.8/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.10/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.15/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.16/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.17/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.18/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.20/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/cc/v3 v3.35.22 h1:BzShpwCAP7TWzFppM4k2t03RhXhgYqaibROWkrWq7lE= -modernc.org/cc/v3 v3.35.22/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/ccgo/v3 v3.9.5/go.mod h1:umuo2EP2oDSBnD3ckjaVUXMrmeAw8C8OSICVa0iFf60= -modernc.org/ccgo/v3 v3.10.0/go.mod h1:c0yBmkRFi7uW4J7fwx/JiijwOjeAeR2NoSaRVFPmjMw= -modernc.org/ccgo/v3 v3.11.0/go.mod h1:dGNposbDp9TOZ/1KBxghxtUp/bzErD0/0QW4hhSaBMI= -modernc.org/ccgo/v3 v3.11.1/go.mod h1:lWHxfsn13L3f7hgGsGlU28D9eUOf6y3ZYHKoPaKU0ag= -modernc.org/ccgo/v3 v3.11.3/go.mod h1:0oHunRBMBiXOKdaglfMlRPBALQqsfrCKXgw9okQ3GEw= -modernc.org/ccgo/v3 v3.12.4/go.mod h1:Bk+m6m2tsooJchP/Yk5ji56cClmN6R1cqc9o/YtbgBQ= -modernc.org/ccgo/v3 v3.12.6/go.mod h1:0Ji3ruvpFPpz+yu+1m0wk68pdr/LENABhTrDkMDWH6c= -modernc.org/ccgo/v3 v3.12.8/go.mod h1:Hq9keM4ZfjCDuDXxaHptpv9N24JhgBZmUG5q60iLgUo= -modernc.org/ccgo/v3 v3.12.11/go.mod h1:0jVcmyDwDKDGWbcrzQ+xwJjbhZruHtouiBEvDfoIsdg= -modernc.org/ccgo/v3 v3.12.14/go.mod h1:GhTu1k0YCpJSuWwtRAEHAol5W7g1/RRfS4/9hc9vF5I= -modernc.org/ccgo/v3 v3.12.18/go.mod h1:jvg/xVdWWmZACSgOiAhpWpwHWylbJaSzayCqNOJKIhs= -modernc.org/ccgo/v3 v3.12.20/go.mod h1:aKEdssiu7gVgSy/jjMastnv/q6wWGRbszbheXgWRHc8= -modernc.org/ccgo/v3 v3.12.21/go.mod h1:ydgg2tEprnyMn159ZO/N4pLBqpL7NOkJ88GT5zNU2dE= -modernc.org/ccgo/v3 v3.12.22/go.mod h1:nyDVFMmMWhMsgQw+5JH6B6o4MnZ+UQNw1pp52XYFPRk= -modernc.org/ccgo/v3 v3.12.25/go.mod h1:UaLyWI26TwyIT4+ZFNjkyTbsPsY3plAEB6E7L/vZV3w= -modernc.org/ccgo/v3 v3.12.29/go.mod h1:FXVjG7YLf9FetsS2OOYcwNhcdOLGt8S9bQ48+OP75cE= -modernc.org/ccgo/v3 v3.12.36/go.mod h1:uP3/Fiezp/Ga8onfvMLpREq+KUjUmYMxXPO8tETHtA8= -modernc.org/ccgo/v3 v3.12.38/go.mod h1:93O0G7baRST1vNj4wnZ49b1kLxt0xCW5Hsa2qRaZPqc= -modernc.org/ccgo/v3 v3.12.43/go.mod h1:k+DqGXd3o7W+inNujK15S5ZYuPoWYLpF5PYougCmthU= -modernc.org/ccgo/v3 v3.12.46/go.mod h1:UZe6EvMSqOxaJ4sznY7b23/k13R8XNlyWsO5bAmSgOE= -modernc.org/ccgo/v3 v3.12.47/go.mod h1:m8d6p0zNps187fhBwzY/ii6gxfjob1VxWb919Nk1HUk= -modernc.org/ccgo/v3 v3.12.50/go.mod h1:bu9YIwtg+HXQxBhsRDE+cJjQRuINuT9PUK4orOco/JI= -modernc.org/ccgo/v3 v3.12.51/go.mod h1:gaIIlx4YpmGO2bLye04/yeblmvWEmE4BBBls4aJXFiE= -modernc.org/ccgo/v3 v3.12.53/go.mod h1:8xWGGTFkdFEWBEsUmi+DBjwu/WLy3SSOrqEmKUjMeEg= -modernc.org/ccgo/v3 v3.12.54/go.mod h1:yANKFTm9llTFVX1FqNKHE0aMcQb1fuPJx6p8AcUx+74= -modernc.org/ccgo/v3 v3.12.55/go.mod h1:rsXiIyJi9psOwiBkplOaHye5L4MOOaCjHg1Fxkj7IeU= -modernc.org/ccgo/v3 v3.12.56/go.mod h1:ljeFks3faDseCkr60JMpeDb2GSO3TKAmrzm7q9YOcMU= -modernc.org/ccgo/v3 v3.12.57/go.mod h1:hNSF4DNVgBl8wYHpMvPqQWDQx8luqxDnNGCMM4NFNMc= -modernc.org/ccgo/v3 v3.12.60/go.mod h1:k/Nn0zdO1xHVWjPYVshDeWKqbRWIfif5dtsIOCUVMqM= -modernc.org/ccgo/v3 v3.12.66/go.mod h1:jUuxlCFZTUZLMV08s7B1ekHX5+LIAurKTTaugUr/EhQ= -modernc.org/ccgo/v3 v3.12.67/go.mod h1:Bll3KwKvGROizP2Xj17GEGOTrlvB1XcVaBrC90ORO84= -modernc.org/ccgo/v3 v3.12.73/go.mod h1:hngkB+nUUqzOf3iqsM48Gf1FZhY599qzVg1iX+BT3cQ= -modernc.org/ccgo/v3 v3.12.81/go.mod h1:p2A1duHoBBg1mFtYvnhAnQyI6vL0uw5PGYLSIgF6rYY= -modernc.org/ccgo/v3 v3.12.84/go.mod h1:ApbflUfa5BKadjHynCficldU1ghjen84tuM5jRynB7w= -modernc.org/ccgo/v3 v3.12.86/go.mod h1:dN7S26DLTgVSni1PVA3KxxHTcykyDurf3OgUzNqTSrU= -modernc.org/ccgo/v3 v3.12.90/go.mod h1:obhSc3CdivCRpYZmrvO88TXlW0NvoSVvdh/ccRjJYko= -modernc.org/ccgo/v3 v3.12.92/go.mod h1:5yDdN7ti9KWPi5bRVWPl8UNhpEAtCjuEE7ayQnzzqHA= -modernc.org/ccgo/v3 v3.13.1/go.mod h1:aBYVOUfIlcSnrsRVU8VRS35y2DIfpgkmVkYZ0tpIXi4= -modernc.org/ccgo/v3 v3.15.1/go.mod h1:md59wBwDT2LznX/OTCPoVS6KIsdRgY8xqQwBV+hkTH0= -modernc.org/ccgo/v3 v3.15.9/go.mod h1:md59wBwDT2LznX/OTCPoVS6KIsdRgY8xqQwBV+hkTH0= -modernc.org/ccgo/v3 v3.15.10/go.mod h1:wQKxoFn0ynxMuCLfFD09c8XPUCc8obfchoVR9Cn0fI8= -modernc.org/ccgo/v3 v3.15.12/go.mod h1:VFePOWoCd8uDGRJpq/zfJ29D0EVzMSyID8LCMWYbX6I= -modernc.org/ccgo/v3 v3.15.13 h1:hqlCzNJTXLrhS70y1PqWckrF9x1btSQRC7JFuQcBg5c= -modernc.org/ccgo/v3 v3.15.13/go.mod h1:QHtvdpeODlXjdK3tsbpyK+7U9JV4PQsrPGIbtmc0KfY= -modernc.org/ccorpus v1.11.1/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= -modernc.org/ccorpus v1.11.4/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= -modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= -modernc.org/libc v1.9.8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w= -modernc.org/libc v1.9.11/go.mod h1:NyF3tsA5ArIjJ83XB0JlqhjTabTCHm9aX4XMPHyQn0Q= -modernc.org/libc v1.11.0/go.mod h1:2lOfPmj7cz+g1MrPNmX65QCzVxgNq2C5o0jdLY2gAYg= -modernc.org/libc v1.11.2/go.mod h1:ioIyrl3ETkugDO3SGZ+6EOKvlP3zSOycUETe4XM4n8M= -modernc.org/libc v1.11.5/go.mod h1:k3HDCP95A6U111Q5TmG3nAyUcp3kR5YFZTeDS9v8vSU= -modernc.org/libc v1.11.6/go.mod h1:ddqmzR6p5i4jIGK1d/EiSw97LBcE3dK24QEwCFvgNgE= -modernc.org/libc v1.11.11/go.mod h1:lXEp9QOOk4qAYOtL3BmMve99S5Owz7Qyowzvg6LiZso= -modernc.org/libc v1.11.13/go.mod h1:ZYawJWlXIzXy2Pzghaf7YfM8OKacP3eZQI81PDLFdY8= -modernc.org/libc v1.11.16/go.mod h1:+DJquzYi+DMRUtWI1YNxrlQO6TcA5+dRRiq8HWBWRC8= -modernc.org/libc v1.11.19/go.mod h1:e0dgEame6mkydy19KKaVPBeEnyJB4LGNb0bBH1EtQ3I= -modernc.org/libc v1.11.24/go.mod h1:FOSzE0UwookyT1TtCJrRkvsOrX2k38HoInhw+cSCUGk= -modernc.org/libc v1.11.26/go.mod h1:SFjnYi9OSd2W7f4ct622o/PAYqk7KHv6GS8NZULIjKY= -modernc.org/libc v1.11.27/go.mod h1:zmWm6kcFXt/jpzeCgfvUNswM0qke8qVwxqZrnddlDiE= -modernc.org/libc v1.11.28/go.mod h1:Ii4V0fTFcbq3qrv3CNn+OGHAvzqMBvC7dBNyC4vHZlg= -modernc.org/libc v1.11.31/go.mod h1:FpBncUkEAtopRNJj8aRo29qUiyx5AvAlAxzlx9GNaVM= -modernc.org/libc v1.11.34/go.mod h1:+Tzc4hnb1iaX/SKAutJmfzES6awxfU1BPvrrJO0pYLg= -modernc.org/libc v1.11.37/go.mod h1:dCQebOwoO1046yTrfUE5nX1f3YpGZQKNcITUYWlrAWo= -modernc.org/libc v1.11.39/go.mod h1:mV8lJMo2S5A31uD0k1cMu7vrJbSA3J3waQJxpV4iqx8= -modernc.org/libc v1.11.42/go.mod h1:yzrLDU+sSjLE+D4bIhS7q1L5UwXDOw99PLSX0BlZvSQ= -modernc.org/libc v1.11.44/go.mod h1:KFq33jsma7F5WXiYelU8quMJasCCTnHK0mkri4yPHgA= -modernc.org/libc v1.11.45/go.mod h1:Y192orvfVQQYFzCNsn+Xt0Hxt4DiO4USpLNXBlXg/tM= -modernc.org/libc v1.11.47/go.mod h1:tPkE4PzCTW27E6AIKIR5IwHAQKCAtudEIeAV1/SiyBg= -modernc.org/libc v1.11.49/go.mod h1:9JrJuK5WTtoTWIFQ7QjX2Mb/bagYdZdscI3xrvHbXjE= -modernc.org/libc v1.11.51/go.mod h1:R9I8u9TS+meaWLdbfQhq2kFknTW0O3aw3kEMqDDxMaM= -modernc.org/libc v1.11.53/go.mod h1:5ip5vWYPAoMulkQ5XlSJTy12Sz5U6blOQiYasilVPsU= -modernc.org/libc v1.11.54/go.mod h1:S/FVnskbzVUrjfBqlGFIPA5m7UwB3n9fojHhCNfSsnw= -modernc.org/libc v1.11.55/go.mod h1:j2A5YBRm6HjNkoSs/fzZrSxCuwWqcMYTDPLNx0URn3M= -modernc.org/libc v1.11.56/go.mod h1:pakHkg5JdMLt2OgRadpPOTnyRXm/uzu+Yyg/LSLdi18= -modernc.org/libc v1.11.58/go.mod h1:ns94Rxv0OWyoQrDqMFfWwka2BcaF6/61CqJRK9LP7S8= -modernc.org/libc v1.11.71/go.mod h1:DUOmMYe+IvKi9n6Mycyx3DbjfzSKrdr/0Vgt3j7P5gw= -modernc.org/libc v1.11.75/go.mod h1:dGRVugT6edz361wmD9gk6ax1AbDSe0x5vji0dGJiPT0= -modernc.org/libc v1.11.82/go.mod h1:NF+Ek1BOl2jeC7lw3a7Jj5PWyHPwWD4aq3wVKxqV1fI= -modernc.org/libc v1.11.86/go.mod h1:ePuYgoQLmvxdNT06RpGnaDKJmDNEkV7ZPKI2jnsvZoE= -modernc.org/libc v1.11.87/go.mod h1:Qvd5iXTeLhI5PS0XSyqMY99282y+3euapQFxM7jYnpY= -modernc.org/libc v1.11.88/go.mod h1:h3oIVe8dxmTcchcFuCcJ4nAWaoiwzKCdv82MM0oiIdQ= -modernc.org/libc v1.11.98/go.mod h1:ynK5sbjsU77AP+nn61+k+wxUGRx9rOFcIqWYYMaDZ4c= -modernc.org/libc v1.11.101/go.mod h1:wLLYgEiY2D17NbBOEp+mIJJJBGSiy7fLL4ZrGGZ+8jI= -modernc.org/libc v1.12.0/go.mod h1:2MH3DaF/gCU8i/UBiVE1VFRos4o523M7zipmwH8SIgQ= -modernc.org/libc v1.14.1/go.mod h1:npFeGWjmZTjFeWALQLrvklVmAxv4m80jnG3+xI8FdJk= -modernc.org/libc v1.14.2/go.mod h1:MX1GBLnRLNdvmK9azU9LCxZ5lMyhrbEMK8rG3X/Fe34= -modernc.org/libc v1.14.3/go.mod h1:GPIvQVOVPizzlqyRX3l756/3ppsAgg1QgPxjr5Q4agQ= -modernc.org/libc v1.14.5 h1:DAHvwGoVRDZs5iJXnX9RJrgXSsorupCWmJ2ac964Owk= -modernc.org/libc v1.14.5/go.mod h1:2PJHINagVxO4QW/5OQdRrvMYo+bm5ClpUFfyXCYl9ak= -modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/mathutil v1.4.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8= -modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc= -modernc.org/memory v1.0.5 h1:XRch8trV7GgvTec2i7jc33YlUI0RKVDBvZ5eZ5m8y14= -modernc.org/memory v1.0.5/go.mod h1:B7OYswTRnfGg+4tDH1t1OeUNnsy2viGTdME4tzd+IjM= -modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A= -modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sqlite v1.14.6 h1:Jt5P3k80EtDBWaq1beAxnWW+5MdHXbZITujnRS7+zWg= -modernc.org/sqlite v1.14.6/go.mod h1:yiCvMv3HblGmzENNIaNtFhfaNIwcla4u2JQEwJPzfEc= -modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs= -modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= -modernc.org/tcl v1.11.0/go.mod h1:zsTUpbQ+NxQEjOjCUlImDLPv1sG8Ww0qp66ZvyOxCgw= -modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk= -modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -modernc.org/z v1.3.0/go.mod h1:+mvgLH814oDjtATDdT3rs84JnUIpkvAF5B8AVkNlE2g= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo= +modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q= +modernc.org/ccgo/v3 v3.16.14 h1:af6KNtFgsVmnDYrWk3PQCS9XT6BXe7o3ZFJKkIKvXNQ= +modernc.org/libc v1.24.1 h1:uvJSeCKL/AgzBo2yYIPPTy82v21KgGnizcGYfBHaNuM= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/memory v1.6.0 h1:i6mzavxrE9a30whzMfwf7XWVODx2r5OYXvU46cirX7o= +modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= +modernc.org/sqlite v1.25.0 h1:AFweiwPNd/b3BoKnBOfFm+Y260guGMF+0UFk0savqeA= +modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= diff --git a/integration-tests/.tool-versions b/integration-tests/.tool-versions index 8a715d61a2b..563ef48e9a6 100644 --- a/integration-tests/.tool-versions +++ b/integration-tests/.tool-versions @@ -1,4 +1,4 @@ -golang 1.20.5 +golang 1.21.0 k3d 5.4.6 kubectl 1.25.5 nodejs 18.13.0 diff --git a/integration-tests/Makefile b/integration-tests/Makefile index 99bf68c912d..110c119df75 100644 --- a/integration-tests/Makefile +++ b/integration-tests/Makefile @@ -65,6 +65,11 @@ install_gotestfmt: build_test_image: ./scripts/buildTestImage $(tag) $(base_tag) "$(suite)" $(push) +#Build a chainlink docker image for local testing and push to k3d registry +.PHONY: build_push_docker_image +build_push_docker_image: + docker build -f ../core/chainlink.Dockerfile --build-arg COMMIT_SHA=$(git rev-parse HEAD) --build-arg CHAINLINK_USER=chainlink -t localhost:5000/chainlink:develop ../ ; docker push localhost:5000/chainlink:develop + ## Test Runner .PHONY: run run: # Need to set network first in case it's unset. Doesn't matter for the runner @@ -186,3 +191,25 @@ test_benchmark_automation: ## Run the automation benchmark tests .PHONY: test_reorg_automation test_reorg_automation: ## Run the automation reorg tests go test -timeout 300m -v -run ^TestAutomationReorg$$ ./reorg -count=1 | tee automation_reorg_run_`date +"%Y%m%d-%H%M%S"`.log + +# image: the name for the chainlink image being built, example: image=chainlink +# tag: the tag for the chainlink image being built, example: tag=latest +# example usage: make build_docker_image image=chainlink tag=latest +.PHONY: build_docker_image +build_docker_image: + docker build -f ../core/chainlink.Dockerfile --build-arg COMMIT_SHA=$(git rev-parse HEAD) --build-arg CHAINLINK_USER=chainlink -t $(image):$(tag) ../ + + +# image: the name for the chainlink image being built, example: image=chainlink +# tag: the tag for the chainlink image being built, example: tag=latest +# args: the args to pass to the test runner, example: args="--focus @cron -p" +# product: the product to run tests for, example: product=cron +# example usage: make run_test_with_local_image image=chainlink tag=latest-dev product=cron +.PHONY: run_test_with_local_image +run_test_with_local_image: build_docker_image + CHAINLINK_IMAGE=$(image) \ + CHAINLINK_VERSION=$(tag) \ + SELECTED_NETWORKS="SIMULATED,SIMULATED_1,SIMULATED_2" \ + ARGS="$(args)" \ + PRODUCT=$(product) \ + ./scripts/run_product_tests \ No newline at end of file diff --git a/integration-tests/README.md b/integration-tests/README.md index ddd07f8fb7b..3a2a59e0fbf 100644 --- a/integration-tests/README.md +++ b/integration-tests/README.md @@ -52,6 +52,35 @@ increase minikube's resources significantly, or get a more substantial cluster. This is necessary to deploy ephemeral testing environments, which include external adapters, chainlink nodes and their DBs, as well as some simulated blockchains, all depending on the types of tests and networks being used. +### Setup Kubernetes Cluster using k3d + +[k3d](https://k3d.io/) is a lightweight wrapper to run k3s (a lightweight kubernetes distribution) in docker. It's a great way to run a local kubernetes cluster for testing. +To create a new cluster you can run: + +```sh +k3d cluster create test-k8s --registry-create test-k8s-registry:0.0.0.0:5000 +``` + +This will create a cluster with a local registry running on port 5000. You can then use the registry to push images to and pull images from. + +To build and push chainlink image to the registry you can run: + +```sh +make build_push_docker_image +```` + +To stop the cluster you can run: + +```sh +k3d cluster stop test-k8s +``` + +To start an existing cluster you can run: + +```sh +k3d cluster start test-k8s +``` + ## Configure Environment See the [example.env](./example.env) file and use it as a template for your own `.env` file. This allows you to configure general settings like what name to associate with your tests, and which Chainlink version to use when running them. @@ -129,9 +158,25 @@ make test_soak_keeper Soak tests will pull all their network information from the env vars that you can set in the `.env` file. *Reminder to run `source .env` for changes to take effect.* -To configure specific parameters of how the soak tests run (e.g. test length, number of contracts), see the [./soak/tests](./soak/tests/) test specifications. +To configure specific parameters of how the soak tests run (e.g. test length, number of contracts), adjust the values in your `.env` file, you can use `example.env` as reference + + +#### Running with custom image +On each PR navigate to the `integration-tests` job, here you will find the images for both chainlink-tests and core. In your env file you need to replace: + +`ENV_JOB_IMAGE="image-location/chainlink-tests:"` + +`CHAINLINK_IMAGE="public.ecr.aws/chainlink/chainlink"` + +`export CHAINLINK_VERSION=""` + +After all the env vars are exported, run the tests. This will kick off a remote runner that will be in charge of running the tests. Locally the test should pass quickly and a namespace will be displayed in the output e.g +`INF Creating new namespace Namespace=soak-ocr-goerli-testnet-957b2` -See the [soak_runner](./soak/soak_runner_test.go) for more info on how the tests are run and configured. +#### Logs and monitoring +- Pod logs: `kubectl logs -n soak-ocr-goerli-testnet-957b2 -c node -f chainlink-0-1` +- Remote runner logs: `kubectl logs -n soak-ocr-goerli-testnet-957b2 -f remote-runner-cs2as` +- Navigate to Grafana chainlink testing insights for all logs ### Performance @@ -143,7 +188,9 @@ make test_perf ## Common Issues -When upgrading to a new version, it's possible the helm charts have changed. There are a myriad of errors that can result from this, so it's best to just try running `helm repo update` when encountering an error you're unsure of. +- When upgrading to a new version, it's possible the helm charts have changed. There are a myriad of errors that can result from this, so it's best to just try running `helm repo update` when encountering an error you're unsure of. +- Docker failing to pull image, make sure you are referencing the correct ECR repo in AWS since develop images are not pushed to the public one. + - If tests hang for some time this is usually the case, so make sure to check the logs each time tests are failing to start

diff --git a/integration-tests/actions/actions.go b/integration-tests/actions/actions.go index 9ca2e341233..ffb71cb7424 100644 --- a/integration-tests/actions/actions.go +++ b/integration-tests/actions/actions.go @@ -32,7 +32,7 @@ var ContractDeploymentInterval = 200 // FundChainlinkNodes will fund all of the provided Chainlink nodes with a set amount of native currency func FundChainlinkNodes( - nodes []*client.Chainlink, + nodes []*client.ChainlinkK8sClient, client blockchain.EVMClient, amount *big.Float, ) error { @@ -41,7 +41,13 @@ func FundChainlinkNodes( if err != nil { return err } - gasEstimates, err := client.EstimateGas(ethereum.CallMsg{}) + recipient := common.HexToAddress(toAddress) + msg := ethereum.CallMsg{ + From: common.HexToAddress(client.GetDefaultWallet().Address()), + To: &recipient, + Value: utils.EtherToWei(amount), + } + gasEstimates, err := client.EstimateGas(msg) if err != nil { return err } @@ -55,7 +61,7 @@ func FundChainlinkNodes( // FundChainlinkNodesAddress will fund all of the provided Chainlink nodes address at given index with a set amount of native currency func FundChainlinkNodesAddress( - nodes []*client.Chainlink, + nodes []*client.ChainlinkK8sClient, client blockchain.EVMClient, amount *big.Float, keyIndex int, @@ -79,7 +85,7 @@ func FundChainlinkNodesAddress( // FundChainlinkNodesAddress will fund all of the provided Chainlink nodes addresses with a set amount of native currency func FundChainlinkNodesAddresses( - nodes []*client.Chainlink, + nodes []*client.ChainlinkClient, client blockchain.EVMClient, amount *big.Float, ) error { @@ -104,7 +110,7 @@ func FundChainlinkNodesAddresses( // FundChainlinkNodes will fund all of the provided Chainlink nodes with a set amount of native currency func FundChainlinkNodesLink( - nodes []*client.Chainlink, + nodes []*client.ChainlinkK8sClient, blockchain blockchain.EVMClient, linkToken contracts.LinkToken, linkAmount *big.Int, @@ -123,7 +129,7 @@ func FundChainlinkNodesLink( } // ChainlinkNodeAddresses will return all the on-chain wallet addresses for a set of Chainlink nodes -func ChainlinkNodeAddresses(nodes []*client.Chainlink) ([]common.Address, error) { +func ChainlinkNodeAddresses(nodes []*client.ChainlinkK8sClient) ([]common.Address, error) { addresses := make([]common.Address, 0) for _, node := range nodes { primaryAddress, err := node.PrimaryEthAddress() @@ -136,7 +142,7 @@ func ChainlinkNodeAddresses(nodes []*client.Chainlink) ([]common.Address, error) } // ChainlinkNodeAddressesAtIndex will return all the on-chain wallet addresses for a set of Chainlink nodes -func ChainlinkNodeAddressesAtIndex(nodes []*client.Chainlink, keyIndex int) ([]common.Address, error) { +func ChainlinkNodeAddressesAtIndex(nodes []*client.ChainlinkK8sClient, keyIndex int) ([]common.Address, error) { addresses := make([]common.Address, 0) for _, node := range nodes { nodeAddresses, err := node.EthAddresses() @@ -149,7 +155,7 @@ func ChainlinkNodeAddressesAtIndex(nodes []*client.Chainlink, keyIndex int) ([]c } // SetChainlinkAPIPageSize specifies the page size from the Chainlink API, useful for high volume testing -func SetChainlinkAPIPageSize(nodes []*client.Chainlink, pageSize int) { +func SetChainlinkAPIPageSize(nodes []*client.ChainlinkK8sClient, pageSize int) { for _, n := range nodes { n.SetPageSize(pageSize) } @@ -192,7 +198,7 @@ func EncodeOnChainVRFProvingKey(vrfKey client.VRFKey) ([2]*big.Int, error) { // GetMockserverInitializerDataForOTPE creates mocked weiwatchers data needed for otpe func GetMockserverInitializerDataForOTPE( OCRInstances []contracts.OffchainAggregator, - chainlinkNodes []*client.Chainlink, + chainlinkNodes []*client.ChainlinkK8sClient, ) (interface{}, error) { var contractsInfo []ctfClient.ContractInfoJSON @@ -240,7 +246,7 @@ func TeardownSuite( t *testing.T, env *environment.Environment, logsFolderPath string, - chainlinkNodes []*client.Chainlink, + chainlinkNodes []*client.ChainlinkK8sClient, optionalTestReporter testreporters.TestReporter, // Optionally pass in a test reporter to log further metrics failingLogLevel zapcore.Level, // Examines logs after the test, and fails the test if any Chainlink logs are found at or above provided level clients ...blockchain.EVMClient, @@ -284,14 +290,14 @@ func TeardownSuite( // soak tests func TeardownRemoteSuite( t *testing.T, - env *environment.Environment, - chainlinkNodes []*client.Chainlink, + namespace string, + chainlinkNodes []*client.ChainlinkK8sClient, optionalTestReporter testreporters.TestReporter, // Optionally pass in a test reporter to log further metrics client blockchain.EVMClient, ) error { l := utils.GetTestLogger(t) var err error - if err = testreporters.SendReport(t, env, "./", optionalTestReporter); err != nil { + if err = testreporters.SendReport(t, namespace, "./", optionalTestReporter); err != nil { l.Warn().Err(err).Msg("Error writing test report") } // Delete all jobs to stop depleting the funds @@ -301,15 +307,18 @@ func TeardownRemoteSuite( } if err = returnFunds(chainlinkNodes, client); err != nil { - l.Error().Err(err).Str("Namespace", env.Cfg.Namespace). + l.Error().Err(err).Str("Namespace", namespace). Msg("Error attempting to return funds from chainlink nodes to network's default wallet. " + "Environment is left running so you can try manually!") } return err } -func DeleteAllJobs(chainlinkNodes []*client.Chainlink) error { +func DeleteAllJobs(chainlinkNodes []*client.ChainlinkK8sClient) error { for _, node := range chainlinkNodes { + if node == nil { + return fmt.Errorf("found a nil chainlink node in the list of chainlink nodes while tearing down: %v", chainlinkNodes) + } jobs, _, err := node.ReadJobs() if err != nil { return errors.Wrap(err, "error reading jobs from chainlink node") @@ -329,9 +338,9 @@ func DeleteAllJobs(chainlinkNodes []*client.Chainlink) error { } // Returns all the funds from the chainlink nodes to the networks default address -func returnFunds(chainlinkNodes []*client.Chainlink, blockchainClient blockchain.EVMClient) error { +func returnFunds(chainlinkNodes []*client.ChainlinkK8sClient, blockchainClient blockchain.EVMClient) error { if blockchainClient == nil { - log.Warn().Msg("No blockchain client found, unable to return funds from chainlink nodes.") + return errors.New("blockchain client is nil, unable to return funds from chainlink nodes") } log.Info().Msg("Attempting to return Chainlink node funds to default network wallets") if blockchainClient.NetworkSimulated() { @@ -391,7 +400,7 @@ func EncodeOnChainExternalJobID(jobID uuid.UUID) [32]byte { func UpgradeChainlinkNodeVersions( testEnvironment *environment.Environment, newImage, newVersion string, - nodes ...*client.Chainlink, + nodes ...*client.ChainlinkK8sClient, ) error { if newImage == "" && newVersion == "" { return errors.New("unable to upgrade node version, found empty image and version, must provide either a new image or a new version") @@ -407,3 +416,19 @@ func UpgradeChainlinkNodeVersions( } return client.ReconnectChainlinkNodes(testEnvironment, nodes) } + +func DeployLINKToken(cd contracts.ContractDeployer) (contracts.LinkToken, error) { + linkToken, err := cd.DeployLinkTokenContract() + if err != nil { + return nil, err + } + return linkToken, err +} + +func DeployMockETHLinkFeed(cd contracts.ContractDeployer, answer *big.Int) (contracts.MockETHLINKFeed, error) { + mockETHLINKFeed, err := cd.DeployMockETHLINKFeed(answer) + if err != nil { + return nil, err + } + return mockETHLINKFeed, err +} diff --git a/integration-tests/actions/automation_ocr_helpers.go b/integration-tests/actions/automation_ocr_helpers.go index 350943dbb6a..4561bc1764a 100644 --- a/integration-tests/actions/automation_ocr_helpers.go +++ b/integration-tests/actions/automation_ocr_helpers.go @@ -11,18 +11,22 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/lib/pq" + ocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" "github.com/stretchr/testify/require" "gopkg.in/guregu/null.v4" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils" - "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" - "github.com/smartcontractkit/ocr2keepers/pkg/config" + ocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + ocr2keepers20config "github.com/smartcontractkit/ocr2keepers/pkg/v2/config" + ocr2keepers30config "github.com/smartcontractkit/ocr2keepers/pkg/v3/config" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/store/models" @@ -30,7 +34,7 @@ import ( func BuildAutoOCR2ConfigVars( t *testing.T, - chainlinkNodes []*client.Chainlink, + chainlinkNodes []*client.ChainlinkK8sClient, registryConfig contracts.KeeperRegistrySettings, registrar string, deltaStage time.Duration, @@ -40,7 +44,7 @@ func BuildAutoOCR2ConfigVars( func BuildAutoOCR2ConfigVarsWithKeyIndex( t *testing.T, - chainlinkNodes []*client.Chainlink, + chainlinkNodes []*client.ChainlinkK8sClient, registryConfig contracts.KeeperRegistrySettings, registrar string, deltaStage time.Duration, @@ -52,40 +56,85 @@ func BuildAutoOCR2ConfigVarsWithKeyIndex( return contracts.OCRv2Config{}, err } - offC, err := json.Marshal(config.OffchainConfig{ - TargetProbability: "0.999", - TargetInRounds: 1, - PerformLockoutWindow: 3600000, // Intentionally set to be higher than in prod for testing purpose - GasLimitPerReport: 5_300_000, - GasOverheadPerUpkeep: 300_000, - SamplingJobDuration: 3000, - MinConfirmations: 0, - MaxUpkeepBatchSize: 1, - }) - if err != nil { - return contracts.OCRv2Config{}, err - } + var offC []byte + var signerOnchainPublicKeys []types.OnchainPublicKey + var transmitterAccounts []types.Account + var f uint8 + var offchainConfigVersion uint64 + var offchainConfig []byte - signerOnchainPublicKeys, transmitterAccounts, f, _, offchainConfigVersion, offchainConfig, err := confighelper.ContractSetConfigArgsForTests( - 10*time.Second, // deltaProgress time.Duration, - 15*time.Second, // deltaResend time.Duration, - 3000*time.Millisecond, // deltaRound time.Duration, - 200*time.Millisecond, // deltaGrace time.Duration, - deltaStage, // deltaStage time.Duration, - 24, // rMax uint8, - S, // s []int, - oracleIdentities, // oracles []OracleIdentityExtra, - offC, // reportingPluginConfig []byte, - 20*time.Millisecond, // maxDurationQuery time.Duration, - 20*time.Millisecond, // maxDurationObservation time.Duration, - 1200*time.Millisecond, // maxDurationReport time.Duration, - 20*time.Millisecond, // maxDurationShouldAcceptFinalizedReport time.Duration, - 20*time.Millisecond, // maxDurationShouldTransmitAcceptedReport time.Duration, - 1, // f int, - nil, // onchainConfig []byte, - ) - if err != nil { - return contracts.OCRv2Config{}, err + if registryConfig.RegistryVersion == ethereum.RegistryVersion_2_1 { + offC, err = json.Marshal(ocr2keepers30config.OffchainConfig{ + TargetProbability: "0.999", + TargetInRounds: 1, + PerformLockoutWindow: 3600000, // Intentionally set to be higher than in prod for testing purpose + GasLimitPerReport: 5_300_000, + GasOverheadPerUpkeep: 300_000, + MinConfirmations: 0, + MaxUpkeepBatchSize: 1, + }) + if err != nil { + return contracts.OCRv2Config{}, err + } + + signerOnchainPublicKeys, transmitterAccounts, f, _, offchainConfigVersion, offchainConfig, err = ocr3.ContractSetConfigArgsForTests( + 10*time.Second, // deltaProgress time.Duration, + 15*time.Second, // deltaResend time.Duration, + 500*time.Millisecond, // deltaInitial time.Duration, + 1000*time.Millisecond, // deltaRound time.Duration, + 200*time.Millisecond, // deltaGrace time.Duration, + 300*time.Millisecond, // deltaCertifiedCommitRequest time.Duration + deltaStage, // deltaStage time.Duration, + 24, // rMax uint64, + S, // s []int, + oracleIdentities, // oracles []OracleIdentityExtra, + offC, // reportingPluginConfig []byte, + 20*time.Millisecond, // maxDurationQuery time.Duration, + 20*time.Millisecond, // maxDurationObservation time.Duration, // good to here + 1200*time.Millisecond, // maxDurationShouldAcceptAttestedReport time.Duration, + 20*time.Millisecond, // maxDurationShouldTransmitAcceptedReport time.Duration, + 1, // f int, + nil, // onchainConfig []byte, + ) + if err != nil { + return contracts.OCRv2Config{}, err + } + } else { + offC, err = json.Marshal(ocr2keepers20config.OffchainConfig{ + TargetProbability: "0.999", + TargetInRounds: 1, + PerformLockoutWindow: 3600000, // Intentionally set to be higher than in prod for testing purpose + GasLimitPerReport: 5_300_000, + GasOverheadPerUpkeep: 300_000, + SamplingJobDuration: 3000, + MinConfirmations: 0, + MaxUpkeepBatchSize: 1, + }) + if err != nil { + return contracts.OCRv2Config{}, err + } + + signerOnchainPublicKeys, transmitterAccounts, f, _, offchainConfigVersion, offchainConfig, err = ocr2.ContractSetConfigArgsForTests( + 10*time.Second, // deltaProgress time.Duration, + 15*time.Second, // deltaResend time.Duration, + 3000*time.Millisecond, // deltaRound time.Duration, + 200*time.Millisecond, // deltaGrace time.Duration, + deltaStage, // deltaStage time.Duration, + 24, // rMax uint8, + S, // s []int, + oracleIdentities, // oracles []OracleIdentityExtra, + offC, // reportingPluginConfig []byte, + 20*time.Millisecond, // maxDurationQuery time.Duration, + 20*time.Millisecond, // maxDurationObservation time.Duration, + 1200*time.Millisecond, // maxDurationReport time.Duration, + 20*time.Millisecond, // maxDurationShouldAcceptFinalizedReport time.Duration, + 20*time.Millisecond, // maxDurationShouldTransmitAcceptedReport time.Duration, + 1, // f int, + nil, // onchainConfig []byte, + ) + if err != nil { + return contracts.OCRv2Config{}, err + } } var signers []common.Address @@ -119,18 +168,27 @@ func BuildAutoOCR2ConfigVarsWithKeyIndex( // CreateOCRKeeperJobs bootstraps the first node and to the other nodes sends ocr jobs func CreateOCRKeeperJobs( t *testing.T, - chainlinkNodes []*client.Chainlink, + chainlinkNodes []*client.ChainlinkK8sClient, registryAddr string, chainID int64, keyIndex int, + registryVersion ethereum.KeeperRegistryVersion, ) { l := utils.GetTestLogger(t) bootstrapNode := chainlinkNodes[0] - bootstrapNode.InternalIP() bootstrapP2PIds, err := bootstrapNode.MustReadP2PKeys() require.NoError(t, err, "Shouldn't fail reading P2P keys from bootstrap node") bootstrapP2PId := bootstrapP2PIds.Data[0].Attributes.PeerID + var contractVersion string + if registryVersion == ethereum.RegistryVersion_2_1 { + contractVersion = "v2.1" + } else if registryVersion == ethereum.RegistryVersion_2_0 { + contractVersion = "v2.0" + } else { + require.FailNow(t, "v2.0 and v2.1 are the only supported versions") + } + bootstrapSpec := &client.OCR2TaskJobSpec{ Name: "ocr2 bootstrap node " + registryAddr, JobType: "bootstrap", @@ -171,6 +229,7 @@ func CreateOCRKeeperJobs( }, PluginConfig: map[string]interface{}{ "mercuryCredentialName": "\"cred1\"", + "contractVersion": "\"" + contractVersion + "\"", }, ContractConfigTrackerPollInterval: *models.NewInterval(time.Second * 15), ContractID: registryAddr, // registryAddr @@ -207,24 +266,14 @@ func DeployAutoOCRRegistryAndRegistrar( return registry, registrar } -func DeployConsumers( - t *testing.T, - registry contracts.KeeperRegistry, - registrar contracts.KeeperRegistrar, - linkToken contracts.LinkToken, - contractDeployer contracts.ContractDeployer, - client blockchain.EVMClient, - numberOfUpkeeps int, - linkFundsForEachUpkeep *big.Int, - upkeepGasLimit uint32, -) ([]contracts.KeeperConsumer, []*big.Int) { - upkeeps := DeployKeeperConsumers(t, contractDeployer, client, numberOfUpkeeps) +func DeployConsumers(t *testing.T, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, linkToken contracts.LinkToken, contractDeployer contracts.ContractDeployer, client blockchain.EVMClient, numberOfUpkeeps int, linkFundsForEachUpkeep *big.Int, upkeepGasLimit uint32, isLogTrigger bool) ([]contracts.KeeperConsumer, []*big.Int) { + upkeeps := DeployKeeperConsumers(t, contractDeployer, client, numberOfUpkeeps, isLogTrigger) var upkeepsAddresses []string for _, upkeep := range upkeeps { upkeepsAddresses = append(upkeepsAddresses, upkeep.Address()) } upkeepIds := RegisterUpkeepContracts( - t, linkToken, linkFundsForEachUpkeep, client, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, + t, linkToken, linkFundsForEachUpkeep, client, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, isLogTrigger, ) return upkeeps, upkeepIds } @@ -251,9 +300,7 @@ func DeployPerformanceConsumers( for _, upkeep := range upkeeps { upkeepsAddresses = append(upkeepsAddresses, upkeep.Address()) } - upkeepIds := RegisterUpkeepContracts( - t, linkToken, linkFundsForEachUpkeep, client, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, - ) + upkeepIds := RegisterUpkeepContracts(t, linkToken, linkFundsForEachUpkeep, client, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, false) return upkeeps, upkeepIds } @@ -274,9 +321,7 @@ func DeployPerformDataCheckerConsumers( for _, upkeep := range upkeeps { upkeepsAddresses = append(upkeepsAddresses, upkeep.Address()) } - upkeepIds := RegisterUpkeepContracts( - t, linkToken, linkFundsForEachUpkeep, client, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, - ) + upkeepIds := RegisterUpkeepContracts(t, linkToken, linkFundsForEachUpkeep, client, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, false) return upkeeps, upkeepIds } diff --git a/integration-tests/actions/keeper_helpers.go b/integration-tests/actions/keeper_helpers.go index f83e2dd6dd4..98c9a51e1c8 100644 --- a/integration-tests/actions/keeper_helpers.go +++ b/integration-tests/actions/keeper_helpers.go @@ -24,7 +24,7 @@ var ZeroAddress = common.Address{} func CreateKeeperJobs( t *testing.T, - chainlinkNodes []*client.Chainlink, + chainlinkNodes []*client.ChainlinkK8sClient, keeperRegistry contracts.KeeperRegistry, ocrConfig contracts.OCRv2Config, ) { @@ -57,7 +57,7 @@ func CreateKeeperJobs( func CreateKeeperJobsWithKeyIndex( t *testing.T, - chainlinkNodes []*client.Chainlink, + chainlinkNodes []*client.ChainlinkK8sClient, keeperRegistry contracts.KeeperRegistry, keyIndex int, ocrConfig contracts.OCRv2Config, @@ -89,7 +89,7 @@ func CreateKeeperJobsWithKeyIndex( } } -func DeleteKeeperJobsWithId(t *testing.T, chainlinkNodes []*client.Chainlink, id int) { +func DeleteKeeperJobsWithId(t *testing.T, chainlinkNodes []*client.ChainlinkK8sClient, id int) { for _, chainlinkNode := range chainlinkNodes { err := chainlinkNode.MustDeleteJob(strconv.Itoa(id)) require.NoError(t, err, "Deleting KeeperV2 Job shouldn't fail") @@ -142,14 +142,12 @@ func DeployKeeperContracts( } registrar := DeployKeeperRegistrar(t, registryVersion, linkToken, registrarSettings, contractDeployer, client, registry) - upkeeps := DeployKeeperConsumers(t, contractDeployer, client, numberOfUpkeeps) + upkeeps := DeployKeeperConsumers(t, contractDeployer, client, numberOfUpkeeps, false) var upkeepsAddresses []string for _, upkeep := range upkeeps { upkeepsAddresses = append(upkeepsAddresses, upkeep.Address()) } - upkeepIds := RegisterUpkeepContracts( - t, linkToken, linkFundsForEachUpkeep, client, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, - ) + upkeepIds := RegisterUpkeepContracts(t, linkToken, linkFundsForEachUpkeep, client, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, false) err = client.WaitForEvents() require.NoError(t, err, "Error waiting for events") @@ -212,9 +210,7 @@ func DeployPerformanceKeeperContracts( upkeepsAddresses = append(upkeepsAddresses, upkeep.Address()) } - upkeepIds := RegisterUpkeepContracts( - t, linkToken, linkFundsForEachUpkeep, client, upkeepGasLimit, registry, registrar, numberOfContracts, upkeepsAddresses, - ) + upkeepIds := RegisterUpkeepContracts(t, linkToken, linkFundsForEachUpkeep, client, upkeepGasLimit, registry, registrar, numberOfContracts, upkeepsAddresses, false) return registry, registrar, upkeeps, upkeepIds } @@ -270,9 +266,7 @@ func DeployPerformDataCheckerContracts( upkeepsAddresses = append(upkeepsAddresses, upkeep.Address()) } - upkeepIds := RegisterUpkeepContracts( - t, linkToken, linkFundsForEachUpkeep, client, upkeepGasLimit, registry, registrar, numberOfContracts, upkeepsAddresses, - ) + upkeepIds := RegisterUpkeepContracts(t, linkToken, linkFundsForEachUpkeep, client, upkeepGasLimit, registry, registrar, numberOfContracts, upkeepsAddresses, false) return registry, registrar, upkeeps, upkeepIds } @@ -330,38 +324,17 @@ func DeployUpkeepTranscoder( return transcoder } -func RegisterUpkeepContracts( - t *testing.T, - linkToken contracts.LinkToken, - linkFunds *big.Int, - client blockchain.EVMClient, - upkeepGasLimit uint32, - registry contracts.KeeperRegistry, - registrar contracts.KeeperRegistrar, - numberOfContracts int, - upkeepAddresses []string, -) []*big.Int { +func RegisterUpkeepContracts(t *testing.T, linkToken contracts.LinkToken, linkFunds *big.Int, client blockchain.EVMClient, upkeepGasLimit uint32, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, numberOfContracts int, upkeepAddresses []string, isLogTrigger bool) []*big.Int { checkData := make([][]byte, 0) for i := 0; i < numberOfContracts; i++ { checkData = append(checkData, []byte("0")) } return RegisterUpkeepContractsWithCheckData( t, linkToken, linkFunds, client, upkeepGasLimit, registry, registrar, - numberOfContracts, upkeepAddresses, checkData) + numberOfContracts, upkeepAddresses, checkData, isLogTrigger) } -func RegisterUpkeepContractsWithCheckData( - t *testing.T, - linkToken contracts.LinkToken, - linkFunds *big.Int, - client blockchain.EVMClient, - upkeepGasLimit uint32, - registry contracts.KeeperRegistry, - registrar contracts.KeeperRegistrar, - numberOfContracts int, - upkeepAddresses []string, - checkData [][]byte, -) []*big.Int { +func RegisterUpkeepContractsWithCheckData(t *testing.T, linkToken contracts.LinkToken, linkFunds *big.Int, client blockchain.EVMClient, upkeepGasLimit uint32, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, numberOfContracts int, upkeepAddresses []string, checkData [][]byte, isLogTrigger bool) []*big.Int { l := utils.GetTestLogger(t) registrationTxHashes := make([]common.Hash, 0) upkeepIds := make([]*big.Int, 0) @@ -376,6 +349,7 @@ func RegisterUpkeepContractsWithCheckData( linkFunds, 0, client.GetDefaultWallet().Address(), + isLogTrigger, ) require.NoError(t, err, "Encoding the register request shouldn't fail") tx, err := linkToken.TransferAndCall(registrar.Address(), linkFunds, req) @@ -419,19 +393,22 @@ func RegisterUpkeepContractsWithCheckData( return upkeepIds } -func DeployKeeperConsumers( - t *testing.T, - contractDeployer contracts.ContractDeployer, - client blockchain.EVMClient, - numberOfContracts int, -) []contracts.KeeperConsumer { +func DeployKeeperConsumers(t *testing.T, contractDeployer contracts.ContractDeployer, client blockchain.EVMClient, numberOfContracts int, isLogTrigger bool) []contracts.KeeperConsumer { l := utils.GetTestLogger(t) keeperConsumerContracts := make([]contracts.KeeperConsumer, 0) for contractCount := 0; contractCount < numberOfContracts; contractCount++ { // Deploy consumer - keeperConsumerInstance, err := contractDeployer.DeployKeeperConsumer(big.NewInt(5)) - require.NoError(t, err, "Deploying KeeperConsumer instance %d shouldn't fail", contractCount+1) + var keeperConsumerInstance contracts.KeeperConsumer + var err error + + if isLogTrigger { + keeperConsumerInstance, err = contractDeployer.DeployAutomationLogTriggerConsumer(big.NewInt(1000)) // 1000 block test range + } else { + keeperConsumerInstance, err = contractDeployer.DeployKeeperConsumer(big.NewInt(5)) + } + + require.NoError(t, err, "Deploying Consumer instance %d shouldn't fail", contractCount+1) keeperConsumerContracts = append(keeperConsumerContracts, keeperConsumerInstance) l.Debug(). Str("Contract Address", keeperConsumerInstance.Address()). @@ -439,7 +416,7 @@ func DeployKeeperConsumers( Int("Out Of", numberOfContracts). Msg("Deployed Keeper Consumer Contract") if (contractCount+1)%ContractDeploymentInterval == 0 { // For large amounts of contract deployments, space things out some - err = client.WaitForEvents() + err := client.WaitForEvents() require.NoError(t, err, "Failed to wait for KeeperConsumer deployments") } } @@ -600,15 +577,14 @@ func RegisterNewUpkeeps( upkeepGasLimit uint32, numberOfNewUpkeeps int, ) ([]contracts.KeeperConsumer, []*big.Int) { - newlyDeployedUpkeeps := DeployKeeperConsumers(t, contractDeployer, client, numberOfNewUpkeeps) + newlyDeployedUpkeeps := DeployKeeperConsumers(t, contractDeployer, client, numberOfNewUpkeeps, false) var addressesOfNewUpkeeps []string for _, upkeep := range newlyDeployedUpkeeps { addressesOfNewUpkeeps = append(addressesOfNewUpkeeps, upkeep.Address()) } - newUpkeepIDs := RegisterUpkeepContracts(t, linkToken, big.NewInt(9e18), client, upkeepGasLimit, - registry, registrar, numberOfNewUpkeeps, addressesOfNewUpkeeps) + newUpkeepIDs := RegisterUpkeepContracts(t, linkToken, big.NewInt(9e18), client, upkeepGasLimit, registry, registrar, numberOfNewUpkeeps, addressesOfNewUpkeeps, false) return newlyDeployedUpkeeps, newUpkeepIDs } diff --git a/integration-tests/actions/keeper_helpers_local.go b/integration-tests/actions/keeper_helpers_local.go new file mode 100644 index 00000000000..6fc7ef43dbe --- /dev/null +++ b/integration-tests/actions/keeper_helpers_local.go @@ -0,0 +1,58 @@ +package actions + +import ( + "fmt" + + "github.com/rs/zerolog/log" + "github.com/smartcontractkit/chainlink/integration-tests/client" + "github.com/smartcontractkit/chainlink/integration-tests/contracts" +) + +func CreateKeeperJobsLocal( + chainlinkNodes []*client.ChainlinkClient, + keeperRegistry contracts.KeeperRegistry, + ocrConfig contracts.OCRv2Config, +) ([]*client.Job, error) { + // Send keeper jobs to registry and chainlink nodes + primaryNode := chainlinkNodes[0] + primaryNodeAddress, err := primaryNode.PrimaryEthAddress() + if err != nil { + log.Error().Err(err).Msg("Reading ETH Keys from Chainlink Client shouldn't fail") + return nil, err + } + nodeAddresses, err := ChainlinkNodeAddressesLocal(chainlinkNodes) + if err != nil { + log.Error().Err(err).Msg("Retrieving on-chain wallet addresses for chainlink nodes shouldn't fail") + return nil, err + } + nodeAddressesStr, payees := make([]string, 0), make([]string, 0) + for _, cla := range nodeAddresses { + nodeAddressesStr = append(nodeAddressesStr, cla.Hex()) + payees = append(payees, primaryNodeAddress) + } + err = keeperRegistry.SetKeepers(nodeAddressesStr, payees, ocrConfig) + if err != nil { + log.Error().Err(err).Msg("Setting keepers in the registry shouldn't fail") + return nil, err + } + jobs := []*client.Job{} + for _, chainlinkNode := range chainlinkNodes { + chainlinkNodeAddress, err := chainlinkNode.PrimaryEthAddress() + if err != nil { + log.Error().Err(err).Msg("Error retrieving chainlink node address") + return nil, err + } + job, err := chainlinkNode.MustCreateJob(&client.KeeperJobSpec{ + Name: fmt.Sprintf("keeper-test-%s", keeperRegistry.Address()), + ContractAddress: keeperRegistry.Address(), + FromAddress: chainlinkNodeAddress, + MinIncomingConfirmations: 1, + }) + if err != nil { + log.Error().Err(err).Msg("Creating KeeperV2 Job shouldn't fail") + return nil, err + } + jobs = append(jobs, job) + } + return jobs, nil +} diff --git a/integration-tests/actions/ocr2_helpers.go b/integration-tests/actions/ocr2_helpers.go index 6c7d054be00..3c37233a0d3 100644 --- a/integration-tests/actions/ocr2_helpers.go +++ b/integration-tests/actions/ocr2_helpers.go @@ -101,7 +101,7 @@ func ConfigureOCRv2AggregatorContracts( } // BuildMedianOCR2Config builds a default OCRv2 config for the given chainlink nodes for a standard median aggregation job -func BuildMedianOCR2Config(workerNodes []*client.Chainlink) (*contracts.OCRv2Config, error) { +func BuildMedianOCR2Config(workerNodes []*client.ChainlinkK8sClient) (*contracts.OCRv2Config, error) { S, oracleIdentities, err := GetOracleIdentities(workerNodes) if err != nil { return nil, err @@ -157,13 +157,13 @@ func BuildMedianOCR2Config(workerNodes []*client.Chainlink) (*contracts.OCRv2Con } // GetOracleIdentities retrieves all chainlink nodes' OCR2 config identities with defaul key index -func GetOracleIdentities(chainlinkNodes []*client.Chainlink) ([]int, []confighelper.OracleIdentityExtra, error) { +func GetOracleIdentities(chainlinkNodes []*client.ChainlinkK8sClient) ([]int, []confighelper.OracleIdentityExtra, error) { return GetOracleIdentitiesWithKeyIndex(chainlinkNodes, 0) } // GetOracleIdentitiesWithKeyIndex retrieves all chainlink nodes' OCR2 config identities by key index func GetOracleIdentitiesWithKeyIndex( - chainlinkNodes []*client.Chainlink, + chainlinkNodes []*client.ChainlinkK8sClient, keyIndex int, ) ([]int, []confighelper.OracleIdentityExtra, error) { S := make([]int, len(chainlinkNodes)) @@ -203,7 +203,7 @@ func GetOracleIdentitiesWithKeyIndex( offchainPkBytesFixed := [ed25519.PublicKeySize]byte{} n := copy(offchainPkBytesFixed[:], offchainPkBytes) if n != ed25519.PublicKeySize { - return fmt.Errorf("Wrong number of elements copied") + return fmt.Errorf("wrong number of elements copied") } configPkBytes, err := hex.DecodeString(strings.TrimPrefix(ocr2Config.ConfigPublicKey, "ocr2cfg_evm_")) @@ -214,7 +214,7 @@ func GetOracleIdentitiesWithKeyIndex( configPkBytesFixed := [ed25519.PublicKeySize]byte{} n = copy(configPkBytesFixed[:], configPkBytes) if n != ed25519.PublicKeySize { - return fmt.Errorf("Wrong number of elements copied") + return fmt.Errorf("wrong number of elements copied") } onchainPkBytes, err := hex.DecodeString(strings.TrimPrefix(ocr2Config.OnChainPublicKey, "ocr2on_evm_")) @@ -251,8 +251,8 @@ func GetOracleIdentitiesWithKeyIndex( // read from different adapters, to be used in combination with SetAdapterResponses func CreateOCRv2Jobs( ocrInstances []contracts.OffchainAggregatorV2, - bootstrapNode *client.Chainlink, - workerChainlinkNodes []*client.Chainlink, + bootstrapNode *client.ChainlinkK8sClient, + workerChainlinkNodes []*client.ChainlinkK8sClient, mockserver *ctfClient.MockserverClient, mockServerPath string, // Path on the mock server for the Chainlink nodes to query mockServerValue int, // Value to get from the mock server when querying the path diff --git a/integration-tests/actions/ocr2_helpers_local.go b/integration-tests/actions/ocr2_helpers_local.go new file mode 100644 index 00000000000..c1e863561da --- /dev/null +++ b/integration-tests/actions/ocr2_helpers_local.go @@ -0,0 +1,269 @@ +package actions + +import ( + "crypto/ed25519" + "encoding/hex" + "fmt" + "github.com/ethereum/go-ethereum/common" + "github.com/google/uuid" + "github.com/lib/pq" + "github.com/rs/zerolog/log" + ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" + "github.com/smartcontractkit/chainlink/integration-tests/client" + "github.com/smartcontractkit/chainlink/integration-tests/contracts" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + "github.com/smartcontractkit/chainlink/v2/core/store/models" + "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" + "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "golang.org/x/sync/errgroup" + "gopkg.in/guregu/null.v4" + "strings" + "time" +) + +func CreateOCRv2JobsLocal( + ocrInstances []contracts.OffchainAggregatorV2, + bootstrapNode *client.ChainlinkClient, + workerChainlinkNodes []*client.ChainlinkClient, + mockserver *ctfClient.MockserverClient, + mockServerPath string, // Path on the mock server for the Chainlink nodes to query + mockServerValue int, // Value to get from the mock server when querying the path + chainId uint64, // EVM chain ID + forwardingAllowed bool, +) error { + // Collect P2P ID + bootstrapP2PIds, err := bootstrapNode.MustReadP2PKeys() + if err != nil { + return err + } + p2pV2Bootstrapper := fmt.Sprintf("%s@%s:%d", bootstrapP2PIds.Data[0].Attributes.PeerID, bootstrapNode.InternalIP(), 6690) + // Set the value for the jobs to report on + err = mockserver.SetValuePath(mockServerPath, mockServerValue) + if err != nil { + return err + } + // Set the juelsPerFeeCoinSource config value + err = mockserver.SetValuePath(fmt.Sprintf("%s/juelsPerFeeCoinSource", mockServerPath), mockServerValue) + if err != nil { + return err + } + + for _, ocrInstance := range ocrInstances { + bootstrapSpec := &client.OCR2TaskJobSpec{ + Name: fmt.Sprintf("ocr2_bootstrap-%s", uuid.NewString()), + JobType: "bootstrap", + OCR2OracleSpec: job.OCR2OracleSpec{ + ContractID: ocrInstance.Address(), + Relay: "evm", + RelayConfig: map[string]interface{}{ + "chainID": chainId, + }, + MonitoringEndpoint: null.StringFrom(fmt.Sprintf("%s/%s", mockserver.Config.ClusterURL, mockServerPath)), + ContractConfigTrackerPollInterval: *models.NewInterval(15 * time.Second), + }, + } + _, err := bootstrapNode.MustCreateJob(bootstrapSpec) + if err != nil { + return fmt.Errorf("creating bootstrap job have failed: %w", err) + } + + for _, chainlinkNode := range workerChainlinkNodes { + nodeTransmitterAddress, err := chainlinkNode.PrimaryEthAddress() + if err != nil { + return fmt.Errorf("getting primary ETH address from OCR node have failed: %w", err) + } + nodeOCRKeys, err := chainlinkNode.MustReadOCR2Keys() + if err != nil { + return fmt.Errorf("getting OCR keys from OCR node have failed: %w", err) + } + nodeOCRKeyId := nodeOCRKeys.Data[0].ID + + bta := &client.BridgeTypeAttributes{ + Name: fmt.Sprintf("%s-%s", mockServerPath, uuid.NewString()), + URL: fmt.Sprintf("%s/%s", mockserver.Config.ClusterURL, mockServerPath), + } + juelsBridge := &client.BridgeTypeAttributes{ + Name: fmt.Sprintf("juels-%s", uuid.NewString()), + URL: fmt.Sprintf("%s/%s/juelsPerFeeCoinSource", mockserver.Config.ClusterURL, mockServerPath), + } + err = chainlinkNode.MustCreateBridge(bta) + if err != nil { + return fmt.Errorf("creating bridge job have failed: %w", err) + } + err = chainlinkNode.MustCreateBridge(juelsBridge) + if err != nil { + return fmt.Errorf("creating bridge job have failed: %w", err) + } + + ocrSpec := &client.OCR2TaskJobSpec{ + Name: fmt.Sprintf("ocr2-%s", uuid.NewString()), + JobType: "offchainreporting2", + MaxTaskDuration: "1m", + ObservationSource: client.ObservationSourceSpecBridge(bta), + ForwardingAllowed: forwardingAllowed, + OCR2OracleSpec: job.OCR2OracleSpec{ + PluginType: "median", + Relay: "evm", + RelayConfig: map[string]interface{}{ + "chainID": chainId, + }, + PluginConfig: map[string]any{ + "juelsPerFeeCoinSource": fmt.Sprintf("\"\"\"%s\"\"\"", client.ObservationSourceSpecBridge(juelsBridge)), + }, + ContractConfigTrackerPollInterval: *models.NewInterval(15 * time.Second), + ContractID: ocrInstance.Address(), // registryAddr + OCRKeyBundleID: null.StringFrom(nodeOCRKeyId), // get node ocr2config.ID + TransmitterID: null.StringFrom(nodeTransmitterAddress), // node addr + P2PV2Bootstrappers: pq.StringArray{p2pV2Bootstrapper}, // bootstrap node key and address @bootstrap:6690 + }, + } + _, err = chainlinkNode.MustCreateJob(ocrSpec) + if err != nil { + return fmt.Errorf("creating OCR task job on OCR node have failed: %w", err) + } + } + } + return nil +} + +func BuildMedianOCR2ConfigLocal(workerNodes []*client.ChainlinkClient) (*contracts.OCRv2Config, error) { + S, oracleIdentities, err := GetOracleIdentitiesWithKeyIndexLocal(workerNodes, 0) + if err != nil { + return nil, err + } + signerKeys, transmitterAccounts, f_, onchainConfig, offchainConfigVersion, offchainConfig, err := confighelper.ContractSetConfigArgsForTests( + 30*time.Second, // deltaProgress time.Duration, + 30*time.Second, // deltaResend time.Duration, + 10*time.Second, // deltaRound time.Duration, + 20*time.Second, // deltaGrace time.Duration, + 20*time.Second, // deltaStage time.Duration, + 3, // rMax uint8, + S, // s []int, + oracleIdentities, // oracles []OracleIdentityExtra, + median.OffchainConfig{ + AlphaReportInfinite: false, + AlphaReportPPB: 1, + AlphaAcceptInfinite: false, + AlphaAcceptPPB: 1, + DeltaC: time.Minute * 30, + }.Encode(), // reportingPluginConfig []byte, + 5*time.Second, // maxDurationQuery time.Duration, + 5*time.Second, // maxDurationObservation time.Duration, + 5*time.Second, // maxDurationReport time.Duration, + 5*time.Second, // maxDurationShouldAcceptFinalizedReport time.Duration, + 5*time.Second, // maxDurationShouldTransmitAcceptedReport time.Duration, + 1, // f int, + nil, // The median reporting plugin has an empty onchain config + ) + if err != nil { + return nil, err + } + + // Convert signers to addresses + var signerAddresses []common.Address + for _, signer := range signerKeys { + signerAddresses = append(signerAddresses, common.BytesToAddress(signer)) + } + + // Convert transmitters to addresses + var transmitterAddresses []common.Address + for _, account := range transmitterAccounts { + transmitterAddresses = append(transmitterAddresses, common.HexToAddress(string(account))) + } + + return &contracts.OCRv2Config{ + Signers: signerAddresses, + Transmitters: transmitterAddresses, + F: f_, + OnchainConfig: onchainConfig, + OffchainConfigVersion: offchainConfigVersion, + OffchainConfig: []byte(fmt.Sprintf("0x%s", offchainConfig)), + }, nil +} + +func GetOracleIdentitiesWithKeyIndexLocal( + chainlinkNodes []*client.ChainlinkClient, + keyIndex int, +) ([]int, []confighelper.OracleIdentityExtra, error) { + S := make([]int, len(chainlinkNodes)) + oracleIdentities := make([]confighelper.OracleIdentityExtra, len(chainlinkNodes)) + sharedSecretEncryptionPublicKeys := make([]types.ConfigEncryptionPublicKey, len(chainlinkNodes)) + eg := &errgroup.Group{} + for i, cl := range chainlinkNodes { + index, chainlinkNode := i, cl + eg.Go(func() error { + addresses, err := chainlinkNode.EthAddresses() + if err != nil { + return err + } + ocr2Keys, err := chainlinkNode.MustReadOCR2Keys() + if err != nil { + return err + } + var ocr2Config client.OCR2KeyAttributes + for _, key := range ocr2Keys.Data { + if key.Attributes.ChainType == string(chaintype.EVM) { + ocr2Config = key.Attributes + break + } + } + + keys, err := chainlinkNode.MustReadP2PKeys() + if err != nil { + return err + } + p2pKeyID := keys.Data[0].Attributes.PeerID + + offchainPkBytes, err := hex.DecodeString(strings.TrimPrefix(ocr2Config.OffChainPublicKey, "ocr2off_evm_")) + if err != nil { + return err + } + + offchainPkBytesFixed := [ed25519.PublicKeySize]byte{} + n := copy(offchainPkBytesFixed[:], offchainPkBytes) + if n != ed25519.PublicKeySize { + return fmt.Errorf("wrong number of elements copied") + } + + configPkBytes, err := hex.DecodeString(strings.TrimPrefix(ocr2Config.ConfigPublicKey, "ocr2cfg_evm_")) + if err != nil { + return err + } + + configPkBytesFixed := [ed25519.PublicKeySize]byte{} + n = copy(configPkBytesFixed[:], configPkBytes) + if n != ed25519.PublicKeySize { + return fmt.Errorf("wrong number of elements copied") + } + + onchainPkBytes, err := hex.DecodeString(strings.TrimPrefix(ocr2Config.OnChainPublicKey, "ocr2on_evm_")) + if err != nil { + return err + } + + sharedSecretEncryptionPublicKeys[index] = configPkBytesFixed + oracleIdentities[index] = confighelper.OracleIdentityExtra{ + OracleIdentity: confighelper.OracleIdentity{ + OnchainPublicKey: onchainPkBytes, + OffchainPublicKey: offchainPkBytesFixed, + PeerID: p2pKeyID, + TransmitAccount: types.Account(addresses[keyIndex]), + }, + ConfigEncryptionPublicKey: configPkBytesFixed, + } + S[index] = 1 + log.Debug(). + Interface("OnChainPK", onchainPkBytes). + Interface("OffChainPK", offchainPkBytesFixed). + Interface("ConfigPK", configPkBytesFixed). + Str("PeerID", p2pKeyID). + Str("Address", addresses[keyIndex]). + Msg("Oracle identity") + return nil + }) + } + + return S, oracleIdentities, eg.Wait() +} diff --git a/integration-tests/actions/ocr2vrf_actions/ocr2vrf_config_helpers.go b/integration-tests/actions/ocr2vrf_actions/ocr2vrf_config_helpers.go index 83033710f41..05b983c2f1e 100644 --- a/integration-tests/actions/ocr2vrf_actions/ocr2vrf_config_helpers.go +++ b/integration-tests/actions/ocr2vrf_actions/ocr2vrf_config_helpers.go @@ -33,8 +33,8 @@ import ( // CreateOCR2VRFJobs bootstraps the first node and to the other nodes sends ocr jobs func CreateOCR2VRFJobs( t *testing.T, - bootstrapNode *client.Chainlink, - nonBootstrapNodes []*client.Chainlink, + bootstrapNode *client.ChainlinkK8sClient, + nonBootstrapNodes []*client.ChainlinkK8sClient, OCR2VRFPluginConfig *OCR2VRFPluginConfig, chainID int64, keyIndex int, @@ -48,7 +48,7 @@ func CreateOCR2VRFJobs( func createNonBootstrapJobs( t *testing.T, - nonBootstrapNodes []*client.Chainlink, + nonBootstrapNodes []*client.ChainlinkK8sClient, OCR2VRFPluginConfig *OCR2VRFPluginConfig, chainID int64, keyIndex int, @@ -95,7 +95,7 @@ func createNonBootstrapJobs( } } -func createBootstrapJob(t *testing.T, bootstrapNode *client.Chainlink, dkgAddress string, chainID int64) string { +func createBootstrapJob(t *testing.T, bootstrapNode *client.ChainlinkK8sClient, dkgAddress string, chainID int64) string { bootstrapP2PIds, err := bootstrapNode.MustReadP2PKeys() require.NoError(t, err, "Shouldn't fail reading P2P keys from bootstrap node") bootstrapP2PId := bootstrapP2PIds.Data[0].Attributes.PeerID diff --git a/integration-tests/actions/ocr2vrf_actions/ocr2vrf_steps.go b/integration-tests/actions/ocr2vrf_actions/ocr2vrf_steps.go index e78ac9828fb..c550fe73a22 100644 --- a/integration-tests/actions/ocr2vrf_actions/ocr2vrf_steps.go +++ b/integration-tests/actions/ocr2vrf_actions/ocr2vrf_steps.go @@ -72,7 +72,7 @@ func SetAndWaitForDKGProcessToFinish(t *testing.T, ocr2VRFPluginConfig *OCR2VRFP func SetAndGetOCR2VRFPluginConfig( t *testing.T, - nonBootstrapNodes []*client.Chainlink, + nonBootstrapNodes []*client.ChainlinkK8sClient, dkg contracts.DKG, vrfBeacon contracts.VRFBeacon, coordinator contracts.VRFCoordinatorV3, @@ -292,7 +292,7 @@ func SetupOCR2VRFUniverse( contractDeployer contracts.ContractDeployer, chainClient blockchain.EVMClient, nodeAddresses []common.Address, - chainlinkNodes []*client.Chainlink, + chainlinkNodes []*client.ChainlinkK8sClient, testNetwork blockchain.EVMNetwork, ) (contracts.DKG, contracts.VRFCoordinatorV3, contracts.VRFBeacon, contracts.VRFBeaconConsumer, *big.Int) { diff --git a/integration-tests/actions/ocr_helpers.go b/integration-tests/actions/ocr_helpers.go index 0325a64f101..bff96c73042 100644 --- a/integration-tests/actions/ocr_helpers.go +++ b/integration-tests/actions/ocr_helpers.go @@ -26,8 +26,8 @@ func DeployOCRContracts( numberOfContracts int, linkTokenContract contracts.LinkToken, contractDeployer contracts.ContractDeployer, - bootstrapNode *client.Chainlink, - workerNodes []*client.Chainlink, + bootstrapNode *client.ChainlinkK8sClient, + workerNodes []*client.ChainlinkK8sClient, client blockchain.EVMClient, ) ([]contracts.OffchainAggregator, error) { // Deploy contracts @@ -118,7 +118,7 @@ func DeployOCRContractsForwarderFlow( numberOfContracts int, linkTokenContract contracts.LinkToken, contractDeployer contracts.ContractDeployer, - workerNodes []*client.Chainlink, + workerNodes []*client.ChainlinkK8sClient, forwarderAddresses []common.Address, client blockchain.EVMClient, ) []contracts.OffchainAggregator { @@ -182,8 +182,8 @@ func DeployOCRContractsForwarderFlow( // read from different adapters, to be used in combination with SetAdapterResponses func CreateOCRJobs( ocrInstances []contracts.OffchainAggregator, - bootstrapNode *client.Chainlink, - workerNodes []*client.Chainlink, + bootstrapNode *client.ChainlinkK8sClient, + workerNodes []*client.ChainlinkK8sClient, mockValue int, mockserver *ctfClient.MockserverClient, ) error { @@ -237,10 +237,11 @@ func CreateOCRJobs( return fmt.Errorf("creating bridge job have failed: %w", err) } + bootstrapPeers := []*client.ChainlinkClient{bootstrapNode.ChainlinkClient} ocrSpec := &client.OCRTaskJobSpec{ ContractAddress: ocrInstance.Address(), P2PPeerID: nodeP2PId, - P2PBootstrapPeers: []*client.Chainlink{bootstrapNode}, + P2PBootstrapPeers: bootstrapPeers, KeyBundleID: nodeOCRKeyId, TransmitterAddress: nodeTransmitterAddress, ObservationSource: client.ObservationSourceSpecBridge(bta), @@ -259,8 +260,8 @@ func CreateOCRJobs( func CreateOCRJobsWithForwarder( t *testing.T, ocrInstances []contracts.OffchainAggregator, - bootstrapNode *client.Chainlink, - workerNodes []*client.Chainlink, + bootstrapNode *client.ChainlinkK8sClient, + workerNodes []*client.ChainlinkK8sClient, mockValue int, mockserver *ctfClient.MockserverClient, ) { @@ -298,10 +299,11 @@ func CreateOCRJobsWithForwarder( err = node.MustCreateBridge(bta) require.NoError(t, err, "Failed creating bridge on OCR node %d", nodeIndex+1) + bootstrapPeers := []*client.ChainlinkClient{bootstrapNode.ChainlinkClient} ocrSpec := &client.OCRTaskJobSpec{ ContractAddress: ocrInstance.Address(), P2PPeerID: nodeP2PId, - P2PBootstrapPeers: []*client.Chainlink{bootstrapNode}, + P2PBootstrapPeers: bootstrapPeers, KeyBundleID: nodeOCRKeyId, TransmitterAddress: nodeTransmitterAddress, ObservationSource: client.ObservationSourceSpecBridge(bta), @@ -338,7 +340,7 @@ func StartNewRound( func SetAdapterResponse( response int, ocrInstance contracts.OffchainAggregator, - chainlinkNode *client.Chainlink, + chainlinkNode *client.ChainlinkK8sClient, mockserver *ctfClient.MockserverClient, ) error { nodeContractPairID, err := BuildNodeContractPairID(chainlinkNode, ocrInstance) @@ -358,7 +360,7 @@ func SetAdapterResponse( func SetAllAdapterResponsesToTheSameValue( response int, ocrInstances []contracts.OffchainAggregator, - chainlinkNodes []*client.Chainlink, + chainlinkNodes []*client.ChainlinkK8sClient, mockserver *ctfClient.MockserverClient, ) error { eg := &errgroup.Group{} @@ -377,24 +379,32 @@ func SetAllAdapterResponsesToTheSameValue( // SetAllAdapterResponsesToDifferentValues sets the mock responses in mockserver that are read by chainlink nodes // to simulate different adapters. This sets all adapter responses for each node and contract to different responses func SetAllAdapterResponsesToDifferentValues( - t *testing.T, responses []int, ocrInstances []contracts.OffchainAggregator, - chainlinkNodes []*client.Chainlink, + chainlinkNodes []*client.ChainlinkK8sClient, mockserver *ctfClient.MockserverClient, -) { - require.Equal(t, len(chainlinkNodes)-1, len(responses), - "Amount of answers %d should be equal to the amount of Chainlink nodes - 1 for the bootstrap %d", len(responses), len(chainlinkNodes)-1) - for _, ocrInstance := range ocrInstances { - for nodeIndex := 1; nodeIndex < len(chainlinkNodes); nodeIndex++ { - err := SetAdapterResponse(responses[nodeIndex-1], ocrInstance, chainlinkNodes[nodeIndex], mockserver) - require.NoError(t, err) +) error { + if len(responses) != len(ocrInstances)*len(chainlinkNodes) { + return fmt.Errorf( + "amount of responses %d should be equal to the amount of OCR instances %d times the amount of Chainlink nodes %d", + len(responses), len(ocrInstances), len(chainlinkNodes), + ) + } + eg := &errgroup.Group{} + for _, o := range ocrInstances { + ocrInstance := o + for ni := 1; ni < len(chainlinkNodes); ni++ { + nodeIndex := ni + eg.Go(func() error { + return SetAdapterResponse(responses[nodeIndex-1], ocrInstance, chainlinkNodes[nodeIndex], mockserver) + }) } } + return eg.Wait() } // BuildNodeContractPairID builds a UUID based on a related pair of a Chainlink node and OCR contract -func BuildNodeContractPairID(node *client.Chainlink, ocrInstance contracts.OffchainAggregator) (string, error) { +func BuildNodeContractPairID(node *client.ChainlinkK8sClient, ocrInstance contracts.OffchainAggregator) (string, error) { if node == nil { return "", fmt.Errorf("chainlink node is nil") } diff --git a/integration-tests/actions/ocr_helpers_local.go b/integration-tests/actions/ocr_helpers_local.go new file mode 100644 index 00000000000..13fc01dcea6 --- /dev/null +++ b/integration-tests/actions/ocr_helpers_local.go @@ -0,0 +1,424 @@ +package actions + +import ( + "fmt" + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/google/uuid" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" + "github.com/smartcontractkit/chainlink/integration-tests/client" + "github.com/smartcontractkit/chainlink/integration-tests/contracts" + "golang.org/x/sync/errgroup" + "math/big" + "strings" +) + +/* + These methods should be cleaned merged after we decouple ChainlinkClient and ChainlinkK8sClient + Please, use them while refactoring other tests to local docker env +*/ + +// FundChainlinkNodesLocal will fund all the provided Chainlink nodes with a set amount of native currency +func FundChainlinkNodesLocal( + nodes []*client.ChainlinkClient, + client blockchain.EVMClient, + amount *big.Float, +) error { + for _, cl := range nodes { + toAddress, err := cl.PrimaryEthAddress() + if err != nil { + return err + } + gasEstimates, err := client.EstimateGas(ethereum.CallMsg{}) + if err != nil { + return err + } + err = client.Fund(toAddress, amount, gasEstimates) + if err != nil { + return err + } + } + return client.WaitForEvents() +} + +func ChainlinkNodeAddressesLocal(nodes []*client.ChainlinkClient) ([]common.Address, error) { + addresses := make([]common.Address, 0) + for _, node := range nodes { + primaryAddress, err := node.PrimaryEthAddress() + if err != nil { + return nil, err + } + addresses = append(addresses, common.HexToAddress(primaryAddress)) + } + return addresses, nil +} + +func DeployOCRContractsLocal( + numberOfContracts int, + linkTokenContract contracts.LinkToken, + contractDeployer contracts.ContractDeployer, + workerNodes []*client.ChainlinkClient, + client blockchain.EVMClient, +) ([]contracts.OffchainAggregator, error) { + // Deploy contracts + var ocrInstances []contracts.OffchainAggregator + for contractCount := 0; contractCount < numberOfContracts; contractCount++ { + ocrInstance, err := contractDeployer.DeployOffChainAggregator( + linkTokenContract.Address(), + contracts.DefaultOffChainAggregatorOptions(), + ) + if err != nil { + return nil, fmt.Errorf("OCR instance deployment have failed: %w", err) + } + ocrInstances = append(ocrInstances, ocrInstance) + err = client.WaitForEvents() + if err != nil { + return nil, fmt.Errorf("failed to wait for OCR contract deployments: %w", err) + } + } + err := client.WaitForEvents() + if err != nil { + return nil, fmt.Errorf("error waiting for OCR contract deployments: %w", err) + } + + // Gather transmitter and address payees + var transmitters, payees []string + for _, node := range workerNodes { + addr, err := node.PrimaryEthAddress() + if err != nil { + return nil, fmt.Errorf("error getting node's primary ETH address: %w", err) + } + transmitters = append(transmitters, addr) + payees = append(payees, client.GetDefaultWallet().Address()) + } + + // Set Payees + for _, ocrInstance := range ocrInstances { + err = ocrInstance.SetPayees(transmitters, payees) + if err != nil { + return nil, fmt.Errorf("error settings OCR payees: %w", err) + } + err = client.WaitForEvents() + if err != nil { + return nil, fmt.Errorf("failed to wait for setting OCR payees: %w", err) + } + } + + // Set Config + transmitterAddresses, err := ChainlinkNodeAddressesLocal(workerNodes) + if err != nil { + return nil, fmt.Errorf("getting node common addresses should not fail: %w", err) + } + for _, ocrInstance := range ocrInstances { + // Exclude the first node, which will be used as a bootstrapper + err = ocrInstance.SetConfigLocal( + workerNodes, + contracts.DefaultOffChainAggregatorConfig(len(workerNodes)), + transmitterAddresses, + ) + if err != nil { + return nil, fmt.Errorf("error setting OCR config for contract '%s': %w", ocrInstance.Address(), err) + } + err = client.WaitForEvents() + if err != nil { + return nil, fmt.Errorf("failed to wait for setting OCR config: %w", err) + } + } + err = client.WaitForEvents() + if err != nil { + return nil, fmt.Errorf("error waiting for OCR contracts to set config: %w", err) + } + return ocrInstances, nil +} + +func CreateOCRJobsLocal( + ocrInstances []contracts.OffchainAggregator, + bootstrapNode *client.ChainlinkClient, + workerNodes []*client.ChainlinkClient, + mockValue int, + mockserver *ctfClient.MockserverClient, +) error { + for _, ocrInstance := range ocrInstances { + bootstrapP2PIds, err := bootstrapNode.MustReadP2PKeys() + if err != nil { + return fmt.Errorf("reading P2P keys from bootstrap node have failed: %w", err) + } + bootstrapP2PId := bootstrapP2PIds.Data[0].Attributes.PeerID + bootstrapSpec := &client.OCRBootstrapJobSpec{ + Name: fmt.Sprintf("bootstrap-%s", uuid.New().String()), + ContractAddress: ocrInstance.Address(), + P2PPeerID: bootstrapP2PId, + IsBootstrapPeer: true, + } + _, err = bootstrapNode.MustCreateJob(bootstrapSpec) + if err != nil { + return fmt.Errorf("creating bootstrap job have failed: %w", err) + } + + for _, node := range workerNodes { + nodeP2PIds, err := node.MustReadP2PKeys() + if err != nil { + return fmt.Errorf("reading P2P keys from OCR node have failed: %w", err) + } + nodeP2PId := nodeP2PIds.Data[0].Attributes.PeerID + nodeTransmitterAddress, err := node.PrimaryEthAddress() + if err != nil { + return fmt.Errorf("getting primary ETH address from OCR node have failed: %w", err) + } + nodeOCRKeys, err := node.MustReadOCRKeys() + if err != nil { + return fmt.Errorf("getting OCR keys from OCR node have failed: %w", err) + } + nodeOCRKeyId := nodeOCRKeys.Data[0].ID + + nodeContractPairID, err := BuildNodeContractPairIDLocal(node, ocrInstance) + if err != nil { + return err + } + bta := &client.BridgeTypeAttributes{ + Name: nodeContractPairID, + URL: fmt.Sprintf("%s/%s", mockserver.Config.ClusterURL, strings.TrimPrefix(nodeContractPairID, "/")), + } + err = SetAdapterResponseLocal(mockValue, ocrInstance, node, mockserver) + if err != nil { + return fmt.Errorf("setting adapter response for OCR node failed: %w", err) + } + err = node.MustCreateBridge(bta) + if err != nil { + return fmt.Errorf("creating bridge job have failed: %w", err) + } + + bootstrapPeers := []*client.ChainlinkClient{bootstrapNode} + ocrSpec := &client.OCRTaskJobSpec{ + ContractAddress: ocrInstance.Address(), + P2PPeerID: nodeP2PId, + P2PBootstrapPeers: bootstrapPeers, + KeyBundleID: nodeOCRKeyId, + TransmitterAddress: nodeTransmitterAddress, + ObservationSource: client.ObservationSourceSpecBridge(bta), + } + _, err = node.MustCreateJob(ocrSpec) + if err != nil { + return fmt.Errorf("creating OCR task job on OCR node have failed: %w", err) + } + } + } + return nil +} + +func BuildNodeContractPairIDLocal(node *client.ChainlinkClient, ocrInstance contracts.OffchainAggregator) (string, error) { + if node == nil { + return "", fmt.Errorf("chainlink node is nil") + } + if ocrInstance == nil { + return "", fmt.Errorf("OCR Instance is nil") + } + nodeAddress, err := node.PrimaryEthAddress() + if err != nil { + return "", fmt.Errorf("getting chainlink node's primary ETH address failed: %w", err) + } + shortNodeAddr := nodeAddress[2:12] + shortOCRAddr := ocrInstance.Address()[2:12] + return strings.ToLower(fmt.Sprintf("node_%s_contract_%s", shortNodeAddr, shortOCRAddr)), nil +} + +func SetAdapterResponseLocal( + response int, + ocrInstance contracts.OffchainAggregator, + chainlinkNode *client.ChainlinkClient, + mockserver *ctfClient.MockserverClient, +) error { + nodeContractPairID, err := BuildNodeContractPairIDLocal(chainlinkNode, ocrInstance) + if err != nil { + return err + } + path := fmt.Sprintf("/%s", nodeContractPairID) + err = mockserver.SetValuePath(path, response) + if err != nil { + return fmt.Errorf("setting mockserver value path failed: %w", err) + } + return nil +} + +func SetAllAdapterResponsesToTheSameValueLocal( + response int, + ocrInstances []contracts.OffchainAggregator, + chainlinkNodes []*client.ChainlinkClient, + mockserver *ctfClient.MockserverClient, +) error { + eg := &errgroup.Group{} + for _, o := range ocrInstances { + ocrInstance := o + for _, n := range chainlinkNodes { + node := n + eg.Go(func() error { + return SetAdapterResponseLocal(response, ocrInstance, node, mockserver) + }) + } + } + return eg.Wait() +} + +func TrackForwarderLocal( + chainClient blockchain.EVMClient, + authorizedForwarder common.Address, + node *client.ChainlinkClient, +) error { + chainID := chainClient.GetChainID() + _, _, err := node.TrackForwarder(chainID, authorizedForwarder) + if err != nil { + return errors.Wrap(err, "failed to track forwarder") + } + log.Info().Str("NodeURL", node.Config.URL). + Str("ForwarderAddress", authorizedForwarder.Hex()). + Str("ChaindID", chainID.String()). + Msg("Forwarder tracked") + return nil +} + +func DeployOCRContractsForwarderFlowLocal( + numberOfContracts int, + linkTokenContract contracts.LinkToken, + contractDeployer contracts.ContractDeployer, + workerNodes []*client.ChainlinkClient, + forwarderAddresses []common.Address, + client blockchain.EVMClient, +) ([]contracts.OffchainAggregator, error) { + // Deploy contracts + var ocrInstances []contracts.OffchainAggregator + for contractCount := 0; contractCount < numberOfContracts; contractCount++ { + ocrInstance, err := contractDeployer.DeployOffChainAggregator( + linkTokenContract.Address(), + contracts.DefaultOffChainAggregatorOptions(), + ) + if err != nil { + return nil, errors.Wrap(err, "failed to deploy offchain aggregator") + } + ocrInstances = append(ocrInstances, ocrInstance) + err = client.WaitForEvents() + if err != nil { + return nil, err + } + } + if err := client.WaitForEvents(); err != nil { + return nil, err + } + + // Gather transmitter and address payees + var transmitters, payees []string + for _, forwarderCommonAddress := range forwarderAddresses { + forwarderAddress := forwarderCommonAddress.Hex() + transmitters = append(transmitters, forwarderAddress) + payees = append(payees, client.GetDefaultWallet().Address()) + } + + // Set Payees + for _, ocrInstance := range ocrInstances { + err := ocrInstance.SetPayees(transmitters, payees) + if err != nil { + return nil, errors.Wrap(err, "failed to set OCR payees") + } + if err := client.WaitForEvents(); err != nil { + return nil, err + } + } + if err := client.WaitForEvents(); err != nil { + return nil, err + } + + // Set Config + for _, ocrInstance := range ocrInstances { + // Exclude the first node, which will be used as a bootstrapper + err := ocrInstance.SetConfigLocal( + workerNodes, + contracts.DefaultOffChainAggregatorConfig(len(workerNodes)), + forwarderAddresses, + ) + if err != nil { + return nil, errors.Wrap(err, "failed to set on-chain config") + } + if err = client.WaitForEvents(); err != nil { + return nil, err + } + } + return ocrInstances, client.WaitForEvents() +} + +func CreateOCRJobsWithForwarderLocal( + ocrInstances []contracts.OffchainAggregator, + bootstrapNode *client.ChainlinkClient, + workerNodes []*client.ChainlinkClient, + mockValue int, + mockserver *ctfClient.MockserverClient, +) error { + for _, ocrInstance := range ocrInstances { + bootstrapP2PIds, err := bootstrapNode.MustReadP2PKeys() + if err != nil { + return err + } + bootstrapP2PId := bootstrapP2PIds.Data[0].Attributes.PeerID + bootstrapSpec := &client.OCRBootstrapJobSpec{ + Name: fmt.Sprintf("bootstrap-%s", uuid.New().String()), + ContractAddress: ocrInstance.Address(), + P2PPeerID: bootstrapP2PId, + IsBootstrapPeer: true, + } + _, err = bootstrapNode.MustCreateJob(bootstrapSpec) + if err != nil { + return err + } + + for _, node := range workerNodes { + nodeP2PIds, err := node.MustReadP2PKeys() + if err != nil { + return err + } + nodeP2PId := nodeP2PIds.Data[0].Attributes.PeerID + nodeTransmitterAddress, err := node.PrimaryEthAddress() + if err != nil { + return err + } + nodeOCRKeys, err := node.MustReadOCRKeys() + if err != nil { + return err + } + nodeOCRKeyId := nodeOCRKeys.Data[0].ID + + nodeContractPairID, err := BuildNodeContractPairIDLocal(node, ocrInstance) + if err != nil { + return err + } + bta := &client.BridgeTypeAttributes{ + Name: nodeContractPairID, + URL: fmt.Sprintf("%s/%s", mockserver.Config.ClusterURL, strings.TrimPrefix(nodeContractPairID, "/")), + } + err = SetAdapterResponseLocal(mockValue, ocrInstance, node, mockserver) + if err != nil { + return err + } + err = node.MustCreateBridge(bta) + if err != nil { + return err + } + + bootstrapPeers := []*client.ChainlinkClient{bootstrapNode} + ocrSpec := &client.OCRTaskJobSpec{ + ContractAddress: ocrInstance.Address(), + P2PPeerID: nodeP2PId, + P2PBootstrapPeers: bootstrapPeers, + KeyBundleID: nodeOCRKeyId, + TransmitterAddress: nodeTransmitterAddress, + ObservationSource: client.ObservationSourceSpecBridge(bta), + ForwardingAllowed: true, + } + _, err = node.MustCreateJob(ocrSpec) + if err != nil { + return err + } + } + } + return nil +} diff --git a/integration-tests/actions/operator_forwarder_helpers.go b/integration-tests/actions/operator_forwarder_helpers.go index b812fb18b71..7add64fbe99 100644 --- a/integration-tests/actions/operator_forwarder_helpers.go +++ b/integration-tests/actions/operator_forwarder_helpers.go @@ -184,7 +184,7 @@ func TrackForwarder( t *testing.T, chainClient blockchain.EVMClient, authorizedForwarder common.Address, - node *client.Chainlink, + node *client.ChainlinkK8sClient, ) { l := utils.GetTestLogger(t) chainID := chainClient.GetChainID() diff --git a/integration-tests/actions/vrfv1/actions.go b/integration-tests/actions/vrfv1/actions.go new file mode 100644 index 00000000000..68d3e584cee --- /dev/null +++ b/integration-tests/actions/vrfv1/actions.go @@ -0,0 +1,38 @@ +package vrfv1 + +import ( + "github.com/pkg/errors" + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink/integration-tests/contracts" +) + +var ( + ErrDeployBHSV1 = "error deploying BlockHashStoreV1 contract" + ErrDeployVRFCootrinatorV1 = "error deploying VRFv1 Coordinator contract" + ErrDeployVRFConsumerV1 = "error deploying VRFv1 Consumer contract" +) + +type Contracts struct { + BHS contracts.BlockHashStore + Coordinator contracts.VRFCoordinator + Consumer contracts.VRFConsumer +} + +func DeployVRFContracts(cd contracts.ContractDeployer, bc blockchain.EVMClient, lt contracts.LinkToken) (*Contracts, error) { + bhs, err := cd.DeployBlockhashStore() + if err != nil { + return nil, errors.Wrap(err, ErrDeployBHSV1) + } + coordinator, err := cd.DeployVRFCoordinator(lt.Address(), bhs.Address()) + if err != nil { + return nil, errors.Wrap(err, ErrDeployVRFCootrinatorV1) + } + consumer, err := cd.DeployVRFConsumer(lt.Address(), coordinator.Address()) + if err != nil { + return nil, errors.Wrap(err, ErrDeployVRFConsumerV1) + } + if err := bc.WaitForEvents(); err != nil { + return nil, err + } + return &Contracts{bhs, coordinator, consumer}, nil +} diff --git a/integration-tests/actions/vrfv2_actions/vrfv2_constants/vrfv2_constants.go b/integration-tests/actions/vrfv2_actions/vrfv2_constants/constants.go similarity index 95% rename from integration-tests/actions/vrfv2_actions/vrfv2_constants/vrfv2_constants.go rename to integration-tests/actions/vrfv2_actions/vrfv2_constants/constants.go index b5e86a88d5c..2ec993e4e6e 100644 --- a/integration-tests/actions/vrfv2_actions/vrfv2_constants/vrfv2_constants.go +++ b/integration-tests/actions/vrfv2_actions/vrfv2_constants/constants.go @@ -13,7 +13,7 @@ var ( //todo - get Sub id when creating subscription - need to listen for SubscriptionCreated Log SubID = uint64(1) VRFSubscriptionFundingAmountLink = big.NewInt(100) - ChainlinkNodeFundingAmountEth = big.NewFloat(1) + ChainlinkNodeFundingAmountEth = big.NewFloat(0.1) NumberOfWords = uint32(3) MaxGasPriceGWei = 1000 CallbackGasLimit = uint32(1000000) diff --git a/integration-tests/actions/vrfv2_actions/vrfv2_steps.go b/integration-tests/actions/vrfv2_actions/vrfv2_steps.go index 73debdbecc5..b59f8c761f1 100644 --- a/integration-tests/actions/vrfv2_actions/vrfv2_steps.go +++ b/integration-tests/actions/vrfv2_actions/vrfv2_steps.go @@ -3,71 +3,86 @@ package vrfv2_actions import ( "context" "fmt" - "math/big" - "strings" - "testing" - "time" - - "github.com/smartcontractkit/chainlink-env/environment" - "github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink" - eth "github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink/integration-tests/actions" - "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2_actions/vrfv2_constants" - "github.com/smartcontractkit/chainlink/integration-tests/config" chainlinkutils "github.com/smartcontractkit/chainlink/v2/core/utils" + "math/big" "github.com/google/uuid" - "github.com/stretchr/testify/require" - + "github.com/pkg/errors" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - "github.com/smartcontractkit/chainlink-testing-framework/utils" - + vrfConst "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2_actions/vrfv2_constants" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" +) + +var ( + ErrNodePrimaryKey = "error getting node's primary ETH key" + ErrCreatingProvingKeyHash = "error creating a keyHash from the proving key" + ErrCreatingProvingKey = "error creating a keyHash from the proving key" + ErrRegisterProvingKey = "error registering proving keys" + ErrEncodingProvingKey = "error encoding proving key" + ErrCreatingVRFv2Key = "error creating VRFv2 key" + ErrDeployBlockHashStore = "error deploying blockhash store" + ErrDeployCoordinator = "error deploying VRFv2 CoordinatorV2" + ErrAdvancedConsumer = "error deploying VRFv2 Advanced Consumer" + ErrABIEncodingFunding = "error Abi encoding subscriptionID" + ErrSendingLinkToken = "error sending Link token" + ErrCreatingVRFv2Job = "error creating VRFv2 job" + ErrParseJob = "error parsing job definition" ) func DeployVRFV2Contracts( - t *testing.T, contractDeployer contracts.ContractDeployer, chainClient blockchain.EVMClient, linkTokenContract contracts.LinkToken, linkEthFeedContract contracts.MockETHLINKFeed, -) VRFV2Contracts { +) (*VRFV2Contracts, error) { bhs, err := contractDeployer.DeployBlockhashStore() - require.NoError(t, err, "Error deploying blockhash store") + if err != nil { + return nil, errors.Wrap(err, ErrDeployBlockHashStore) + } coordinator, err := contractDeployer.DeployVRFCoordinatorV2(linkTokenContract.Address(), bhs.Address(), linkEthFeedContract.Address()) - require.NoError(t, err, "Error deploying VRFv2 Coordinator") + if err != nil { + return nil, errors.Wrap(err, ErrDeployCoordinator) + } loadTestConsumer, err := contractDeployer.DeployVRFv2LoadTestConsumer(coordinator.Address()) - require.NoError(t, err, "Error deploying VRFv2 Advanced Consumer") + if err != nil { + return nil, errors.Wrap(err, ErrAdvancedConsumer) + } err = chainClient.WaitForEvents() - require.NoError(t, err, "Error waiting for events") - - return VRFV2Contracts{coordinator, bhs, loadTestConsumer} + if err != nil { + return nil, err + } + return &VRFV2Contracts{coordinator, bhs, loadTestConsumer}, nil } func CreateVRFV2Jobs( - t *testing.T, - chainlinkNodes []*client.Chainlink, + chainlinkNodes []*client.ChainlinkClient, coordinator contracts.VRFCoordinatorV2, c blockchain.EVMClient, minIncomingConfirmations uint16, -) []VRFV2JobInfo { - l := utils.GetTestLogger(t) +) ([]VRFV2JobInfo, error) { jobInfo := make([]VRFV2JobInfo, 0) for _, chainlinkNode := range chainlinkNodes { vrfKey, err := chainlinkNode.MustCreateVRFKey() - require.NoError(t, err, "Error creating VRF key") - l.Debug().Interface("Key JSON", vrfKey).Msg("Created proving key") + if err != nil { + return nil, errors.Wrap(err, ErrCreatingVRFv2Key) + } pubKeyCompressed := vrfKey.Data.ID jobUUID := uuid.New() os := &client.VRFV2TxPipelineSpec{ Address: coordinator.Address(), } ost, err := os.String() - require.NoError(t, err, "Error getting job string") + if err != nil { + return nil, errors.Wrap(err, ErrParseJob) + } nativeTokenPrimaryKeyAddress, err := chainlinkNode.PrimaryEthAddress() - require.NoError(t, err, "Error getting node's primary ETH key") + if err != nil { + return nil, errors.Wrap(err, ErrNodePrimaryKey) + } job, err := chainlinkNode.MustCreateJob(&client.VRFV2JobSpec{ Name: fmt.Sprintf("vrf-%s", jobUUID), CoordinatorAddress: coordinator.Address(), @@ -79,10 +94,17 @@ func CreateVRFV2Jobs( ObservationSource: ost, BatchFulfillmentEnabled: false, }) - require.NoError(t, err, "Error creating VRFv2 job") - provingKey := VRFV2RegisterProvingKey(t, vrfKey, nativeTokenPrimaryKeyAddress, coordinator) + if err != nil { + return nil, errors.Wrap(err, ErrCreatingVRFv2Job) + } + provingKey, err := VRFV2RegisterProvingKey(vrfKey, nativeTokenPrimaryKeyAddress, coordinator) + if err != nil { + return nil, errors.Wrap(err, ErrCreatingProvingKey) + } keyHash, err := coordinator.HashOfKey(context.Background(), provingKey) - require.NoError(t, err, "Error creating a keyHash from the proving key") + if err != nil { + return nil, errors.Wrap(err, ErrCreatingProvingKeyHash) + } ji := VRFV2JobInfo{ Job: job, VRFKey: vrfKey, @@ -91,188 +113,119 @@ func CreateVRFV2Jobs( } jobInfo = append(jobInfo, ji) } - return jobInfo + return jobInfo, nil } func VRFV2RegisterProvingKey( - t *testing.T, vrfKey *client.VRFKey, oracleAddress string, coordinator contracts.VRFCoordinatorV2, -) VRFV2EncodedProvingKey { +) (VRFV2EncodedProvingKey, error) { provingKey, err := actions.EncodeOnChainVRFProvingKey(*vrfKey) - require.NoError(t, err, "Error encoding proving key") + if err != nil { + return VRFV2EncodedProvingKey{}, errors.Wrap(err, ErrEncodingProvingKey) + } err = coordinator.RegisterProvingKey( oracleAddress, provingKey, ) - require.NoError(t, err, "Error registering proving keys") - return provingKey + if err != nil { + return VRFV2EncodedProvingKey{}, errors.Wrap(err, ErrRegisterProvingKey) + } + return provingKey, nil } -func FundVRFCoordinatorV2Subscription(t *testing.T, linkToken contracts.LinkToken, coordinator contracts.VRFCoordinatorV2, chainClient blockchain.EVMClient, subscriptionID uint64, linkFundingAmount *big.Int) { +func FundVRFCoordinatorV2Subscription(linkToken contracts.LinkToken, coordinator contracts.VRFCoordinatorV2, chainClient blockchain.EVMClient, subscriptionID uint64, linkFundingAmount *big.Int) error { encodedSubId, err := chainlinkutils.ABIEncode(`[{"type":"uint64"}]`, subscriptionID) - require.NoError(t, err, "Error Abi encoding subscriptionID") + if err != nil { + return errors.Wrap(err, ErrABIEncodingFunding) + } _, err = linkToken.TransferAndCall(coordinator.Address(), big.NewInt(0).Mul(linkFundingAmount, big.NewInt(1e18)), encodedSubId) - require.NoError(t, err, "Error sending Link token") - err = chainClient.WaitForEvents() - require.NoError(t, err, "Error waiting for TXs to complete") + if err != nil { + return errors.Wrap(err, ErrSendingLinkToken) + } + return chainClient.WaitForEvents() } -func SetupVRFV2Universe( - t *testing.T, - linkToken contracts.LinkToken, - mockETHLinkFeed contracts.MockETHLINKFeed, - contractDeployer contracts.ContractDeployer, - chainClient blockchain.EVMClient, - chainlinkNodes []*client.Chainlink, - testNetwork blockchain.EVMNetwork, - existingTestEnvironment *environment.Environment, - chainlinkNodeFundingAmountEth *big.Float, - vrfSubscriptionFundingAmountInLink *big.Int, - newEnvNamespacePrefix string, - newEnvTTL time.Duration, -) (VRFV2Contracts, []*client.Chainlink, []VRFV2JobInfo, *environment.Environment) { - - vrfV2Contracts := DeployVRFV2Contracts( - t, - contractDeployer, - chainClient, - linkToken, - mockETHLinkFeed, - ) - - err := actions.FundChainlinkNodes(chainlinkNodes, chainClient, chainlinkNodeFundingAmountEth) - require.NoError(t, err) - err = chainClient.WaitForEvents() - require.NoError(t, err) - - err = vrfV2Contracts.Coordinator.SetConfig( - uint16(vrfv2_constants.MinimumConfirmations), - vrfv2_constants.MaxGasLimitVRFCoordinatorConfig, - vrfv2_constants.StalenessSeconds, - vrfv2_constants.GasAfterPaymentCalculation, - vrfv2_constants.LinkEthFeedResponse, - vrfv2_constants.VRFCoordinatorV2FeeConfig, - ) - require.NoError(t, err) - err = chainClient.WaitForEvents() - require.NoError(t, err) - - err = vrfV2Contracts.Coordinator.CreateSubscription() - require.NoError(t, err) - err = chainClient.WaitForEvents() - require.NoError(t, err) - - err = vrfV2Contracts.Coordinator.AddConsumer(vrfv2_constants.SubID, vrfV2Contracts.LoadTestConsumer.Address()) - require.NoError(t, err, "Error adding a Load Test Consumer to a subscription in VRFCoordinator contract") - - FundVRFCoordinatorV2Subscription( - t, - linkToken, - vrfV2Contracts.Coordinator, - chainClient, - vrfv2_constants.SubID, - vrfSubscriptionFundingAmountInLink, - ) - - vrfV2jobs := CreateVRFV2Jobs( - t, - chainlinkNodes, - vrfV2Contracts.Coordinator, - chainClient, - vrfv2_constants.MinimumConfirmations, - ) - - nativeTokenPrimaryKeyAddress, err := chainlinkNodes[0].PrimaryEthAddress() - require.NoError(t, err, "Error getting node's primary ETH key") - - evmKeySpecificConfigTemplate := ` -[[EVM.KeySpecific]] -Key = '%s' - -[EVM.KeySpecific.GasEstimator] -PriceMax = '%d gwei' -` - //todo - make evmKeySpecificConfigTemplate for multiple eth keys - evmKeySpecificConfig := fmt.Sprintf(evmKeySpecificConfigTemplate, nativeTokenPrimaryKeyAddress, vrfv2_constants.MaxGasPriceGWei) - tomlConfigWithUpdates := fmt.Sprintf("%s\n%s", config.BaseVRFV2NetworkDetailTomlConfig, evmKeySpecificConfig) +/* setup for load tests */ + +func SetupLocalLoadTestEnv(nodesFunding *big.Float, subFundingLINK *big.Int) (*test_env.CLClusterTestEnv, *VRFV2Contracts, [32]byte, error) { + env, err := test_env.NewCLTestEnvBuilder(). + WithGeth(). + WithLogWatcher(). + WithMockServer(1). + WithCLNodes(1). + WithFunding(nodesFunding). + Build() + if err != nil { + return nil, nil, [32]byte{}, err + } + env.ParallelTransactions(true) - //todo - this does not show up?? - newEnvLabel := "updatedWithRollout=true" - testEnvironmentAfterRedeployment := SetupVRFV2Environment( - t, - testNetwork, - tomlConfigWithUpdates, - existingTestEnvironment.Cfg.Namespace, - newEnvNamespacePrefix, - newEnvLabel, - newEnvTTL, + mockFeed, err := actions.DeployMockETHLinkFeed(env.ContractDeployer, vrfConst.LinkEthFeedResponse) + if err != nil { + return nil, nil, [32]byte{}, err + } + lt, err := actions.DeployLINKToken(env.ContractDeployer) + if err != nil { + return nil, nil, [32]byte{}, err + } + vrfv2Contracts, err := DeployVRFV2Contracts(env.ContractDeployer, env.EVMClient, lt, mockFeed) + if err != nil { + return nil, nil, [32]byte{}, err + } + err = env.EVMClient.WaitForEvents() + if err != nil { + return nil, nil, [32]byte{}, err + } + err = vrfv2Contracts.Coordinator.SetConfig( + vrfConst.MinimumConfirmations, + vrfConst.MaxGasLimitVRFCoordinatorConfig, + vrfConst.StalenessSeconds, + vrfConst.GasAfterPaymentCalculation, + vrfConst.LinkEthFeedResponse, + vrfConst.VRFCoordinatorV2FeeConfig, ) - - err = testEnvironmentAfterRedeployment.RolloutStatefulSets() - require.NoError(t, err, "Error performing rollout restart for test environment") - - err = testEnvironmentAfterRedeployment.Run() - require.NoError(t, err, "Error running test environment") - - //need to get node's urls again since port changed after redeployment - chainlinkNodesAfterRedeployment, err := client.ConnectChainlinkNodes(testEnvironmentAfterRedeployment) - require.NoError(t, err) - - return vrfV2Contracts, chainlinkNodesAfterRedeployment, vrfV2jobs, testEnvironmentAfterRedeployment -} - -func SetupVRFV2Environment( - t *testing.T, - testNetwork blockchain.EVMNetwork, - networkDetailTomlConfig string, - existingNamespace string, - namespacePrefix string, - newEnvLabel string, - ttl time.Duration, -) (testEnvironment *environment.Environment) { - gethChartConfig := getGethChartConfig(testNetwork) - - if existingNamespace != "" { - testEnvironment = environment.New(&environment.Config{ - Namespace: existingNamespace, - Test: t, - TTL: ttl, - Labels: []string{newEnvLabel}, - }) - } else { - testEnvironment = environment.New(&environment.Config{ - NamespacePrefix: fmt.Sprintf("%s-%s", namespacePrefix, strings.ReplaceAll(strings.ToLower(testNetwork.Name), " ", "-")), - Test: t, - TTL: ttl, - }) + if err != nil { + return nil, nil, [32]byte{}, err } - - cd, err := chainlink.NewDeployment(1, map[string]any{ - "toml": client.AddNetworkDetailedConfig("", networkDetailTomlConfig, testNetwork), - //need to restart the node with updated eth key config - "db": map[string]interface{}{ - "stateful": "true", - }, - }) - require.NoError(t, err, "Error creating chainlink deployment") - testEnvironment = testEnvironment. - AddHelm(gethChartConfig). - AddHelmCharts(cd) - err = testEnvironment.Run() - require.NoError(t, err, "Error running test environment") - return testEnvironment -} - -func getGethChartConfig(testNetwork blockchain.EVMNetwork) environment.ConnectedChart { - evmConfig := eth.New(nil) - if !testNetwork.Simulated { - evmConfig = eth.New(ð.Props{ - NetworkName: testNetwork.Name, - Simulated: testNetwork.Simulated, - WsURLs: testNetwork.URLs, - }) + err = env.EVMClient.WaitForEvents() + if err != nil { + return nil, nil, [32]byte{}, err + } + err = vrfv2Contracts.Coordinator.CreateSubscription() + if err != nil { + return nil, nil, [32]byte{}, err + } + err = env.EVMClient.WaitForEvents() + if err != nil { + return nil, nil, [32]byte{}, err + } + err = vrfv2Contracts.Coordinator.AddConsumer(vrfConst.SubID, vrfv2Contracts.LoadTestConsumer.Address()) + if err != nil { + return nil, nil, [32]byte{}, err + } + err = FundVRFCoordinatorV2Subscription(lt, vrfv2Contracts.Coordinator, env.EVMClient, vrfConst.SubID, subFundingLINK) + if err != nil { + return nil, nil, [32]byte{}, err + } + jobs, err := CreateVRFV2Jobs(env.GetAPIs(), vrfv2Contracts.Coordinator, env.EVMClient, vrfConst.MinimumConfirmations) + if err != nil { + return nil, nil, [32]byte{}, err + } + // this part is here because VRFv2 can work with only a specific key + // [[EVM.KeySpecific]] + // Key = '...' + addr, err := env.CLNodes[0].API.PrimaryEthAddress() + if err != nil { + return nil, nil, [32]byte{}, err + } + nodeConfig := node.NewConfig(env.CLNodes[0].NodeConfig, + node.WithVRFv2EVMEstimator(addr), + ) + err = env.CLNodes[0].Restart(nodeConfig) + if err != nil { + return nil, nil, [32]byte{}, err } - return evmConfig + return env, vrfv2Contracts, jobs[0].KeyHash, nil } diff --git a/integration-tests/chaos/automation_chaos_test.go b/integration-tests/chaos/automation_chaos_test.go index 985cb11bcb2..dd2a39a57be 100644 --- a/integration-tests/chaos/automation_chaos_test.go +++ b/integration-tests/chaos/automation_chaos_test.go @@ -193,11 +193,11 @@ func TestAutomationChaos(t *testing.T) { return } - err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, 1, 2, ChaosGroupMinority) + err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=", 1, 2, ChaosGroupMinority) require.NoError(t, err) - err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, 3, 5, ChaosGroupMajority) + err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=", 3, 5, ChaosGroupMajority) require.NoError(t, err) - err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, 2, 5, ChaosGroupMajorityPlus) + err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=", 2, 5, ChaosGroupMajorityPlus) require.NoError(t, err) chainClient, err := blockchain.NewEVMClient(network, testEnvironment) @@ -235,7 +235,7 @@ func TestAutomationChaos(t *testing.T) { chainClient, ) - actions.CreateOCRKeeperJobs(t, chainlinkNodes, registry.Address(), network.ChainID, 0) + actions.CreateOCRKeeperJobs(t, chainlinkNodes, registry.Address(), network.ChainID, 0, eth_contracts.RegistryVersion_2_0) nodesWithoutBootstrap := chainlinkNodes[1:] ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, defaultOCRRegistryConfig, registrar.Address(), 5*time.Second) require.NoError(t, err, "Error building OCR config vars") @@ -243,17 +243,7 @@ func TestAutomationChaos(t *testing.T) { require.NoError(t, err, "Registry config should be be set successfully") require.NoError(t, chainClient.WaitForEvents(), "Waiting for config to be set") - consumers, upkeepIDs := actions.DeployConsumers( - t, - registry, - registrar, - linkToken, - contractDeployer, - chainClient, - numberOfUpkeeps, - big.NewInt(defaultLinkFunds), - defaultUpkeepGasLimit, - ) + consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, false) l.Info().Msg("Waiting for all upkeeps to be performed") diff --git a/integration-tests/chaos/ocr2vrf_chaos_test.go b/integration-tests/chaos/ocr2vrf_chaos_test.go index 00723a468b2..7d10107ba56 100644 --- a/integration-tests/chaos/ocr2vrf_chaos_test.go +++ b/integration-tests/chaos/ocr2vrf_chaos_test.go @@ -134,9 +134,9 @@ func TestOCR2VRFChaos(t *testing.T) { return } - err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, 1, 2, ChaosGroupMinority) + err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=", 1, 2, ChaosGroupMinority) require.NoError(t, err) - err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, 3, 5, ChaosGroupMajority) + err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=", 3, 5, ChaosGroupMajority) require.NoError(t, err) chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment) diff --git a/integration-tests/chaos/ocr_chaos_test.go b/integration-tests/chaos/ocr_chaos_test.go index 13c0db64ed1..58b4d5bea65 100644 --- a/integration-tests/chaos/ocr_chaos_test.go +++ b/integration-tests/chaos/ocr_chaos_test.go @@ -145,11 +145,11 @@ func TestOCRChaos(t *testing.T) { return } - err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, 1, 2, ChaosGroupMinority) + err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=", 1, 2, ChaosGroupMinority) require.NoError(t, err) - err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, 3, 5, ChaosGroupMajority) + err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=", 3, 5, ChaosGroupMajority) require.NoError(t, err) - err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, 2, 5, ChaosGroupMajorityPlus) + err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=", 2, 5, ChaosGroupMajorityPlus) require.NoError(t, err) chainClient, err := blockchain.NewEVMClient(blockchain.SimulatedEVMNetwork, testEnvironment) diff --git a/integration-tests/client/chainlink.go b/integration-tests/client/chainlink.go index b87377ca4e2..7d3bd0284d0 100644 --- a/integration-tests/client/chainlink.go +++ b/integration-tests/client/chainlink.go @@ -5,8 +5,6 @@ import ( "fmt" "math/big" "net/http" - "os" - "regexp" "strings" "sync" "time" @@ -15,8 +13,7 @@ import ( "github.com/go-resty/resty/v2" "github.com/rs/zerolog/log" "golang.org/x/sync/errgroup" - - "github.com/smartcontractkit/chainlink-env/environment" + "os" ) const ( @@ -31,12 +28,12 @@ var ( OneLINK = big.NewFloat(1e18) mapKeyTypeToChain = map[string]string{ "evm": "eTHKeys", - "solana": "encryptedStarkNetKeys", - "starknet": "encryptedSolanaKeys", + "solana": "encryptedSolanaKeys", + "starknet": "encryptedStarkNetKeys", } ) -type Chainlink struct { +type ChainlinkClient struct { APIClient *resty.Client Config *ChainlinkConfig pageSize int @@ -44,26 +41,39 @@ type Chainlink struct { ethAddresses []string } -// NewChainlink creates a new Chainlink model using a provided config -func NewChainlink(c *ChainlinkConfig) (*Chainlink, error) { - rc := resty.New().SetBaseURL(c.URL) - - if c.HTTPTimeout != nil { - rc.SetTimeout(*c.HTTPTimeout) +// NewChainlinkClient creates a new Chainlink model using a provided config +func NewChainlinkClient(c *ChainlinkConfig) (*ChainlinkClient, error) { + rc, err := initRestyClient(c.URL, c.Email, c.Password, c.HTTPTimeout) + if err != nil { + return nil, err } + _, isSet := os.LookupEnv("CL_CLIENT_DEBUG") + if isSet { + rc.SetDebug(true) + } + return &ChainlinkClient{ + Config: c, + APIClient: rc, + pageSize: 25, + }, nil +} - session := &Session{Email: c.Email, Password: c.Password} - +func initRestyClient(url string, email string, password string, timeout *time.Duration) (*resty.Client, error) { + rc := resty.New().SetBaseURL(url) + if timeout != nil { + rc.SetTimeout(*timeout) + } + session := &Session{Email: email, Password: password} // Retry the connection on boot up, sometimes pods can still be starting up and not ready to accept connections var resp *resty.Response var err error - retryCount := 5 + retryCount := 20 for i := 0; i < retryCount; i++ { resp, err = rc.R().SetBody(session).Post("/sessions") if err != nil { - log.Debug().Err(err).Str("URL", c.URL).Interface("Session Details", session).Msg("Error connecting to Chainlink node, retrying") - time.Sleep(3 * time.Second) - } else { // Connection successful + log.Debug().Err(err).Str("URL", url).Interface("Session Details", session).Msg("Error connecting to Chainlink node, retrying") + time.Sleep(5 * time.Second) + } else { break } } @@ -71,25 +81,16 @@ func NewChainlink(c *ChainlinkConfig) (*Chainlink, error) { return nil, fmt.Errorf("error connecting to chainlink node after %d attempts: %w", retryCount, err) } rc.SetCookies(resp.Cookies()) - return &Chainlink{ - Config: c, - APIClient: rc, - pageSize: 25, - }, nil + return rc, nil } // URL Chainlink instance http url -func (c *Chainlink) URL() string { +func (c *ChainlinkClient) URL() string { return c.Config.URL } -// Name Chainlink instance chart/service name -func (c *Chainlink) Name() string { - return c.Config.ChartName -} - // CreateJobRaw creates a Chainlink job based on the provided spec string -func (c *Chainlink) CreateJobRaw(spec string) (*Job, *http.Response, error) { +func (c *ChainlinkClient) CreateJobRaw(spec string) (*Job, *http.Response, error) { job := &Job{} log.Info().Str("Node URL", c.Config.URL).Msg("Creating Job") log.Trace().Str("Node URL", c.Config.URL).Str("Job Body", spec).Msg("Creating Job") @@ -107,7 +108,7 @@ func (c *Chainlink) CreateJobRaw(spec string) (*Job, *http.Response, error) { // MustCreateJob creates a Chainlink job based on the provided spec struct and returns error if // the request is unsuccessful -func (c *Chainlink) MustCreateJob(spec JobSpec) (*Job, error) { +func (c *ChainlinkClient) MustCreateJob(spec JobSpec) (*Job, error) { job, resp, err := c.CreateJob(spec) if err != nil { return nil, err @@ -116,7 +117,7 @@ func (c *Chainlink) MustCreateJob(spec JobSpec) (*Job, error) { } // CreateJob creates a Chainlink job based on the provided spec struct -func (c *Chainlink) CreateJob(spec JobSpec) (*Job, *http.Response, error) { +func (c *ChainlinkClient) CreateJob(spec JobSpec) (*Job, *http.Response, error) { job := &Job{} specString, err := spec.String() if err != nil { @@ -137,7 +138,7 @@ func (c *Chainlink) CreateJob(spec JobSpec) (*Job, *http.Response, error) { } // ReadJobs reads all jobs from the Chainlink node -func (c *Chainlink) ReadJobs() (*ResponseSlice, *http.Response, error) { +func (c *ChainlinkClient) ReadJobs() (*ResponseSlice, *http.Response, error) { specObj := &ResponseSlice{} log.Info().Str(NodeURL, c.Config.URL).Msg("Getting Jobs") resp, err := c.APIClient.R(). @@ -150,7 +151,7 @@ func (c *Chainlink) ReadJobs() (*ResponseSlice, *http.Response, error) { } // ReadJob reads a job with the provided ID from the Chainlink node -func (c *Chainlink) ReadJob(id string) (*Response, *http.Response, error) { +func (c *ChainlinkClient) ReadJob(id string) (*Response, *http.Response, error) { specObj := &Response{} log.Info().Str(NodeURL, c.Config.URL).Str("ID", id).Msg("Reading Job") resp, err := c.APIClient.R(). @@ -167,7 +168,7 @@ func (c *Chainlink) ReadJob(id string) (*Response, *http.Response, error) { // MustDeleteJob deletes a job with a provided ID from the Chainlink node and returns error if // the request is unsuccessful -func (c *Chainlink) MustDeleteJob(id string) error { +func (c *ChainlinkClient) MustDeleteJob(id string) error { resp, err := c.DeleteJob(id) if err != nil { return err @@ -176,7 +177,7 @@ func (c *Chainlink) MustDeleteJob(id string) error { } // DeleteJob deletes a job with a provided ID from the Chainlink node -func (c *Chainlink) DeleteJob(id string) (*http.Response, error) { +func (c *ChainlinkClient) DeleteJob(id string) (*http.Response, error) { log.Info().Str(NodeURL, c.Config.URL).Str("ID", id).Msg("Deleting Job") resp, err := c.APIClient.R(). SetPathParams(map[string]string{ @@ -190,7 +191,7 @@ func (c *Chainlink) DeleteJob(id string) (*http.Response, error) { } // CreateSpec creates a job spec on the Chainlink node -func (c *Chainlink) CreateSpec(spec string) (*Spec, *http.Response, error) { +func (c *ChainlinkClient) CreateSpec(spec string) (*Spec, *http.Response, error) { s := &Spec{} r := strings.NewReplacer("\n", "", " ", "", "\\", "") // Makes it more compact and readable for logging log.Info().Str(NodeURL, c.Config.URL).Str("Spec", r.Replace(spec)).Msg("Creating Spec") @@ -205,7 +206,7 @@ func (c *Chainlink) CreateSpec(spec string) (*Spec, *http.Response, error) { } // ReadSpec reads a job spec with the provided ID on the Chainlink node -func (c *Chainlink) ReadSpec(id string) (*Response, *http.Response, error) { +func (c *ChainlinkClient) ReadSpec(id string) (*Response, *http.Response, error) { specObj := &Response{} log.Info().Str(NodeURL, c.Config.URL).Str("ID", id).Msg("Reading Spec") resp, err := c.APIClient.R(). @@ -222,7 +223,7 @@ func (c *Chainlink) ReadSpec(id string) (*Response, *http.Response, error) { // MustReadRunsByJob attempts to read all runs for a job and returns error if // the request is unsuccessful -func (c *Chainlink) MustReadRunsByJob(jobID string) (*JobRunsResponse, error) { +func (c *ChainlinkClient) MustReadRunsByJob(jobID string) (*JobRunsResponse, error) { runsObj, resp, err := c.ReadRunsByJob(jobID) if err != nil { return nil, err @@ -231,7 +232,7 @@ func (c *Chainlink) MustReadRunsByJob(jobID string) (*JobRunsResponse, error) { } // ReadRunsByJob reads all runs for a job -func (c *Chainlink) ReadRunsByJob(jobID string) (*JobRunsResponse, *http.Response, error) { +func (c *ChainlinkClient) ReadRunsByJob(jobID string) (*JobRunsResponse, *http.Response, error) { runsObj := &JobRunsResponse{} log.Debug().Str(NodeURL, c.Config.URL).Str("JobID", jobID).Msg("Reading runs for a job") resp, err := c.APIClient.R(). @@ -247,7 +248,7 @@ func (c *Chainlink) ReadRunsByJob(jobID string) (*JobRunsResponse, *http.Respons } // DeleteSpec deletes a job spec with the provided ID from the Chainlink node -func (c *Chainlink) DeleteSpec(id string) (*http.Response, error) { +func (c *ChainlinkClient) DeleteSpec(id string) (*http.Response, error) { log.Info().Str(NodeURL, c.Config.URL).Str("ID", id).Msg("Deleting Spec") resp, err := c.APIClient.R(). SetPathParams(map[string]string{ @@ -262,7 +263,7 @@ func (c *Chainlink) DeleteSpec(id string) (*http.Response, error) { // MustCreateBridge creates a bridge on the Chainlink node based on the provided attributes and returns error if // the request is unsuccessful -func (c *Chainlink) MustCreateBridge(bta *BridgeTypeAttributes) error { +func (c *ChainlinkClient) MustCreateBridge(bta *BridgeTypeAttributes) error { resp, err := c.CreateBridge(bta) if err != nil { return err @@ -270,7 +271,7 @@ func (c *Chainlink) MustCreateBridge(bta *BridgeTypeAttributes) error { return VerifyStatusCode(resp.StatusCode, http.StatusOK) } -func (c *Chainlink) CreateBridge(bta *BridgeTypeAttributes) (*http.Response, error) { +func (c *ChainlinkClient) CreateBridge(bta *BridgeTypeAttributes) (*http.Response, error) { log.Info().Str(NodeURL, c.Config.URL).Str("Name", bta.Name).Msg("Creating Bridge") resp, err := c.APIClient.R(). SetBody(bta). @@ -282,7 +283,7 @@ func (c *Chainlink) CreateBridge(bta *BridgeTypeAttributes) (*http.Response, err } // ReadBridge reads a bridge from the Chainlink node based on the provided name -func (c *Chainlink) ReadBridge(name string) (*BridgeType, *http.Response, error) { +func (c *ChainlinkClient) ReadBridge(name string) (*BridgeType, *http.Response, error) { bt := BridgeType{} log.Info().Str(NodeURL, c.Config.URL).Str("Name", name).Msg("Reading Bridge") resp, err := c.APIClient.R(). @@ -298,7 +299,7 @@ func (c *Chainlink) ReadBridge(name string) (*BridgeType, *http.Response, error) } // DeleteBridge deletes a bridge on the Chainlink node based on the provided name -func (c *Chainlink) DeleteBridge(name string) (*http.Response, error) { +func (c *ChainlinkClient) DeleteBridge(name string) (*http.Response, error) { log.Info().Str(NodeURL, c.Config.URL).Str("Name", name).Msg("Deleting Bridge") resp, err := c.APIClient.R(). SetPathParams(map[string]string{ @@ -312,7 +313,7 @@ func (c *Chainlink) DeleteBridge(name string) (*http.Response, error) { } // CreateOCRKey creates an OCRKey on the Chainlink node -func (c *Chainlink) CreateOCRKey() (*OCRKey, *http.Response, error) { +func (c *ChainlinkClient) CreateOCRKey() (*OCRKey, *http.Response, error) { ocrKey := &OCRKey{} log.Info().Str(NodeURL, c.Config.URL).Msg("Creating OCR Key") resp, err := c.APIClient.R(). @@ -326,7 +327,7 @@ func (c *Chainlink) CreateOCRKey() (*OCRKey, *http.Response, error) { // MustReadOCRKeys reads all OCRKeys from the Chainlink node and returns error if // the request is unsuccessful -func (c *Chainlink) MustReadOCRKeys() (*OCRKeys, error) { +func (c *ChainlinkClient) MustReadOCRKeys() (*OCRKeys, error) { ocrKeys := &OCRKeys{} log.Info().Str(NodeURL, c.Config.URL).Msg("Reading OCR Keys") resp, err := c.APIClient.R(). @@ -348,7 +349,7 @@ func (c *Chainlink) MustReadOCRKeys() (*OCRKeys, error) { } // DeleteOCRKey deletes an OCRKey based on the provided ID -func (c *Chainlink) DeleteOCRKey(id string) (*http.Response, error) { +func (c *ChainlinkClient) DeleteOCRKey(id string) (*http.Response, error) { log.Info().Str(NodeURL, c.Config.URL).Str("ID", id).Msg("Deleting OCR Key") resp, err := c.APIClient.R(). SetPathParams(map[string]string{ @@ -362,7 +363,7 @@ func (c *Chainlink) DeleteOCRKey(id string) (*http.Response, error) { } // CreateOCR2Key creates an OCR2Key on the Chainlink node -func (c *Chainlink) CreateOCR2Key(chain string) (*OCR2Key, *http.Response, error) { +func (c *ChainlinkClient) CreateOCR2Key(chain string) (*OCR2Key, *http.Response, error) { ocr2Key := &OCR2Key{} log.Info().Str(NodeURL, c.Config.URL).Msg("Creating OCR2 Key") resp, err := c.APIClient.R(). @@ -378,7 +379,7 @@ func (c *Chainlink) CreateOCR2Key(chain string) (*OCR2Key, *http.Response, error } // ReadOCR2Keys reads all OCR2Keys from the Chainlink node -func (c *Chainlink) ReadOCR2Keys() (*OCR2Keys, *http.Response, error) { +func (c *ChainlinkClient) ReadOCR2Keys() (*OCR2Keys, *http.Response, error) { ocr2Keys := &OCR2Keys{} log.Info().Str(NodeURL, c.Config.URL).Msg("Reading OCR2 Keys") resp, err := c.APIClient.R(). @@ -388,7 +389,7 @@ func (c *Chainlink) ReadOCR2Keys() (*OCR2Keys, *http.Response, error) { } // MustReadOCR2Keys reads all OCR2Keys from the Chainlink node returns err if response not 200 -func (c *Chainlink) MustReadOCR2Keys() (*OCR2Keys, error) { +func (c *ChainlinkClient) MustReadOCR2Keys() (*OCR2Keys, error) { ocr2Keys := &OCR2Keys{} log.Info().Str(NodeURL, c.Config.URL).Msg("Reading OCR2 Keys") resp, err := c.APIClient.R(). @@ -402,7 +403,7 @@ func (c *Chainlink) MustReadOCR2Keys() (*OCR2Keys, error) { } // DeleteOCR2Key deletes an OCR2Key based on the provided ID -func (c *Chainlink) DeleteOCR2Key(id string) (*http.Response, error) { +func (c *ChainlinkClient) DeleteOCR2Key(id string) (*http.Response, error) { log.Info().Str(NodeURL, c.Config.URL).Str("ID", id).Msg("Deleting OCR2 Key") resp, err := c.APIClient.R(). SetPathParams(map[string]string{ @@ -416,7 +417,7 @@ func (c *Chainlink) DeleteOCR2Key(id string) (*http.Response, error) { } // CreateP2PKey creates an P2PKey on the Chainlink node -func (c *Chainlink) CreateP2PKey() (*P2PKey, *http.Response, error) { +func (c *ChainlinkClient) CreateP2PKey() (*P2PKey, *http.Response, error) { p2pKey := &P2PKey{} log.Info().Str(NodeURL, c.Config.URL).Msg("Creating P2P Key") resp, err := c.APIClient.R(). @@ -430,7 +431,7 @@ func (c *Chainlink) CreateP2PKey() (*P2PKey, *http.Response, error) { // MustReadP2PKeys reads all P2PKeys from the Chainlink node and returns error if // the request is unsuccessful -func (c *Chainlink) MustReadP2PKeys() (*P2PKeys, error) { +func (c *ChainlinkClient) MustReadP2PKeys() (*P2PKeys, error) { p2pKeys := &P2PKeys{} log.Info().Str(NodeURL, c.Config.URL).Msg("Reading P2P Keys") resp, err := c.APIClient.R(). @@ -452,7 +453,7 @@ func (c *Chainlink) MustReadP2PKeys() (*P2PKeys, error) { } // DeleteP2PKey deletes a P2PKey on the Chainlink node based on the provided ID -func (c *Chainlink) DeleteP2PKey(id int) (*http.Response, error) { +func (c *ChainlinkClient) DeleteP2PKey(id int) (*http.Response, error) { log.Info().Str(NodeURL, c.Config.URL).Int("ID", id).Msg("Deleting P2P Key") resp, err := c.APIClient.R(). SetPathParams(map[string]string{ @@ -467,7 +468,7 @@ func (c *Chainlink) DeleteP2PKey(id int) (*http.Response, error) { // MustReadETHKeys reads all ETH keys from the Chainlink node and returns error if // the request is unsuccessful -func (c *Chainlink) MustReadETHKeys() (*ETHKeys, error) { +func (c *ChainlinkClient) MustReadETHKeys() (*ETHKeys, error) { ethKeys := ÐKeys{} log.Info().Str(NodeURL, c.Config.URL).Msg("Reading ETH Keys") resp, err := c.APIClient.R(). @@ -484,7 +485,7 @@ func (c *Chainlink) MustReadETHKeys() (*ETHKeys, error) { } // UpdateEthKeyMaxGasPriceGWei updates the maxGasPriceGWei for an eth key -func (c *Chainlink) UpdateEthKeyMaxGasPriceGWei(keyId string, gWei int) (*ETHKey, *http.Response, error) { +func (c *ChainlinkClient) UpdateEthKeyMaxGasPriceGWei(keyId string, gWei int) (*ETHKey, *http.Response, error) { ethKey := ÐKey{} log.Info().Str(NodeURL, c.Config.URL).Str("ID", keyId).Int("maxGasPriceGWei", gWei).Msg("Update maxGasPriceGWei for eth key") resp, err := c.APIClient.R(). @@ -507,7 +508,7 @@ func (c *Chainlink) UpdateEthKeyMaxGasPriceGWei(keyId string, gWei int) (*ETHKey } // ReadPrimaryETHKey reads updated information about the Chainlink's primary ETH key -func (c *Chainlink) ReadPrimaryETHKey() (*ETHKeyData, error) { +func (c *ChainlinkClient) ReadPrimaryETHKey() (*ETHKeyData, error) { ethKeys, err := c.MustReadETHKeys() if err != nil { return nil, err @@ -519,7 +520,7 @@ func (c *Chainlink) ReadPrimaryETHKey() (*ETHKeyData, error) { } // ReadETHKeyAtIndex reads updated information about the Chainlink's ETH key at given index -func (c *Chainlink) ReadETHKeyAtIndex(keyIndex int) (*ETHKeyData, error) { +func (c *ChainlinkClient) ReadETHKeyAtIndex(keyIndex int) (*ETHKeyData, error) { ethKeys, err := c.MustReadETHKeys() if err != nil { return nil, err @@ -531,7 +532,7 @@ func (c *Chainlink) ReadETHKeyAtIndex(keyIndex int) (*ETHKeyData, error) { } // PrimaryEthAddress returns the primary ETH address for the Chainlink node -func (c *Chainlink) PrimaryEthAddress() (string, error) { +func (c *ChainlinkClient) PrimaryEthAddress() (string, error) { if c.primaryEthAddress == "" { ethKeys, err := c.MustReadETHKeys() if err != nil { @@ -543,7 +544,7 @@ func (c *Chainlink) PrimaryEthAddress() (string, error) { } // EthAddresses returns the ETH addresses for the Chainlink node -func (c *Chainlink) EthAddresses() ([]string, error) { +func (c *ChainlinkClient) EthAddresses() ([]string, error) { if len(c.ethAddresses) == 0 { ethKeys, err := c.MustReadETHKeys() c.ethAddresses = make([]string, len(ethKeys.Data)) @@ -558,7 +559,7 @@ func (c *Chainlink) EthAddresses() ([]string, error) { } // EthAddresses returns the ETH addresses of the Chainlink node for a specific chain id -func (c *Chainlink) EthAddressesForChain(chainId string) ([]string, error) { +func (c *ChainlinkClient) EthAddressesForChain(chainId string) ([]string, error) { var ethAddresses []string ethKeys, err := c.MustReadETHKeys() if err != nil { @@ -573,7 +574,7 @@ func (c *Chainlink) EthAddressesForChain(chainId string) ([]string, error) { } // PrimaryEthAddressForChain returns the primary ETH address for the Chainlink node for mentioned chain -func (c *Chainlink) PrimaryEthAddressForChain(chainId string) (string, error) { +func (c *ChainlinkClient) PrimaryEthAddressForChain(chainId string) (string, error) { ethKeys, err := c.MustReadETHKeys() if err != nil { return "", err @@ -587,7 +588,7 @@ func (c *Chainlink) PrimaryEthAddressForChain(chainId string) (string, error) { } // ExportEVMKeys exports Chainlink private EVM keys -func (c *Chainlink) ExportEVMKeys() ([]*ExportedEVMKey, error) { +func (c *ChainlinkClient) ExportEVMKeys() ([]*ExportedEVMKey, error) { exportedKeys := make([]*ExportedEVMKey, 0) keys, err := c.MustReadETHKeys() if err != nil { @@ -615,7 +616,7 @@ func (c *Chainlink) ExportEVMKeys() ([]*ExportedEVMKey, error) { } // ExportEVMKeysForChain exports Chainlink private EVM keys for a particular chain -func (c *Chainlink) ExportEVMKeysForChain(chainid string) ([]*ExportedEVMKey, error) { +func (c *ChainlinkClient) ExportEVMKeysForChain(chainid string) ([]*ExportedEVMKey, error) { exportedKeys := make([]*ExportedEVMKey, 0) keys, err := c.MustReadETHKeys() if err != nil { @@ -643,7 +644,7 @@ func (c *Chainlink) ExportEVMKeysForChain(chainid string) ([]*ExportedEVMKey, er } // CreateTxKey creates a tx key on the Chainlink node -func (c *Chainlink) CreateTxKey(chain string, chainId string) (*TxKey, *http.Response, error) { +func (c *ChainlinkClient) CreateTxKey(chain string, chainId string) (*TxKey, *http.Response, error) { txKey := &TxKey{} log.Info().Str(NodeURL, c.Config.URL).Msg("Creating Tx Key") resp, err := c.APIClient.R(). @@ -660,7 +661,7 @@ func (c *Chainlink) CreateTxKey(chain string, chainId string) (*TxKey, *http.Res } // ReadTxKeys reads all tx keys from the Chainlink node -func (c *Chainlink) ReadTxKeys(chain string) (*TxKeys, *http.Response, error) { +func (c *ChainlinkClient) ReadTxKeys(chain string) (*TxKeys, *http.Response, error) { txKeys := &TxKeys{} log.Info().Str(NodeURL, c.Config.URL).Msg("Reading Tx Keys") resp, err := c.APIClient.R(). @@ -676,7 +677,7 @@ func (c *Chainlink) ReadTxKeys(chain string) (*TxKeys, *http.Response, error) { } // DeleteTxKey deletes an tx key based on the provided ID -func (c *Chainlink) DeleteTxKey(chain string, id string) (*http.Response, error) { +func (c *ChainlinkClient) DeleteTxKey(chain string, id string) (*http.Response, error) { log.Info().Str(NodeURL, c.Config.URL).Str("ID", id).Msg("Deleting Tx Key") resp, err := c.APIClient.R(). SetPathParams(map[string]string{ @@ -692,7 +693,7 @@ func (c *Chainlink) DeleteTxKey(chain string, id string) (*http.Response, error) // MustReadTransactionAttempts reads all transaction attempts on the Chainlink node // and returns error if the request is unsuccessful -func (c *Chainlink) MustReadTransactionAttempts() (*TransactionsData, error) { +func (c *ChainlinkClient) MustReadTransactionAttempts() (*TransactionsData, error) { txsData := &TransactionsData{} log.Info().Str(NodeURL, c.Config.URL).Msg("Reading Transaction Attempts") resp, err := c.APIClient.R(). @@ -706,7 +707,7 @@ func (c *Chainlink) MustReadTransactionAttempts() (*TransactionsData, error) { } // ReadTransactions reads all transactions made by the Chainlink node -func (c *Chainlink) ReadTransactions() (*TransactionsData, *http.Response, error) { +func (c *ChainlinkClient) ReadTransactions() (*TransactionsData, *http.Response, error) { txsData := &TransactionsData{} log.Info().Str(NodeURL, c.Config.URL).Msg("Reading Transactions") resp, err := c.APIClient.R(). @@ -721,7 +722,7 @@ func (c *Chainlink) ReadTransactions() (*TransactionsData, *http.Response, error // MustSendNativeToken sends native token (ETH usually) of a specified amount from one of its addresses to the target address // and returns error if the request is unsuccessful // WARNING: The txdata object that Chainlink sends back is almost always blank. -func (c *Chainlink) MustSendNativeToken(amount *big.Int, fromAddress, toAddress string) (TransactionData, error) { +func (c *ChainlinkClient) MustSendNativeToken(amount *big.Int, fromAddress, toAddress string) (TransactionData, error) { request := SendEtherRequest{ DestinationAddress: toAddress, FromAddress: fromAddress, @@ -748,7 +749,7 @@ func (c *Chainlink) MustSendNativeToken(amount *big.Int, fromAddress, toAddress } // ReadVRFKeys reads all VRF keys from the Chainlink node -func (c *Chainlink) ReadVRFKeys() (*VRFKeys, *http.Response, error) { +func (c *ChainlinkClient) ReadVRFKeys() (*VRFKeys, *http.Response, error) { vrfKeys := &VRFKeys{} log.Info().Str(NodeURL, c.Config.URL).Msg("Reading VRF Keys") resp, err := c.APIClient.R(). @@ -765,7 +766,7 @@ func (c *Chainlink) ReadVRFKeys() (*VRFKeys, *http.Response, error) { // MustCreateVRFKey creates a VRF key on the Chainlink node // and returns error if the request is unsuccessful -func (c *Chainlink) MustCreateVRFKey() (*VRFKey, error) { +func (c *ChainlinkClient) MustCreateVRFKey() (*VRFKey, error) { vrfKey := &VRFKey{} log.Info().Str(NodeURL, c.Config.URL).Msg("Creating VRF Key") resp, err := c.APIClient.R(). @@ -778,7 +779,7 @@ func (c *Chainlink) MustCreateVRFKey() (*VRFKey, error) { } // ExportVRFKey exports a vrf key by key id -func (c *Chainlink) ExportVRFKey(keyId string) (*VRFExportKey, *http.Response, error) { +func (c *ChainlinkClient) ExportVRFKey(keyId string) (*VRFExportKey, *http.Response, error) { vrfExportKey := &VRFExportKey{} log.Info().Str(NodeURL, c.Config.URL).Str("ID", keyId).Msg("Exporting VRF Key") resp, err := c.APIClient.R(). @@ -794,7 +795,7 @@ func (c *Chainlink) ExportVRFKey(keyId string) (*VRFExportKey, *http.Response, e } // ImportVRFKey import vrf key -func (c *Chainlink) ImportVRFKey(vrfExportKey *VRFExportKey) (*VRFKey, *http.Response, error) { +func (c *ChainlinkClient) ImportVRFKey(vrfExportKey *VRFExportKey) (*VRFKey, *http.Response, error) { vrfKey := &VRFKey{} log.Info().Str(NodeURL, c.Config.URL).Str("ID", vrfExportKey.VrfKey.Address).Msg("Importing VRF Key") resp, err := c.APIClient.R(). @@ -809,7 +810,7 @@ func (c *Chainlink) ImportVRFKey(vrfExportKey *VRFExportKey) (*VRFKey, *http.Res // MustCreateDkgSignKey creates a DKG Sign key on the Chainlink node // and returns error if the request is unsuccessful -func (c *Chainlink) MustCreateDkgSignKey() (*DKGSignKey, error) { +func (c *ChainlinkClient) MustCreateDkgSignKey() (*DKGSignKey, error) { dkgSignKey := &DKGSignKey{} log.Info().Str(NodeURL, c.Config.URL).Msg("Creating DKG Sign Key") resp, err := c.APIClient.R(). @@ -823,7 +824,7 @@ func (c *Chainlink) MustCreateDkgSignKey() (*DKGSignKey, error) { // MustCreateDkgEncryptKey creates a DKG Encrypt key on the Chainlink node // and returns error if the request is unsuccessful -func (c *Chainlink) MustCreateDkgEncryptKey() (*DKGEncryptKey, error) { +func (c *ChainlinkClient) MustCreateDkgEncryptKey() (*DKGEncryptKey, error) { dkgEncryptKey := &DKGEncryptKey{} log.Info().Str(NodeURL, c.Config.URL).Msg("Creating DKG Encrypt Key") resp, err := c.APIClient.R(). @@ -836,7 +837,7 @@ func (c *Chainlink) MustCreateDkgEncryptKey() (*DKGEncryptKey, error) { } // MustReadDKGSignKeys reads all DKG Sign Keys from the Chainlink node returns err if response not 200 -func (c *Chainlink) MustReadDKGSignKeys() (*DKGSignKeys, error) { +func (c *ChainlinkClient) MustReadDKGSignKeys() (*DKGSignKeys, error) { dkgSignKeys := &DKGSignKeys{} log.Info().Str(NodeURL, c.Config.URL).Msg("Reading DKG Sign Keys") resp, err := c.APIClient.R(). @@ -850,7 +851,7 @@ func (c *Chainlink) MustReadDKGSignKeys() (*DKGSignKeys, error) { } // MustReadDKGEncryptKeys reads all DKG Encrypt Keys from the Chainlink node returns err if response not 200 -func (c *Chainlink) MustReadDKGEncryptKeys() (*DKGEncryptKeys, error) { +func (c *ChainlinkClient) MustReadDKGEncryptKeys() (*DKGEncryptKeys, error) { dkgEncryptKeys := &DKGEncryptKeys{} log.Info().Str(NodeURL, c.Config.URL).Msg("Reading DKG Encrypt Keys") resp, err := c.APIClient.R(). @@ -864,7 +865,7 @@ func (c *Chainlink) MustReadDKGEncryptKeys() (*DKGEncryptKeys, error) { } // CreateCSAKey creates a CSA key on the Chainlink node, only 1 CSA key per noe -func (c *Chainlink) CreateCSAKey() (*CSAKey, *http.Response, error) { +func (c *ChainlinkClient) CreateCSAKey() (*CSAKey, *http.Response, error) { csaKey := &CSAKey{} log.Info().Str(NodeURL, c.Config.URL).Msg("Creating CSA Key") resp, err := c.APIClient.R(). @@ -877,7 +878,7 @@ func (c *Chainlink) CreateCSAKey() (*CSAKey, *http.Response, error) { } // ReadCSAKeys reads CSA keys from the Chainlink node -func (c *Chainlink) ReadCSAKeys() (*CSAKeys, *http.Response, error) { +func (c *ChainlinkClient) ReadCSAKeys() (*CSAKeys, *http.Response, error) { csaKeys := &CSAKeys{} log.Info().Str(NodeURL, c.Config.URL).Msg("Reading CSA Keys") resp, err := c.APIClient.R(). @@ -893,7 +894,7 @@ func (c *Chainlink) ReadCSAKeys() (*CSAKeys, *http.Response, error) { } // CreateEI creates an EI on the Chainlink node based on the provided attributes and returns the respective secrets -func (c *Chainlink) CreateEI(eia *EIAttributes) (*EIKeyCreate, *http.Response, error) { +func (c *ChainlinkClient) CreateEI(eia *EIAttributes) (*EIKeyCreate, *http.Response, error) { ei := EIKeyCreate{} log.Info().Str(NodeURL, c.Config.URL).Str("Name", eia.Name).Msg("Creating External Initiator") resp, err := c.APIClient.R(). @@ -907,7 +908,7 @@ func (c *Chainlink) CreateEI(eia *EIAttributes) (*EIKeyCreate, *http.Response, e } // ReadEIs reads all of the configured EIs from the Chainlink node -func (c *Chainlink) ReadEIs() (*EIKeys, *http.Response, error) { +func (c *ChainlinkClient) ReadEIs() (*EIKeys, *http.Response, error) { ei := EIKeys{} log.Info().Str(NodeURL, c.Config.URL).Msg("Reading EI Keys") resp, err := c.APIClient.R(). @@ -920,7 +921,7 @@ func (c *Chainlink) ReadEIs() (*EIKeys, *http.Response, error) { } // DeleteEI deletes an external initiator in the Chainlink node based on the provided name -func (c *Chainlink) DeleteEI(name string) (*http.Response, error) { +func (c *ChainlinkClient) DeleteEI(name string) (*http.Response, error) { log.Info().Str(NodeURL, c.Config.URL).Str("Name", name).Msg("Deleting EI") resp, err := c.APIClient.R(). SetPathParams(map[string]string{ @@ -934,7 +935,7 @@ func (c *Chainlink) DeleteEI(name string) (*http.Response, error) { } // CreateCosmosChain creates a cosmos chain -func (c *Chainlink) CreateCosmosChain(chain *CosmosChainAttributes) (*CosmosChainCreate, *http.Response, error) { +func (c *ChainlinkClient) CreateCosmosChain(chain *CosmosChainAttributes) (*CosmosChainCreate, *http.Response, error) { response := CosmosChainCreate{} log.Info().Str(NodeURL, c.Config.URL).Str("Chain ID", chain.ChainID).Msg("Creating Cosmos Chain") resp, err := c.APIClient.R(). @@ -948,7 +949,7 @@ func (c *Chainlink) CreateCosmosChain(chain *CosmosChainAttributes) (*CosmosChai } // CreateCosmosNode creates a cosmos node -func (c *Chainlink) CreateCosmosNode(node *CosmosNodeAttributes) (*CosmosNodeCreate, *http.Response, error) { +func (c *ChainlinkClient) CreateCosmosNode(node *CosmosNodeAttributes) (*CosmosNodeCreate, *http.Response, error) { response := CosmosNodeCreate{} log.Info().Str(NodeURL, c.Config.URL).Str("Name", node.Name).Msg("Creating Cosmos Node") resp, err := c.APIClient.R(). @@ -962,7 +963,7 @@ func (c *Chainlink) CreateCosmosNode(node *CosmosNodeAttributes) (*CosmosNodeCre } // CreateSolanaChain creates a solana chain -func (c *Chainlink) CreateSolanaChain(chain *SolanaChainAttributes) (*SolanaChainCreate, *http.Response, error) { +func (c *ChainlinkClient) CreateSolanaChain(chain *SolanaChainAttributes) (*SolanaChainCreate, *http.Response, error) { response := SolanaChainCreate{} log.Info().Str(NodeURL, c.Config.URL).Str("Chain ID", chain.ChainID).Msg("Creating Solana Chain") resp, err := c.APIClient.R(). @@ -976,7 +977,7 @@ func (c *Chainlink) CreateSolanaChain(chain *SolanaChainAttributes) (*SolanaChai } // CreateSolanaNode creates a solana node -func (c *Chainlink) CreateSolanaNode(node *SolanaNodeAttributes) (*SolanaNodeCreate, *http.Response, error) { +func (c *ChainlinkClient) CreateSolanaNode(node *SolanaNodeAttributes) (*SolanaNodeCreate, *http.Response, error) { response := SolanaNodeCreate{} log.Info().Str(NodeURL, c.Config.URL).Str("Name", node.Name).Msg("Creating Solana Node") resp, err := c.APIClient.R(). @@ -990,7 +991,7 @@ func (c *Chainlink) CreateSolanaNode(node *SolanaNodeAttributes) (*SolanaNodeCre } // CreateStarkNetChain creates a starknet chain -func (c *Chainlink) CreateStarkNetChain(chain *StarkNetChainAttributes) (*StarkNetChainCreate, *http.Response, error) { +func (c *ChainlinkClient) CreateStarkNetChain(chain *StarkNetChainAttributes) (*StarkNetChainCreate, *http.Response, error) { response := StarkNetChainCreate{} log.Info().Str(NodeURL, c.Config.URL).Str("Chain ID", chain.ChainID).Msg("Creating StarkNet Chain") resp, err := c.APIClient.R(). @@ -1004,7 +1005,7 @@ func (c *Chainlink) CreateStarkNetChain(chain *StarkNetChainAttributes) (*StarkN } // CreateStarkNetNode creates a starknet node -func (c *Chainlink) CreateStarkNetNode(node *StarkNetNodeAttributes) (*StarkNetNodeCreate, *http.Response, error) { +func (c *ChainlinkClient) CreateStarkNetNode(node *StarkNetNodeAttributes) (*StarkNetNodeCreate, *http.Response, error) { response := StarkNetNodeCreate{} log.Info().Str(NodeURL, c.Config.URL).Str("Name", node.Name).Msg("Creating StarkNet Node") resp, err := c.APIClient.R(). @@ -1018,13 +1019,13 @@ func (c *Chainlink) CreateStarkNetNode(node *StarkNetNodeAttributes) (*StarkNetN } // InternalIP retrieves the inter-cluster IP of the Chainlink node, for use with inter-node communications -func (c *Chainlink) InternalIP() string { +func (c *ChainlinkClient) InternalIP() string { return c.Config.InternalIP } // Profile starts a profile session on the Chainlink node for a pre-determined length, then runs the provided function // to profile it. -func (c *Chainlink) Profile(profileTime time.Duration, profileFunction func(*Chainlink)) (*ChainlinkProfileResults, error) { +func (c *ChainlinkClient) Profile(profileTime time.Duration, profileFunction func(*ChainlinkClient)) (*ChainlinkProfileResults, error) { profileSeconds := int(profileTime.Seconds()) profileResults := NewBlankChainlinkProfileResults() profileErrorGroup := new(errgroup.Group) @@ -1085,70 +1086,10 @@ func (c *Chainlink) Profile(profileTime time.Duration, profileFunction func(*Cha } // SetPageSize globally sets the page -func (c *Chainlink) SetPageSize(size int) { +func (c *ChainlinkClient) SetPageSize(size int) { c.pageSize = size } -// ConnectChainlinkNodes creates new Chainlink clients -func ConnectChainlinkNodes(e *environment.Environment) ([]*Chainlink, error) { - var clients []*Chainlink - for _, nodeDetails := range e.ChainlinkNodeDetails { - c, err := NewChainlink(&ChainlinkConfig{ - URL: nodeDetails.LocalIP, - Email: "notreal@fakeemail.ch", - Password: "fj293fbBnlQ!f9vNs", - InternalIP: parseHostname(nodeDetails.InternalIP), - ChartName: nodeDetails.ChartName, - PodName: nodeDetails.PodName, - }) - if err != nil { - return nil, err - } - log.Debug(). - Str("URL", c.Config.URL). - Str("Internal IP", c.Config.InternalIP). - Str("Chart Name", c.Config.ChartName). - Str("Pod Name", c.Config.PodName). - Msg("Connected to Chainlink node") - clients = append(clients, c) - } - return clients, nil -} - -// ReconnectChainlinkNodes reconnects to Chainlink nodes after they have been modified, say through a Helm upgrade -// Note: Experimental as of now, will likely not work predictably. -func ReconnectChainlinkNodes(testEnvironment *environment.Environment, nodes []*Chainlink) (err error) { - for _, node := range nodes { - for _, details := range testEnvironment.ChainlinkNodeDetails { - if details.ChartName == node.Config.ChartName { // Make the link from client to pod consistent - node, err = NewChainlink(&ChainlinkConfig{ - URL: details.LocalIP, - Email: "notreal@fakeemail.ch", - Password: "fj293fbBnlQ!f9vNs", - InternalIP: parseHostname(details.InternalIP), - ChartName: details.ChartName, - PodName: details.PodName, - }) - if err != nil { - return err - } - log.Debug(). - Str("URL", node.Config.URL). - Str("Internal IP", node.Config.InternalIP). - Str("Chart Name", node.Config.ChartName). - Str("Pod Name", node.Config.PodName). - Msg("Reconnected to Chainlink node") - } - } - } - return nil -} - -func parseHostname(s string) string { - r := regexp.MustCompile(`://(?P.*):`) - return r.FindStringSubmatch(s)[1] -} - func VerifyStatusCode(actStatusCd, expStatusCd int) error { if actStatusCd != expStatusCd { return fmt.Errorf( @@ -1160,7 +1101,7 @@ func VerifyStatusCode(actStatusCd, expStatusCd int) error { return nil } -func CreateNodeKeysBundle(nodes []*Chainlink, chainName string, chainId string) ([]NodeKeysBundle, []*CLNodesWithKeys, error) { +func CreateNodeKeysBundle(nodes []*ChainlinkClient, chainName string, chainId string) ([]NodeKeysBundle, []*CLNodesWithKeys, error) { nkb := make([]NodeKeysBundle, 0) var clNodes []*CLNodesWithKeys for _, n := range nodes { @@ -1227,7 +1168,7 @@ func CreateNodeKeysBundle(nodes []*Chainlink, chainName string, chainId string) } // TrackForwarder track forwarder address in db. -func (c *Chainlink) TrackForwarder(chainID *big.Int, address common.Address) (*Forwarder, *http.Response, error) { +func (c *ChainlinkClient) TrackForwarder(chainID *big.Int, address common.Address) (*Forwarder, *http.Response, error) { response := &Forwarder{} request := ForwarderAttributes{ ChainID: chainID.String(), @@ -1253,7 +1194,7 @@ func (c *Chainlink) TrackForwarder(chainID *big.Int, address common.Address) (*F } // GetForwarders get list of tracked forwarders -func (c *Chainlink) GetForwarders() (*Forwarders, *http.Response, error) { +func (c *ChainlinkClient) GetForwarders() (*Forwarders, *http.Response, error) { response := &Forwarders{} log.Info().Str(NodeURL, c.Config.URL).Msg("Reading Tracked Forwarders") resp, err := c.APIClient.R(). @@ -1268,32 +1209,3 @@ func (c *Chainlink) GetForwarders() (*Forwarders, *http.Response, error) { } return response, resp.RawResponse, err } - -// UpgradeVersion upgrades the chainlink node to the new version -// Note: You need to call Run() on the test environment for changes to take effect -// Note: This function is not thread safe, call from a single thread -func (c *Chainlink) UpgradeVersion(testEnvironment *environment.Environment, newImage, newVersion string) error { - if newVersion == "" { - return fmt.Errorf("new version is empty") - } - if newImage == "" { - newImage = os.Getenv("CHAINLINK_IMAGE") - } - log.Info(). - Str("Chart Name", c.Config.ChartName). - Str("Old Image", os.Getenv("CHAINLINK_IMAGE")). - Str("Old Version", os.Getenv("CHAINLINK_VERSION")). - Str("New Image", newImage). - Str("New Version", newVersion). - Msg("Upgrading Chainlink Node") - upgradeVals := map[string]any{ - "chainlink": map[string]any{ - "image": map[string]any{ - "image": newImage, - "version": newVersion, - }, - }, - } - testEnvironment, err := testEnvironment.UpdateHelm(c.Config.ChartName, upgradeVals) - return err -} diff --git a/integration-tests/client/chainlink_k8s.go b/integration-tests/client/chainlink_k8s.go new file mode 100644 index 00000000000..4aa7c6d0fec --- /dev/null +++ b/integration-tests/client/chainlink_k8s.go @@ -0,0 +1,155 @@ +// Package client enables interaction with APIs of test components like the mockserver and Chainlink nodes +package client + +import ( + "fmt" + "os" + "regexp" + + "github.com/rs/zerolog/log" + + "github.com/smartcontractkit/chainlink-env/environment" +) + +type ChainlinkK8sClient struct { + ChartName string + PodName string + *ChainlinkClient +} + +// NewChainlink creates a new Chainlink model using a provided config +func NewChainlinkK8sClient(c *ChainlinkConfig, podName, chartName string) (*ChainlinkK8sClient, error) { + rc, err := initRestyClient(c.URL, c.Email, c.Password, c.HTTPTimeout) + if err != nil { + return nil, err + } + _, isSet := os.LookupEnv("CL_CLIENT_DEBUG") + if isSet { + rc.SetDebug(true) + } + return &ChainlinkK8sClient{ + ChainlinkClient: &ChainlinkClient{ + APIClient: rc, + pageSize: 25, + Config: c, + }, + ChartName: chartName, + PodName: podName, + }, nil +} + +// UpgradeVersion upgrades the chainlink node to the new version +// Note: You need to call Run() on the test environment for changes to take effect +// Note: This function is not thread safe, call from a single thread +func (c *ChainlinkK8sClient) UpgradeVersion(testEnvironment *environment.Environment, newImage, newVersion string) error { + if newVersion == "" { + return fmt.Errorf("new version is empty") + } + if newImage == "" { + newImage = os.Getenv("CHAINLINK_IMAGE") + } + log.Info(). + Str("Chart Name", c.ChartName). + Str("Old Image", os.Getenv("CHAINLINK_IMAGE")). + Str("Old Version", os.Getenv("CHAINLINK_VERSION")). + Str("New Image", newImage). + Str("New Version", newVersion). + Msg("Upgrading Chainlink Node") + upgradeVals := map[string]any{ + "chainlink": map[string]any{ + "image": map[string]any{ + "image": newImage, + "version": newVersion, + }, + }, + } + testEnvironment, err := testEnvironment.UpdateHelm(c.ChartName, upgradeVals) + return err +} + +// Name Chainlink instance chart/service name +func (c *ChainlinkK8sClient) Name() string { + return c.ChartName +} + +func parseHostname(s string) string { + r := regexp.MustCompile(`://(?P.*):`) + return r.FindStringSubmatch(s)[1] +} + +// ConnectChainlinkNodes creates new Chainlink clients +func ConnectChainlinkNodes(e *environment.Environment) ([]*ChainlinkK8sClient, error) { + var clients []*ChainlinkK8sClient + for _, nodeDetails := range e.ChainlinkNodeDetails { + c, err := NewChainlinkK8sClient(&ChainlinkConfig{ + URL: nodeDetails.LocalIP, + Email: "notreal@fakeemail.ch", + Password: "fj293fbBnlQ!f9vNs", + InternalIP: parseHostname(nodeDetails.InternalIP), + }, nodeDetails.PodName, nodeDetails.ChartName) + if err != nil { + return nil, err + } + log.Debug(). + Str("URL", c.Config.URL). + Str("Internal IP", c.Config.InternalIP). + Str("Chart Name", nodeDetails.ChartName). + Str("Pod Name", nodeDetails.PodName). + Msg("Connected to Chainlink node") + clients = append(clients, c) + } + return clients, nil +} + +// ReconnectChainlinkNodes reconnects to Chainlink nodes after they have been modified, say through a Helm upgrade +// Note: Experimental as of now, will likely not work predictably. +func ReconnectChainlinkNodes(testEnvironment *environment.Environment, nodes []*ChainlinkK8sClient) (err error) { + for _, node := range nodes { + for _, details := range testEnvironment.ChainlinkNodeDetails { + if details.ChartName == node.ChartName { // Make the link from client to pod consistent + node, err = NewChainlinkK8sClient(&ChainlinkConfig{ + URL: details.LocalIP, + Email: "notreal@fakeemail.ch", + Password: "fj293fbBnlQ!f9vNs", + InternalIP: parseHostname(details.InternalIP), + }, details.PodName, details.ChartName) + if err != nil { + return err + } + log.Debug(). + Str("URL", node.Config.URL). + Str("Internal IP", node.Config.InternalIP). + Str("Chart Name", node.ChartName). + Str("Pod Name", node.PodName). + Msg("Reconnected to Chainlink node") + } + } + } + return nil +} + +// ConnectChainlinkNodeURLs creates new Chainlink clients based on just URLs, should only be used inside K8s tests +func ConnectChainlinkNodeURLs(urls []string) ([]*ChainlinkK8sClient, error) { + var clients []*ChainlinkK8sClient + for _, url := range urls { + c, err := ConnectChainlinkNodeURL(url) + if err != nil { + return nil, err + } + clients = append(clients, c) + } + return clients, nil +} + +// ConnectChainlinkNodeURL creates a new Chainlink client based on just a URL, should only be used inside K8s tests +func ConnectChainlinkNodeURL(url string) (*ChainlinkK8sClient, error) { + return NewChainlinkK8sClient(&ChainlinkConfig{ + URL: url, + Email: "notreal@fakeemail.ch", + Password: "fj293fbBnlQ!f9vNs", + InternalIP: parseHostname(url), + }, + parseHostname(url), // a decent guess + "connectedNodeByURL", // an intentionally bad decision + ) +} diff --git a/integration-tests/client/chainlink_models.go b/integration-tests/client/chainlink_models.go index 2a3d2a42a53..881b2d125e8 100644 --- a/integration-tests/client/chainlink_models.go +++ b/integration-tests/client/chainlink_models.go @@ -21,9 +21,7 @@ type ChainlinkConfig struct { URL string Email string Password string - InternalIP string // Can change if the node is restarted. Prefer RemoteURL if possible - ChartName string - PodName string + InternalIP string HTTPTimeout *time.Duration } @@ -430,7 +428,6 @@ type CosmosChainConfig struct { type CosmosChainAttributes struct { ChainID string `json:"chainID"` Config CosmosChainConfig `json:"config"` - FCDURL string `json:"fcdURL" db:"fcd_url"` } // CosmosChain is the model that represents the terra chain when read @@ -600,7 +597,7 @@ schedule = "{{.Schedule}}" observationSource = """ {{.ObservationSource}} """` - return marshallTemplate(c, "CRON Job", cronJobTemplateString) + return MarshallTemplate(c, "CRON Job", cronJobTemplateString) } // PipelineSpec common API call pipeline @@ -620,7 +617,7 @@ func (d *PipelineSpec) String() (string, error) { fetch [type=bridge name="{{.BridgeTypeAttributes.Name}}" requestData="{{.BridgeTypeAttributes.RequestData}}"]; parse [type=jsonparse path="{{.DataPath}}"]; fetch -> parse;` - return marshallTemplate(d, "API call pipeline template", sourceString) + return MarshallTemplate(d, "API call pipeline template", sourceString) } // VRFV2TxPipelineSpec VRFv2 request with tx callback @@ -657,7 +654,7 @@ simulate [type=ethcall contract="{{ .Address }}" data="$(vrf.output)"] decode_log->vrf->estimate_gas->simulate` - return marshallTemplate(d, "VRFV2 pipeline template", sourceString) + return MarshallTemplate(d, "VRFV2 pipeline template", sourceString) } // VRFTxPipelineSpec VRF request with tx callback @@ -689,7 +686,7 @@ submit_tx [type=ethtx to="{{.Address}}" data="$(encode_tx)" txMeta="{\\"requestTxHash\\": $(jobRun.logTxHash),\\"requestID\\": $(decode_log.requestID),\\"jobID\\": $(jobSpec.databaseID)}"] decode_log->vrf->encode_tx->submit_tx` - return marshallTemplate(d, "VRF pipeline template", sourceString) + return MarshallTemplate(d, "VRF pipeline template", sourceString) } // DirectRequestTxPipelineSpec oracle request with tx callback @@ -721,7 +718,7 @@ func (d *DirectRequestTxPipelineSpec) String() (string, error) { parse [type=jsonparse path="{{.DataPath}}"] submit [type=ethtx to="$(decode_log.requester)" data="$(encode_tx)" failOnRevert=true] decode_log -> fetch -> parse -> encode_tx -> submit` - return marshallTemplate(d, "Direct request pipeline template", sourceString) + return MarshallTemplate(d, "Direct request pipeline template", sourceString) } // DirectRequestJobSpec represents a direct request spec @@ -748,7 +745,7 @@ minIncomingConfirmations = {{.MinIncomingConfirmations}} observationSource = """ {{.ObservationSource}} """` - return marshallTemplate(d, "Direct Request Job", directRequestTemplateString) + return MarshallTemplate(d, "Direct Request Job", directRequestTemplateString) } // FluxMonitorJobSpec represents a flux monitor spec @@ -790,7 +787,7 @@ maxTaskDuration = {{if not .Precision}} "180s" {{else}} {{.Precision}} {{end}} observationSource = """ {{.ObservationSource}} """` - return marshallTemplate(f, "Flux Monitor Job", fluxMonitorTemplateString) + return MarshallTemplate(f, "Flux Monitor Job", fluxMonitorTemplateString) } // KeeperJobSpec represents a V2 keeper spec @@ -814,7 +811,7 @@ contractAddress = "{{.ContractAddress}}" fromAddress = "{{.FromAddress}}" minIncomingConfirmations = {{.MinIncomingConfirmations}} ` - return marshallTemplate(k, "Keeper Job", keeperTemplateString) + return MarshallTemplate(k, "Keeper Job", keeperTemplateString) } // OCRBootstrapJobSpec represents the spec for bootstrapping an OCR job, given to one node that then must be linked @@ -845,26 +842,26 @@ contractAddress = "{{.ContractAddress}}" p2pBootstrapPeers = [] isBootstrapPeer = {{.IsBootstrapPeer}} p2pPeerID = "{{.P2PPeerID}}"` - return marshallTemplate(o, "OCR Bootstrap Job", ocrTemplateString) + return MarshallTemplate(o, "OCR Bootstrap Job", ocrTemplateString) } // OCRTaskJobSpec represents an OCR job that is given to other nodes, meant to communicate with the bootstrap node, // and provide their answers type OCRTaskJobSpec struct { - Name string `toml:"name"` - BlockChainTimeout time.Duration `toml:"blockchainTimeout"` // Optional - ContractConfirmations int `toml:"contractConfigConfirmations"` // Optional - TrackerPollInterval time.Duration `toml:"contractConfigTrackerPollInterval"` // Optional - TrackerSubscribeInterval time.Duration `toml:"contractConfigTrackerSubscribeInterval"` // Optional - ForwardingAllowed bool `toml:"forwardingAllowed"` // Optional, by default false - ContractAddress string `toml:"contractAddress"` // Address of the OCR contract - P2PBootstrapPeers []*Chainlink `toml:"p2pBootstrapPeers"` // P2P ID of the bootstrap node - IsBootstrapPeer bool `toml:"isBootstrapPeer"` // Typically false - P2PPeerID string `toml:"p2pPeerID"` // This node's P2P ID - KeyBundleID string `toml:"keyBundleID"` // ID of this node's OCR key bundle - MonitoringEndpoint string `toml:"monitoringEndpoint"` // Typically "chain.link:4321" - TransmitterAddress string `toml:"transmitterAddress"` // ETH address this node will use to transmit its answer - ObservationSource string `toml:"observationSource"` // List of commands for the Chainlink node + Name string `toml:"name"` + BlockChainTimeout time.Duration `toml:"blockchainTimeout"` // Optional + ContractConfirmations int `toml:"contractConfigConfirmations"` // Optional + TrackerPollInterval time.Duration `toml:"contractConfigTrackerPollInterval"` // Optional + TrackerSubscribeInterval time.Duration `toml:"contractConfigTrackerSubscribeInterval"` // Optional + ForwardingAllowed bool `toml:"forwardingAllowed"` // Optional, by default false + ContractAddress string `toml:"contractAddress"` // Address of the OCR contract + P2PBootstrapPeers []*ChainlinkClient `toml:"p2pBootstrapPeers"` // P2P ID of the bootstrap node + IsBootstrapPeer bool `toml:"isBootstrapPeer"` // Typically false + P2PPeerID string `toml:"p2pPeerID"` // This node's P2P ID + KeyBundleID string `toml:"keyBundleID"` // ID of this node's OCR key bundle + MonitoringEndpoint string `toml:"monitoringEndpoint"` // Typically "chain.link:4321" + TransmitterAddress string `toml:"transmitterAddress"` // ETH address this node will use to transmit its answer + ObservationSource string `toml:"observationSource"` // List of commands for the Chainlink node } // P2PData holds the remote ip and the peer id and port @@ -956,7 +953,7 @@ observationSource = """ {{.ObservationSource}} """` - return marshallTemplate(specWrap, "OCR Job", ocrTemplateString) + return MarshallTemplate(specWrap, "OCR Job", ocrTemplateString) } // OCR2TaskJobSpec represents an OCR2 job that is given to other nodes, meant to communicate with the bootstrap node, @@ -1064,13 +1061,13 @@ observationSource = """ [relayConfig]{{range $key, $value := .RelayConfig}} {{$key}} = {{$value}}{{end}} ` - return marshallTemplate(specWrap, "OCR2 Job", ocr2TemplateString) + return MarshallTemplate(specWrap, "OCR2 Job", ocr2TemplateString) } // VRFV2JobSpec represents a VRFV2 job type VRFV2JobSpec struct { Name string `toml:"name"` - CoordinatorAddress string `toml:"coordinatorAddress"` // Address of the VRF Coordinator contract + CoordinatorAddress string `toml:"coordinatorAddress"` // Address of the VRF CoordinatorV2 contract PublicKey string `toml:"publicKey"` // Public key of the proving key ExternalJobID string `toml:"externalJobID"` ObservationSource string `toml:"observationSource"` // List of commands for the Chainlink node @@ -1104,13 +1101,13 @@ observationSource = """ {{.ObservationSource}} """ ` - return marshallTemplate(v, "VRFV2 Job", vrfTemplateString) + return MarshallTemplate(v, "VRFV2 Job", vrfTemplateString) } // VRFJobSpec represents a VRF job type VRFJobSpec struct { Name string `toml:"name"` - CoordinatorAddress string `toml:"coordinatorAddress"` // Address of the VRF Coordinator contract + CoordinatorAddress string `toml:"coordinatorAddress"` // Address of the VRF CoordinatorV2 contract PublicKey string `toml:"publicKey"` // Public key of the proving key ExternalJobID string `toml:"externalJobID"` ObservationSource string `toml:"observationSource"` // List of commands for the Chainlink node @@ -1134,13 +1131,13 @@ observationSource = """ {{.ObservationSource}} """ ` - return marshallTemplate(v, "VRF Job", vrfTemplateString) + return MarshallTemplate(v, "VRF Job", vrfTemplateString) } // BlockhashStoreJobSpec represents a blockhashstore job type BlockhashStoreJobSpec struct { Name string `toml:"name"` - CoordinatorV2Address string `toml:"coordinatorV2Address"` // Address of the VRF Coordinator contract + CoordinatorV2Address string `toml:"coordinatorV2Address"` // Address of the VRF CoordinatorV2 contract WaitBlocks int `toml:"waitBlocks"` LookbackBlocks int `toml:"lookbackBlocks"` BlockhashStoreAddress string `toml:"blockhashStoreAddress"` @@ -1166,7 +1163,7 @@ pollPeriod = "{{.PollPeriod}}" runTimeout = "{{.RunTimeout}}" evmChainID = "{{.EVMChainID}}" ` - return marshallTemplate(b, "BlockhashStore Job", vrfTemplateString) + return MarshallTemplate(b, "BlockhashStore Job", vrfTemplateString) } // WebhookJobSpec reprsents a webhook job @@ -1191,7 +1188,7 @@ externalInitiators = [ observationSource = """ {{.ObservationSource}} """` - return marshallTemplate(w, "Webhook Job", webHookTemplateString) + return MarshallTemplate(w, "Webhook Job", webHookTemplateString) } // ObservationSourceSpecHTTP creates a http GET task spec for json data @@ -1211,7 +1208,7 @@ func ObservationSourceSpecBridge(bta *BridgeTypeAttributes) string { } // marshallTemplate Helper to marshall templates -func marshallTemplate(jobSpec interface{}, name, templateString string) (string, error) { +func MarshallTemplate(jobSpec interface{}, name, templateString string) (string, error) { var buf bytes.Buffer tmpl, err := template.New(name).Parse(templateString) if err != nil { @@ -1291,7 +1288,7 @@ func NewBlankChainlinkProfileResults() *ChainlinkProfileResults { } type CLNodesWithKeys struct { - Node *Chainlink + Node *ChainlinkClient KeysBundle NodeKeysBundle } diff --git a/integration-tests/contracts/contract_deployer.go b/integration-tests/contracts/contract_deployer.go index 2de959db6de..578ca1ea549 100644 --- a/integration-tests/contracts/contract_deployer.go +++ b/integration-tests/contracts/contract_deployer.go @@ -10,28 +10,38 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/rs/zerolog/log" - + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/libocr/gethwrappers/offchainaggregator" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" ocrConfigHelper "github.com/smartcontractkit/libocr/offchainreporting/confighelper" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - + eth_contracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_load_test_client" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_consumer_benchmark" + automationForwarderLogic "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_forwarder_logic" + registrar21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registrar_wrapper2_1" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/flags_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/flux_aggregator_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/functions_billing_registry_events_mock" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/functions_oracle_events_mock" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/gas_wrapper" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/gas_wrapper_mock" + iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registrar_wrapper1_2" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registrar_wrapper1_2_mock" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registrar_wrapper2_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_logic1_3" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_logic2_0" + registrylogica21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_logic_a_wrapper_2_1" + registrylogicb21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_logic_b_wrapper_2_1" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_1" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_1_mock" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_2" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_3" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper2_0" + registry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper_2_1" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/log_upkeep_counter_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_aggregator_proxy" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_ethlink_aggregator_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_gas_aggregator_wrapper" @@ -39,8 +49,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/oracle_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/test_api_consumer_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/upkeep_transcoder" - - eth_contracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" ) // ContractDeployer is an interface for abstracting the contract deployment methods across network implementations @@ -52,6 +60,7 @@ type ContractDeployer interface { DeployLinkTokenContract() (LinkToken, error) LoadLinkToken(address common.Address) (LinkToken, error) DeployOffChainAggregator(linkAddr string, offchainOptions OffchainOptions) (OffchainAggregator, error) + LoadOffChainAggregator(address *common.Address) (OffchainAggregator, error) DeployVRFContract() (VRF, error) DeployMockETHLINKFeed(answer *big.Int) (MockETHLINKFeed, error) LoadETHLINKFeed(address common.Address) (MockETHLINKFeed, error) @@ -63,6 +72,7 @@ type ContractDeployer interface { DeployKeeperRegistry(opts *KeeperRegistryOpts) (KeeperRegistry, error) LoadKeeperRegistry(address common.Address, registryVersion eth_contracts.KeeperRegistryVersion) (KeeperRegistry, error) DeployKeeperConsumer(updateInterval *big.Int) (KeeperConsumer, error) + DeployAutomationLogTriggerConsumer(testInterval *big.Int) (KeeperConsumer, error) DeployKeeperConsumerPerformance( testBlockRange, averageCadence, @@ -88,11 +98,17 @@ type ContractDeployer interface { DeployOperatorFactory(linkAddr string) (OperatorFactory, error) DeployStaking(params eth_contracts.StakingPoolConstructorParams) (Staking, error) DeployBatchBlockhashStore(blockhashStoreAddr string) (BatchBlockhashStore, error) + DeployFunctionsLoadTestClient(router string) (FunctionsLoadTestClient, error) DeployFunctionsOracleEventsMock() (FunctionsOracleEventsMock, error) DeployFunctionsBillingRegistryEventsMock() (FunctionsBillingRegistryEventsMock, error) + DeployStakingEventsMock() (StakingEventsMock, error) + DeployOffchainAggregatorEventsMock() (OffchainAggregatorEventsMock, error) DeployMockAggregatorProxy(aggregatorAddr string) (MockAggregatorProxy, error) DeployOffchainAggregatorV2(linkAddr string, offchainOptions OffchainOptions) (OffchainAggregatorV2, error) DeployKeeperRegistryCheckUpkeepGasUsageWrapper(keeperRegistryAddr string) (KeeperRegistryCheckUpkeepGasUsageWrapper, error) + DeployKeeperRegistry11Mock() (KeeperRegistry11Mock, error) + DeployKeeperRegistrar12Mock() (KeeperRegistrar12Mock, error) + DeployKeeperGasWrapperMock() (KeeperGasWrapperMock, error) } // NewContractDeployer returns an instance of a contract deployer based on the client type @@ -116,6 +132,10 @@ func NewContractDeployer(bcClient blockchain.EVMClient) (ContractDeployer, error return &CeloContractDeployer{NewEthereumContractDeployer(clientImpl)}, nil case *blockchain.QuorumClient: return &QuorumContractDeployer{NewEthereumContractDeployer(clientImpl)}, nil + case *blockchain.BSCClient: + return &BSCContractDeployer{NewEthereumContractDeployer(clientImpl)}, nil + case *blockchain.ScrollClient: + return &ScrollContractDeployer{NewEthereumContractDeployer(clientImpl)}, nil } return nil, errors.New("unknown blockchain client implementation for contract deployer, register blockchain client in NewContractDeployer") } @@ -162,6 +182,14 @@ type QuorumContractDeployer struct { *EthereumContractDeployer } +type BSCContractDeployer struct { + *EthereumContractDeployer +} + +type ScrollContractDeployer struct { + *EthereumContractDeployer +} + // NewEthereumContractDeployer returns an instantiated instance of the ETH contract deployer func NewEthereumContractDeployer(ethClient blockchain.EVMClient) *EthereumContractDeployer { return &EthereumContractDeployer{ @@ -250,6 +278,23 @@ func (e *EthereumContractDeployer) DeployStaking(params eth_contracts.StakingPoo }, nil } +func (e *EthereumContractDeployer) DeployFunctionsLoadTestClient(router string) (FunctionsLoadTestClient, error) { + address, _, instance, err := e.client.DeployContract("FunctionsLoadTestClient", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return functions_load_test_client.DeployFunctionsLoadTestClient(auth, backend, common.HexToAddress(router)) + }) + if err != nil { + return nil, err + } + return &EthereumFunctionsLoadTestClient{ + client: e.client, + instance: instance.(*functions_load_test_client.FunctionsLoadTestClient), + address: *address, + }, nil +} + func (e *EthereumContractDeployer) DeployFunctionsOracleEventsMock() (FunctionsOracleEventsMock, error) { address, _, instance, err := e.client.DeployContract("FunctionsOracleEventsMock", func( auth *bind.TransactOpts, @@ -284,6 +329,91 @@ func (e *EthereumContractDeployer) DeployFunctionsBillingRegistryEventsMock() (F }, nil } +func (e *EthereumContractDeployer) DeployStakingEventsMock() (StakingEventsMock, error) { + address, _, instance, err := e.client.DeployContract("StakingEventsMock", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return eth_contracts.DeployStakingEventsMock(auth, backend) + }) + if err != nil { + return nil, err + } + return &EthereumStakingEventsMock{ + client: e.client, + eventsMock: instance.(*eth_contracts.StakingEventsMock), + address: address, + }, nil +} + +func (e *EthereumContractDeployer) DeployKeeperRegistry11Mock() (KeeperRegistry11Mock, error) { + address, _, instance, err := e.client.DeployContract("KeeperRegistry11Mock", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return keeper_registry_wrapper1_1_mock.DeployKeeperRegistryMock(auth, backend) + }) + if err != nil { + return nil, err + } + return &EthereumKeeperRegistry11Mock{ + client: e.client, + registryMock: instance.(*keeper_registry_wrapper1_1_mock.KeeperRegistryMock), + address: address, + }, nil +} + +func (e *EthereumContractDeployer) DeployKeeperRegistrar12Mock() (KeeperRegistrar12Mock, error) { + address, _, instance, err := e.client.DeployContract("KeeperRegistrar12Mock", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return keeper_registrar_wrapper1_2_mock.DeployKeeperRegistrarMock(auth, backend) + }) + if err != nil { + return nil, err + } + return &EthereumKeeperRegistrar12Mock{ + client: e.client, + registrarMock: instance.(*keeper_registrar_wrapper1_2_mock.KeeperRegistrarMock), + address: address, + }, nil +} + +func (e *EthereumContractDeployer) DeployKeeperGasWrapperMock() (KeeperGasWrapperMock, error) { + address, _, instance, err := e.client.DeployContract("KeeperGasWrapperMock", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return gas_wrapper_mock.DeployKeeperRegistryCheckUpkeepGasUsageWrapperMock(auth, backend) + }) + if err != nil { + return nil, err + } + return &EthereumKeeperGasWrapperMock{ + client: e.client, + gasWrapperMock: instance.(*gas_wrapper_mock.KeeperRegistryCheckUpkeepGasUsageWrapperMock), + address: address, + }, nil +} + +func (e *EthereumContractDeployer) DeployOffchainAggregatorEventsMock() (OffchainAggregatorEventsMock, error) { + address, _, instance, err := e.client.DeployContract("OffchainAggregatorEventsMock", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return eth_contracts.DeployOffchainAggregatorEventsMock(auth, backend) + }) + if err != nil { + return nil, err + } + return &EthereumOffchainAggregatorEventsMock{ + client: e.client, + eventsMock: instance.(*eth_contracts.OffchainAggregatorEventsMock), + address: address, + }, nil +} + // DeployLinkTokenContract deploys a Link Token contract to an EVM chain func (e *EthereumContractDeployer) DeployLinkTokenContract() (LinkToken, error) { linkTokenAddress, _, instance, err := e.client.DeployContract("LINK Token", func( @@ -403,6 +533,24 @@ func (e *EthereumContractDeployer) DeployOffChainAggregator( }, err } +// LoadOffChainAggregator loads an already deployed offchain aggregator contract +func (e *EthereumContractDeployer) LoadOffChainAggregator(address *common.Address) (OffchainAggregator, error) { + instance, err := e.client.LoadContract("OffChainAggregator", *address, func( + address common.Address, + backend bind.ContractBackend, + ) (interface{}, error) { + return offchainaggregator.NewOffchainAggregator(address, backend) + }) + if err != nil { + return nil, err + } + return &EthereumOffchainAggregator{ + address: address, + client: e.client, + ocr: instance.(*offchainaggregator.OffchainAggregator), + }, err +} + // DeployAPIConsumer deploys api consumer for oracle func (e *EthereumContractDeployer) DeployAPIConsumer(linkAddr string) (APIConsumer, error) { addr, _, instance, err := e.client.DeployContract("TestAPIConsumer", func( @@ -550,6 +698,36 @@ func (e *EthereumContractDeployer) DeployKeeperRegistrar(registryVersion eth_con registrar20: instance.(*keeper_registrar_wrapper2_0.KeeperRegistrar), address: address, }, err + } else if registryVersion == eth_contracts.RegistryVersion_2_1 { + // deploy registrar 2.1 + address, _, instance, err := e.client.DeployContract("AutomationRegistrar", func( + opts *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + // set default TriggerType to 0(conditional), AutoApproveConfigType to 2(auto approve enabled), AutoApproveMaxAllowed to 1000 + triggerConfigs := []registrar21.AutomationRegistrar21InitialTriggerConfig{ + {TriggerType: 0, AutoApproveType: 2, AutoApproveMaxAllowed: 1000}, + {TriggerType: 1, AutoApproveType: 2, AutoApproveMaxAllowed: 1000}, + } + + return registrar21.DeployAutomationRegistrar( + opts, + backend, + common.HexToAddress(linkAddr), + common.HexToAddress(registrarSettings.RegistryAddr), + registrarSettings.MinLinkJuels, + triggerConfigs) + }) + + if err != nil { + return nil, err + } + + return &EthereumKeeperRegistrar{ + client: e.client, + registrar21: instance.(*registrar21.AutomationRegistrar), + address: address, + }, err } // non OCR registrar address, _, instance, err := e.client.DeployContract("KeeperRegistrar", func( @@ -589,21 +767,37 @@ func (e *EthereumContractDeployer) LoadKeeperRegistrar(address common.Address, r client: e.client, registrar: instance.(*keeper_registrar_wrapper1_2.KeeperRegistrar), }, err + } else if registryVersion == eth_contracts.RegistryVersion_2_0 { + instance, err := e.client.LoadContract("KeeperRegistrar", address, func( + address common.Address, + backend bind.ContractBackend, + ) (interface{}, error) { + return keeper_registrar_wrapper2_0.NewKeeperRegistrar(address, backend) + }) + if err != nil { + return nil, err + } + return &EthereumKeeperRegistrar{ + address: &address, + client: e.client, + registrar20: instance.(*keeper_registrar_wrapper2_0.KeeperRegistrar), + }, err + } else { + instance, err := e.client.LoadContract("AutomationRegistrar", address, func( + address common.Address, + backend bind.ContractBackend, + ) (interface{}, error) { + return registrar21.NewAutomationRegistrar(address, backend) + }) + if err != nil { + return nil, err + } + return &EthereumKeeperRegistrar{ + address: &address, + client: e.client, + registrar21: instance.(*registrar21.AutomationRegistrar), + }, err } - instance, err := e.client.LoadContract("KeeperRegistrar", address, func( - address common.Address, - backend bind.ContractBackend, - ) (interface{}, error) { - return keeper_registrar_wrapper2_0.NewKeeperRegistrar(address, backend) - }) - if err != nil { - return nil, err - } - return &EthereumKeeperRegistrar{ - address: &address, - client: e.client, - registrar20: instance.(*keeper_registrar_wrapper2_0.KeeperRegistrar), - }, err } func (e *EthereumContractDeployer) DeployKeeperRegistry( @@ -793,6 +987,93 @@ func (e *EthereumContractDeployer) DeployKeeperRegistry( address: address, }, err + case eth_contracts.RegistryVersion_2_1: + automationForwarderLogicAddr, _, _, err := e.client.DeployContract("automationForwarderLogic", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return automationForwarderLogic.DeployAutomationForwarderLogic(auth, backend) + }) + + if err != nil { + return nil, err + } + + if err := e.client.WaitForEvents(); err != nil { + return nil, err + } + + registryLogicBAddr, _, _, err := e.client.DeployContract("KeeperRegistryLogicB2_1", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + + return registrylogicb21.DeployKeeperRegistryLogicB( + auth, + backend, + mode, + common.HexToAddress(opts.LinkAddr), + common.HexToAddress(opts.ETHFeedAddr), + common.HexToAddress(opts.GasFeedAddr), + *automationForwarderLogicAddr, + ) + }) + if err != nil { + return nil, err + } + + if err := e.client.WaitForEvents(); err != nil { + return nil, err + } + + registryLogicAAddr, _, _, err := e.client.DeployContract("KeeperRegistryLogicA2_1", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + + return registrylogica21.DeployKeeperRegistryLogicA( + auth, + backend, + *registryLogicBAddr, + ) + }) + if err != nil { + return nil, err + } + if err := e.client.WaitForEvents(); err != nil { + return nil, err + } + + address, _, _, err := e.client.DeployContract("KeeperRegistry2_1", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return registry21.DeployKeeperRegistry( + auth, + backend, + *registryLogicAAddr, + ) + }) + if err != nil { + return nil, err + } + if err := e.client.WaitForEvents(); err != nil { + return nil, err + } + + registryMaster, err := iregistry21.NewIKeeperRegistryMaster( + *address, + e.client.Backend(), + ) + if err != nil { + return nil, err + } + return &EthereumKeeperRegistry{ + client: e.client, + version: eth_contracts.RegistryVersion_2_1, + registry2_1: registryMaster, + address: address, + }, err default: return nil, fmt.Errorf("keeper registry version %d is not supported", opts.RegistryVersion) } @@ -861,6 +1142,21 @@ func (e *EthereumContractDeployer) LoadKeeperRegistry(address common.Address, re client: e.client, registry2_0: instance.(*keeper_registry_wrapper2_0.KeeperRegistry), }, err + case eth_contracts.RegistryVersion_2_1: + instance, err := e.client.LoadContract("KeeperRegistry", address, func( + address common.Address, + backend bind.ContractBackend, + ) (interface{}, error) { + return iregistry21.NewIKeeperRegistryMaster(address, backend) + }) + if err != nil { + return nil, err + } + return &EthereumKeeperRegistry{ + address: &address, + client: e.client, + registry2_1: instance.(*iregistry21.IKeeperRegistryMaster), + }, err default: return nil, fmt.Errorf("keeper registry version %d is not supported", registryVersion) } @@ -883,6 +1179,25 @@ func (e *EthereumContractDeployer) DeployKeeperConsumer(updateInterval *big.Int) }, err } +func (e *EthereumContractDeployer) DeployAutomationLogTriggerConsumer(testInterval *big.Int) (KeeperConsumer, error) { + address, _, instance, err := e.client.DeployContract("LogUpkeepCounter", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return log_upkeep_counter_wrapper.DeployLogUpkeepCounter( + auth, backend, testInterval, + ) + }) + if err != nil { + return nil, err + } + return &EthereumAutomationLogCounterConsumer{ + client: e.client, + consumer: instance.(*log_upkeep_counter_wrapper.LogUpkeepCounter), + address: address, + }, err +} + func (e *EthereumContractDeployer) DeployUpkeepCounter(testRange *big.Int, interval *big.Int) (UpkeepCounter, error) { address, _, instance, err := e.client.DeployContract("UpkeepCounter", func( auth *bind.TransactOpts, diff --git a/integration-tests/contracts/contract_loader.go b/integration-tests/contracts/contract_loader.go index 14995296b8f..7517ef7ba7e 100644 --- a/integration-tests/contracts/contract_loader.go +++ b/integration-tests/contracts/contract_loader.go @@ -6,14 +6,24 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_coordinator" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_load_test_client" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_router" "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/operator_wrapper" ) // ContractLoader is an interface for abstracting the contract loading methods across network implementations type ContractLoader interface { + LoadLINKToken(address string) (LinkToken, error) LoadOperatorContract(address common.Address) (Operator, error) LoadAuthorizedForwarder(address common.Address) (AuthorizedForwarder, error) + + /* functions 1_0_0 */ + LoadFunctionsCoordinator(addr string) (FunctionsCoordinator, error) + LoadFunctionsRouter(addr string) (FunctionsRouter, error) + LoadFunctionsLoadTestClient(addr string) (FunctionsLoadTestClient, error) } // NewContractLoader returns an instance of a contract Loader based on the client type @@ -72,6 +82,78 @@ func NewEthereumContractLoader(ethClient blockchain.EVMClient) *EthereumContract } } +// LoadLINKToken returns deployed on given address LINK Token contract instance +func (e *EthereumContractLoader) LoadLINKToken(addr string) (LinkToken, error) { + instance, err := e.client.LoadContract("LINK Token", common.HexToAddress(addr), func( + address common.Address, + backend bind.ContractBackend, + ) (interface{}, error) { + return link_token_interface.NewLinkToken(address, backend) + }) + if err != nil { + return nil, err + } + return &EthereumLinkToken{ + client: e.client, + instance: instance.(*link_token_interface.LinkToken), + address: common.HexToAddress(addr), + }, err +} + +// LoadFunctionsCoordinator returns deployed on given address FunctionsCoordinator contract instance +func (e *EthereumContractLoader) LoadFunctionsCoordinator(addr string) (FunctionsCoordinator, error) { + instance, err := e.client.LoadContract("Functions Coordinator", common.HexToAddress(addr), func( + address common.Address, + backend bind.ContractBackend, + ) (interface{}, error) { + return functions_coordinator.NewFunctionsCoordinator(address, backend) + }) + if err != nil { + return nil, err + } + return &EthereumFunctionsCoordinator{ + client: e.client, + instance: instance.(*functions_coordinator.FunctionsCoordinator), + address: common.HexToAddress(addr), + }, err +} + +// LoadFunctionsRouter returns deployed on given address FunctionsRouter contract instance +func (e *EthereumContractLoader) LoadFunctionsRouter(addr string) (FunctionsRouter, error) { + instance, err := e.client.LoadContract("Functions Router", common.HexToAddress(addr), func( + address common.Address, + backend bind.ContractBackend, + ) (interface{}, error) { + return functions_router.NewFunctionsRouter(address, backend) + }) + if err != nil { + return nil, err + } + return &EthereumFunctionsRouter{ + client: e.client, + instance: instance.(*functions_router.FunctionsRouter), + address: common.HexToAddress(addr), + }, err +} + +// LoadFunctionsLoadTestClient returns deployed on given address FunctionsLoadTestClient contract instance +func (e *EthereumContractLoader) LoadFunctionsLoadTestClient(addr string) (FunctionsLoadTestClient, error) { + instance, err := e.client.LoadContract("FunctionsLoadTestClient", common.HexToAddress(addr), func( + address common.Address, + backend bind.ContractBackend, + ) (interface{}, error) { + return functions_load_test_client.NewFunctionsLoadTestClient(address, backend) + }) + if err != nil { + return nil, err + } + return &EthereumFunctionsLoadTestClient{ + client: e.client, + instance: instance.(*functions_load_test_client.FunctionsLoadTestClient), + address: common.HexToAddress(addr), + }, err +} + // LoadOperatorContract returns deployed on given address Operator contract instance func (e *EthereumContractLoader) LoadOperatorContract(address common.Address) (Operator, error) { instance, err := e.client.LoadContract("Operator", address, func( diff --git a/integration-tests/contracts/contract_models.go b/integration-tests/contracts/contract_models.go index cdae8ec3cc2..9af61d7d880 100644 --- a/integration-tests/contracts/contract_models.go +++ b/integration-tests/contracts/contract_models.go @@ -8,17 +8,15 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/smartcontractkit/libocr/gethwrappers/offchainaggregator" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" ocrConfigHelper "github.com/smartcontractkit/libocr/offchainreporting/confighelper" ocrConfigHelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/flux_aggregator_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/functions_billing_registry_events_mock" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/operator_factory" - - "github.com/smartcontractkit/chainlink/integration-tests/client" ) type FluxAggregatorOptions struct { @@ -139,7 +137,8 @@ type OffchainAggregator interface { Address() string Fund(nativeAmount *big.Float) error GetContractData(ctx context.Context) (*OffchainAggregatorData, error) - SetConfig(chainlinkNodes []*client.Chainlink, ocrConfig OffChainAggregatorConfig, transmitters []common.Address) error + SetConfig(chainlinkNodes []*client.ChainlinkK8sClient, ocrConfig OffChainAggregatorConfig, transmitters []common.Address) error + SetConfigLocal(chainlinkNodes []*client.ChainlinkClient, ocrConfig OffChainAggregatorConfig, transmitters []common.Address) error SetPayees([]string, []string) error RequestNewRound() error GetLatestAnswer(ctx context.Context) (*big.Int, error) @@ -238,6 +237,55 @@ type FunctionsBillingRegistryEventsMock interface { BillingEnd(requestId [32]byte, subscriptionId uint64, signerPayment *big.Int, transmitterPayment *big.Int, totalCost *big.Int, success bool) error } +type StakingEventsMock interface { + Address() string + PoolSizeIncreased(maxPoolSize *big.Int) error + MaxCommunityStakeAmountIncreased(maxStakeAmount *big.Int) error + MaxOperatorStakeAmountIncreased(maxStakeAmount *big.Int) error + RewardInitialized(rate *big.Int, available *big.Int, startTimestamp *big.Int, endTimestamp *big.Int) error + AlertRaised(alerter common.Address, roundId *big.Int, rewardAmount *big.Int) error + Staked(staker common.Address, newStake *big.Int, totalStake *big.Int) error + OperatorAdded(operator common.Address) error + OperatorRemoved(operator common.Address, amount *big.Int) error + FeedOperatorsSet(feedOperators []common.Address) error +} + +type OffchainAggregatorEventsMock interface { + Address() string + ConfigSet(previousConfigBlockNumber uint32, configCount uint64, signers []common.Address, transmitters []common.Address, threshold uint8, encodedConfigVersion uint64, encoded []byte) error + NewTransmission(aggregatorRoundId uint32, answer *big.Int, transmitter common.Address, observations []*big.Int, observers []byte, rawReportContext [32]byte) error +} + +type KeeperRegistry11Mock interface { + Address() string + EmitUpkeepPerformed(id *big.Int, success bool, from common.Address, payment *big.Int, performData []byte) error + EmitUpkeepCanceled(id *big.Int, atBlockHeight uint64) error + EmitFundsWithdrawn(id *big.Int, amount *big.Int, to common.Address) error + EmitKeepersUpdated(keepers []common.Address, payees []common.Address) error + EmitUpkeepRegistered(id *big.Int, executeGas uint32, admin common.Address) error + EmitFundsAdded(id *big.Int, from common.Address, amount *big.Int) error + SetUpkeepCount(_upkeepCount *big.Int) error + SetCanceledUpkeepList(_canceledUpkeepList []*big.Int) error + SetKeeperList(_keepers []common.Address) error + SetConfig(_paymentPremiumPPB uint32, _flatFeeMicroLink uint32, _blockCountPerTurn *big.Int, _checkGasLimit uint32, _stalenessSeconds *big.Int, _gasCeilingMultiplier uint16, _fallbackGasPrice *big.Int, _fallbackLinkPrice *big.Int) error + SetUpkeep(id *big.Int, _target common.Address, _executeGas uint32, _balance *big.Int, _admin common.Address, _maxValidBlocknumber uint64, _lastKeeper common.Address, _checkData []byte) error + SetMinBalance(id *big.Int, minBalance *big.Int) error + SetCheckUpkeepData(id *big.Int, performData []byte, maxLinkPayment *big.Int, gasLimit *big.Int, adjustedGasWei *big.Int, linkEth *big.Int) error + SetPerformUpkeepSuccess(id *big.Int, success bool) error +} + +type KeeperRegistrar12Mock interface { + Address() string + EmitRegistrationRequested(hash [32]byte, name string, encryptedEmail []byte, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, checkData []byte, amount *big.Int, source uint8) error + EmitRegistrationApproved(hash [32]byte, displayName string, upkeepId *big.Int) error + SetRegistrationConfig(_autoApproveConfigType uint8, _autoApproveMaxAllowed uint32, _approvedCount uint32, _keeperRegistry common.Address, _minLINKJuels *big.Int) error +} + +type KeeperGasWrapperMock interface { + Address() string + SetMeasureCheckGasResult(result bool, payload []byte, gas *big.Int) error +} + type MockAggregatorProxy interface { Address() string UpdateAggregator(aggregator common.Address) error @@ -285,3 +333,17 @@ type AuthorizedForwarder interface { Owner(ctx context.Context) (string, error) GetAuthorizedSenders(ctx context.Context) ([]string, error) } + +type FunctionsCoordinator interface { + Address() string +} + +type FunctionsRouter interface { + Address() string + CreateSubscriptionWithConsumer(consumer string) (uint64, error) +} + +type FunctionsLoadTestClient interface { + Address() string + SendRequest(source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) error +} diff --git a/integration-tests/contracts/ethereum/KeeperRegistryVersions.go b/integration-tests/contracts/ethereum/KeeperRegistryVersions.go index 9ce38e0d82b..f15e43524d0 100644 --- a/integration-tests/contracts/ethereum/KeeperRegistryVersions.go +++ b/integration-tests/contracts/ethereum/KeeperRegistryVersions.go @@ -17,4 +17,5 @@ const ( RegistryVersion_1_2 RegistryVersion_1_3 RegistryVersion_2_0 + RegistryVersion_2_1 ) diff --git a/integration-tests/contracts/ethereum/OffchainAggregatorEventsMock.go b/integration-tests/contracts/ethereum/OffchainAggregatorEventsMock.go new file mode 100644 index 00000000000..86963e01a45 --- /dev/null +++ b/integration-tests/contracts/ethereum/OffchainAggregatorEventsMock.go @@ -0,0 +1,2582 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package ethereum + +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 OffchainAggregatorEventsMockMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"int256\",\"name\":\"current\",\"type\":\"int256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"roundId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"}],\"name\":\"AnswerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"old\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"current\",\"type\":\"address\"}],\"name\":\"BillingAccessControllerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"maximumGasPrice\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"reasonableGasPrice\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"microLinkPerEth\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"linkGweiPerObservation\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"linkGweiPerTransmission\",\"type\":\"uint32\"}],\"name\":\"BillingSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"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\":\"threshold\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"encodedConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"encoded\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_oldLinkToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_newLinkToken\",\"type\":\"address\"}],\"name\":\"LinkTokenSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"roundId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"startedBy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startedAt\",\"type\":\"uint256\"}],\"name\":\"NewRound\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"aggregatorRoundId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"int192\",\"name\":\"answer\",\"type\":\"int192\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"int192[]\",\"name\":\"observations\",\"type\":\"int192[]\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"observers\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"rawReportContext\",\"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\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"}],\"name\":\"OraclePaid\",\"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\":\"address\",\"name\":\"old\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"current\",\"type\":\"address\"}],\"name\":\"RequesterAccessControllerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes16\",\"name\":\"configDigest\",\"type\":\"bytes16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"round\",\"type\":\"uint8\"}],\"name\":\"RoundRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousValidator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousGasLimit\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"currentValidator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"currentGasLimit\",\"type\":\"uint32\"}],\"name\":\"ValidatorConfigSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"current\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"roundId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"}],\"name\":\"emitAnswerUpdated\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"old\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"current\",\"type\":\"address\"}],\"name\":\"emitBillingAccessControllerSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"maximumGasPrice\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"reasonableGasPrice\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"microLinkPerEth\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"linkGweiPerObservation\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"linkGweiPerTransmission\",\"type\":\"uint32\"}],\"name\":\"emitBillingSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"threshold\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"encodedConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"encoded\",\"type\":\"bytes\"}],\"name\":\"emitConfigSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_oldLinkToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_newLinkToken\",\"type\":\"address\"}],\"name\":\"emitLinkTokenSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"roundId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"startedBy\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"startedAt\",\"type\":\"uint256\"}],\"name\":\"emitNewRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"aggregatorRoundId\",\"type\":\"uint32\"},{\"internalType\":\"int192\",\"name\":\"answer\",\"type\":\"int192\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"int192[]\",\"name\":\"observations\",\"type\":\"int192[]\"},{\"internalType\":\"bytes\",\"name\":\"observers\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"rawReportContext\",\"type\":\"bytes32\"}],\"name\":\"emitNewTransmission\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"}],\"name\":\"emitOraclePaid\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"emitOwnershipTransferRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"emitOwnershipTransferred\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"current\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"emitPayeeshipTransferRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"previous\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"current\",\"type\":\"address\"}],\"name\":\"emitPayeeshipTransferred\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"old\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"current\",\"type\":\"address\"}],\"name\":\"emitRequesterAccessControllerSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"bytes16\",\"name\":\"configDigest\",\"type\":\"bytes16\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"round\",\"type\":\"uint8\"}],\"name\":\"emitRoundRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"previousValidator\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"previousGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"currentValidator\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"currentGasLimit\",\"type\":\"uint32\"}],\"name\":\"emitValidatorConfigSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50610faf806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638b28369d11610097578063a57c1e0c11610066578063a57c1e0c146101cd578063b019b4e8146101e0578063f7420bc2146101f3578063faf1347c1461020657600080fd5b80638b28369d1461018157806395aa14461461019457806399e1a39b146101a7578063a3296557146101ba57600080fd5b806358e1e734116100d357806358e1e734146101355780636602e6ce14610148578063715bd44e1461015b57806389ffde8d1461016e57600080fd5b8063275c7ea4146100fa5780632c769fd71461010f578063448be1e014610122575b600080fd5b61010d610108366004610c76565b610219565b005b61010d61011d366004610aad565b610265565b61010d610130366004610931565b6102a5565b61010d610143366004610964565b6102fa565b61010d610156366004610a64565b610370565b61010d6101693660046109f4565b6103d3565b61010d61017c366004610931565b61045b565b61010d61018f366004610ad9565b6104a8565b61010d6101a2366004610b0e565b6104f1565b61010d6101b5366004610964565b61053f565b61010d6101c8366004610c11565b6105b5565b61010d6101db366004610931565b610614565b61010d6101ee366004610931565b610672565b61010d610201366004610931565b6106d0565b61010d6102143660046109a7565b61072e565b7f25d719d88a4512dd76c7442b910a83360845505894eb444ef299409e180f8fb9878787878787876040516102549796959493929190610e8a565b60405180910390a150505050505050565b81837f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f8360405161029891815260200190565b60405180910390a3505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8085168252831660208201527f793cb73064f3c8cde7e187ae515511e6e56d1ee89bf08b82fa60fb70f8d4891291015b60405180910390a15050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b360405160405180910390a4505050565b6040805163ffffffff80861682528316602082015273ffffffffffffffffffffffffffffffffffffffff80851692908716917fb04e3a37abe9c0fcdfebdeae019a8e2b12ddf53f5d55ffb0caccc1bedaca1541910160405180910390a350505050565b604080517fffffffffffffffffffffffffffffffff000000000000000000000000000000008516815263ffffffff8416602082015260ff831681830152905173ffffffffffffffffffffffffffffffffffffffff8616917f3ea16a923ff4b1df6526e854c9e3a995c43385d70e73359e10623c74f0b52037919081900360600190a250505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8085168252831660208201527f27b89aede8b560578baaa25ee5ce3852c5eecad1e114b941bbd89e1eb4bae63491016102ee565b8173ffffffffffffffffffffffffffffffffffffffff16837f0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac602718360405161029891815260200190565b8563ffffffff167ff6a97944f31ea060dfde0566e4167c1a1082551e64b60ecb14d599a9d023d451868686868660405161052f959493929190610dfd565b60405180910390a2505050505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e3836760405160405180910390a4505050565b6040805163ffffffff878116825286811660208301528581168284015284811660608301528316608082015290517fd0d9486a2c673e2a4b57fc82e4c8a556b3e2b82dd5db07e2c04a920ca0f469b69181900360a00190a15050505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4966a50c93f855342ccf6c5c0d358b85b91335b2acedc7da0932f691f351711a60405160405180910390a35050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127860405160405180910390a35050565b8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fd0b1dac935d85bd54cf0a33b0d41d39f8cf53a968465fc7ea2377526b8ac712c856040516107a491815260200190565b60405180910390a450505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146107d657600080fd5b919050565b600082601f8301126107ec57600080fd5b813560206108016107fc83610f4f565b610f00565b80838252828201915082860187848660051b890101111561082157600080fd5b60005b8581101561084757610835826107b2565b84529284019290840190600101610824565b5090979650505050505050565b600082601f83011261086557600080fd5b813567ffffffffffffffff81111561087f5761087f610f73565b6108b060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610f00565b8181528460208386010111156108c557600080fd5b816020850160208301376000918101602001919091529392505050565b8035601781900b81146107d657600080fd5b803563ffffffff811681146107d657600080fd5b803567ffffffffffffffff811681146107d657600080fd5b803560ff811681146107d657600080fd5b6000806040838503121561094457600080fd5b61094d836107b2565b915061095b602084016107b2565b90509250929050565b60008060006060848603121561097957600080fd5b610982846107b2565b9250610990602085016107b2565b915061099e604085016107b2565b90509250925092565b600080600080608085870312156109bd57600080fd5b6109c6856107b2565b93506109d4602086016107b2565b9250604085013591506109e9606086016107b2565b905092959194509250565b60008060008060808587031215610a0a57600080fd5b610a13856107b2565b935060208501357fffffffffffffffffffffffffffffffff0000000000000000000000000000000081168114610a4857600080fd5b9250610a56604086016108f4565b91506109e960608601610920565b60008060008060808587031215610a7a57600080fd5b610a83856107b2565b9350610a91602086016108f4565b9250610a9f604086016107b2565b91506109e9606086016108f4565b600080600060608486031215610ac257600080fd5b505081359360208301359350604090920135919050565b600080600060608486031215610aee57600080fd5b83359250610afe602085016107b2565b9150604084013590509250925092565b60008060008060008060c08789031215610b2757600080fd5b610b30876108f4565b95506020610b3f8189016108e2565b9550610b4d604089016107b2565b9450606088013567ffffffffffffffff80821115610b6a57600080fd5b818a0191508a601f830112610b7e57600080fd5b8135610b8c6107fc82610f4f565b8082825285820191508585018e878560051b8801011115610bac57600080fd5b600095505b83861015610bd657610bc2816108e2565b835260019590950194918601918601610bb1565b509750505060808a0135925080831115610bef57600080fd5b5050610bfd89828a01610854565b92505060a087013590509295509295509295565b600080600080600060a08688031215610c2957600080fd5b610c32866108f4565b9450610c40602087016108f4565b9350610c4e604087016108f4565b9250610c5c606087016108f4565b9150610c6a608087016108f4565b90509295509295909350565b600080600080600080600060e0888a031215610c9157600080fd5b610c9a886108f4565b9650610ca860208901610908565b9550604088013567ffffffffffffffff80821115610cc557600080fd5b610cd18b838c016107db565b965060608a0135915080821115610ce757600080fd5b610cf38b838c016107db565b9550610d0160808b01610920565b9450610d0f60a08b01610908565b935060c08a0135915080821115610d2557600080fd5b50610d328a828b01610854565b91505092959891949750929550565b600081518084526020808501945080840160005b83811015610d8757815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101610d55565b509495945050505050565b6000815180845260005b81811015610db857602081850181015186830182015201610d9c565b81811115610dca576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600060a08201601788810b8452602073ffffffffffffffffffffffffffffffffffffffff89168186015260a0604086015282885180855260c087019150828a01945060005b81811015610e60578551850b83529483019491830191600101610e42565b50508581036060870152610e748189610d92565b9450505050508260808301529695505050505050565b63ffffffff88168152600067ffffffffffffffff808916602084015260e06040840152610eba60e0840189610d41565b8381036060850152610ecc8189610d41565b905060ff8716608085015281861660a085015283810360c0850152610ef18186610d92565b9b9a5050505050505050505050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610f4757610f47610f73565b604052919050565b600067ffffffffffffffff821115610f6957610f69610f73565b5060051b60200190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", +} + +var OffchainAggregatorEventsMockABI = OffchainAggregatorEventsMockMetaData.ABI + +var OffchainAggregatorEventsMockBin = OffchainAggregatorEventsMockMetaData.Bin + +func DeployOffchainAggregatorEventsMock(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *OffchainAggregatorEventsMock, error) { + parsed, err := OffchainAggregatorEventsMockMetaData.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(OffchainAggregatorEventsMockBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &OffchainAggregatorEventsMock{OffchainAggregatorEventsMockCaller: OffchainAggregatorEventsMockCaller{contract: contract}, OffchainAggregatorEventsMockTransactor: OffchainAggregatorEventsMockTransactor{contract: contract}, OffchainAggregatorEventsMockFilterer: OffchainAggregatorEventsMockFilterer{contract: contract}}, nil +} + +type OffchainAggregatorEventsMock struct { + address common.Address + abi abi.ABI + OffchainAggregatorEventsMockCaller + OffchainAggregatorEventsMockTransactor + OffchainAggregatorEventsMockFilterer +} + +type OffchainAggregatorEventsMockCaller struct { + contract *bind.BoundContract +} + +type OffchainAggregatorEventsMockTransactor struct { + contract *bind.BoundContract +} + +type OffchainAggregatorEventsMockFilterer struct { + contract *bind.BoundContract +} + +type OffchainAggregatorEventsMockSession struct { + Contract *OffchainAggregatorEventsMock + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type OffchainAggregatorEventsMockCallerSession struct { + Contract *OffchainAggregatorEventsMockCaller + CallOpts bind.CallOpts +} + +type OffchainAggregatorEventsMockTransactorSession struct { + Contract *OffchainAggregatorEventsMockTransactor + TransactOpts bind.TransactOpts +} + +type OffchainAggregatorEventsMockRaw struct { + Contract *OffchainAggregatorEventsMock +} + +type OffchainAggregatorEventsMockCallerRaw struct { + Contract *OffchainAggregatorEventsMockCaller +} + +type OffchainAggregatorEventsMockTransactorRaw struct { + Contract *OffchainAggregatorEventsMockTransactor +} + +func NewOffchainAggregatorEventsMock(address common.Address, backend bind.ContractBackend) (*OffchainAggregatorEventsMock, error) { + abi, err := abi.JSON(strings.NewReader(OffchainAggregatorEventsMockABI)) + if err != nil { + return nil, err + } + contract, err := bindOffchainAggregatorEventsMock(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &OffchainAggregatorEventsMock{address: address, abi: abi, OffchainAggregatorEventsMockCaller: OffchainAggregatorEventsMockCaller{contract: contract}, OffchainAggregatorEventsMockTransactor: OffchainAggregatorEventsMockTransactor{contract: contract}, OffchainAggregatorEventsMockFilterer: OffchainAggregatorEventsMockFilterer{contract: contract}}, nil +} + +func NewOffchainAggregatorEventsMockCaller(address common.Address, caller bind.ContractCaller) (*OffchainAggregatorEventsMockCaller, error) { + contract, err := bindOffchainAggregatorEventsMock(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &OffchainAggregatorEventsMockCaller{contract: contract}, nil +} + +func NewOffchainAggregatorEventsMockTransactor(address common.Address, transactor bind.ContractTransactor) (*OffchainAggregatorEventsMockTransactor, error) { + contract, err := bindOffchainAggregatorEventsMock(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &OffchainAggregatorEventsMockTransactor{contract: contract}, nil +} + +func NewOffchainAggregatorEventsMockFilterer(address common.Address, filterer bind.ContractFilterer) (*OffchainAggregatorEventsMockFilterer, error) { + contract, err := bindOffchainAggregatorEventsMock(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &OffchainAggregatorEventsMockFilterer{contract: contract}, nil +} + +func bindOffchainAggregatorEventsMock(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := OffchainAggregatorEventsMockMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OffchainAggregatorEventsMock.Contract.OffchainAggregatorEventsMockCaller.contract.Call(opts, result, method, params...) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.OffchainAggregatorEventsMockTransactor.contract.Transfer(opts) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.OffchainAggregatorEventsMockTransactor.contract.Transact(opts, method, params...) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OffchainAggregatorEventsMock.Contract.contract.Call(opts, result, method, params...) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.contract.Transfer(opts) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.contract.Transact(opts, method, params...) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactor) EmitAnswerUpdated(opts *bind.TransactOpts, current *big.Int, roundId *big.Int, updatedAt *big.Int) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.contract.Transact(opts, "emitAnswerUpdated", current, roundId, updatedAt) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockSession) EmitAnswerUpdated(current *big.Int, roundId *big.Int, updatedAt *big.Int) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitAnswerUpdated(&_OffchainAggregatorEventsMock.TransactOpts, current, roundId, updatedAt) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactorSession) EmitAnswerUpdated(current *big.Int, roundId *big.Int, updatedAt *big.Int) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitAnswerUpdated(&_OffchainAggregatorEventsMock.TransactOpts, current, roundId, updatedAt) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactor) EmitBillingAccessControllerSet(opts *bind.TransactOpts, old common.Address, current common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.contract.Transact(opts, "emitBillingAccessControllerSet", old, current) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockSession) EmitBillingAccessControllerSet(old common.Address, current common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitBillingAccessControllerSet(&_OffchainAggregatorEventsMock.TransactOpts, old, current) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactorSession) EmitBillingAccessControllerSet(old common.Address, current common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitBillingAccessControllerSet(&_OffchainAggregatorEventsMock.TransactOpts, old, current) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactor) EmitBillingSet(opts *bind.TransactOpts, maximumGasPrice uint32, reasonableGasPrice uint32, microLinkPerEth uint32, linkGweiPerObservation uint32, linkGweiPerTransmission uint32) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.contract.Transact(opts, "emitBillingSet", maximumGasPrice, reasonableGasPrice, microLinkPerEth, linkGweiPerObservation, linkGweiPerTransmission) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockSession) EmitBillingSet(maximumGasPrice uint32, reasonableGasPrice uint32, microLinkPerEth uint32, linkGweiPerObservation uint32, linkGweiPerTransmission uint32) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitBillingSet(&_OffchainAggregatorEventsMock.TransactOpts, maximumGasPrice, reasonableGasPrice, microLinkPerEth, linkGweiPerObservation, linkGweiPerTransmission) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactorSession) EmitBillingSet(maximumGasPrice uint32, reasonableGasPrice uint32, microLinkPerEth uint32, linkGweiPerObservation uint32, linkGweiPerTransmission uint32) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitBillingSet(&_OffchainAggregatorEventsMock.TransactOpts, maximumGasPrice, reasonableGasPrice, microLinkPerEth, linkGweiPerObservation, linkGweiPerTransmission) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactor) EmitConfigSet(opts *bind.TransactOpts, previousConfigBlockNumber uint32, configCount uint64, signers []common.Address, transmitters []common.Address, threshold uint8, encodedConfigVersion uint64, encoded []byte) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.contract.Transact(opts, "emitConfigSet", previousConfigBlockNumber, configCount, signers, transmitters, threshold, encodedConfigVersion, encoded) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockSession) EmitConfigSet(previousConfigBlockNumber uint32, configCount uint64, signers []common.Address, transmitters []common.Address, threshold uint8, encodedConfigVersion uint64, encoded []byte) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitConfigSet(&_OffchainAggregatorEventsMock.TransactOpts, previousConfigBlockNumber, configCount, signers, transmitters, threshold, encodedConfigVersion, encoded) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactorSession) EmitConfigSet(previousConfigBlockNumber uint32, configCount uint64, signers []common.Address, transmitters []common.Address, threshold uint8, encodedConfigVersion uint64, encoded []byte) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitConfigSet(&_OffchainAggregatorEventsMock.TransactOpts, previousConfigBlockNumber, configCount, signers, transmitters, threshold, encodedConfigVersion, encoded) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactor) EmitLinkTokenSet(opts *bind.TransactOpts, _oldLinkToken common.Address, _newLinkToken common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.contract.Transact(opts, "emitLinkTokenSet", _oldLinkToken, _newLinkToken) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockSession) EmitLinkTokenSet(_oldLinkToken common.Address, _newLinkToken common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitLinkTokenSet(&_OffchainAggregatorEventsMock.TransactOpts, _oldLinkToken, _newLinkToken) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactorSession) EmitLinkTokenSet(_oldLinkToken common.Address, _newLinkToken common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitLinkTokenSet(&_OffchainAggregatorEventsMock.TransactOpts, _oldLinkToken, _newLinkToken) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactor) EmitNewRound(opts *bind.TransactOpts, roundId *big.Int, startedBy common.Address, startedAt *big.Int) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.contract.Transact(opts, "emitNewRound", roundId, startedBy, startedAt) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockSession) EmitNewRound(roundId *big.Int, startedBy common.Address, startedAt *big.Int) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitNewRound(&_OffchainAggregatorEventsMock.TransactOpts, roundId, startedBy, startedAt) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactorSession) EmitNewRound(roundId *big.Int, startedBy common.Address, startedAt *big.Int) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitNewRound(&_OffchainAggregatorEventsMock.TransactOpts, roundId, startedBy, startedAt) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactor) EmitNewTransmission(opts *bind.TransactOpts, aggregatorRoundId uint32, answer *big.Int, transmitter common.Address, observations []*big.Int, observers []byte, rawReportContext [32]byte) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.contract.Transact(opts, "emitNewTransmission", aggregatorRoundId, answer, transmitter, observations, observers, rawReportContext) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockSession) EmitNewTransmission(aggregatorRoundId uint32, answer *big.Int, transmitter common.Address, observations []*big.Int, observers []byte, rawReportContext [32]byte) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitNewTransmission(&_OffchainAggregatorEventsMock.TransactOpts, aggregatorRoundId, answer, transmitter, observations, observers, rawReportContext) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactorSession) EmitNewTransmission(aggregatorRoundId uint32, answer *big.Int, transmitter common.Address, observations []*big.Int, observers []byte, rawReportContext [32]byte) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitNewTransmission(&_OffchainAggregatorEventsMock.TransactOpts, aggregatorRoundId, answer, transmitter, observations, observers, rawReportContext) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactor) EmitOraclePaid(opts *bind.TransactOpts, transmitter common.Address, payee common.Address, amount *big.Int, linkToken common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.contract.Transact(opts, "emitOraclePaid", transmitter, payee, amount, linkToken) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockSession) EmitOraclePaid(transmitter common.Address, payee common.Address, amount *big.Int, linkToken common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitOraclePaid(&_OffchainAggregatorEventsMock.TransactOpts, transmitter, payee, amount, linkToken) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactorSession) EmitOraclePaid(transmitter common.Address, payee common.Address, amount *big.Int, linkToken common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitOraclePaid(&_OffchainAggregatorEventsMock.TransactOpts, transmitter, payee, amount, linkToken) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactor) EmitOwnershipTransferRequested(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.contract.Transact(opts, "emitOwnershipTransferRequested", from, to) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockSession) EmitOwnershipTransferRequested(from common.Address, to common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitOwnershipTransferRequested(&_OffchainAggregatorEventsMock.TransactOpts, from, to) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactorSession) EmitOwnershipTransferRequested(from common.Address, to common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitOwnershipTransferRequested(&_OffchainAggregatorEventsMock.TransactOpts, from, to) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactor) EmitOwnershipTransferred(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.contract.Transact(opts, "emitOwnershipTransferred", from, to) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockSession) EmitOwnershipTransferred(from common.Address, to common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitOwnershipTransferred(&_OffchainAggregatorEventsMock.TransactOpts, from, to) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactorSession) EmitOwnershipTransferred(from common.Address, to common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitOwnershipTransferred(&_OffchainAggregatorEventsMock.TransactOpts, from, to) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactor) EmitPayeeshipTransferRequested(opts *bind.TransactOpts, transmitter common.Address, current common.Address, proposed common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.contract.Transact(opts, "emitPayeeshipTransferRequested", transmitter, current, proposed) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockSession) EmitPayeeshipTransferRequested(transmitter common.Address, current common.Address, proposed common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitPayeeshipTransferRequested(&_OffchainAggregatorEventsMock.TransactOpts, transmitter, current, proposed) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactorSession) EmitPayeeshipTransferRequested(transmitter common.Address, current common.Address, proposed common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitPayeeshipTransferRequested(&_OffchainAggregatorEventsMock.TransactOpts, transmitter, current, proposed) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactor) EmitPayeeshipTransferred(opts *bind.TransactOpts, transmitter common.Address, previous common.Address, current common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.contract.Transact(opts, "emitPayeeshipTransferred", transmitter, previous, current) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockSession) EmitPayeeshipTransferred(transmitter common.Address, previous common.Address, current common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitPayeeshipTransferred(&_OffchainAggregatorEventsMock.TransactOpts, transmitter, previous, current) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactorSession) EmitPayeeshipTransferred(transmitter common.Address, previous common.Address, current common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitPayeeshipTransferred(&_OffchainAggregatorEventsMock.TransactOpts, transmitter, previous, current) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactor) EmitRequesterAccessControllerSet(opts *bind.TransactOpts, old common.Address, current common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.contract.Transact(opts, "emitRequesterAccessControllerSet", old, current) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockSession) EmitRequesterAccessControllerSet(old common.Address, current common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitRequesterAccessControllerSet(&_OffchainAggregatorEventsMock.TransactOpts, old, current) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactorSession) EmitRequesterAccessControllerSet(old common.Address, current common.Address) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitRequesterAccessControllerSet(&_OffchainAggregatorEventsMock.TransactOpts, old, current) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactor) EmitRoundRequested(opts *bind.TransactOpts, requester common.Address, configDigest [16]byte, epoch uint32, round uint8) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.contract.Transact(opts, "emitRoundRequested", requester, configDigest, epoch, round) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockSession) EmitRoundRequested(requester common.Address, configDigest [16]byte, epoch uint32, round uint8) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitRoundRequested(&_OffchainAggregatorEventsMock.TransactOpts, requester, configDigest, epoch, round) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactorSession) EmitRoundRequested(requester common.Address, configDigest [16]byte, epoch uint32, round uint8) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitRoundRequested(&_OffchainAggregatorEventsMock.TransactOpts, requester, configDigest, epoch, round) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactor) EmitValidatorConfigSet(opts *bind.TransactOpts, previousValidator common.Address, previousGasLimit uint32, currentValidator common.Address, currentGasLimit uint32) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.contract.Transact(opts, "emitValidatorConfigSet", previousValidator, previousGasLimit, currentValidator, currentGasLimit) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockSession) EmitValidatorConfigSet(previousValidator common.Address, previousGasLimit uint32, currentValidator common.Address, currentGasLimit uint32) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitValidatorConfigSet(&_OffchainAggregatorEventsMock.TransactOpts, previousValidator, previousGasLimit, currentValidator, currentGasLimit) +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockTransactorSession) EmitValidatorConfigSet(previousValidator common.Address, previousGasLimit uint32, currentValidator common.Address, currentGasLimit uint32) (*types.Transaction, error) { + return _OffchainAggregatorEventsMock.Contract.EmitValidatorConfigSet(&_OffchainAggregatorEventsMock.TransactOpts, previousValidator, previousGasLimit, currentValidator, currentGasLimit) +} + +type OffchainAggregatorEventsMockAnswerUpdatedIterator struct { + Event *OffchainAggregatorEventsMockAnswerUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OffchainAggregatorEventsMockAnswerUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OffchainAggregatorEventsMockAnswerUpdated) + 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(OffchainAggregatorEventsMockAnswerUpdated) + 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 *OffchainAggregatorEventsMockAnswerUpdatedIterator) Error() error { + return it.fail +} + +func (it *OffchainAggregatorEventsMockAnswerUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OffchainAggregatorEventsMockAnswerUpdated struct { + Current *big.Int + RoundId *big.Int + UpdatedAt *big.Int + Raw types.Log +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) FilterAnswerUpdated(opts *bind.FilterOpts, current []*big.Int, roundId []*big.Int) (*OffchainAggregatorEventsMockAnswerUpdatedIterator, error) { + + var currentRule []interface{} + for _, currentItem := range current { + currentRule = append(currentRule, currentItem) + } + var roundIdRule []interface{} + for _, roundIdItem := range roundId { + roundIdRule = append(roundIdRule, roundIdItem) + } + + logs, sub, err := _OffchainAggregatorEventsMock.contract.FilterLogs(opts, "AnswerUpdated", currentRule, roundIdRule) + if err != nil { + return nil, err + } + return &OffchainAggregatorEventsMockAnswerUpdatedIterator{contract: _OffchainAggregatorEventsMock.contract, event: "AnswerUpdated", logs: logs, sub: sub}, nil +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) WatchAnswerUpdated(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockAnswerUpdated, current []*big.Int, roundId []*big.Int) (event.Subscription, error) { + + var currentRule []interface{} + for _, currentItem := range current { + currentRule = append(currentRule, currentItem) + } + var roundIdRule []interface{} + for _, roundIdItem := range roundId { + roundIdRule = append(roundIdRule, roundIdItem) + } + + logs, sub, err := _OffchainAggregatorEventsMock.contract.WatchLogs(opts, "AnswerUpdated", currentRule, roundIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(OffchainAggregatorEventsMockAnswerUpdated) + if err := _OffchainAggregatorEventsMock.contract.UnpackLog(event, "AnswerUpdated", 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 (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) ParseAnswerUpdated(log types.Log) (*OffchainAggregatorEventsMockAnswerUpdated, error) { + event := new(OffchainAggregatorEventsMockAnswerUpdated) + if err := _OffchainAggregatorEventsMock.contract.UnpackLog(event, "AnswerUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type OffchainAggregatorEventsMockBillingAccessControllerSetIterator struct { + Event *OffchainAggregatorEventsMockBillingAccessControllerSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OffchainAggregatorEventsMockBillingAccessControllerSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OffchainAggregatorEventsMockBillingAccessControllerSet) + 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(OffchainAggregatorEventsMockBillingAccessControllerSet) + 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 *OffchainAggregatorEventsMockBillingAccessControllerSetIterator) Error() error { + return it.fail +} + +func (it *OffchainAggregatorEventsMockBillingAccessControllerSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OffchainAggregatorEventsMockBillingAccessControllerSet struct { + Old common.Address + Current common.Address + Raw types.Log +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) FilterBillingAccessControllerSet(opts *bind.FilterOpts) (*OffchainAggregatorEventsMockBillingAccessControllerSetIterator, error) { + + logs, sub, err := _OffchainAggregatorEventsMock.contract.FilterLogs(opts, "BillingAccessControllerSet") + if err != nil { + return nil, err + } + return &OffchainAggregatorEventsMockBillingAccessControllerSetIterator{contract: _OffchainAggregatorEventsMock.contract, event: "BillingAccessControllerSet", logs: logs, sub: sub}, nil +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) WatchBillingAccessControllerSet(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockBillingAccessControllerSet) (event.Subscription, error) { + + logs, sub, err := _OffchainAggregatorEventsMock.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(OffchainAggregatorEventsMockBillingAccessControllerSet) + if err := _OffchainAggregatorEventsMock.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 (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) ParseBillingAccessControllerSet(log types.Log) (*OffchainAggregatorEventsMockBillingAccessControllerSet, error) { + event := new(OffchainAggregatorEventsMockBillingAccessControllerSet) + if err := _OffchainAggregatorEventsMock.contract.UnpackLog(event, "BillingAccessControllerSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type OffchainAggregatorEventsMockBillingSetIterator struct { + Event *OffchainAggregatorEventsMockBillingSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OffchainAggregatorEventsMockBillingSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OffchainAggregatorEventsMockBillingSet) + 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(OffchainAggregatorEventsMockBillingSet) + 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 *OffchainAggregatorEventsMockBillingSetIterator) Error() error { + return it.fail +} + +func (it *OffchainAggregatorEventsMockBillingSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OffchainAggregatorEventsMockBillingSet struct { + MaximumGasPrice uint32 + ReasonableGasPrice uint32 + MicroLinkPerEth uint32 + LinkGweiPerObservation uint32 + LinkGweiPerTransmission uint32 + Raw types.Log +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) FilterBillingSet(opts *bind.FilterOpts) (*OffchainAggregatorEventsMockBillingSetIterator, error) { + + logs, sub, err := _OffchainAggregatorEventsMock.contract.FilterLogs(opts, "BillingSet") + if err != nil { + return nil, err + } + return &OffchainAggregatorEventsMockBillingSetIterator{contract: _OffchainAggregatorEventsMock.contract, event: "BillingSet", logs: logs, sub: sub}, nil +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) WatchBillingSet(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockBillingSet) (event.Subscription, error) { + + logs, sub, err := _OffchainAggregatorEventsMock.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(OffchainAggregatorEventsMockBillingSet) + if err := _OffchainAggregatorEventsMock.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 (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) ParseBillingSet(log types.Log) (*OffchainAggregatorEventsMockBillingSet, error) { + event := new(OffchainAggregatorEventsMockBillingSet) + if err := _OffchainAggregatorEventsMock.contract.UnpackLog(event, "BillingSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type OffchainAggregatorEventsMockConfigSetIterator struct { + Event *OffchainAggregatorEventsMockConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OffchainAggregatorEventsMockConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OffchainAggregatorEventsMockConfigSet) + 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(OffchainAggregatorEventsMockConfigSet) + 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 *OffchainAggregatorEventsMockConfigSetIterator) Error() error { + return it.fail +} + +func (it *OffchainAggregatorEventsMockConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OffchainAggregatorEventsMockConfigSet struct { + PreviousConfigBlockNumber uint32 + ConfigCount uint64 + Signers []common.Address + Transmitters []common.Address + Threshold uint8 + EncodedConfigVersion uint64 + Encoded []byte + Raw types.Log +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) FilterConfigSet(opts *bind.FilterOpts) (*OffchainAggregatorEventsMockConfigSetIterator, error) { + + logs, sub, err := _OffchainAggregatorEventsMock.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &OffchainAggregatorEventsMockConfigSetIterator{contract: _OffchainAggregatorEventsMock.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockConfigSet) (event.Subscription, error) { + + logs, sub, err := _OffchainAggregatorEventsMock.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(OffchainAggregatorEventsMockConfigSet) + if err := _OffchainAggregatorEventsMock.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 (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) ParseConfigSet(log types.Log) (*OffchainAggregatorEventsMockConfigSet, error) { + event := new(OffchainAggregatorEventsMockConfigSet) + if err := _OffchainAggregatorEventsMock.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type OffchainAggregatorEventsMockLinkTokenSetIterator struct { + Event *OffchainAggregatorEventsMockLinkTokenSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OffchainAggregatorEventsMockLinkTokenSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OffchainAggregatorEventsMockLinkTokenSet) + 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(OffchainAggregatorEventsMockLinkTokenSet) + 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 *OffchainAggregatorEventsMockLinkTokenSetIterator) Error() error { + return it.fail +} + +func (it *OffchainAggregatorEventsMockLinkTokenSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OffchainAggregatorEventsMockLinkTokenSet struct { + OldLinkToken common.Address + NewLinkToken common.Address + Raw types.Log +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) FilterLinkTokenSet(opts *bind.FilterOpts, _oldLinkToken []common.Address, _newLinkToken []common.Address) (*OffchainAggregatorEventsMockLinkTokenSetIterator, error) { + + var _oldLinkTokenRule []interface{} + for _, _oldLinkTokenItem := range _oldLinkToken { + _oldLinkTokenRule = append(_oldLinkTokenRule, _oldLinkTokenItem) + } + var _newLinkTokenRule []interface{} + for _, _newLinkTokenItem := range _newLinkToken { + _newLinkTokenRule = append(_newLinkTokenRule, _newLinkTokenItem) + } + + logs, sub, err := _OffchainAggregatorEventsMock.contract.FilterLogs(opts, "LinkTokenSet", _oldLinkTokenRule, _newLinkTokenRule) + if err != nil { + return nil, err + } + return &OffchainAggregatorEventsMockLinkTokenSetIterator{contract: _OffchainAggregatorEventsMock.contract, event: "LinkTokenSet", logs: logs, sub: sub}, nil +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) WatchLinkTokenSet(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockLinkTokenSet, _oldLinkToken []common.Address, _newLinkToken []common.Address) (event.Subscription, error) { + + var _oldLinkTokenRule []interface{} + for _, _oldLinkTokenItem := range _oldLinkToken { + _oldLinkTokenRule = append(_oldLinkTokenRule, _oldLinkTokenItem) + } + var _newLinkTokenRule []interface{} + for _, _newLinkTokenItem := range _newLinkToken { + _newLinkTokenRule = append(_newLinkTokenRule, _newLinkTokenItem) + } + + logs, sub, err := _OffchainAggregatorEventsMock.contract.WatchLogs(opts, "LinkTokenSet", _oldLinkTokenRule, _newLinkTokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(OffchainAggregatorEventsMockLinkTokenSet) + if err := _OffchainAggregatorEventsMock.contract.UnpackLog(event, "LinkTokenSet", 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 (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) ParseLinkTokenSet(log types.Log) (*OffchainAggregatorEventsMockLinkTokenSet, error) { + event := new(OffchainAggregatorEventsMockLinkTokenSet) + if err := _OffchainAggregatorEventsMock.contract.UnpackLog(event, "LinkTokenSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type OffchainAggregatorEventsMockNewRoundIterator struct { + Event *OffchainAggregatorEventsMockNewRound + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OffchainAggregatorEventsMockNewRoundIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OffchainAggregatorEventsMockNewRound) + 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(OffchainAggregatorEventsMockNewRound) + 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 *OffchainAggregatorEventsMockNewRoundIterator) Error() error { + return it.fail +} + +func (it *OffchainAggregatorEventsMockNewRoundIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OffchainAggregatorEventsMockNewRound struct { + RoundId *big.Int + StartedBy common.Address + StartedAt *big.Int + Raw types.Log +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) FilterNewRound(opts *bind.FilterOpts, roundId []*big.Int, startedBy []common.Address) (*OffchainAggregatorEventsMockNewRoundIterator, error) { + + var roundIdRule []interface{} + for _, roundIdItem := range roundId { + roundIdRule = append(roundIdRule, roundIdItem) + } + var startedByRule []interface{} + for _, startedByItem := range startedBy { + startedByRule = append(startedByRule, startedByItem) + } + + logs, sub, err := _OffchainAggregatorEventsMock.contract.FilterLogs(opts, "NewRound", roundIdRule, startedByRule) + if err != nil { + return nil, err + } + return &OffchainAggregatorEventsMockNewRoundIterator{contract: _OffchainAggregatorEventsMock.contract, event: "NewRound", logs: logs, sub: sub}, nil +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) WatchNewRound(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockNewRound, roundId []*big.Int, startedBy []common.Address) (event.Subscription, error) { + + var roundIdRule []interface{} + for _, roundIdItem := range roundId { + roundIdRule = append(roundIdRule, roundIdItem) + } + var startedByRule []interface{} + for _, startedByItem := range startedBy { + startedByRule = append(startedByRule, startedByItem) + } + + logs, sub, err := _OffchainAggregatorEventsMock.contract.WatchLogs(opts, "NewRound", roundIdRule, startedByRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(OffchainAggregatorEventsMockNewRound) + if err := _OffchainAggregatorEventsMock.contract.UnpackLog(event, "NewRound", 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 (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) ParseNewRound(log types.Log) (*OffchainAggregatorEventsMockNewRound, error) { + event := new(OffchainAggregatorEventsMockNewRound) + if err := _OffchainAggregatorEventsMock.contract.UnpackLog(event, "NewRound", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type OffchainAggregatorEventsMockNewTransmissionIterator struct { + Event *OffchainAggregatorEventsMockNewTransmission + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OffchainAggregatorEventsMockNewTransmissionIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OffchainAggregatorEventsMockNewTransmission) + 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(OffchainAggregatorEventsMockNewTransmission) + 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 *OffchainAggregatorEventsMockNewTransmissionIterator) Error() error { + return it.fail +} + +func (it *OffchainAggregatorEventsMockNewTransmissionIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OffchainAggregatorEventsMockNewTransmission struct { + AggregatorRoundId uint32 + Answer *big.Int + Transmitter common.Address + Observations []*big.Int + Observers []byte + RawReportContext [32]byte + Raw types.Log +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) FilterNewTransmission(opts *bind.FilterOpts, aggregatorRoundId []uint32) (*OffchainAggregatorEventsMockNewTransmissionIterator, error) { + + var aggregatorRoundIdRule []interface{} + for _, aggregatorRoundIdItem := range aggregatorRoundId { + aggregatorRoundIdRule = append(aggregatorRoundIdRule, aggregatorRoundIdItem) + } + + logs, sub, err := _OffchainAggregatorEventsMock.contract.FilterLogs(opts, "NewTransmission", aggregatorRoundIdRule) + if err != nil { + return nil, err + } + return &OffchainAggregatorEventsMockNewTransmissionIterator{contract: _OffchainAggregatorEventsMock.contract, event: "NewTransmission", logs: logs, sub: sub}, nil +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) WatchNewTransmission(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockNewTransmission, aggregatorRoundId []uint32) (event.Subscription, error) { + + var aggregatorRoundIdRule []interface{} + for _, aggregatorRoundIdItem := range aggregatorRoundId { + aggregatorRoundIdRule = append(aggregatorRoundIdRule, aggregatorRoundIdItem) + } + + logs, sub, err := _OffchainAggregatorEventsMock.contract.WatchLogs(opts, "NewTransmission", aggregatorRoundIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(OffchainAggregatorEventsMockNewTransmission) + if err := _OffchainAggregatorEventsMock.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 (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) ParseNewTransmission(log types.Log) (*OffchainAggregatorEventsMockNewTransmission, error) { + event := new(OffchainAggregatorEventsMockNewTransmission) + if err := _OffchainAggregatorEventsMock.contract.UnpackLog(event, "NewTransmission", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type OffchainAggregatorEventsMockOraclePaidIterator struct { + Event *OffchainAggregatorEventsMockOraclePaid + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OffchainAggregatorEventsMockOraclePaidIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OffchainAggregatorEventsMockOraclePaid) + 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(OffchainAggregatorEventsMockOraclePaid) + 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 *OffchainAggregatorEventsMockOraclePaidIterator) Error() error { + return it.fail +} + +func (it *OffchainAggregatorEventsMockOraclePaidIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OffchainAggregatorEventsMockOraclePaid struct { + Transmitter common.Address + Payee common.Address + Amount *big.Int + LinkToken common.Address + Raw types.Log +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) FilterOraclePaid(opts *bind.FilterOpts, transmitter []common.Address, payee []common.Address, linkToken []common.Address) (*OffchainAggregatorEventsMockOraclePaidIterator, 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 := _OffchainAggregatorEventsMock.contract.FilterLogs(opts, "OraclePaid", transmitterRule, payeeRule, linkTokenRule) + if err != nil { + return nil, err + } + return &OffchainAggregatorEventsMockOraclePaidIterator{contract: _OffchainAggregatorEventsMock.contract, event: "OraclePaid", logs: logs, sub: sub}, nil +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) WatchOraclePaid(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockOraclePaid, 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 := _OffchainAggregatorEventsMock.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(OffchainAggregatorEventsMockOraclePaid) + if err := _OffchainAggregatorEventsMock.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 (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) ParseOraclePaid(log types.Log) (*OffchainAggregatorEventsMockOraclePaid, error) { + event := new(OffchainAggregatorEventsMockOraclePaid) + if err := _OffchainAggregatorEventsMock.contract.UnpackLog(event, "OraclePaid", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type OffchainAggregatorEventsMockOwnershipTransferRequestedIterator struct { + Event *OffchainAggregatorEventsMockOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OffchainAggregatorEventsMockOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OffchainAggregatorEventsMockOwnershipTransferRequested) + 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(OffchainAggregatorEventsMockOwnershipTransferRequested) + 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 *OffchainAggregatorEventsMockOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *OffchainAggregatorEventsMockOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OffchainAggregatorEventsMockOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*OffchainAggregatorEventsMockOwnershipTransferRequestedIterator, 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 := _OffchainAggregatorEventsMock.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &OffchainAggregatorEventsMockOwnershipTransferRequestedIterator{contract: _OffchainAggregatorEventsMock.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockOwnershipTransferRequested, 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 := _OffchainAggregatorEventsMock.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(OffchainAggregatorEventsMockOwnershipTransferRequested) + if err := _OffchainAggregatorEventsMock.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 (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) ParseOwnershipTransferRequested(log types.Log) (*OffchainAggregatorEventsMockOwnershipTransferRequested, error) { + event := new(OffchainAggregatorEventsMockOwnershipTransferRequested) + if err := _OffchainAggregatorEventsMock.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type OffchainAggregatorEventsMockOwnershipTransferredIterator struct { + Event *OffchainAggregatorEventsMockOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OffchainAggregatorEventsMockOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OffchainAggregatorEventsMockOwnershipTransferred) + 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(OffchainAggregatorEventsMockOwnershipTransferred) + 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 *OffchainAggregatorEventsMockOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *OffchainAggregatorEventsMockOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OffchainAggregatorEventsMockOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*OffchainAggregatorEventsMockOwnershipTransferredIterator, 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 := _OffchainAggregatorEventsMock.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &OffchainAggregatorEventsMockOwnershipTransferredIterator{contract: _OffchainAggregatorEventsMock.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockOwnershipTransferred, 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 := _OffchainAggregatorEventsMock.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(OffchainAggregatorEventsMockOwnershipTransferred) + if err := _OffchainAggregatorEventsMock.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 (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) ParseOwnershipTransferred(log types.Log) (*OffchainAggregatorEventsMockOwnershipTransferred, error) { + event := new(OffchainAggregatorEventsMockOwnershipTransferred) + if err := _OffchainAggregatorEventsMock.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type OffchainAggregatorEventsMockPayeeshipTransferRequestedIterator struct { + Event *OffchainAggregatorEventsMockPayeeshipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OffchainAggregatorEventsMockPayeeshipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OffchainAggregatorEventsMockPayeeshipTransferRequested) + 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(OffchainAggregatorEventsMockPayeeshipTransferRequested) + 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 *OffchainAggregatorEventsMockPayeeshipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *OffchainAggregatorEventsMockPayeeshipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OffchainAggregatorEventsMockPayeeshipTransferRequested struct { + Transmitter common.Address + Current common.Address + Proposed common.Address + Raw types.Log +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) FilterPayeeshipTransferRequested(opts *bind.FilterOpts, transmitter []common.Address, current []common.Address, proposed []common.Address) (*OffchainAggregatorEventsMockPayeeshipTransferRequestedIterator, 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 := _OffchainAggregatorEventsMock.contract.FilterLogs(opts, "PayeeshipTransferRequested", transmitterRule, currentRule, proposedRule) + if err != nil { + return nil, err + } + return &OffchainAggregatorEventsMockPayeeshipTransferRequestedIterator{contract: _OffchainAggregatorEventsMock.contract, event: "PayeeshipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) WatchPayeeshipTransferRequested(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockPayeeshipTransferRequested, 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 := _OffchainAggregatorEventsMock.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(OffchainAggregatorEventsMockPayeeshipTransferRequested) + if err := _OffchainAggregatorEventsMock.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 (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) ParsePayeeshipTransferRequested(log types.Log) (*OffchainAggregatorEventsMockPayeeshipTransferRequested, error) { + event := new(OffchainAggregatorEventsMockPayeeshipTransferRequested) + if err := _OffchainAggregatorEventsMock.contract.UnpackLog(event, "PayeeshipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type OffchainAggregatorEventsMockPayeeshipTransferredIterator struct { + Event *OffchainAggregatorEventsMockPayeeshipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OffchainAggregatorEventsMockPayeeshipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OffchainAggregatorEventsMockPayeeshipTransferred) + 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(OffchainAggregatorEventsMockPayeeshipTransferred) + 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 *OffchainAggregatorEventsMockPayeeshipTransferredIterator) Error() error { + return it.fail +} + +func (it *OffchainAggregatorEventsMockPayeeshipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OffchainAggregatorEventsMockPayeeshipTransferred struct { + Transmitter common.Address + Previous common.Address + Current common.Address + Raw types.Log +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) FilterPayeeshipTransferred(opts *bind.FilterOpts, transmitter []common.Address, previous []common.Address, current []common.Address) (*OffchainAggregatorEventsMockPayeeshipTransferredIterator, 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 := _OffchainAggregatorEventsMock.contract.FilterLogs(opts, "PayeeshipTransferred", transmitterRule, previousRule, currentRule) + if err != nil { + return nil, err + } + return &OffchainAggregatorEventsMockPayeeshipTransferredIterator{contract: _OffchainAggregatorEventsMock.contract, event: "PayeeshipTransferred", logs: logs, sub: sub}, nil +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) WatchPayeeshipTransferred(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockPayeeshipTransferred, 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 := _OffchainAggregatorEventsMock.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(OffchainAggregatorEventsMockPayeeshipTransferred) + if err := _OffchainAggregatorEventsMock.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 (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) ParsePayeeshipTransferred(log types.Log) (*OffchainAggregatorEventsMockPayeeshipTransferred, error) { + event := new(OffchainAggregatorEventsMockPayeeshipTransferred) + if err := _OffchainAggregatorEventsMock.contract.UnpackLog(event, "PayeeshipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type OffchainAggregatorEventsMockRequesterAccessControllerSetIterator struct { + Event *OffchainAggregatorEventsMockRequesterAccessControllerSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OffchainAggregatorEventsMockRequesterAccessControllerSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OffchainAggregatorEventsMockRequesterAccessControllerSet) + 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(OffchainAggregatorEventsMockRequesterAccessControllerSet) + 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 *OffchainAggregatorEventsMockRequesterAccessControllerSetIterator) Error() error { + return it.fail +} + +func (it *OffchainAggregatorEventsMockRequesterAccessControllerSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OffchainAggregatorEventsMockRequesterAccessControllerSet struct { + Old common.Address + Current common.Address + Raw types.Log +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) FilterRequesterAccessControllerSet(opts *bind.FilterOpts) (*OffchainAggregatorEventsMockRequesterAccessControllerSetIterator, error) { + + logs, sub, err := _OffchainAggregatorEventsMock.contract.FilterLogs(opts, "RequesterAccessControllerSet") + if err != nil { + return nil, err + } + return &OffchainAggregatorEventsMockRequesterAccessControllerSetIterator{contract: _OffchainAggregatorEventsMock.contract, event: "RequesterAccessControllerSet", logs: logs, sub: sub}, nil +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) WatchRequesterAccessControllerSet(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockRequesterAccessControllerSet) (event.Subscription, error) { + + logs, sub, err := _OffchainAggregatorEventsMock.contract.WatchLogs(opts, "RequesterAccessControllerSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(OffchainAggregatorEventsMockRequesterAccessControllerSet) + if err := _OffchainAggregatorEventsMock.contract.UnpackLog(event, "RequesterAccessControllerSet", 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 (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) ParseRequesterAccessControllerSet(log types.Log) (*OffchainAggregatorEventsMockRequesterAccessControllerSet, error) { + event := new(OffchainAggregatorEventsMockRequesterAccessControllerSet) + if err := _OffchainAggregatorEventsMock.contract.UnpackLog(event, "RequesterAccessControllerSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type OffchainAggregatorEventsMockRoundRequestedIterator struct { + Event *OffchainAggregatorEventsMockRoundRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OffchainAggregatorEventsMockRoundRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OffchainAggregatorEventsMockRoundRequested) + 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(OffchainAggregatorEventsMockRoundRequested) + 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 *OffchainAggregatorEventsMockRoundRequestedIterator) Error() error { + return it.fail +} + +func (it *OffchainAggregatorEventsMockRoundRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OffchainAggregatorEventsMockRoundRequested struct { + Requester common.Address + ConfigDigest [16]byte + Epoch uint32 + Round uint8 + Raw types.Log +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) FilterRoundRequested(opts *bind.FilterOpts, requester []common.Address) (*OffchainAggregatorEventsMockRoundRequestedIterator, error) { + + var requesterRule []interface{} + for _, requesterItem := range requester { + requesterRule = append(requesterRule, requesterItem) + } + + logs, sub, err := _OffchainAggregatorEventsMock.contract.FilterLogs(opts, "RoundRequested", requesterRule) + if err != nil { + return nil, err + } + return &OffchainAggregatorEventsMockRoundRequestedIterator{contract: _OffchainAggregatorEventsMock.contract, event: "RoundRequested", logs: logs, sub: sub}, nil +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) WatchRoundRequested(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockRoundRequested, requester []common.Address) (event.Subscription, error) { + + var requesterRule []interface{} + for _, requesterItem := range requester { + requesterRule = append(requesterRule, requesterItem) + } + + logs, sub, err := _OffchainAggregatorEventsMock.contract.WatchLogs(opts, "RoundRequested", 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(OffchainAggregatorEventsMockRoundRequested) + if err := _OffchainAggregatorEventsMock.contract.UnpackLog(event, "RoundRequested", 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 (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) ParseRoundRequested(log types.Log) (*OffchainAggregatorEventsMockRoundRequested, error) { + event := new(OffchainAggregatorEventsMockRoundRequested) + if err := _OffchainAggregatorEventsMock.contract.UnpackLog(event, "RoundRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type OffchainAggregatorEventsMockValidatorConfigSetIterator struct { + Event *OffchainAggregatorEventsMockValidatorConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OffchainAggregatorEventsMockValidatorConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OffchainAggregatorEventsMockValidatorConfigSet) + 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(OffchainAggregatorEventsMockValidatorConfigSet) + 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 *OffchainAggregatorEventsMockValidatorConfigSetIterator) Error() error { + return it.fail +} + +func (it *OffchainAggregatorEventsMockValidatorConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OffchainAggregatorEventsMockValidatorConfigSet struct { + PreviousValidator common.Address + PreviousGasLimit uint32 + CurrentValidator common.Address + CurrentGasLimit uint32 + Raw types.Log +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) FilterValidatorConfigSet(opts *bind.FilterOpts, previousValidator []common.Address, currentValidator []common.Address) (*OffchainAggregatorEventsMockValidatorConfigSetIterator, error) { + + var previousValidatorRule []interface{} + for _, previousValidatorItem := range previousValidator { + previousValidatorRule = append(previousValidatorRule, previousValidatorItem) + } + + var currentValidatorRule []interface{} + for _, currentValidatorItem := range currentValidator { + currentValidatorRule = append(currentValidatorRule, currentValidatorItem) + } + + logs, sub, err := _OffchainAggregatorEventsMock.contract.FilterLogs(opts, "ValidatorConfigSet", previousValidatorRule, currentValidatorRule) + if err != nil { + return nil, err + } + return &OffchainAggregatorEventsMockValidatorConfigSetIterator{contract: _OffchainAggregatorEventsMock.contract, event: "ValidatorConfigSet", logs: logs, sub: sub}, nil +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) WatchValidatorConfigSet(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockValidatorConfigSet, previousValidator []common.Address, currentValidator []common.Address) (event.Subscription, error) { + + var previousValidatorRule []interface{} + for _, previousValidatorItem := range previousValidator { + previousValidatorRule = append(previousValidatorRule, previousValidatorItem) + } + + var currentValidatorRule []interface{} + for _, currentValidatorItem := range currentValidator { + currentValidatorRule = append(currentValidatorRule, currentValidatorItem) + } + + logs, sub, err := _OffchainAggregatorEventsMock.contract.WatchLogs(opts, "ValidatorConfigSet", previousValidatorRule, currentValidatorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(OffchainAggregatorEventsMockValidatorConfigSet) + if err := _OffchainAggregatorEventsMock.contract.UnpackLog(event, "ValidatorConfigSet", 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 (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMockFilterer) ParseValidatorConfigSet(log types.Log) (*OffchainAggregatorEventsMockValidatorConfigSet, error) { + event := new(OffchainAggregatorEventsMockValidatorConfigSet) + if err := _OffchainAggregatorEventsMock.contract.UnpackLog(event, "ValidatorConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMock) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _OffchainAggregatorEventsMock.abi.Events["AnswerUpdated"].ID: + return _OffchainAggregatorEventsMock.ParseAnswerUpdated(log) + case _OffchainAggregatorEventsMock.abi.Events["BillingAccessControllerSet"].ID: + return _OffchainAggregatorEventsMock.ParseBillingAccessControllerSet(log) + case _OffchainAggregatorEventsMock.abi.Events["BillingSet"].ID: + return _OffchainAggregatorEventsMock.ParseBillingSet(log) + case _OffchainAggregatorEventsMock.abi.Events["ConfigSet"].ID: + return _OffchainAggregatorEventsMock.ParseConfigSet(log) + case _OffchainAggregatorEventsMock.abi.Events["LinkTokenSet"].ID: + return _OffchainAggregatorEventsMock.ParseLinkTokenSet(log) + case _OffchainAggregatorEventsMock.abi.Events["NewRound"].ID: + return _OffchainAggregatorEventsMock.ParseNewRound(log) + case _OffchainAggregatorEventsMock.abi.Events["NewTransmission"].ID: + return _OffchainAggregatorEventsMock.ParseNewTransmission(log) + case _OffchainAggregatorEventsMock.abi.Events["OraclePaid"].ID: + return _OffchainAggregatorEventsMock.ParseOraclePaid(log) + case _OffchainAggregatorEventsMock.abi.Events["OwnershipTransferRequested"].ID: + return _OffchainAggregatorEventsMock.ParseOwnershipTransferRequested(log) + case _OffchainAggregatorEventsMock.abi.Events["OwnershipTransferred"].ID: + return _OffchainAggregatorEventsMock.ParseOwnershipTransferred(log) + case _OffchainAggregatorEventsMock.abi.Events["PayeeshipTransferRequested"].ID: + return _OffchainAggregatorEventsMock.ParsePayeeshipTransferRequested(log) + case _OffchainAggregatorEventsMock.abi.Events["PayeeshipTransferred"].ID: + return _OffchainAggregatorEventsMock.ParsePayeeshipTransferred(log) + case _OffchainAggregatorEventsMock.abi.Events["RequesterAccessControllerSet"].ID: + return _OffchainAggregatorEventsMock.ParseRequesterAccessControllerSet(log) + case _OffchainAggregatorEventsMock.abi.Events["RoundRequested"].ID: + return _OffchainAggregatorEventsMock.ParseRoundRequested(log) + case _OffchainAggregatorEventsMock.abi.Events["ValidatorConfigSet"].ID: + return _OffchainAggregatorEventsMock.ParseValidatorConfigSet(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (OffchainAggregatorEventsMockAnswerUpdated) Topic() common.Hash { + return common.HexToHash("0x0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f") +} + +func (OffchainAggregatorEventsMockBillingAccessControllerSet) Topic() common.Hash { + return common.HexToHash("0x793cb73064f3c8cde7e187ae515511e6e56d1ee89bf08b82fa60fb70f8d48912") +} + +func (OffchainAggregatorEventsMockBillingSet) Topic() common.Hash { + return common.HexToHash("0xd0d9486a2c673e2a4b57fc82e4c8a556b3e2b82dd5db07e2c04a920ca0f469b6") +} + +func (OffchainAggregatorEventsMockConfigSet) Topic() common.Hash { + return common.HexToHash("0x25d719d88a4512dd76c7442b910a83360845505894eb444ef299409e180f8fb9") +} + +func (OffchainAggregatorEventsMockLinkTokenSet) Topic() common.Hash { + return common.HexToHash("0x4966a50c93f855342ccf6c5c0d358b85b91335b2acedc7da0932f691f351711a") +} + +func (OffchainAggregatorEventsMockNewRound) Topic() common.Hash { + return common.HexToHash("0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271") +} + +func (OffchainAggregatorEventsMockNewTransmission) Topic() common.Hash { + return common.HexToHash("0xf6a97944f31ea060dfde0566e4167c1a1082551e64b60ecb14d599a9d023d451") +} + +func (OffchainAggregatorEventsMockOraclePaid) Topic() common.Hash { + return common.HexToHash("0xd0b1dac935d85bd54cf0a33b0d41d39f8cf53a968465fc7ea2377526b8ac712c") +} + +func (OffchainAggregatorEventsMockOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (OffchainAggregatorEventsMockOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (OffchainAggregatorEventsMockPayeeshipTransferRequested) Topic() common.Hash { + return common.HexToHash("0x84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e38367") +} + +func (OffchainAggregatorEventsMockPayeeshipTransferred) Topic() common.Hash { + return common.HexToHash("0x78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b3") +} + +func (OffchainAggregatorEventsMockRequesterAccessControllerSet) Topic() common.Hash { + return common.HexToHash("0x27b89aede8b560578baaa25ee5ce3852c5eecad1e114b941bbd89e1eb4bae634") +} + +func (OffchainAggregatorEventsMockRoundRequested) Topic() common.Hash { + return common.HexToHash("0x3ea16a923ff4b1df6526e854c9e3a995c43385d70e73359e10623c74f0b52037") +} + +func (OffchainAggregatorEventsMockValidatorConfigSet) Topic() common.Hash { + return common.HexToHash("0xb04e3a37abe9c0fcdfebdeae019a8e2b12ddf53f5d55ffb0caccc1bedaca1541") +} + +func (_OffchainAggregatorEventsMock *OffchainAggregatorEventsMock) Address() common.Address { + return _OffchainAggregatorEventsMock.address +} + +type OffchainAggregatorEventsMockInterface interface { + EmitAnswerUpdated(opts *bind.TransactOpts, current *big.Int, roundId *big.Int, updatedAt *big.Int) (*types.Transaction, error) + + EmitBillingAccessControllerSet(opts *bind.TransactOpts, old common.Address, current common.Address) (*types.Transaction, error) + + EmitBillingSet(opts *bind.TransactOpts, maximumGasPrice uint32, reasonableGasPrice uint32, microLinkPerEth uint32, linkGweiPerObservation uint32, linkGweiPerTransmission uint32) (*types.Transaction, error) + + EmitConfigSet(opts *bind.TransactOpts, previousConfigBlockNumber uint32, configCount uint64, signers []common.Address, transmitters []common.Address, threshold uint8, encodedConfigVersion uint64, encoded []byte) (*types.Transaction, error) + + EmitLinkTokenSet(opts *bind.TransactOpts, _oldLinkToken common.Address, _newLinkToken common.Address) (*types.Transaction, error) + + EmitNewRound(opts *bind.TransactOpts, roundId *big.Int, startedBy common.Address, startedAt *big.Int) (*types.Transaction, error) + + EmitNewTransmission(opts *bind.TransactOpts, aggregatorRoundId uint32, answer *big.Int, transmitter common.Address, observations []*big.Int, observers []byte, rawReportContext [32]byte) (*types.Transaction, error) + + EmitOraclePaid(opts *bind.TransactOpts, transmitter common.Address, payee common.Address, amount *big.Int, linkToken common.Address) (*types.Transaction, error) + + EmitOwnershipTransferRequested(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) + + EmitOwnershipTransferred(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) + + EmitPayeeshipTransferRequested(opts *bind.TransactOpts, transmitter common.Address, current common.Address, proposed common.Address) (*types.Transaction, error) + + EmitPayeeshipTransferred(opts *bind.TransactOpts, transmitter common.Address, previous common.Address, current common.Address) (*types.Transaction, error) + + EmitRequesterAccessControllerSet(opts *bind.TransactOpts, old common.Address, current common.Address) (*types.Transaction, error) + + EmitRoundRequested(opts *bind.TransactOpts, requester common.Address, configDigest [16]byte, epoch uint32, round uint8) (*types.Transaction, error) + + EmitValidatorConfigSet(opts *bind.TransactOpts, previousValidator common.Address, previousGasLimit uint32, currentValidator common.Address, currentGasLimit uint32) (*types.Transaction, error) + + FilterAnswerUpdated(opts *bind.FilterOpts, current []*big.Int, roundId []*big.Int) (*OffchainAggregatorEventsMockAnswerUpdatedIterator, error) + + WatchAnswerUpdated(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockAnswerUpdated, current []*big.Int, roundId []*big.Int) (event.Subscription, error) + + ParseAnswerUpdated(log types.Log) (*OffchainAggregatorEventsMockAnswerUpdated, error) + + FilterBillingAccessControllerSet(opts *bind.FilterOpts) (*OffchainAggregatorEventsMockBillingAccessControllerSetIterator, error) + + WatchBillingAccessControllerSet(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockBillingAccessControllerSet) (event.Subscription, error) + + ParseBillingAccessControllerSet(log types.Log) (*OffchainAggregatorEventsMockBillingAccessControllerSet, error) + + FilterBillingSet(opts *bind.FilterOpts) (*OffchainAggregatorEventsMockBillingSetIterator, error) + + WatchBillingSet(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockBillingSet) (event.Subscription, error) + + ParseBillingSet(log types.Log) (*OffchainAggregatorEventsMockBillingSet, error) + + FilterConfigSet(opts *bind.FilterOpts) (*OffchainAggregatorEventsMockConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*OffchainAggregatorEventsMockConfigSet, error) + + FilterLinkTokenSet(opts *bind.FilterOpts, _oldLinkToken []common.Address, _newLinkToken []common.Address) (*OffchainAggregatorEventsMockLinkTokenSetIterator, error) + + WatchLinkTokenSet(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockLinkTokenSet, _oldLinkToken []common.Address, _newLinkToken []common.Address) (event.Subscription, error) + + ParseLinkTokenSet(log types.Log) (*OffchainAggregatorEventsMockLinkTokenSet, error) + + FilterNewRound(opts *bind.FilterOpts, roundId []*big.Int, startedBy []common.Address) (*OffchainAggregatorEventsMockNewRoundIterator, error) + + WatchNewRound(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockNewRound, roundId []*big.Int, startedBy []common.Address) (event.Subscription, error) + + ParseNewRound(log types.Log) (*OffchainAggregatorEventsMockNewRound, error) + + FilterNewTransmission(opts *bind.FilterOpts, aggregatorRoundId []uint32) (*OffchainAggregatorEventsMockNewTransmissionIterator, error) + + WatchNewTransmission(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockNewTransmission, aggregatorRoundId []uint32) (event.Subscription, error) + + ParseNewTransmission(log types.Log) (*OffchainAggregatorEventsMockNewTransmission, error) + + FilterOraclePaid(opts *bind.FilterOpts, transmitter []common.Address, payee []common.Address, linkToken []common.Address) (*OffchainAggregatorEventsMockOraclePaidIterator, error) + + WatchOraclePaid(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockOraclePaid, transmitter []common.Address, payee []common.Address, linkToken []common.Address) (event.Subscription, error) + + ParseOraclePaid(log types.Log) (*OffchainAggregatorEventsMockOraclePaid, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*OffchainAggregatorEventsMockOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*OffchainAggregatorEventsMockOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*OffchainAggregatorEventsMockOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*OffchainAggregatorEventsMockOwnershipTransferred, error) + + FilterPayeeshipTransferRequested(opts *bind.FilterOpts, transmitter []common.Address, current []common.Address, proposed []common.Address) (*OffchainAggregatorEventsMockPayeeshipTransferRequestedIterator, error) + + WatchPayeeshipTransferRequested(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockPayeeshipTransferRequested, transmitter []common.Address, current []common.Address, proposed []common.Address) (event.Subscription, error) + + ParsePayeeshipTransferRequested(log types.Log) (*OffchainAggregatorEventsMockPayeeshipTransferRequested, error) + + FilterPayeeshipTransferred(opts *bind.FilterOpts, transmitter []common.Address, previous []common.Address, current []common.Address) (*OffchainAggregatorEventsMockPayeeshipTransferredIterator, error) + + WatchPayeeshipTransferred(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockPayeeshipTransferred, transmitter []common.Address, previous []common.Address, current []common.Address) (event.Subscription, error) + + ParsePayeeshipTransferred(log types.Log) (*OffchainAggregatorEventsMockPayeeshipTransferred, error) + + FilterRequesterAccessControllerSet(opts *bind.FilterOpts) (*OffchainAggregatorEventsMockRequesterAccessControllerSetIterator, error) + + WatchRequesterAccessControllerSet(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockRequesterAccessControllerSet) (event.Subscription, error) + + ParseRequesterAccessControllerSet(log types.Log) (*OffchainAggregatorEventsMockRequesterAccessControllerSet, error) + + FilterRoundRequested(opts *bind.FilterOpts, requester []common.Address) (*OffchainAggregatorEventsMockRoundRequestedIterator, error) + + WatchRoundRequested(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockRoundRequested, requester []common.Address) (event.Subscription, error) + + ParseRoundRequested(log types.Log) (*OffchainAggregatorEventsMockRoundRequested, error) + + FilterValidatorConfigSet(opts *bind.FilterOpts, previousValidator []common.Address, currentValidator []common.Address) (*OffchainAggregatorEventsMockValidatorConfigSetIterator, error) + + WatchValidatorConfigSet(opts *bind.WatchOpts, sink chan<- *OffchainAggregatorEventsMockValidatorConfigSet, previousValidator []common.Address, currentValidator []common.Address) (event.Subscription, error) + + ParseValidatorConfigSet(log types.Log) (*OffchainAggregatorEventsMockValidatorConfigSet, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/integration-tests/contracts/ethereum/StakingEventsMock.go b/integration-tests/contracts/ethereum/StakingEventsMock.go new file mode 100644 index 00000000000..5a1a1663ba9 --- /dev/null +++ b/integration-tests/contracts/ethereum/StakingEventsMock.go @@ -0,0 +1,3675 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package ethereum + +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 StakingEventsMockMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"alerter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"roundId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"rewardAmount\",\"type\":\"uint256\"}],\"name\":\"AlertRaised\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"feedOperators\",\"type\":\"address[]\"}],\"name\":\"FeedOperatorsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxStakeAmount\",\"type\":\"uint256\"}],\"name\":\"MaxCommunityStakeAmountIncreased\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxStakeAmount\",\"type\":\"uint256\"}],\"name\":\"MaxOperatorStakeAmountIncreased\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"newMerkleRoot\",\"type\":\"bytes32\"}],\"name\":\"MerkleRootChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"principal\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"baseReward\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"delegationReward\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"Migrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"migrationTarget\",\"type\":\"address\"}],\"name\":\"MigrationTargetAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"migrationTarget\",\"type\":\"address\"}],\"name\":\"MigrationTargetProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"OperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"OperatorRemoved\",\"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\":[],\"name\":\"PoolConcluded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"PoolOpened\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxPoolSize\",\"type\":\"uint256\"}],\"name\":\"PoolSizeIncreased\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountAdded\",\"type\":\"uint256\"}],\"name\":\"RewardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"rate\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startTimestamp\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"endTimestamp\",\"type\":\"uint256\"}],\"name\":\"RewardInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"rate\",\"type\":\"uint256\"}],\"name\":\"RewardRateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"operator\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"slashedBaseRewards\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"slashedDelegatedRewards\",\"type\":\"uint256[]\"}],\"name\":\"RewardSlashed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"RewardWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newStake\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalStake\",\"type\":\"uint256\"}],\"name\":\"Staked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"principal\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"baseReward\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"delegationReward\",\"type\":\"uint256\"}],\"name\":\"Unstaked\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"alerter\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"roundId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rewardAmount\",\"type\":\"uint256\"}],\"name\":\"emitAlertRaised\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feedOperators\",\"type\":\"address[]\"}],\"name\":\"emitFeedOperatorsSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxStakeAmount\",\"type\":\"uint256\"}],\"name\":\"emitMaxCommunityStakeAmountIncreased\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxStakeAmount\",\"type\":\"uint256\"}],\"name\":\"emitMaxOperatorStakeAmountIncreased\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"newMerkleRoot\",\"type\":\"bytes32\"}],\"name\":\"emitMerkleRootChanged\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"principal\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseReward\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"delegationReward\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"emitMigrated\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"migrationTarget\",\"type\":\"address\"}],\"name\":\"emitMigrationTargetAccepted\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"migrationTarget\",\"type\":\"address\"}],\"name\":\"emitMigrationTargetProposed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"emitOperatorAdded\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"emitOperatorRemoved\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"emitOwnershipTransferRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"emitOwnershipTransferred\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"emitPaused\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emitPoolConcluded\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emitPoolOpened\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxPoolSize\",\"type\":\"uint256\"}],\"name\":\"emitPoolSizeIncreased\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountAdded\",\"type\":\"uint256\"}],\"name\":\"emitRewardAdded\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"rate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"startTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endTimestamp\",\"type\":\"uint256\"}],\"name\":\"emitRewardInitialized\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"rate\",\"type\":\"uint256\"}],\"name\":\"emitRewardRateChanged\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"operator\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"slashedBaseRewards\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"slashedDelegatedRewards\",\"type\":\"uint256[]\"}],\"name\":\"emitRewardSlashed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"emitRewardWithdrawn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newStake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalStake\",\"type\":\"uint256\"}],\"name\":\"emitStaked\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"emitUnpaused\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"principal\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseReward\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"delegationReward\",\"type\":\"uint256\"}],\"name\":\"emitUnstaked\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50610f7b806100206000396000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c80639ec3ce4b116100e3578063b019b4e81161008c578063f7420bc211610066578063f7420bc214610318578063fa2d7fd01461032b578063fe60093f1461033e57600080fd5b8063b019b4e8146102df578063e0275fae146102f2578063eb6289de1461030557600080fd5b8063ab8711bc116100bd578063ab8711bc146102b1578063add49a96146102c4578063aeac9600146102cc57600080fd5b80639ec3ce4b146102785780639f676e9f1461028b578063a5f3d6831461029e57600080fd5b80637be5c756116101455780639a8d2df71161011f5780639a8d2df71461023f5780639b022d73146102525780639e81ace31461026557600080fd5b80637be5c756146102065780637e31a64b146102195780639652ab7b1461022c57600080fd5b80632752e639116101765780632752e639146101d85780633e8f1e05146101eb5780635d21e09a146101f357600080fd5b8063086c1c4a1461019d5780631351da48146101b257806313c664e8146101c5575b600080fd5b6101b06101ab366004610b25565b610351565b005b6101b06101c0366004610a73565b6103b6565b6101b06101d3366004610d04565b610403565b6101b06101e6366004610b5e565b610433565b6101b0610479565b6101b0610201366004610d04565b6104a4565b6101b0610214366004610a73565b6104d4565b6101b0610227366004610d04565b61051a565b6101b061023a366004610a73565b61054a565b6101b061024d366004610a73565b610590565b6101b0610260366004610d04565b6105d6565b6101b0610273366004610c7c565b610606565b6101b0610286366004610a73565b610645565b6101b0610299366004610d1d565b61068b565b6101b06102ac366004610c3f565b6106d0565b6101b06102bf366004610af2565b6106ff565b6101b0610753565b6101b06102da366004610d04565b61077e565b6101b06102ed366004610a95565b6107ae565b6101b0610300366004610af2565b61080c565b6101b0610313366004610ac8565b610860565b6101b0610326366004610a95565b6108b3565b6101b0610339366004610d04565b610911565b6101b061034c366004610d04565b610941565b6040805173ffffffffffffffffffffffffffffffffffffffff8616815260208101859052908101839052606081018290527f204fccf0d92ed8d48f204adb39b2e81e92bad0dedb93f5716ca9478cfb57de00906080015b60405180910390a150505050565b60405173ffffffffffffffffffffffffffffffffffffffff821681527fac6fa858e9350a46cec16539926e0fde25b7629f84b5a72bffaae4df888ae86d906020015b60405180910390a150565b6040518181527f816587cb2e773af4f3689a03d7520fabff3462605ded374b485b13994c0d7b52906020016103f8565b7f667838b33bdc898470de09e0e746990f2adc11b965b7fe6828e502ebc39e0434858585858560405161046a959493929190610dd0565b60405180910390a15050505050565b6040517fded6ebf04e261e1eb2f3e3b268a2e6aee5b478c15b341eba5cf18b9bc80c2e6390600090a1565b6040518181527fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d906020016103f8565b60405173ffffffffffffffffffffffffffffffffffffffff821681527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258906020016103f8565b6040518181527fb5f554e5ef00806bace1edbb84186512ebcefa2af7706085143f501f29314df7906020016103f8565b60405173ffffffffffffffffffffffffffffffffffffffff821681527ffa33c052bbee754f3c0482a89962daffe749191fa33c696a61e947fbfd68bd84906020016103f8565b60405173ffffffffffffffffffffffffffffffffffffffff821681527f5c74c441be501340b2713817a6c6975e6f3d4a4ae39fa1ac0bf75d3c54a0cad3906020016103f8565b6040518181527f7f4f497e086b2eb55f8a9885ba00d33399bbe0ebcb92ea092834386435a1b9c0906020016103f8565b7e635ea9da6e262e92bb713d71840af7c567807ff35bf73e927490c61283248083838360405161063893929190610e89565b60405180910390a1505050565b60405173ffffffffffffffffffffffffffffffffffffffff821681527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020016103f8565b6040805185815260208101859052908101839052606081018290527f125fc8494f786b470e3c39d0932a62e9e09e291ebd81ea19c57604f6d2b1d167906080016103a8565b7f40aed8e423b39a56b445ae160f4c071fc2cfb48ee0b6dcd5ffeb6bc5b18d10d0816040516103f89190610e76565b6040805173ffffffffffffffffffffffffffffffffffffffff85168152602081018490529081018290527f1449c6dd7851abc30abf37f57715f492010519147cc2652fbc38202c18a6ee9090606001610638565b6040517ff7d0e0f15586495da8c687328ead30fb829d9da55538cb0ef73dd229e517cdb890600090a1565b6040518181527f1b930366dfeaa7eb3b325021e4ae81e36527063452ee55b86c95f85b36f4c31c906020016103f8565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6040805173ffffffffffffffffffffffffffffffffffffffff85168152602081018490529081018290527fd2720e8f454493f612cc97499fe8cbce7fa4d4c18d346fe7104e9042df1c1edd90606001610638565b6040805173ffffffffffffffffffffffffffffffffffffffff84168152602081018390527f2360404a74478febece1a14f11275f22ada88d19ef96f7d785913010bfff4479910160405180910390a15050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127860405160405180910390a35050565b6040518181527f150a6ec0e6f4e9ddcaaaa1674f157d91165a42d60653016f87a9fc870a39f050906020016103f8565b6040518181527f1e3be2efa25bca5bff2215c7b30b31086e703d6aa7d9b9a1f8ba62c5291219ad906020016103f8565b803573ffffffffffffffffffffffffffffffffffffffff8116811461099557600080fd5b919050565b600082601f8301126109ab57600080fd5b813560206109c06109bb83610f1b565b610ecc565b80838252828201915082860187848660051b89010111156109e057600080fd5b60005b85811015610a06576109f482610971565b845292840192908401906001016109e3565b5090979650505050505050565b600082601f830112610a2457600080fd5b81356020610a346109bb83610f1b565b80838252828201915082860187848660051b8901011115610a5457600080fd5b60005b85811015610a0657813584529284019290840190600101610a57565b600060208284031215610a8557600080fd5b610a8e82610971565b9392505050565b60008060408385031215610aa857600080fd5b610ab183610971565b9150610abf60208401610971565b90509250929050565b60008060408385031215610adb57600080fd5b610ae483610971565b946020939093013593505050565b600080600060608486031215610b0757600080fd5b610b1084610971565b95602085013595506040909401359392505050565b60008060008060808587031215610b3b57600080fd5b610b4485610971565b966020860135965060408601359560600135945092505050565b600080600080600060a08688031215610b7657600080fd5b610b7f86610971565b945060208087013594506040870135935060608701359250608087013567ffffffffffffffff80821115610bb257600080fd5b818901915089601f830112610bc657600080fd5b813581811115610bd857610bd8610f3f565b610c08847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610ecc565b91508082528a84828501011115610c1e57600080fd5b80848401858401376000848284010152508093505050509295509295909350565b600060208284031215610c5157600080fd5b813567ffffffffffffffff811115610c6857600080fd5b610c748482850161099a565b949350505050565b600080600060608486031215610c9157600080fd5b833567ffffffffffffffff80821115610ca957600080fd5b610cb58783880161099a565b94506020860135915080821115610ccb57600080fd5b610cd787838801610a13565b93506040860135915080821115610ced57600080fd5b50610cfa86828701610a13565b9150509250925092565b600060208284031215610d1657600080fd5b5035919050565b60008060008060808587031215610d3357600080fd5b5050823594602084013594506040840135936060013592509050565b600081518084526020808501945080840160005b83811015610d9557815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101610d63565b509495945050505050565b600081518084526020808501945080840160005b83811015610d9557815187529582019590820190600101610db4565b73ffffffffffffffffffffffffffffffffffffffff8616815260006020868184015285604084015284606084015260a0608084015283518060a085015260005b81811015610e2c5785810183015185820160c001528201610e10565b81811115610e3e57600060c083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160c001979650505050505050565b602081526000610a8e6020830184610d4f565b606081526000610e9c6060830186610d4f565b8281036020840152610eae8186610da0565b90508281036040840152610ec28185610da0565b9695505050505050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610f1357610f13610f3f565b604052919050565b600067ffffffffffffffff821115610f3557610f35610f3f565b5060051b60200190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", +} + +var StakingEventsMockABI = StakingEventsMockMetaData.ABI + +var StakingEventsMockBin = StakingEventsMockMetaData.Bin + +func DeployStakingEventsMock(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *StakingEventsMock, error) { + parsed, err := StakingEventsMockMetaData.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(StakingEventsMockBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &StakingEventsMock{StakingEventsMockCaller: StakingEventsMockCaller{contract: contract}, StakingEventsMockTransactor: StakingEventsMockTransactor{contract: contract}, StakingEventsMockFilterer: StakingEventsMockFilterer{contract: contract}}, nil +} + +type StakingEventsMock struct { + address common.Address + abi abi.ABI + StakingEventsMockCaller + StakingEventsMockTransactor + StakingEventsMockFilterer +} + +type StakingEventsMockCaller struct { + contract *bind.BoundContract +} + +type StakingEventsMockTransactor struct { + contract *bind.BoundContract +} + +type StakingEventsMockFilterer struct { + contract *bind.BoundContract +} + +type StakingEventsMockSession struct { + Contract *StakingEventsMock + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type StakingEventsMockCallerSession struct { + Contract *StakingEventsMockCaller + CallOpts bind.CallOpts +} + +type StakingEventsMockTransactorSession struct { + Contract *StakingEventsMockTransactor + TransactOpts bind.TransactOpts +} + +type StakingEventsMockRaw struct { + Contract *StakingEventsMock +} + +type StakingEventsMockCallerRaw struct { + Contract *StakingEventsMockCaller +} + +type StakingEventsMockTransactorRaw struct { + Contract *StakingEventsMockTransactor +} + +func NewStakingEventsMock(address common.Address, backend bind.ContractBackend) (*StakingEventsMock, error) { + abi, err := abi.JSON(strings.NewReader(StakingEventsMockABI)) + if err != nil { + return nil, err + } + contract, err := bindStakingEventsMock(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &StakingEventsMock{address: address, abi: abi, StakingEventsMockCaller: StakingEventsMockCaller{contract: contract}, StakingEventsMockTransactor: StakingEventsMockTransactor{contract: contract}, StakingEventsMockFilterer: StakingEventsMockFilterer{contract: contract}}, nil +} + +func NewStakingEventsMockCaller(address common.Address, caller bind.ContractCaller) (*StakingEventsMockCaller, error) { + contract, err := bindStakingEventsMock(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &StakingEventsMockCaller{contract: contract}, nil +} + +func NewStakingEventsMockTransactor(address common.Address, transactor bind.ContractTransactor) (*StakingEventsMockTransactor, error) { + contract, err := bindStakingEventsMock(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &StakingEventsMockTransactor{contract: contract}, nil +} + +func NewStakingEventsMockFilterer(address common.Address, filterer bind.ContractFilterer) (*StakingEventsMockFilterer, error) { + contract, err := bindStakingEventsMock(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &StakingEventsMockFilterer{contract: contract}, nil +} + +func bindStakingEventsMock(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := StakingEventsMockMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_StakingEventsMock *StakingEventsMockRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _StakingEventsMock.Contract.StakingEventsMockCaller.contract.Call(opts, result, method, params...) +} + +func (_StakingEventsMock *StakingEventsMockRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _StakingEventsMock.Contract.StakingEventsMockTransactor.contract.Transfer(opts) +} + +func (_StakingEventsMock *StakingEventsMockRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _StakingEventsMock.Contract.StakingEventsMockTransactor.contract.Transact(opts, method, params...) +} + +func (_StakingEventsMock *StakingEventsMockCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _StakingEventsMock.Contract.contract.Call(opts, result, method, params...) +} + +func (_StakingEventsMock *StakingEventsMockTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _StakingEventsMock.Contract.contract.Transfer(opts) +} + +func (_StakingEventsMock *StakingEventsMockTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _StakingEventsMock.Contract.contract.Transact(opts, method, params...) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitAlertRaised(opts *bind.TransactOpts, alerter common.Address, roundId *big.Int, rewardAmount *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitAlertRaised", alerter, roundId, rewardAmount) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitAlertRaised(alerter common.Address, roundId *big.Int, rewardAmount *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitAlertRaised(&_StakingEventsMock.TransactOpts, alerter, roundId, rewardAmount) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitAlertRaised(alerter common.Address, roundId *big.Int, rewardAmount *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitAlertRaised(&_StakingEventsMock.TransactOpts, alerter, roundId, rewardAmount) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitFeedOperatorsSet(opts *bind.TransactOpts, feedOperators []common.Address) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitFeedOperatorsSet", feedOperators) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitFeedOperatorsSet(feedOperators []common.Address) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitFeedOperatorsSet(&_StakingEventsMock.TransactOpts, feedOperators) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitFeedOperatorsSet(feedOperators []common.Address) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitFeedOperatorsSet(&_StakingEventsMock.TransactOpts, feedOperators) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitMaxCommunityStakeAmountIncreased(opts *bind.TransactOpts, maxStakeAmount *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitMaxCommunityStakeAmountIncreased", maxStakeAmount) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitMaxCommunityStakeAmountIncreased(maxStakeAmount *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitMaxCommunityStakeAmountIncreased(&_StakingEventsMock.TransactOpts, maxStakeAmount) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitMaxCommunityStakeAmountIncreased(maxStakeAmount *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitMaxCommunityStakeAmountIncreased(&_StakingEventsMock.TransactOpts, maxStakeAmount) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitMaxOperatorStakeAmountIncreased(opts *bind.TransactOpts, maxStakeAmount *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitMaxOperatorStakeAmountIncreased", maxStakeAmount) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitMaxOperatorStakeAmountIncreased(maxStakeAmount *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitMaxOperatorStakeAmountIncreased(&_StakingEventsMock.TransactOpts, maxStakeAmount) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitMaxOperatorStakeAmountIncreased(maxStakeAmount *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitMaxOperatorStakeAmountIncreased(&_StakingEventsMock.TransactOpts, maxStakeAmount) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitMerkleRootChanged(opts *bind.TransactOpts, newMerkleRoot [32]byte) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitMerkleRootChanged", newMerkleRoot) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitMerkleRootChanged(newMerkleRoot [32]byte) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitMerkleRootChanged(&_StakingEventsMock.TransactOpts, newMerkleRoot) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitMerkleRootChanged(newMerkleRoot [32]byte) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitMerkleRootChanged(&_StakingEventsMock.TransactOpts, newMerkleRoot) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitMigrated(opts *bind.TransactOpts, staker common.Address, principal *big.Int, baseReward *big.Int, delegationReward *big.Int, data []byte) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitMigrated", staker, principal, baseReward, delegationReward, data) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitMigrated(staker common.Address, principal *big.Int, baseReward *big.Int, delegationReward *big.Int, data []byte) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitMigrated(&_StakingEventsMock.TransactOpts, staker, principal, baseReward, delegationReward, data) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitMigrated(staker common.Address, principal *big.Int, baseReward *big.Int, delegationReward *big.Int, data []byte) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitMigrated(&_StakingEventsMock.TransactOpts, staker, principal, baseReward, delegationReward, data) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitMigrationTargetAccepted(opts *bind.TransactOpts, migrationTarget common.Address) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitMigrationTargetAccepted", migrationTarget) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitMigrationTargetAccepted(migrationTarget common.Address) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitMigrationTargetAccepted(&_StakingEventsMock.TransactOpts, migrationTarget) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitMigrationTargetAccepted(migrationTarget common.Address) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitMigrationTargetAccepted(&_StakingEventsMock.TransactOpts, migrationTarget) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitMigrationTargetProposed(opts *bind.TransactOpts, migrationTarget common.Address) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitMigrationTargetProposed", migrationTarget) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitMigrationTargetProposed(migrationTarget common.Address) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitMigrationTargetProposed(&_StakingEventsMock.TransactOpts, migrationTarget) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitMigrationTargetProposed(migrationTarget common.Address) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitMigrationTargetProposed(&_StakingEventsMock.TransactOpts, migrationTarget) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitOperatorAdded(opts *bind.TransactOpts, operator common.Address) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitOperatorAdded", operator) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitOperatorAdded(operator common.Address) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitOperatorAdded(&_StakingEventsMock.TransactOpts, operator) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitOperatorAdded(operator common.Address) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitOperatorAdded(&_StakingEventsMock.TransactOpts, operator) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitOperatorRemoved(opts *bind.TransactOpts, operator common.Address, amount *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitOperatorRemoved", operator, amount) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitOperatorRemoved(operator common.Address, amount *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitOperatorRemoved(&_StakingEventsMock.TransactOpts, operator, amount) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitOperatorRemoved(operator common.Address, amount *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitOperatorRemoved(&_StakingEventsMock.TransactOpts, operator, amount) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitOwnershipTransferRequested(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitOwnershipTransferRequested", from, to) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitOwnershipTransferRequested(from common.Address, to common.Address) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitOwnershipTransferRequested(&_StakingEventsMock.TransactOpts, from, to) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitOwnershipTransferRequested(from common.Address, to common.Address) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitOwnershipTransferRequested(&_StakingEventsMock.TransactOpts, from, to) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitOwnershipTransferred(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitOwnershipTransferred", from, to) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitOwnershipTransferred(from common.Address, to common.Address) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitOwnershipTransferred(&_StakingEventsMock.TransactOpts, from, to) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitOwnershipTransferred(from common.Address, to common.Address) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitOwnershipTransferred(&_StakingEventsMock.TransactOpts, from, to) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitPaused(opts *bind.TransactOpts, account common.Address) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitPaused", account) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitPaused(account common.Address) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitPaused(&_StakingEventsMock.TransactOpts, account) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitPaused(account common.Address) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitPaused(&_StakingEventsMock.TransactOpts, account) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitPoolConcluded(opts *bind.TransactOpts) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitPoolConcluded") +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitPoolConcluded() (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitPoolConcluded(&_StakingEventsMock.TransactOpts) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitPoolConcluded() (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitPoolConcluded(&_StakingEventsMock.TransactOpts) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitPoolOpened(opts *bind.TransactOpts) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitPoolOpened") +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitPoolOpened() (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitPoolOpened(&_StakingEventsMock.TransactOpts) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitPoolOpened() (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitPoolOpened(&_StakingEventsMock.TransactOpts) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitPoolSizeIncreased(opts *bind.TransactOpts, maxPoolSize *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitPoolSizeIncreased", maxPoolSize) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitPoolSizeIncreased(maxPoolSize *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitPoolSizeIncreased(&_StakingEventsMock.TransactOpts, maxPoolSize) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitPoolSizeIncreased(maxPoolSize *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitPoolSizeIncreased(&_StakingEventsMock.TransactOpts, maxPoolSize) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitRewardAdded(opts *bind.TransactOpts, amountAdded *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitRewardAdded", amountAdded) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitRewardAdded(amountAdded *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitRewardAdded(&_StakingEventsMock.TransactOpts, amountAdded) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitRewardAdded(amountAdded *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitRewardAdded(&_StakingEventsMock.TransactOpts, amountAdded) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitRewardInitialized(opts *bind.TransactOpts, rate *big.Int, available *big.Int, startTimestamp *big.Int, endTimestamp *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitRewardInitialized", rate, available, startTimestamp, endTimestamp) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitRewardInitialized(rate *big.Int, available *big.Int, startTimestamp *big.Int, endTimestamp *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitRewardInitialized(&_StakingEventsMock.TransactOpts, rate, available, startTimestamp, endTimestamp) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitRewardInitialized(rate *big.Int, available *big.Int, startTimestamp *big.Int, endTimestamp *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitRewardInitialized(&_StakingEventsMock.TransactOpts, rate, available, startTimestamp, endTimestamp) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitRewardRateChanged(opts *bind.TransactOpts, rate *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitRewardRateChanged", rate) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitRewardRateChanged(rate *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitRewardRateChanged(&_StakingEventsMock.TransactOpts, rate) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitRewardRateChanged(rate *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitRewardRateChanged(&_StakingEventsMock.TransactOpts, rate) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitRewardSlashed(opts *bind.TransactOpts, operator []common.Address, slashedBaseRewards []*big.Int, slashedDelegatedRewards []*big.Int) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitRewardSlashed", operator, slashedBaseRewards, slashedDelegatedRewards) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitRewardSlashed(operator []common.Address, slashedBaseRewards []*big.Int, slashedDelegatedRewards []*big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitRewardSlashed(&_StakingEventsMock.TransactOpts, operator, slashedBaseRewards, slashedDelegatedRewards) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitRewardSlashed(operator []common.Address, slashedBaseRewards []*big.Int, slashedDelegatedRewards []*big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitRewardSlashed(&_StakingEventsMock.TransactOpts, operator, slashedBaseRewards, slashedDelegatedRewards) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitRewardWithdrawn(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitRewardWithdrawn", amount) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitRewardWithdrawn(amount *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitRewardWithdrawn(&_StakingEventsMock.TransactOpts, amount) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitRewardWithdrawn(amount *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitRewardWithdrawn(&_StakingEventsMock.TransactOpts, amount) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitStaked(opts *bind.TransactOpts, staker common.Address, newStake *big.Int, totalStake *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitStaked", staker, newStake, totalStake) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitStaked(staker common.Address, newStake *big.Int, totalStake *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitStaked(&_StakingEventsMock.TransactOpts, staker, newStake, totalStake) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitStaked(staker common.Address, newStake *big.Int, totalStake *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitStaked(&_StakingEventsMock.TransactOpts, staker, newStake, totalStake) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitUnpaused(opts *bind.TransactOpts, account common.Address) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitUnpaused", account) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitUnpaused(account common.Address) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitUnpaused(&_StakingEventsMock.TransactOpts, account) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitUnpaused(account common.Address) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitUnpaused(&_StakingEventsMock.TransactOpts, account) +} + +func (_StakingEventsMock *StakingEventsMockTransactor) EmitUnstaked(opts *bind.TransactOpts, staker common.Address, principal *big.Int, baseReward *big.Int, delegationReward *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.contract.Transact(opts, "emitUnstaked", staker, principal, baseReward, delegationReward) +} + +func (_StakingEventsMock *StakingEventsMockSession) EmitUnstaked(staker common.Address, principal *big.Int, baseReward *big.Int, delegationReward *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitUnstaked(&_StakingEventsMock.TransactOpts, staker, principal, baseReward, delegationReward) +} + +func (_StakingEventsMock *StakingEventsMockTransactorSession) EmitUnstaked(staker common.Address, principal *big.Int, baseReward *big.Int, delegationReward *big.Int) (*types.Transaction, error) { + return _StakingEventsMock.Contract.EmitUnstaked(&_StakingEventsMock.TransactOpts, staker, principal, baseReward, delegationReward) +} + +type StakingEventsMockAlertRaisedIterator struct { + Event *StakingEventsMockAlertRaised + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockAlertRaisedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockAlertRaised) + 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(StakingEventsMockAlertRaised) + 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 *StakingEventsMockAlertRaisedIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockAlertRaisedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockAlertRaised struct { + Alerter common.Address + RoundId *big.Int + RewardAmount *big.Int + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterAlertRaised(opts *bind.FilterOpts) (*StakingEventsMockAlertRaisedIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "AlertRaised") + if err != nil { + return nil, err + } + return &StakingEventsMockAlertRaisedIterator{contract: _StakingEventsMock.contract, event: "AlertRaised", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchAlertRaised(opts *bind.WatchOpts, sink chan<- *StakingEventsMockAlertRaised) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "AlertRaised") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockAlertRaised) + if err := _StakingEventsMock.contract.UnpackLog(event, "AlertRaised", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParseAlertRaised(log types.Log) (*StakingEventsMockAlertRaised, error) { + event := new(StakingEventsMockAlertRaised) + if err := _StakingEventsMock.contract.UnpackLog(event, "AlertRaised", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockFeedOperatorsSetIterator struct { + Event *StakingEventsMockFeedOperatorsSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockFeedOperatorsSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockFeedOperatorsSet) + 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(StakingEventsMockFeedOperatorsSet) + 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 *StakingEventsMockFeedOperatorsSetIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockFeedOperatorsSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockFeedOperatorsSet struct { + FeedOperators []common.Address + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterFeedOperatorsSet(opts *bind.FilterOpts) (*StakingEventsMockFeedOperatorsSetIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "FeedOperatorsSet") + if err != nil { + return nil, err + } + return &StakingEventsMockFeedOperatorsSetIterator{contract: _StakingEventsMock.contract, event: "FeedOperatorsSet", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchFeedOperatorsSet(opts *bind.WatchOpts, sink chan<- *StakingEventsMockFeedOperatorsSet) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "FeedOperatorsSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockFeedOperatorsSet) + if err := _StakingEventsMock.contract.UnpackLog(event, "FeedOperatorsSet", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParseFeedOperatorsSet(log types.Log) (*StakingEventsMockFeedOperatorsSet, error) { + event := new(StakingEventsMockFeedOperatorsSet) + if err := _StakingEventsMock.contract.UnpackLog(event, "FeedOperatorsSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockMaxCommunityStakeAmountIncreasedIterator struct { + Event *StakingEventsMockMaxCommunityStakeAmountIncreased + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockMaxCommunityStakeAmountIncreasedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockMaxCommunityStakeAmountIncreased) + 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(StakingEventsMockMaxCommunityStakeAmountIncreased) + 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 *StakingEventsMockMaxCommunityStakeAmountIncreasedIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockMaxCommunityStakeAmountIncreasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockMaxCommunityStakeAmountIncreased struct { + MaxStakeAmount *big.Int + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterMaxCommunityStakeAmountIncreased(opts *bind.FilterOpts) (*StakingEventsMockMaxCommunityStakeAmountIncreasedIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "MaxCommunityStakeAmountIncreased") + if err != nil { + return nil, err + } + return &StakingEventsMockMaxCommunityStakeAmountIncreasedIterator{contract: _StakingEventsMock.contract, event: "MaxCommunityStakeAmountIncreased", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchMaxCommunityStakeAmountIncreased(opts *bind.WatchOpts, sink chan<- *StakingEventsMockMaxCommunityStakeAmountIncreased) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "MaxCommunityStakeAmountIncreased") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockMaxCommunityStakeAmountIncreased) + if err := _StakingEventsMock.contract.UnpackLog(event, "MaxCommunityStakeAmountIncreased", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParseMaxCommunityStakeAmountIncreased(log types.Log) (*StakingEventsMockMaxCommunityStakeAmountIncreased, error) { + event := new(StakingEventsMockMaxCommunityStakeAmountIncreased) + if err := _StakingEventsMock.contract.UnpackLog(event, "MaxCommunityStakeAmountIncreased", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockMaxOperatorStakeAmountIncreasedIterator struct { + Event *StakingEventsMockMaxOperatorStakeAmountIncreased + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockMaxOperatorStakeAmountIncreasedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockMaxOperatorStakeAmountIncreased) + 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(StakingEventsMockMaxOperatorStakeAmountIncreased) + 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 *StakingEventsMockMaxOperatorStakeAmountIncreasedIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockMaxOperatorStakeAmountIncreasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockMaxOperatorStakeAmountIncreased struct { + MaxStakeAmount *big.Int + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterMaxOperatorStakeAmountIncreased(opts *bind.FilterOpts) (*StakingEventsMockMaxOperatorStakeAmountIncreasedIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "MaxOperatorStakeAmountIncreased") + if err != nil { + return nil, err + } + return &StakingEventsMockMaxOperatorStakeAmountIncreasedIterator{contract: _StakingEventsMock.contract, event: "MaxOperatorStakeAmountIncreased", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchMaxOperatorStakeAmountIncreased(opts *bind.WatchOpts, sink chan<- *StakingEventsMockMaxOperatorStakeAmountIncreased) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "MaxOperatorStakeAmountIncreased") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockMaxOperatorStakeAmountIncreased) + if err := _StakingEventsMock.contract.UnpackLog(event, "MaxOperatorStakeAmountIncreased", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParseMaxOperatorStakeAmountIncreased(log types.Log) (*StakingEventsMockMaxOperatorStakeAmountIncreased, error) { + event := new(StakingEventsMockMaxOperatorStakeAmountIncreased) + if err := _StakingEventsMock.contract.UnpackLog(event, "MaxOperatorStakeAmountIncreased", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockMerkleRootChangedIterator struct { + Event *StakingEventsMockMerkleRootChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockMerkleRootChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockMerkleRootChanged) + 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(StakingEventsMockMerkleRootChanged) + 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 *StakingEventsMockMerkleRootChangedIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockMerkleRootChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockMerkleRootChanged struct { + NewMerkleRoot [32]byte + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterMerkleRootChanged(opts *bind.FilterOpts) (*StakingEventsMockMerkleRootChangedIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "MerkleRootChanged") + if err != nil { + return nil, err + } + return &StakingEventsMockMerkleRootChangedIterator{contract: _StakingEventsMock.contract, event: "MerkleRootChanged", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchMerkleRootChanged(opts *bind.WatchOpts, sink chan<- *StakingEventsMockMerkleRootChanged) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "MerkleRootChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockMerkleRootChanged) + if err := _StakingEventsMock.contract.UnpackLog(event, "MerkleRootChanged", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParseMerkleRootChanged(log types.Log) (*StakingEventsMockMerkleRootChanged, error) { + event := new(StakingEventsMockMerkleRootChanged) + if err := _StakingEventsMock.contract.UnpackLog(event, "MerkleRootChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockMigratedIterator struct { + Event *StakingEventsMockMigrated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockMigratedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockMigrated) + 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(StakingEventsMockMigrated) + 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 *StakingEventsMockMigratedIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockMigratedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockMigrated struct { + Staker common.Address + Principal *big.Int + BaseReward *big.Int + DelegationReward *big.Int + Data []byte + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterMigrated(opts *bind.FilterOpts) (*StakingEventsMockMigratedIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "Migrated") + if err != nil { + return nil, err + } + return &StakingEventsMockMigratedIterator{contract: _StakingEventsMock.contract, event: "Migrated", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchMigrated(opts *bind.WatchOpts, sink chan<- *StakingEventsMockMigrated) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "Migrated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockMigrated) + if err := _StakingEventsMock.contract.UnpackLog(event, "Migrated", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParseMigrated(log types.Log) (*StakingEventsMockMigrated, error) { + event := new(StakingEventsMockMigrated) + if err := _StakingEventsMock.contract.UnpackLog(event, "Migrated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockMigrationTargetAcceptedIterator struct { + Event *StakingEventsMockMigrationTargetAccepted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockMigrationTargetAcceptedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockMigrationTargetAccepted) + 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(StakingEventsMockMigrationTargetAccepted) + 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 *StakingEventsMockMigrationTargetAcceptedIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockMigrationTargetAcceptedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockMigrationTargetAccepted struct { + MigrationTarget common.Address + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterMigrationTargetAccepted(opts *bind.FilterOpts) (*StakingEventsMockMigrationTargetAcceptedIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "MigrationTargetAccepted") + if err != nil { + return nil, err + } + return &StakingEventsMockMigrationTargetAcceptedIterator{contract: _StakingEventsMock.contract, event: "MigrationTargetAccepted", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchMigrationTargetAccepted(opts *bind.WatchOpts, sink chan<- *StakingEventsMockMigrationTargetAccepted) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "MigrationTargetAccepted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockMigrationTargetAccepted) + if err := _StakingEventsMock.contract.UnpackLog(event, "MigrationTargetAccepted", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParseMigrationTargetAccepted(log types.Log) (*StakingEventsMockMigrationTargetAccepted, error) { + event := new(StakingEventsMockMigrationTargetAccepted) + if err := _StakingEventsMock.contract.UnpackLog(event, "MigrationTargetAccepted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockMigrationTargetProposedIterator struct { + Event *StakingEventsMockMigrationTargetProposed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockMigrationTargetProposedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockMigrationTargetProposed) + 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(StakingEventsMockMigrationTargetProposed) + 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 *StakingEventsMockMigrationTargetProposedIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockMigrationTargetProposedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockMigrationTargetProposed struct { + MigrationTarget common.Address + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterMigrationTargetProposed(opts *bind.FilterOpts) (*StakingEventsMockMigrationTargetProposedIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "MigrationTargetProposed") + if err != nil { + return nil, err + } + return &StakingEventsMockMigrationTargetProposedIterator{contract: _StakingEventsMock.contract, event: "MigrationTargetProposed", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchMigrationTargetProposed(opts *bind.WatchOpts, sink chan<- *StakingEventsMockMigrationTargetProposed) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "MigrationTargetProposed") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockMigrationTargetProposed) + if err := _StakingEventsMock.contract.UnpackLog(event, "MigrationTargetProposed", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParseMigrationTargetProposed(log types.Log) (*StakingEventsMockMigrationTargetProposed, error) { + event := new(StakingEventsMockMigrationTargetProposed) + if err := _StakingEventsMock.contract.UnpackLog(event, "MigrationTargetProposed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockOperatorAddedIterator struct { + Event *StakingEventsMockOperatorAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockOperatorAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockOperatorAdded) + 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(StakingEventsMockOperatorAdded) + 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 *StakingEventsMockOperatorAddedIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockOperatorAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockOperatorAdded struct { + Operator common.Address + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterOperatorAdded(opts *bind.FilterOpts) (*StakingEventsMockOperatorAddedIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "OperatorAdded") + if err != nil { + return nil, err + } + return &StakingEventsMockOperatorAddedIterator{contract: _StakingEventsMock.contract, event: "OperatorAdded", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchOperatorAdded(opts *bind.WatchOpts, sink chan<- *StakingEventsMockOperatorAdded) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "OperatorAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockOperatorAdded) + if err := _StakingEventsMock.contract.UnpackLog(event, "OperatorAdded", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParseOperatorAdded(log types.Log) (*StakingEventsMockOperatorAdded, error) { + event := new(StakingEventsMockOperatorAdded) + if err := _StakingEventsMock.contract.UnpackLog(event, "OperatorAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockOperatorRemovedIterator struct { + Event *StakingEventsMockOperatorRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockOperatorRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockOperatorRemoved) + 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(StakingEventsMockOperatorRemoved) + 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 *StakingEventsMockOperatorRemovedIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockOperatorRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockOperatorRemoved struct { + Operator common.Address + Amount *big.Int + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterOperatorRemoved(opts *bind.FilterOpts) (*StakingEventsMockOperatorRemovedIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "OperatorRemoved") + if err != nil { + return nil, err + } + return &StakingEventsMockOperatorRemovedIterator{contract: _StakingEventsMock.contract, event: "OperatorRemoved", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchOperatorRemoved(opts *bind.WatchOpts, sink chan<- *StakingEventsMockOperatorRemoved) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "OperatorRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockOperatorRemoved) + if err := _StakingEventsMock.contract.UnpackLog(event, "OperatorRemoved", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParseOperatorRemoved(log types.Log) (*StakingEventsMockOperatorRemoved, error) { + event := new(StakingEventsMockOperatorRemoved) + if err := _StakingEventsMock.contract.UnpackLog(event, "OperatorRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockOwnershipTransferRequestedIterator struct { + Event *StakingEventsMockOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockOwnershipTransferRequested) + 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(StakingEventsMockOwnershipTransferRequested) + 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 *StakingEventsMockOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*StakingEventsMockOwnershipTransferRequestedIterator, 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 := _StakingEventsMock.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &StakingEventsMockOwnershipTransferRequestedIterator{contract: _StakingEventsMock.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *StakingEventsMockOwnershipTransferRequested, 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 := _StakingEventsMock.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(StakingEventsMockOwnershipTransferRequested) + if err := _StakingEventsMock.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 (_StakingEventsMock *StakingEventsMockFilterer) ParseOwnershipTransferRequested(log types.Log) (*StakingEventsMockOwnershipTransferRequested, error) { + event := new(StakingEventsMockOwnershipTransferRequested) + if err := _StakingEventsMock.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockOwnershipTransferredIterator struct { + Event *StakingEventsMockOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockOwnershipTransferred) + 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(StakingEventsMockOwnershipTransferred) + 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 *StakingEventsMockOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*StakingEventsMockOwnershipTransferredIterator, 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 := _StakingEventsMock.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &StakingEventsMockOwnershipTransferredIterator{contract: _StakingEventsMock.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *StakingEventsMockOwnershipTransferred, 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 := _StakingEventsMock.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(StakingEventsMockOwnershipTransferred) + if err := _StakingEventsMock.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 (_StakingEventsMock *StakingEventsMockFilterer) ParseOwnershipTransferred(log types.Log) (*StakingEventsMockOwnershipTransferred, error) { + event := new(StakingEventsMockOwnershipTransferred) + if err := _StakingEventsMock.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockPausedIterator struct { + Event *StakingEventsMockPaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockPausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockPaused) + 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(StakingEventsMockPaused) + 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 *StakingEventsMockPausedIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockPaused struct { + Account common.Address + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterPaused(opts *bind.FilterOpts) (*StakingEventsMockPausedIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &StakingEventsMockPausedIterator{contract: _StakingEventsMock.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *StakingEventsMockPaused) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "Paused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockPaused) + if err := _StakingEventsMock.contract.UnpackLog(event, "Paused", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParsePaused(log types.Log) (*StakingEventsMockPaused, error) { + event := new(StakingEventsMockPaused) + if err := _StakingEventsMock.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockPoolConcludedIterator struct { + Event *StakingEventsMockPoolConcluded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockPoolConcludedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockPoolConcluded) + 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(StakingEventsMockPoolConcluded) + 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 *StakingEventsMockPoolConcludedIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockPoolConcludedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockPoolConcluded struct { + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterPoolConcluded(opts *bind.FilterOpts) (*StakingEventsMockPoolConcludedIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "PoolConcluded") + if err != nil { + return nil, err + } + return &StakingEventsMockPoolConcludedIterator{contract: _StakingEventsMock.contract, event: "PoolConcluded", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchPoolConcluded(opts *bind.WatchOpts, sink chan<- *StakingEventsMockPoolConcluded) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "PoolConcluded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockPoolConcluded) + if err := _StakingEventsMock.contract.UnpackLog(event, "PoolConcluded", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParsePoolConcluded(log types.Log) (*StakingEventsMockPoolConcluded, error) { + event := new(StakingEventsMockPoolConcluded) + if err := _StakingEventsMock.contract.UnpackLog(event, "PoolConcluded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockPoolOpenedIterator struct { + Event *StakingEventsMockPoolOpened + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockPoolOpenedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockPoolOpened) + 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(StakingEventsMockPoolOpened) + 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 *StakingEventsMockPoolOpenedIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockPoolOpenedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockPoolOpened struct { + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterPoolOpened(opts *bind.FilterOpts) (*StakingEventsMockPoolOpenedIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "PoolOpened") + if err != nil { + return nil, err + } + return &StakingEventsMockPoolOpenedIterator{contract: _StakingEventsMock.contract, event: "PoolOpened", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchPoolOpened(opts *bind.WatchOpts, sink chan<- *StakingEventsMockPoolOpened) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "PoolOpened") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockPoolOpened) + if err := _StakingEventsMock.contract.UnpackLog(event, "PoolOpened", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParsePoolOpened(log types.Log) (*StakingEventsMockPoolOpened, error) { + event := new(StakingEventsMockPoolOpened) + if err := _StakingEventsMock.contract.UnpackLog(event, "PoolOpened", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockPoolSizeIncreasedIterator struct { + Event *StakingEventsMockPoolSizeIncreased + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockPoolSizeIncreasedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockPoolSizeIncreased) + 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(StakingEventsMockPoolSizeIncreased) + 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 *StakingEventsMockPoolSizeIncreasedIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockPoolSizeIncreasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockPoolSizeIncreased struct { + MaxPoolSize *big.Int + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterPoolSizeIncreased(opts *bind.FilterOpts) (*StakingEventsMockPoolSizeIncreasedIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "PoolSizeIncreased") + if err != nil { + return nil, err + } + return &StakingEventsMockPoolSizeIncreasedIterator{contract: _StakingEventsMock.contract, event: "PoolSizeIncreased", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchPoolSizeIncreased(opts *bind.WatchOpts, sink chan<- *StakingEventsMockPoolSizeIncreased) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "PoolSizeIncreased") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockPoolSizeIncreased) + if err := _StakingEventsMock.contract.UnpackLog(event, "PoolSizeIncreased", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParsePoolSizeIncreased(log types.Log) (*StakingEventsMockPoolSizeIncreased, error) { + event := new(StakingEventsMockPoolSizeIncreased) + if err := _StakingEventsMock.contract.UnpackLog(event, "PoolSizeIncreased", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockRewardAddedIterator struct { + Event *StakingEventsMockRewardAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockRewardAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockRewardAdded) + 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(StakingEventsMockRewardAdded) + 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 *StakingEventsMockRewardAddedIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockRewardAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockRewardAdded struct { + AmountAdded *big.Int + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterRewardAdded(opts *bind.FilterOpts) (*StakingEventsMockRewardAddedIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "RewardAdded") + if err != nil { + return nil, err + } + return &StakingEventsMockRewardAddedIterator{contract: _StakingEventsMock.contract, event: "RewardAdded", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchRewardAdded(opts *bind.WatchOpts, sink chan<- *StakingEventsMockRewardAdded) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "RewardAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockRewardAdded) + if err := _StakingEventsMock.contract.UnpackLog(event, "RewardAdded", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParseRewardAdded(log types.Log) (*StakingEventsMockRewardAdded, error) { + event := new(StakingEventsMockRewardAdded) + if err := _StakingEventsMock.contract.UnpackLog(event, "RewardAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockRewardInitializedIterator struct { + Event *StakingEventsMockRewardInitialized + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockRewardInitializedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockRewardInitialized) + 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(StakingEventsMockRewardInitialized) + 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 *StakingEventsMockRewardInitializedIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockRewardInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockRewardInitialized struct { + Rate *big.Int + Available *big.Int + StartTimestamp *big.Int + EndTimestamp *big.Int + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterRewardInitialized(opts *bind.FilterOpts) (*StakingEventsMockRewardInitializedIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "RewardInitialized") + if err != nil { + return nil, err + } + return &StakingEventsMockRewardInitializedIterator{contract: _StakingEventsMock.contract, event: "RewardInitialized", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchRewardInitialized(opts *bind.WatchOpts, sink chan<- *StakingEventsMockRewardInitialized) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "RewardInitialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockRewardInitialized) + if err := _StakingEventsMock.contract.UnpackLog(event, "RewardInitialized", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParseRewardInitialized(log types.Log) (*StakingEventsMockRewardInitialized, error) { + event := new(StakingEventsMockRewardInitialized) + if err := _StakingEventsMock.contract.UnpackLog(event, "RewardInitialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockRewardRateChangedIterator struct { + Event *StakingEventsMockRewardRateChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockRewardRateChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockRewardRateChanged) + 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(StakingEventsMockRewardRateChanged) + 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 *StakingEventsMockRewardRateChangedIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockRewardRateChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockRewardRateChanged struct { + Rate *big.Int + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterRewardRateChanged(opts *bind.FilterOpts) (*StakingEventsMockRewardRateChangedIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "RewardRateChanged") + if err != nil { + return nil, err + } + return &StakingEventsMockRewardRateChangedIterator{contract: _StakingEventsMock.contract, event: "RewardRateChanged", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchRewardRateChanged(opts *bind.WatchOpts, sink chan<- *StakingEventsMockRewardRateChanged) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "RewardRateChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockRewardRateChanged) + if err := _StakingEventsMock.contract.UnpackLog(event, "RewardRateChanged", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParseRewardRateChanged(log types.Log) (*StakingEventsMockRewardRateChanged, error) { + event := new(StakingEventsMockRewardRateChanged) + if err := _StakingEventsMock.contract.UnpackLog(event, "RewardRateChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockRewardSlashedIterator struct { + Event *StakingEventsMockRewardSlashed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockRewardSlashedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockRewardSlashed) + 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(StakingEventsMockRewardSlashed) + 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 *StakingEventsMockRewardSlashedIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockRewardSlashedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockRewardSlashed struct { + Operator []common.Address + SlashedBaseRewards []*big.Int + SlashedDelegatedRewards []*big.Int + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterRewardSlashed(opts *bind.FilterOpts) (*StakingEventsMockRewardSlashedIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "RewardSlashed") + if err != nil { + return nil, err + } + return &StakingEventsMockRewardSlashedIterator{contract: _StakingEventsMock.contract, event: "RewardSlashed", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchRewardSlashed(opts *bind.WatchOpts, sink chan<- *StakingEventsMockRewardSlashed) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "RewardSlashed") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockRewardSlashed) + if err := _StakingEventsMock.contract.UnpackLog(event, "RewardSlashed", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParseRewardSlashed(log types.Log) (*StakingEventsMockRewardSlashed, error) { + event := new(StakingEventsMockRewardSlashed) + if err := _StakingEventsMock.contract.UnpackLog(event, "RewardSlashed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockRewardWithdrawnIterator struct { + Event *StakingEventsMockRewardWithdrawn + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockRewardWithdrawnIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockRewardWithdrawn) + 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(StakingEventsMockRewardWithdrawn) + 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 *StakingEventsMockRewardWithdrawnIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockRewardWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockRewardWithdrawn struct { + Amount *big.Int + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterRewardWithdrawn(opts *bind.FilterOpts) (*StakingEventsMockRewardWithdrawnIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "RewardWithdrawn") + if err != nil { + return nil, err + } + return &StakingEventsMockRewardWithdrawnIterator{contract: _StakingEventsMock.contract, event: "RewardWithdrawn", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchRewardWithdrawn(opts *bind.WatchOpts, sink chan<- *StakingEventsMockRewardWithdrawn) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "RewardWithdrawn") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockRewardWithdrawn) + if err := _StakingEventsMock.contract.UnpackLog(event, "RewardWithdrawn", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParseRewardWithdrawn(log types.Log) (*StakingEventsMockRewardWithdrawn, error) { + event := new(StakingEventsMockRewardWithdrawn) + if err := _StakingEventsMock.contract.UnpackLog(event, "RewardWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockStakedIterator struct { + Event *StakingEventsMockStaked + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockStakedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockStaked) + 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(StakingEventsMockStaked) + 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 *StakingEventsMockStakedIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockStakedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockStaked struct { + Staker common.Address + NewStake *big.Int + TotalStake *big.Int + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterStaked(opts *bind.FilterOpts) (*StakingEventsMockStakedIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "Staked") + if err != nil { + return nil, err + } + return &StakingEventsMockStakedIterator{contract: _StakingEventsMock.contract, event: "Staked", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchStaked(opts *bind.WatchOpts, sink chan<- *StakingEventsMockStaked) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "Staked") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockStaked) + if err := _StakingEventsMock.contract.UnpackLog(event, "Staked", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParseStaked(log types.Log) (*StakingEventsMockStaked, error) { + event := new(StakingEventsMockStaked) + if err := _StakingEventsMock.contract.UnpackLog(event, "Staked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockUnpausedIterator struct { + Event *StakingEventsMockUnpaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockUnpausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockUnpaused) + 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(StakingEventsMockUnpaused) + 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 *StakingEventsMockUnpausedIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockUnpaused struct { + Account common.Address + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterUnpaused(opts *bind.FilterOpts) (*StakingEventsMockUnpausedIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &StakingEventsMockUnpausedIterator{contract: _StakingEventsMock.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *StakingEventsMockUnpaused) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockUnpaused) + if err := _StakingEventsMock.contract.UnpackLog(event, "Unpaused", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParseUnpaused(log types.Log) (*StakingEventsMockUnpaused, error) { + event := new(StakingEventsMockUnpaused) + if err := _StakingEventsMock.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type StakingEventsMockUnstakedIterator struct { + Event *StakingEventsMockUnstaked + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *StakingEventsMockUnstakedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(StakingEventsMockUnstaked) + 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(StakingEventsMockUnstaked) + 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 *StakingEventsMockUnstakedIterator) Error() error { + return it.fail +} + +func (it *StakingEventsMockUnstakedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type StakingEventsMockUnstaked struct { + Staker common.Address + Principal *big.Int + BaseReward *big.Int + DelegationReward *big.Int + Raw types.Log +} + +func (_StakingEventsMock *StakingEventsMockFilterer) FilterUnstaked(opts *bind.FilterOpts) (*StakingEventsMockUnstakedIterator, error) { + + logs, sub, err := _StakingEventsMock.contract.FilterLogs(opts, "Unstaked") + if err != nil { + return nil, err + } + return &StakingEventsMockUnstakedIterator{contract: _StakingEventsMock.contract, event: "Unstaked", logs: logs, sub: sub}, nil +} + +func (_StakingEventsMock *StakingEventsMockFilterer) WatchUnstaked(opts *bind.WatchOpts, sink chan<- *StakingEventsMockUnstaked) (event.Subscription, error) { + + logs, sub, err := _StakingEventsMock.contract.WatchLogs(opts, "Unstaked") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(StakingEventsMockUnstaked) + if err := _StakingEventsMock.contract.UnpackLog(event, "Unstaked", 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 (_StakingEventsMock *StakingEventsMockFilterer) ParseUnstaked(log types.Log) (*StakingEventsMockUnstaked, error) { + event := new(StakingEventsMockUnstaked) + if err := _StakingEventsMock.contract.UnpackLog(event, "Unstaked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_StakingEventsMock *StakingEventsMock) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _StakingEventsMock.abi.Events["AlertRaised"].ID: + return _StakingEventsMock.ParseAlertRaised(log) + case _StakingEventsMock.abi.Events["FeedOperatorsSet"].ID: + return _StakingEventsMock.ParseFeedOperatorsSet(log) + case _StakingEventsMock.abi.Events["MaxCommunityStakeAmountIncreased"].ID: + return _StakingEventsMock.ParseMaxCommunityStakeAmountIncreased(log) + case _StakingEventsMock.abi.Events["MaxOperatorStakeAmountIncreased"].ID: + return _StakingEventsMock.ParseMaxOperatorStakeAmountIncreased(log) + case _StakingEventsMock.abi.Events["MerkleRootChanged"].ID: + return _StakingEventsMock.ParseMerkleRootChanged(log) + case _StakingEventsMock.abi.Events["Migrated"].ID: + return _StakingEventsMock.ParseMigrated(log) + case _StakingEventsMock.abi.Events["MigrationTargetAccepted"].ID: + return _StakingEventsMock.ParseMigrationTargetAccepted(log) + case _StakingEventsMock.abi.Events["MigrationTargetProposed"].ID: + return _StakingEventsMock.ParseMigrationTargetProposed(log) + case _StakingEventsMock.abi.Events["OperatorAdded"].ID: + return _StakingEventsMock.ParseOperatorAdded(log) + case _StakingEventsMock.abi.Events["OperatorRemoved"].ID: + return _StakingEventsMock.ParseOperatorRemoved(log) + case _StakingEventsMock.abi.Events["OwnershipTransferRequested"].ID: + return _StakingEventsMock.ParseOwnershipTransferRequested(log) + case _StakingEventsMock.abi.Events["OwnershipTransferred"].ID: + return _StakingEventsMock.ParseOwnershipTransferred(log) + case _StakingEventsMock.abi.Events["Paused"].ID: + return _StakingEventsMock.ParsePaused(log) + case _StakingEventsMock.abi.Events["PoolConcluded"].ID: + return _StakingEventsMock.ParsePoolConcluded(log) + case _StakingEventsMock.abi.Events["PoolOpened"].ID: + return _StakingEventsMock.ParsePoolOpened(log) + case _StakingEventsMock.abi.Events["PoolSizeIncreased"].ID: + return _StakingEventsMock.ParsePoolSizeIncreased(log) + case _StakingEventsMock.abi.Events["RewardAdded"].ID: + return _StakingEventsMock.ParseRewardAdded(log) + case _StakingEventsMock.abi.Events["RewardInitialized"].ID: + return _StakingEventsMock.ParseRewardInitialized(log) + case _StakingEventsMock.abi.Events["RewardRateChanged"].ID: + return _StakingEventsMock.ParseRewardRateChanged(log) + case _StakingEventsMock.abi.Events["RewardSlashed"].ID: + return _StakingEventsMock.ParseRewardSlashed(log) + case _StakingEventsMock.abi.Events["RewardWithdrawn"].ID: + return _StakingEventsMock.ParseRewardWithdrawn(log) + case _StakingEventsMock.abi.Events["Staked"].ID: + return _StakingEventsMock.ParseStaked(log) + case _StakingEventsMock.abi.Events["Unpaused"].ID: + return _StakingEventsMock.ParseUnpaused(log) + case _StakingEventsMock.abi.Events["Unstaked"].ID: + return _StakingEventsMock.ParseUnstaked(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (StakingEventsMockAlertRaised) Topic() common.Hash { + return common.HexToHash("0xd2720e8f454493f612cc97499fe8cbce7fa4d4c18d346fe7104e9042df1c1edd") +} + +func (StakingEventsMockFeedOperatorsSet) Topic() common.Hash { + return common.HexToHash("0x40aed8e423b39a56b445ae160f4c071fc2cfb48ee0b6dcd5ffeb6bc5b18d10d0") +} + +func (StakingEventsMockMaxCommunityStakeAmountIncreased) Topic() common.Hash { + return common.HexToHash("0xb5f554e5ef00806bace1edbb84186512ebcefa2af7706085143f501f29314df7") +} + +func (StakingEventsMockMaxOperatorStakeAmountIncreased) Topic() common.Hash { + return common.HexToHash("0x816587cb2e773af4f3689a03d7520fabff3462605ded374b485b13994c0d7b52") +} + +func (StakingEventsMockMerkleRootChanged) Topic() common.Hash { + return common.HexToHash("0x1b930366dfeaa7eb3b325021e4ae81e36527063452ee55b86c95f85b36f4c31c") +} + +func (StakingEventsMockMigrated) Topic() common.Hash { + return common.HexToHash("0x667838b33bdc898470de09e0e746990f2adc11b965b7fe6828e502ebc39e0434") +} + +func (StakingEventsMockMigrationTargetAccepted) Topic() common.Hash { + return common.HexToHash("0xfa33c052bbee754f3c0482a89962daffe749191fa33c696a61e947fbfd68bd84") +} + +func (StakingEventsMockMigrationTargetProposed) Topic() common.Hash { + return common.HexToHash("0x5c74c441be501340b2713817a6c6975e6f3d4a4ae39fa1ac0bf75d3c54a0cad3") +} + +func (StakingEventsMockOperatorAdded) Topic() common.Hash { + return common.HexToHash("0xac6fa858e9350a46cec16539926e0fde25b7629f84b5a72bffaae4df888ae86d") +} + +func (StakingEventsMockOperatorRemoved) Topic() common.Hash { + return common.HexToHash("0x2360404a74478febece1a14f11275f22ada88d19ef96f7d785913010bfff4479") +} + +func (StakingEventsMockOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (StakingEventsMockOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (StakingEventsMockPaused) Topic() common.Hash { + return common.HexToHash("0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258") +} + +func (StakingEventsMockPoolConcluded) Topic() common.Hash { + return common.HexToHash("0xf7d0e0f15586495da8c687328ead30fb829d9da55538cb0ef73dd229e517cdb8") +} + +func (StakingEventsMockPoolOpened) Topic() common.Hash { + return common.HexToHash("0xded6ebf04e261e1eb2f3e3b268a2e6aee5b478c15b341eba5cf18b9bc80c2e63") +} + +func (StakingEventsMockPoolSizeIncreased) Topic() common.Hash { + return common.HexToHash("0x7f4f497e086b2eb55f8a9885ba00d33399bbe0ebcb92ea092834386435a1b9c0") +} + +func (StakingEventsMockRewardAdded) Topic() common.Hash { + return common.HexToHash("0xde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d") +} + +func (StakingEventsMockRewardInitialized) Topic() common.Hash { + return common.HexToHash("0x125fc8494f786b470e3c39d0932a62e9e09e291ebd81ea19c57604f6d2b1d167") +} + +func (StakingEventsMockRewardRateChanged) Topic() common.Hash { + return common.HexToHash("0x1e3be2efa25bca5bff2215c7b30b31086e703d6aa7d9b9a1f8ba62c5291219ad") +} + +func (StakingEventsMockRewardSlashed) Topic() common.Hash { + return common.HexToHash("0x00635ea9da6e262e92bb713d71840af7c567807ff35bf73e927490c612832480") +} + +func (StakingEventsMockRewardWithdrawn) Topic() common.Hash { + return common.HexToHash("0x150a6ec0e6f4e9ddcaaaa1674f157d91165a42d60653016f87a9fc870a39f050") +} + +func (StakingEventsMockStaked) Topic() common.Hash { + return common.HexToHash("0x1449c6dd7851abc30abf37f57715f492010519147cc2652fbc38202c18a6ee90") +} + +func (StakingEventsMockUnpaused) Topic() common.Hash { + return common.HexToHash("0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa") +} + +func (StakingEventsMockUnstaked) Topic() common.Hash { + return common.HexToHash("0x204fccf0d92ed8d48f204adb39b2e81e92bad0dedb93f5716ca9478cfb57de00") +} + +func (_StakingEventsMock *StakingEventsMock) Address() common.Address { + return _StakingEventsMock.address +} + +type StakingEventsMockInterface interface { + EmitAlertRaised(opts *bind.TransactOpts, alerter common.Address, roundId *big.Int, rewardAmount *big.Int) (*types.Transaction, error) + + EmitFeedOperatorsSet(opts *bind.TransactOpts, feedOperators []common.Address) (*types.Transaction, error) + + EmitMaxCommunityStakeAmountIncreased(opts *bind.TransactOpts, maxStakeAmount *big.Int) (*types.Transaction, error) + + EmitMaxOperatorStakeAmountIncreased(opts *bind.TransactOpts, maxStakeAmount *big.Int) (*types.Transaction, error) + + EmitMerkleRootChanged(opts *bind.TransactOpts, newMerkleRoot [32]byte) (*types.Transaction, error) + + EmitMigrated(opts *bind.TransactOpts, staker common.Address, principal *big.Int, baseReward *big.Int, delegationReward *big.Int, data []byte) (*types.Transaction, error) + + EmitMigrationTargetAccepted(opts *bind.TransactOpts, migrationTarget common.Address) (*types.Transaction, error) + + EmitMigrationTargetProposed(opts *bind.TransactOpts, migrationTarget common.Address) (*types.Transaction, error) + + EmitOperatorAdded(opts *bind.TransactOpts, operator common.Address) (*types.Transaction, error) + + EmitOperatorRemoved(opts *bind.TransactOpts, operator common.Address, amount *big.Int) (*types.Transaction, error) + + EmitOwnershipTransferRequested(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) + + EmitOwnershipTransferred(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) + + EmitPaused(opts *bind.TransactOpts, account common.Address) (*types.Transaction, error) + + EmitPoolConcluded(opts *bind.TransactOpts) (*types.Transaction, error) + + EmitPoolOpened(opts *bind.TransactOpts) (*types.Transaction, error) + + EmitPoolSizeIncreased(opts *bind.TransactOpts, maxPoolSize *big.Int) (*types.Transaction, error) + + EmitRewardAdded(opts *bind.TransactOpts, amountAdded *big.Int) (*types.Transaction, error) + + EmitRewardInitialized(opts *bind.TransactOpts, rate *big.Int, available *big.Int, startTimestamp *big.Int, endTimestamp *big.Int) (*types.Transaction, error) + + EmitRewardRateChanged(opts *bind.TransactOpts, rate *big.Int) (*types.Transaction, error) + + EmitRewardSlashed(opts *bind.TransactOpts, operator []common.Address, slashedBaseRewards []*big.Int, slashedDelegatedRewards []*big.Int) (*types.Transaction, error) + + EmitRewardWithdrawn(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) + + EmitStaked(opts *bind.TransactOpts, staker common.Address, newStake *big.Int, totalStake *big.Int) (*types.Transaction, error) + + EmitUnpaused(opts *bind.TransactOpts, account common.Address) (*types.Transaction, error) + + EmitUnstaked(opts *bind.TransactOpts, staker common.Address, principal *big.Int, baseReward *big.Int, delegationReward *big.Int) (*types.Transaction, error) + + FilterAlertRaised(opts *bind.FilterOpts) (*StakingEventsMockAlertRaisedIterator, error) + + WatchAlertRaised(opts *bind.WatchOpts, sink chan<- *StakingEventsMockAlertRaised) (event.Subscription, error) + + ParseAlertRaised(log types.Log) (*StakingEventsMockAlertRaised, error) + + FilterFeedOperatorsSet(opts *bind.FilterOpts) (*StakingEventsMockFeedOperatorsSetIterator, error) + + WatchFeedOperatorsSet(opts *bind.WatchOpts, sink chan<- *StakingEventsMockFeedOperatorsSet) (event.Subscription, error) + + ParseFeedOperatorsSet(log types.Log) (*StakingEventsMockFeedOperatorsSet, error) + + FilterMaxCommunityStakeAmountIncreased(opts *bind.FilterOpts) (*StakingEventsMockMaxCommunityStakeAmountIncreasedIterator, error) + + WatchMaxCommunityStakeAmountIncreased(opts *bind.WatchOpts, sink chan<- *StakingEventsMockMaxCommunityStakeAmountIncreased) (event.Subscription, error) + + ParseMaxCommunityStakeAmountIncreased(log types.Log) (*StakingEventsMockMaxCommunityStakeAmountIncreased, error) + + FilterMaxOperatorStakeAmountIncreased(opts *bind.FilterOpts) (*StakingEventsMockMaxOperatorStakeAmountIncreasedIterator, error) + + WatchMaxOperatorStakeAmountIncreased(opts *bind.WatchOpts, sink chan<- *StakingEventsMockMaxOperatorStakeAmountIncreased) (event.Subscription, error) + + ParseMaxOperatorStakeAmountIncreased(log types.Log) (*StakingEventsMockMaxOperatorStakeAmountIncreased, error) + + FilterMerkleRootChanged(opts *bind.FilterOpts) (*StakingEventsMockMerkleRootChangedIterator, error) + + WatchMerkleRootChanged(opts *bind.WatchOpts, sink chan<- *StakingEventsMockMerkleRootChanged) (event.Subscription, error) + + ParseMerkleRootChanged(log types.Log) (*StakingEventsMockMerkleRootChanged, error) + + FilterMigrated(opts *bind.FilterOpts) (*StakingEventsMockMigratedIterator, error) + + WatchMigrated(opts *bind.WatchOpts, sink chan<- *StakingEventsMockMigrated) (event.Subscription, error) + + ParseMigrated(log types.Log) (*StakingEventsMockMigrated, error) + + FilterMigrationTargetAccepted(opts *bind.FilterOpts) (*StakingEventsMockMigrationTargetAcceptedIterator, error) + + WatchMigrationTargetAccepted(opts *bind.WatchOpts, sink chan<- *StakingEventsMockMigrationTargetAccepted) (event.Subscription, error) + + ParseMigrationTargetAccepted(log types.Log) (*StakingEventsMockMigrationTargetAccepted, error) + + FilterMigrationTargetProposed(opts *bind.FilterOpts) (*StakingEventsMockMigrationTargetProposedIterator, error) + + WatchMigrationTargetProposed(opts *bind.WatchOpts, sink chan<- *StakingEventsMockMigrationTargetProposed) (event.Subscription, error) + + ParseMigrationTargetProposed(log types.Log) (*StakingEventsMockMigrationTargetProposed, error) + + FilterOperatorAdded(opts *bind.FilterOpts) (*StakingEventsMockOperatorAddedIterator, error) + + WatchOperatorAdded(opts *bind.WatchOpts, sink chan<- *StakingEventsMockOperatorAdded) (event.Subscription, error) + + ParseOperatorAdded(log types.Log) (*StakingEventsMockOperatorAdded, error) + + FilterOperatorRemoved(opts *bind.FilterOpts) (*StakingEventsMockOperatorRemovedIterator, error) + + WatchOperatorRemoved(opts *bind.WatchOpts, sink chan<- *StakingEventsMockOperatorRemoved) (event.Subscription, error) + + ParseOperatorRemoved(log types.Log) (*StakingEventsMockOperatorRemoved, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*StakingEventsMockOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *StakingEventsMockOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*StakingEventsMockOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*StakingEventsMockOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *StakingEventsMockOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*StakingEventsMockOwnershipTransferred, error) + + FilterPaused(opts *bind.FilterOpts) (*StakingEventsMockPausedIterator, error) + + WatchPaused(opts *bind.WatchOpts, sink chan<- *StakingEventsMockPaused) (event.Subscription, error) + + ParsePaused(log types.Log) (*StakingEventsMockPaused, error) + + FilterPoolConcluded(opts *bind.FilterOpts) (*StakingEventsMockPoolConcludedIterator, error) + + WatchPoolConcluded(opts *bind.WatchOpts, sink chan<- *StakingEventsMockPoolConcluded) (event.Subscription, error) + + ParsePoolConcluded(log types.Log) (*StakingEventsMockPoolConcluded, error) + + FilterPoolOpened(opts *bind.FilterOpts) (*StakingEventsMockPoolOpenedIterator, error) + + WatchPoolOpened(opts *bind.WatchOpts, sink chan<- *StakingEventsMockPoolOpened) (event.Subscription, error) + + ParsePoolOpened(log types.Log) (*StakingEventsMockPoolOpened, error) + + FilterPoolSizeIncreased(opts *bind.FilterOpts) (*StakingEventsMockPoolSizeIncreasedIterator, error) + + WatchPoolSizeIncreased(opts *bind.WatchOpts, sink chan<- *StakingEventsMockPoolSizeIncreased) (event.Subscription, error) + + ParsePoolSizeIncreased(log types.Log) (*StakingEventsMockPoolSizeIncreased, error) + + FilterRewardAdded(opts *bind.FilterOpts) (*StakingEventsMockRewardAddedIterator, error) + + WatchRewardAdded(opts *bind.WatchOpts, sink chan<- *StakingEventsMockRewardAdded) (event.Subscription, error) + + ParseRewardAdded(log types.Log) (*StakingEventsMockRewardAdded, error) + + FilterRewardInitialized(opts *bind.FilterOpts) (*StakingEventsMockRewardInitializedIterator, error) + + WatchRewardInitialized(opts *bind.WatchOpts, sink chan<- *StakingEventsMockRewardInitialized) (event.Subscription, error) + + ParseRewardInitialized(log types.Log) (*StakingEventsMockRewardInitialized, error) + + FilterRewardRateChanged(opts *bind.FilterOpts) (*StakingEventsMockRewardRateChangedIterator, error) + + WatchRewardRateChanged(opts *bind.WatchOpts, sink chan<- *StakingEventsMockRewardRateChanged) (event.Subscription, error) + + ParseRewardRateChanged(log types.Log) (*StakingEventsMockRewardRateChanged, error) + + FilterRewardSlashed(opts *bind.FilterOpts) (*StakingEventsMockRewardSlashedIterator, error) + + WatchRewardSlashed(opts *bind.WatchOpts, sink chan<- *StakingEventsMockRewardSlashed) (event.Subscription, error) + + ParseRewardSlashed(log types.Log) (*StakingEventsMockRewardSlashed, error) + + FilterRewardWithdrawn(opts *bind.FilterOpts) (*StakingEventsMockRewardWithdrawnIterator, error) + + WatchRewardWithdrawn(opts *bind.WatchOpts, sink chan<- *StakingEventsMockRewardWithdrawn) (event.Subscription, error) + + ParseRewardWithdrawn(log types.Log) (*StakingEventsMockRewardWithdrawn, error) + + FilterStaked(opts *bind.FilterOpts) (*StakingEventsMockStakedIterator, error) + + WatchStaked(opts *bind.WatchOpts, sink chan<- *StakingEventsMockStaked) (event.Subscription, error) + + ParseStaked(log types.Log) (*StakingEventsMockStaked, error) + + FilterUnpaused(opts *bind.FilterOpts) (*StakingEventsMockUnpausedIterator, error) + + WatchUnpaused(opts *bind.WatchOpts, sink chan<- *StakingEventsMockUnpaused) (event.Subscription, error) + + ParseUnpaused(log types.Log) (*StakingEventsMockUnpaused, error) + + FilterUnstaked(opts *bind.FilterOpts) (*StakingEventsMockUnstakedIterator, error) + + WatchUnstaked(opts *bind.WatchOpts, sink chan<- *StakingEventsMockUnstaked) (event.Subscription, error) + + ParseUnstaked(log types.Log) (*StakingEventsMockUnstaked, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/integration-tests/contracts/ethereum/src/VRFv2Consumer.sol b/integration-tests/contracts/ethereum/src/VRFv2Consumer.sol index 390937b563c..333318f4990 100644 --- a/integration-tests/contracts/ethereum/src/VRFv2Consumer.sol +++ b/integration-tests/contracts/ethereum/src/VRFv2Consumer.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.7; import "../../../../../contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol"; import "../../../../../contracts/src/v0.8/VRFConsumerBaseV2.sol"; -import "../../../../../contracts/src/v0.8/ConfirmedOwner.sol"; +import "../../../../contracts/src/v0.8/shared/access/ConfirmedOwner.sol"; /** * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY. diff --git a/integration-tests/contracts/ethereum_contracts.go b/integration-tests/contracts/ethereum_contracts.go index 198d747f296..e419a02e578 100644 --- a/integration-tests/contracts/ethereum_contracts.go +++ b/integration-tests/contracts/ethereum_contracts.go @@ -12,19 +12,29 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/rs/zerolog/log" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/libocr/gethwrappers/offchainaggregator" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" ocrConfigHelper "github.com/smartcontractkit/libocr/offchainreporting/confighelper" ocrTypes "github.com/smartcontractkit/libocr/offchainreporting/types" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/pkg/errors" + "github.com/smartcontractkit/chainlink/integration-tests/client" + eth_contracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_client_example" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_coordinator" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_load_test_client" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/authorized_forwarder" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/flags_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/flux_aggregator_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/functions_billing_registry_events_mock" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/functions_oracle_events_mock" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/gas_wrapper" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/gas_wrapper_mock" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registrar_wrapper1_2_mock" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_1_mock" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_aggregator_proxy" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_ethlink_aggregator_wrapper" @@ -33,9 +43,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/operator_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/oracle_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/test_api_consumer_wrapper" - - "github.com/smartcontractkit/chainlink/integration-tests/client" - eth_contracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" + "strings" ) // EthereumOracle oracle for "directrequest" job tests @@ -327,6 +335,409 @@ func (f *EthereumFunctionsBillingRegistryEventsMock) BillingEnd(requestId [32]by return f.client.ProcessTransaction(tx) } +// EthereumStakingEventsMock represents the basic events mock contract +type EthereumStakingEventsMock struct { + client blockchain.EVMClient + eventsMock *eth_contracts.StakingEventsMock + address *common.Address +} + +func (f *EthereumStakingEventsMock) Address() string { + return f.address.Hex() +} + +func (f *EthereumStakingEventsMock) MaxCommunityStakeAmountIncreased(maxStakeAmount *big.Int) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.eventsMock.EmitMaxCommunityStakeAmountIncreased(opts, maxStakeAmount) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumStakingEventsMock) PoolSizeIncreased(maxPoolSize *big.Int) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.eventsMock.EmitPoolSizeIncreased(opts, maxPoolSize) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumStakingEventsMock) MaxOperatorStakeAmountIncreased(maxStakeAmount *big.Int) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.eventsMock.EmitMaxOperatorStakeAmountIncreased(opts, maxStakeAmount) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumStakingEventsMock) RewardInitialized(rate *big.Int, available *big.Int, startTimestamp *big.Int, endTimestamp *big.Int) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.eventsMock.EmitRewardInitialized(opts, rate, available, startTimestamp, endTimestamp) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumStakingEventsMock) AlertRaised(alerter common.Address, roundId *big.Int, rewardAmount *big.Int) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.eventsMock.EmitAlertRaised(opts, alerter, roundId, rewardAmount) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumStakingEventsMock) Staked(staker common.Address, newStake *big.Int, totalStake *big.Int) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.eventsMock.EmitStaked(opts, staker, newStake, totalStake) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumStakingEventsMock) OperatorAdded(operator common.Address) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.eventsMock.EmitOperatorAdded(opts, operator) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumStakingEventsMock) OperatorRemoved(operator common.Address, amount *big.Int) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.eventsMock.EmitOperatorRemoved(opts, operator, amount) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumStakingEventsMock) FeedOperatorsSet(feedOperators []common.Address) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.eventsMock.EmitFeedOperatorsSet(opts, feedOperators) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +// EthereumOffchainAggregatorEventsMock represents the basic events mock contract +type EthereumOffchainAggregatorEventsMock struct { + client blockchain.EVMClient + eventsMock *eth_contracts.OffchainAggregatorEventsMock + address *common.Address +} + +func (f *EthereumOffchainAggregatorEventsMock) Address() string { + return f.address.Hex() +} + +func (f *EthereumOffchainAggregatorEventsMock) ConfigSet(previousConfigBlockNumber uint32, configCount uint64, signers []common.Address, transmitters []common.Address, threshold uint8, encodedConfigVersion uint64, encoded []byte) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.eventsMock.EmitConfigSet(opts, previousConfigBlockNumber, configCount, signers, transmitters, threshold, encodedConfigVersion, encoded) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumOffchainAggregatorEventsMock) NewTransmission(aggregatorRoundId uint32, answer *big.Int, transmitter common.Address, observations []*big.Int, observers []byte, rawReportContext [32]byte) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.eventsMock.EmitNewTransmission(opts, aggregatorRoundId, answer, transmitter, observations, observers, rawReportContext) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +// EthereumKeeperRegistry11Mock represents the basic keeper registry 1.1 mock contract +type EthereumKeeperRegistry11Mock struct { + client blockchain.EVMClient + registryMock *keeper_registry_wrapper1_1_mock.KeeperRegistryMock + address *common.Address +} + +func (f *EthereumKeeperRegistry11Mock) Address() string { + return f.address.Hex() +} + +func (f *EthereumKeeperRegistry11Mock) EmitUpkeepPerformed(id *big.Int, success bool, from common.Address, payment *big.Int, performData []byte) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.registryMock.EmitUpkeepPerformed(opts, id, success, from, payment, performData) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumKeeperRegistry11Mock) EmitUpkeepCanceled(id *big.Int, atBlockHeight uint64) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.registryMock.EmitUpkeepCanceled(opts, id, atBlockHeight) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumKeeperRegistry11Mock) EmitFundsWithdrawn(id *big.Int, amount *big.Int, to common.Address) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.registryMock.EmitFundsWithdrawn(opts, id, amount, to) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumKeeperRegistry11Mock) EmitKeepersUpdated(keepers []common.Address, payees []common.Address) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.registryMock.EmitKeepersUpdated(opts, keepers, payees) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumKeeperRegistry11Mock) EmitUpkeepRegistered(id *big.Int, executeGas uint32, admin common.Address) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.registryMock.EmitUpkeepRegistered(opts, id, executeGas, admin) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumKeeperRegistry11Mock) EmitFundsAdded(id *big.Int, from common.Address, amount *big.Int) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.registryMock.EmitFundsAdded(opts, id, from, amount) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumKeeperRegistry11Mock) SetUpkeepCount(_upkeepCount *big.Int) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.registryMock.SetUpkeepCount(opts, _upkeepCount) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumKeeperRegistry11Mock) SetCanceledUpkeepList(_canceledUpkeepList []*big.Int) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.registryMock.SetCanceledUpkeepList(opts, _canceledUpkeepList) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumKeeperRegistry11Mock) SetKeeperList(_keepers []common.Address) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.registryMock.SetKeeperList(opts, _keepers) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumKeeperRegistry11Mock) SetConfig(_paymentPremiumPPB uint32, _flatFeeMicroLink uint32, _blockCountPerTurn *big.Int, _checkGasLimit uint32, _stalenessSeconds *big.Int, _gasCeilingMultiplier uint16, _fallbackGasPrice *big.Int, _fallbackLinkPrice *big.Int) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.registryMock.SetConfig(opts, _paymentPremiumPPB, _flatFeeMicroLink, _blockCountPerTurn, _checkGasLimit, _stalenessSeconds, _gasCeilingMultiplier, _fallbackGasPrice, _fallbackLinkPrice) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumKeeperRegistry11Mock) SetUpkeep(id *big.Int, _target common.Address, _executeGas uint32, _balance *big.Int, _admin common.Address, _maxValidBlocknumber uint64, _lastKeeper common.Address, _checkData []byte) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.registryMock.SetUpkeep(opts, id, _target, _executeGas, _balance, _admin, _maxValidBlocknumber, _lastKeeper, _checkData) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumKeeperRegistry11Mock) SetMinBalance(id *big.Int, minBalance *big.Int) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.registryMock.SetMinBalance(opts, id, minBalance) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumKeeperRegistry11Mock) SetCheckUpkeepData(id *big.Int, performData []byte, maxLinkPayment *big.Int, gasLimit *big.Int, adjustedGasWei *big.Int, linkEth *big.Int) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.registryMock.SetCheckUpkeepData(opts, id, performData, maxLinkPayment, gasLimit, adjustedGasWei, linkEth) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumKeeperRegistry11Mock) SetPerformUpkeepSuccess(id *big.Int, success bool) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.registryMock.SetPerformUpkeepSuccess(opts, id, success) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +// EthereumKeeperRegistrar12Mock represents the basic keeper registrar 1.2 mock contract +type EthereumKeeperRegistrar12Mock struct { + client blockchain.EVMClient + registrarMock *keeper_registrar_wrapper1_2_mock.KeeperRegistrarMock + address *common.Address +} + +func (f *EthereumKeeperRegistrar12Mock) Address() string { + return f.address.Hex() +} + +func (f *EthereumKeeperRegistrar12Mock) EmitRegistrationRequested(hash [32]byte, name string, encryptedEmail []byte, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, checkData []byte, amount *big.Int, source uint8) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.registrarMock.EmitRegistrationRequested(opts, hash, name, encryptedEmail, upkeepContract, gasLimit, adminAddress, checkData, amount, source) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumKeeperRegistrar12Mock) EmitRegistrationApproved(hash [32]byte, displayName string, upkeepId *big.Int) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.registrarMock.EmitRegistrationApproved(opts, hash, displayName, upkeepId) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +func (f *EthereumKeeperRegistrar12Mock) SetRegistrationConfig(_autoApproveConfigType uint8, _autoApproveMaxAllowed uint32, _approvedCount uint32, _keeperRegistry common.Address, _minLINKJuels *big.Int) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.registrarMock.SetRegistrationConfig(opts, _autoApproveConfigType, _autoApproveMaxAllowed, _approvedCount, _keeperRegistry, _minLINKJuels) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + +// EthereumKeeperGasWrapperMock represents the basic keeper gas wrapper mock contract +type EthereumKeeperGasWrapperMock struct { + client blockchain.EVMClient + gasWrapperMock *gas_wrapper_mock.KeeperRegistryCheckUpkeepGasUsageWrapperMock + address *common.Address +} + +func (f *EthereumKeeperGasWrapperMock) Address() string { + return f.address.Hex() +} + +func (f *EthereumKeeperGasWrapperMock) SetMeasureCheckGasResult(result bool, payload []byte, gas *big.Int) error { + opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := f.gasWrapperMock.SetMeasureCheckGasResult(opts, result, payload, gas) + if err != nil { + return err + } + return f.client.ProcessTransaction(tx) +} + // EthereumFluxAggregator represents the basic flux aggregation contract type EthereumFluxAggregator struct { client blockchain.EVMClient @@ -779,7 +1190,7 @@ func (o *EthereumOffchainAggregator) SetPayees( // SetConfig sets the payees and the offchain reporting protocol configuration func (o *EthereumOffchainAggregator) SetConfig( - chainlinkNodes []*client.Chainlink, + chainlinkNodes []*client.ChainlinkK8sClient, ocrConfig OffChainAggregatorConfig, transmitters []common.Address, ) error { @@ -791,7 +1202,7 @@ func (o *EthereumOffchainAggregator) SetConfig( return err } if len(ocrKeys.Data) == 0 { - return fmt.Errorf("no OCR keys found for node %s", node.Config.ChartName) + return fmt.Errorf("no OCR keys found for node %v", node) } primaryOCRKey := ocrKeys.Data[0] if err != nil { @@ -1526,3 +1937,92 @@ type EthereumKeeperRegistryCheckUpkeepGasUsageWrapper struct { func (e *EthereumKeeperRegistryCheckUpkeepGasUsageWrapper) Address() string { return e.address.Hex() } + +/* Functions 1_0_0 */ + +type EthereumFunctionsRouter struct { + address common.Address + client blockchain.EVMClient + instance *functions_router.FunctionsRouter +} + +func (e *EthereumFunctionsRouter) Address() string { + return e.address.Hex() +} + +func (e *EthereumFunctionsRouter) CreateSubscriptionWithConsumer(consumer string) (uint64, error) { + opts, err := e.client.TransactionOpts(e.client.GetDefaultWallet()) + if err != nil { + return 0, err + } + tx, err := e.instance.CreateSubscriptionWithConsumer(opts, common.HexToAddress(consumer)) + if err != nil { + return 0, err + } + if err := e.client.ProcessTransaction(tx); err != nil { + return 0, err + } + r, err := e.client.GetTxReceipt(tx.Hash()) + if err != nil { + return 0, err + } + for _, l := range r.Logs { + log.Warn().Interface("Log", common.Bytes2Hex(l.Data)).Send() + } + topicsMap := map[string]interface{}{} + + fabi, err := abi.JSON(strings.NewReader(functions_router.FunctionsRouterABI)) + if err != nil { + return 0, err + } + for _, ev := range fabi.Events { + log.Warn().Str("EventName", ev.Name).Send() + } + topicOneInputs := abi.Arguments{fabi.Events["SubscriptionCreated"].Inputs[0]} + topicOneHash := []common.Hash{r.Logs[0].Topics[1:][0]} + if err := abi.ParseTopicsIntoMap(topicsMap, topicOneInputs, topicOneHash); err != nil { + return 0, errors.Wrap(err, "failed to decode topic value") + } + log.Warn().Interface("NewTopicsDecoded", topicsMap).Send() + if topicsMap["subscriptionId"] == 0 { + return 0, errors.New("failed to decode subscription ID after creation") + } + return topicsMap["subscriptionId"].(uint64), nil +} + +type EthereumFunctionsCoordinator struct { + address common.Address + client blockchain.EVMClient + instance *functions_coordinator.FunctionsCoordinator +} + +func (e *EthereumFunctionsCoordinator) Address() string { + return e.address.Hex() +} + +type EthereumFunctionsLoadTestClient struct { + address common.Address + client blockchain.EVMClient + instance *functions_load_test_client.FunctionsLoadTestClient +} + +func (e *EthereumFunctionsLoadTestClient) Address() string { + return e.address.Hex() +} + +func (e *EthereumFunctionsLoadTestClient) SendRequest(source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) error { + opts, err := e.client.TransactionOpts(e.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := e.instance.SendRequest(opts, source, encryptedSecretsReferences, args, subscriptionId, jobId) + if err != nil { + return err + } + if err := e.client.ProcessTransaction(tx); err != nil { + return err + } + revertReason, _, _ := e.client.RevertReasonFromTx(tx.Hash(), functions_client_example.FunctionsClientExampleABI) + log.Debug().Str("RevertReason", revertReason).Send() + return nil +} diff --git a/integration-tests/contracts/ethereum_contracts_local.go b/integration-tests/contracts/ethereum_contracts_local.go new file mode 100644 index 00000000000..aba6bc354e1 --- /dev/null +++ b/integration-tests/contracts/ethereum_contracts_local.go @@ -0,0 +1,96 @@ +package contracts + +import ( + "encoding/hex" + "fmt" + "github.com/ethereum/go-ethereum/common" + "github.com/rs/zerolog/log" + "github.com/smartcontractkit/chainlink/integration-tests/client" + ocrConfigHelper "github.com/smartcontractkit/libocr/offchainreporting/confighelper" + ocrTypes "github.com/smartcontractkit/libocr/offchainreporting/types" +) + +// SetConfigLocal sets the payees and the offchain reporting protocol configuration +func (o *EthereumOffchainAggregator) SetConfigLocal( + chainlinkNodes []*client.ChainlinkClient, + ocrConfig OffChainAggregatorConfig, + transmitters []common.Address, +) error { + // Gather necessary addresses and keys from our chainlink nodes to properly configure the OCR contract + log.Info().Str("Contract Address", o.address.Hex()).Msg("Configuring OCR Contract") + for i, node := range chainlinkNodes { + ocrKeys, err := node.MustReadOCRKeys() + if err != nil { + return err + } + if len(ocrKeys.Data) == 0 { + return fmt.Errorf("no OCR keys found for node %v", node) + } + primaryOCRKey := ocrKeys.Data[0] + if err != nil { + return err + } + p2pKeys, err := node.MustReadP2PKeys() + if err != nil { + return err + } + primaryP2PKey := p2pKeys.Data[0] + + // Need to convert the key representations + var onChainSigningAddress [20]byte + var configPublicKey [32]byte + offchainSigningAddress, err := hex.DecodeString(primaryOCRKey.Attributes.OffChainPublicKey) + if err != nil { + return err + } + decodeConfigKey, err := hex.DecodeString(primaryOCRKey.Attributes.ConfigPublicKey) + if err != nil { + return err + } + + // https://stackoverflow.com/questions/8032170/how-to-assign-string-to-bytes-array + copy(onChainSigningAddress[:], common.HexToAddress(primaryOCRKey.Attributes.OnChainSigningAddress).Bytes()) + copy(configPublicKey[:], decodeConfigKey) + + oracleIdentity := ocrConfigHelper.OracleIdentity{ + TransmitAddress: transmitters[i], + OnChainSigningAddress: onChainSigningAddress, + PeerID: primaryP2PKey.Attributes.PeerID, + OffchainPublicKey: offchainSigningAddress, + } + oracleIdentityExtra := ocrConfigHelper.OracleIdentityExtra{ + OracleIdentity: oracleIdentity, + SharedSecretEncryptionPublicKey: ocrTypes.SharedSecretEncryptionPublicKey(configPublicKey), + } + + ocrConfig.OracleIdentities = append(ocrConfig.OracleIdentities, oracleIdentityExtra) + } + + signers, transmitters, threshold, encodedConfigVersion, encodedConfig, err := ocrConfigHelper.ContractSetConfigArgs( + ocrConfig.DeltaProgress, + ocrConfig.DeltaResend, + ocrConfig.DeltaRound, + ocrConfig.DeltaGrace, + ocrConfig.DeltaC, + ocrConfig.AlphaPPB, + ocrConfig.DeltaStage, + ocrConfig.RMax, + ocrConfig.S, + ocrConfig.OracleIdentities, + ocrConfig.F, + ) + if err != nil { + return err + } + + // Set Config + opts, err := o.client.TransactionOpts(o.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := o.ocr.SetConfig(opts, signers, transmitters, threshold, encodedConfigVersion, encodedConfig) + if err != nil { + return err + } + return o.client.ProcessTransaction(tx) +} diff --git a/integration-tests/contracts/ethereum_keeper_contracts.go b/integration-tests/contracts/ethereum_keeper_contracts.go index afbc3db400d..0d21fd9e739 100644 --- a/integration-tests/contracts/ethereum_keeper_contracts.go +++ b/integration-tests/contracts/ethereum_keeper_contracts.go @@ -11,20 +11,27 @@ import ( geth "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/rs/zerolog/log" + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" goabi "github.com/umbracle/ethgo/abi" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + cltypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_consumer_benchmark" + registrar21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registrar_wrapper2_1" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registrar_wrapper1_2" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registrar_wrapper2_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_1" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_2" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_3" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper2_0" + registry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper_2_1" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/log_upkeep_counter_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/upkeep_transcoder" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -32,20 +39,13 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/testreporters" ) +var utilsABI = cltypes.MustGetABI(automation_utils_2_1.AutomationUtilsABI) +var registrarABI = cltypes.MustGetABI(registrar21.AutomationRegistrarABI) + type KeeperRegistrar interface { Address() string - EncodeRegisterRequest( - name string, - email []byte, - upkeepAddr string, - gasLimit uint32, - adminAddr string, - checkData []byte, - amount *big.Int, - source uint8, - senderAddr string, - ) ([]byte, error) + EncodeRegisterRequest(name string, email []byte, upkeepAddr string, gasLimit uint32, adminAddr string, checkData []byte, amount *big.Int, source uint8, senderAddr string, isLogTrigger bool) ([]byte, error) Fund(ethAmount *big.Float) error } @@ -81,6 +81,7 @@ type KeeperConsumer interface { Address() string Fund(ethAmount *big.Float) error Counter(ctx context.Context) (*big.Int, error) + Start() error } type UpkeepCounter interface { @@ -154,6 +155,7 @@ type KeeperRegistrySettings struct { FallbackLinkPrice *big.Int // LINK price used if the LINK price feed is stale MaxCheckDataSize uint32 MaxPerformDataSize uint32 + RegistryVersion ethereum.KeeperRegistryVersion } // KeeperRegistrarSettings represents settings for registrar contract @@ -194,6 +196,7 @@ type EthereumKeeperRegistry struct { registry1_2 *keeper_registry_wrapper1_2.KeeperRegistry registry1_3 *keeper_registry_wrapper1_3.KeeperRegistry registry2_0 *keeper_registry_wrapper2_0.KeeperRegistry + registry2_1 *i_keeper_registry_master_wrapper_2_1.IKeeperRegistryMaster address *common.Address } @@ -210,23 +213,46 @@ func (v *EthereumKeeperRegistry) Fund(ethAmount *big.Float) error { } func (rcs *KeeperRegistrySettings) EncodeOnChainConfig(registrar string) ([]byte, error) { - configType := goabi.MustNewType("tuple(uint32 paymentPremiumPPB,uint32 flatFeeMicroLink,uint32 checkGasLimit,uint24 stalenessSeconds,uint16 gasCeilingMultiplier,uint96 minUpkeepSpend,uint32 maxPerformGas,uint32 maxCheckDataSize,uint32 maxPerformDataSize,uint256 fallbackGasPrice,uint256 fallbackLinkPrice,address transcoder,address registrar)") - onchainConfig, err := goabi.Encode(map[string]interface{}{ - "paymentPremiumPPB": rcs.PaymentPremiumPPB, - "flatFeeMicroLink": rcs.FlatFeeMicroLINK, - "checkGasLimit": rcs.CheckGasLimit, - "stalenessSeconds": rcs.StalenessSeconds, - "gasCeilingMultiplier": rcs.GasCeilingMultiplier, - "minUpkeepSpend": rcs.MinUpkeepSpend, - "maxPerformGas": rcs.MaxPerformGas, - "maxCheckDataSize": rcs.MaxCheckDataSize, - "maxPerformDataSize": rcs.MaxPerformDataSize, - "fallbackGasPrice": rcs.FallbackGasPrice, - "fallbackLinkPrice": rcs.FallbackLinkPrice, - "transcoder": common.Address{}, - "registrar": registrar, - }, configType) - return onchainConfig, err + if rcs.RegistryVersion == ethereum.RegistryVersion_2_1 { + onchainConfigStruct := registry21.KeeperRegistryBase21OnchainConfig{ + PaymentPremiumPPB: rcs.PaymentPremiumPPB, + FlatFeeMicroLink: rcs.FlatFeeMicroLINK, + CheckGasLimit: rcs.CheckGasLimit, + StalenessSeconds: rcs.StalenessSeconds, + GasCeilingMultiplier: rcs.GasCeilingMultiplier, + MinUpkeepSpend: rcs.MinUpkeepSpend, + MaxPerformGas: rcs.MaxPerformGas, + MaxCheckDataSize: rcs.MaxCheckDataSize, + MaxPerformDataSize: rcs.MaxPerformDataSize, + MaxRevertDataSize: uint32(1000), + FallbackGasPrice: rcs.FallbackGasPrice, + FallbackLinkPrice: rcs.FallbackLinkPrice, + Transcoder: common.Address{}, + Registrars: []common.Address{common.HexToAddress(registrar)}, + UpkeepPrivilegeManager: common.Address{}, + } + encodedOnchainConfig, err := utilsABI.Methods["_onChainConfig"].Inputs.Pack(&onchainConfigStruct) + + return encodedOnchainConfig, err + } else { + configType := goabi.MustNewType("tuple(uint32 paymentPremiumPPB,uint32 flatFeeMicroLink,uint32 checkGasLimit,uint24 stalenessSeconds,uint16 gasCeilingMultiplier,uint96 minUpkeepSpend,uint32 maxPerformGas,uint32 maxCheckDataSize,uint32 maxPerformDataSize,uint256 fallbackGasPrice,uint256 fallbackLinkPrice,address transcoder,address registrar)") + onchainConfig, err := goabi.Encode(map[string]interface{}{ + "paymentPremiumPPB": rcs.PaymentPremiumPPB, + "flatFeeMicroLink": rcs.FlatFeeMicroLINK, + "checkGasLimit": rcs.CheckGasLimit, + "stalenessSeconds": rcs.StalenessSeconds, + "gasCeilingMultiplier": rcs.GasCeilingMultiplier, + "minUpkeepSpend": rcs.MinUpkeepSpend, + "maxPerformGas": rcs.MaxPerformGas, + "maxCheckDataSize": rcs.MaxCheckDataSize, + "maxPerformDataSize": rcs.MaxPerformDataSize, + "fallbackGasPrice": rcs.FallbackGasPrice, + "fallbackLinkPrice": rcs.FallbackLinkPrice, + "transcoder": common.Address{}, + "registrar": registrar, + }, configType) + return onchainConfig, err + } } func (v *EthereumKeeperRegistry) SetConfig(config KeeperRegistrySettings, ocrConfig OCRv2Config) error { @@ -318,6 +344,19 @@ func (v *EthereumKeeperRegistry) SetConfig(config KeeperRegistrySettings, ocrCon return err } return v.client.ProcessTransaction(tx) + case ethereum.RegistryVersion_2_1: + tx, err := v.registry2_1.SetConfig(txOpts, + ocrConfig.Signers, + ocrConfig.Transmitters, + ocrConfig.F, + ocrConfig.OnchainConfig, + ocrConfig.OffchainConfigVersion, + ocrConfig.OffchainConfig, + ) + if err != nil { + return err + } + return v.client.ProcessTransaction(tx) } return fmt.Errorf("keeper registry version %d is not supported", v.version) @@ -700,6 +739,11 @@ func (v *EthereumKeeperRegistry) CancelUpkeep(id *big.Int) error { if err != nil { return err } + case ethereum.RegistryVersion_2_1: + tx, err = v.registry2_1.CancelUpkeep(opts, id) + if err != nil { + return err + } } log.Info(). @@ -947,7 +991,14 @@ func (v *EthereumKeeperRegistry) ParseUpkeepIdFromRegisteredLog(log *types.Log) return nil, err } return parsedLog.Id, nil + case ethereum.RegistryVersion_2_1: + parsedLog, err := v.registry2_1.ParseUpkeepRegistered(*log) + if err != nil { + return nil, err + } + return parsedLog.Id, nil } + return nil, fmt.Errorf("keeper registry version %d is not supported", v.version) } @@ -1453,6 +1504,11 @@ type EthereumKeeperConsumer struct { address *common.Address } +// Just pass for non-logtrigger +func (v *EthereumKeeperConsumer) Start() error { + return nil +} + func (v *EthereumKeeperConsumer) Address() string { return v.address.Hex() } @@ -1477,6 +1533,49 @@ func (v *EthereumKeeperConsumer) Counter(ctx context.Context) (*big.Int, error) return cnt, nil } +type EthereumAutomationLogCounterConsumer struct { + client blockchain.EVMClient + consumer *log_upkeep_counter_wrapper.LogUpkeepCounter + address *common.Address +} + +func (v *EthereumAutomationLogCounterConsumer) Address() string { + return v.address.Hex() +} + +func (v *EthereumAutomationLogCounterConsumer) Start() error { + txOpts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) + if err != nil { + return err + } + + tx, err := v.consumer.Start(txOpts) + if err != nil { + return err + } + return v.client.ProcessTransaction(tx) +} + +func (v *EthereumAutomationLogCounterConsumer) Fund(ethAmount *big.Float) error { + gasEstimates, err := v.client.EstimateGas(geth.CallMsg{}) + if err != nil { + return err + } + return v.client.Fund(v.address.Hex(), ethAmount, gasEstimates) +} + +func (v *EthereumAutomationLogCounterConsumer) Counter(ctx context.Context) (*big.Int, error) { + opts := &bind.CallOpts{ + From: common.HexToAddress(v.client.GetDefaultWallet().Address()), + Context: ctx, + } + cnt, err := v.consumer.Counter(opts) + if err != nil { + return nil, err + } + return cnt, nil +} + // EthereumKeeperConsumerPerformance represents a more complicated keeper consumer contract, one intended only for // performance tests. type EthereumKeeperConsumerPerformance struct { @@ -1618,6 +1717,7 @@ type EthereumKeeperRegistrar struct { client blockchain.EVMClient registrar *keeper_registrar_wrapper1_2.KeeperRegistrar registrar20 *keeper_registrar_wrapper2_0.KeeperRegistrar + registrar21 *registrar21.AutomationRegistrar address *common.Address } @@ -1634,17 +1734,7 @@ func (v *EthereumKeeperRegistrar) Fund(ethAmount *big.Float) error { } // EncodeRegisterRequest encodes register request to call it through link token TransferAndCall -func (v *EthereumKeeperRegistrar) EncodeRegisterRequest( - name string, - email []byte, - upkeepAddr string, - gasLimit uint32, - adminAddr string, - checkData []byte, - amount *big.Int, - source uint8, - senderAddr string, -) ([]byte, error) { +func (v *EthereumKeeperRegistrar) EncodeRegisterRequest(name string, email []byte, upkeepAddr string, gasLimit uint32, adminAddr string, checkData []byte, amount *big.Int, source uint8, senderAddr string, isLogTrigger bool) ([]byte, error) { if v.registrar20 != nil { registryABI, err := abi.JSON(strings.NewReader(keeper_registrar_wrapper2_0.KeeperRegistrarMetaData.ABI)) if err != nil { @@ -1662,10 +1752,80 @@ func (v *EthereumKeeperRegistrar) EncodeRegisterRequest( amount, common.HexToAddress(senderAddr), ) + if err != nil { return nil, err } return req, nil + } else if v.registrar21 != nil { + if isLogTrigger { + // bytes representation of 0x3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d + topic0InBytes := [32]byte{ + 61, 83, 163, 149, 80, 224, 70, 136, + 6, 88, 39, 243, 187, 134, 88, 76, + 176, 7, 171, 158, 188, 167, 235, + 213, 40, 231, 48, 28, 156, 49, 235, 93, + } + + // bytes representation of 0x0000000000000000000000000000000000000000000000000000000000000000 + bytes0 := [32]byte{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + } + + logTriggerConfigStruct := automation_utils_2_1.LogTriggerConfig{ + ContractAddress: common.HexToAddress(upkeepAddr), + FilterSelector: 0, + Topic0: topic0InBytes, + Topic1: bytes0, + Topic2: bytes0, + Topic3: bytes0, + } + encodedLogTriggerConfig, err := utilsABI.Methods["_logTriggerConfig"].Inputs.Pack(&logTriggerConfigStruct) + if err != nil { + return nil, err + } + + req, err := registrarABI.Pack( + "register", + name, + email, + common.HexToAddress(upkeepAddr), + gasLimit, + common.HexToAddress(adminAddr), + uint8(1), // trigger type + checkData, + encodedLogTriggerConfig, // triggerConfig + []byte{}, // offchainConfig + amount, + common.HexToAddress(senderAddr), + ) + + if err != nil { + return nil, err + } + return req, nil + + } else { + req, err := registrarABI.Pack( + "register", + name, + email, + common.HexToAddress(upkeepAddr), + gasLimit, + common.HexToAddress(adminAddr), + uint8(0), // trigger type + checkData, + []byte{}, // triggerConfig + []byte{}, // offchainConfig + amount, + common.HexToAddress(senderAddr), + ) + + if err != nil { + return nil, err + } + return req, nil + } } registryABI, err := abi.JSON(strings.NewReader(keeper_registrar_wrapper1_2.KeeperRegistrarMetaData.ABI)) if err != nil { diff --git a/integration-tests/docker/README.md b/integration-tests/docker/README.md new file mode 100644 index 00000000000..b8ef1fc49d2 --- /dev/null +++ b/integration-tests/docker/README.md @@ -0,0 +1,21 @@ +## Docker environment +This folder contains Chainlink cluster environment created with `testcontainers-go` + +### CLI for Local Testing Environment + +The command-line interface (CLI) located at `./integration-tests/docker/cmd/test_env.go` can be utilized to initiate a local testing environment. It is intended to replace Docker Compose in the near future. + + +Example: +``` +# Set required envs +export CHAINLINK_IMAGE="" +export CHAINLINK_VERSION="" +# Stream logs to Loki +export LOKI_TOKEN=... +export LOKI_URL=https://${loki_host}/loki/api/v1/push + +cd ./integration-tests/docker/cmd + +go run test_env.go start-env cl-cluster +``` \ No newline at end of file diff --git a/integration-tests/docker/cmd/test_env.go b/integration-tests/docker/cmd/test_env.go new file mode 100644 index 00000000000..1acf5947505 --- /dev/null +++ b/integration-tests/docker/cmd/test_env.go @@ -0,0 +1,76 @@ +package main + +import ( + "io" + defaultlog "log" + "os" + "os/signal" + "syscall" + + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + "github.com/smartcontractkit/chainlink/integration-tests/utils" + "github.com/spf13/cobra" + "github.com/testcontainers/testcontainers-go" +) + +func main() { + rootCmd := &cobra.Command{ + Use: "test_env", + Short: "CL cluster docker test env management tool", + } + + startEnvCmd := &cobra.Command{ + Use: "start-env", + Short: "Start new docker test env", + } + rootCmd.AddCommand(startEnvCmd) + + startFullEnvCmd := &cobra.Command{ + Use: "cl-cluster", + Short: "Basic CL cluster", + RunE: func(cmd *cobra.Command, args []string) error { + utils.SetupCoreDockerEnvLogger() + log.Info().Msg("Starting CL cluster test environment..") + + _, err := test_env.NewCLTestEnvBuilder(). + WithGeth(). + WithMockServer(1). + WithCLNodes(6). + Build() + if err != nil { + return err + } + + log.Info().Msg("Cl cluster is ready") + + handleExitSignal() + + return nil + }, + } + startEnvCmd.AddCommand(startFullEnvCmd) + + // Set default log level for non-testcontainer code + zerolog.SetGlobalLevel(zerolog.InfoLevel) + + // Discard testcontainers logs + testcontainers.Logger = defaultlog.New(io.Discard, "", defaultlog.LstdFlags) + + if err := rootCmd.Execute(); err != nil { + log.Error().Err(err).Msg("Error") + os.Exit(1) + } +} + +func handleExitSignal() { + // Create a channel to receive exit signals + exitChan := make(chan os.Signal, 1) + signal.Notify(exitChan, os.Interrupt, syscall.SIGTERM) + + log.Info().Msg("Press Ctrl+C to destroy the test environment") + + // Block until an exit signal is received + <-exitChan +} diff --git a/integration-tests/docker/docker.go b/integration-tests/docker/docker.go new file mode 100644 index 00000000000..d5803e0a163 --- /dev/null +++ b/integration-tests/docker/docker.go @@ -0,0 +1,30 @@ +package docker + +import ( + "context" + "fmt" + + "github.com/google/uuid" + "github.com/rs/zerolog/log" + tc "github.com/testcontainers/testcontainers-go" +) + +func CreateNetwork() (*tc.DockerNetwork, error) { + uuidObj, _ := uuid.NewRandom() + var networkName = fmt.Sprintf("network-%s", uuidObj.String()) + network, err := tc.GenericNetwork(context.Background(), tc.GenericNetworkRequest{ + NetworkRequest: tc.NetworkRequest{ + Name: networkName, + CheckDuplicate: true, + }, + }) + if err != nil { + return nil, err + } + dockerNetwork, ok := network.(*tc.DockerNetwork) + if !ok { + return nil, fmt.Errorf("failed to cast network to *dockertest.Network") + } + log.Trace().Any("network", dockerNetwork).Msgf("created network") + return dockerNetwork, nil +} diff --git a/integration-tests/docker/test_env/cl_node.go b/integration-tests/docker/test_env/cl_node.go new file mode 100644 index 00000000000..4d690e9dd76 --- /dev/null +++ b/integration-tests/docker/test_env/cl_node.go @@ -0,0 +1,443 @@ +package test_env + +import ( + "context" + "crypto/ed25519" + "encoding/hex" + "fmt" + "math/big" + "net/url" + "os" + "strings" + "sync" + "time" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/google/uuid" + "github.com/pelletier/go-toml/v2" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + tc "github.com/testcontainers/testcontainers-go" + tcwait "github.com/testcontainers/testcontainers-go/wait" + + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/logwatch" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + + "github.com/smartcontractkit/chainlink/integration-tests/client" + "github.com/smartcontractkit/chainlink/integration-tests/utils" + "github.com/smartcontractkit/chainlink/integration-tests/utils/templates" +) + +var ( + ErrConnectNodeClient = "could not connect Node HTTP Client" + ErrStartCLNodeContainer = "failed to start CL node container" +) + +type ClNode struct { + EnvComponent + API *client.ChainlinkClient + NodeConfig *chainlink.Config + NodeSecretsConfigTOML string + PostgresDb *PostgresDb + lw *logwatch.LogWatch +} + +type ClNodeOption = func(c *ClNode) + +// Sets custom node container name if name is not empty +func WithNodeContainerName(name string) ClNodeOption { + return func(c *ClNode) { + if name != "" { + c.ContainerName = name + } + } +} + +// Sets custom node db container name if name is not empty +func WithDbContainerName(name string) ClNodeOption { + return func(c *ClNode) { + if name != "" { + c.PostgresDb.ContainerName = name + } + } +} + +func WithLogWatch(lw *logwatch.LogWatch) ClNodeOption { + return func(c *ClNode) { + c.lw = lw + } +} + +func NewClNode(networks []string, nodeConfig *chainlink.Config, opts ...ClNodeOption) *ClNode { + nodeDefaultCName := fmt.Sprintf("%s-%s", "cl-node", uuid.NewString()[0:8]) + pgDefaultCName := fmt.Sprintf("pg-%s", nodeDefaultCName) + pgDb := NewPostgresDb(networks, WithPostgresDbContainerName(pgDefaultCName)) + n := &ClNode{ + EnvComponent: EnvComponent{ + ContainerName: nodeDefaultCName, + Networks: networks, + }, + NodeConfig: nodeConfig, + PostgresDb: pgDb, + } + for _, opt := range opts { + opt(n) + } + return n +} + +// Restart restarts only CL node, DB container is reused +func (n *ClNode) Restart(cfg *chainlink.Config) error { + if err := n.Container.Terminate(context.Background()); err != nil { + return err + } + n.NodeConfig = cfg + return n.StartContainer() +} + +func (n *ClNode) PrimaryETHAddress() (string, error) { + return n.API.PrimaryEthAddress() +} + +func (n *ClNode) AddBootstrapJob(verifierAddr common.Address, fromBlock uint64, chainId int64, + feedId [32]byte) (*client.Job, error) { + spec := utils.BuildBootstrapSpec(verifierAddr, chainId, fromBlock, feedId) + return n.API.MustCreateJob(spec) +} + +func (n *ClNode) AddMercuryOCRJob(verifierAddr common.Address, fromBlock uint64, chainId int64, + feedId [32]byte, customAllowedFaults *int, bootstrapUrl string, + mercuryServerUrl string, mercuryServerPubKey string, + eaUrls []*url.URL) (*client.Job, error) { + + csaKeys, _, err := n.API.ReadCSAKeys() + if err != nil { + return nil, err + } + csaPubKey := csaKeys.Data[0].ID + + nodeOCRKeys, err := n.API.MustReadOCR2Keys() + if err != nil { + return nil, err + } + + var nodeOCRKeyId []string + for _, key := range nodeOCRKeys.Data { + if key.Attributes.ChainType == string(chaintype.EVM) { + nodeOCRKeyId = append(nodeOCRKeyId, key.ID) + break + } + } + + bridges := utils.BuildBridges(eaUrls) + for _, b := range bridges { + err = n.API.MustCreateBridge(&b) + if err != nil { + return nil, err + } + } + + var allowedFaults int + if customAllowedFaults != nil { + allowedFaults = *customAllowedFaults + } else { + allowedFaults = 2 + } + + spec := utils.BuildOCRSpec( + verifierAddr, chainId, fromBlock, feedId, bridges, + csaPubKey, mercuryServerUrl, mercuryServerPubKey, nodeOCRKeyId[0], + bootstrapUrl, allowedFaults) + + return n.API.MustCreateJob(spec) +} + +func (n *ClNode) GetContainerName() string { + name, err := n.Container.Name(context.Background()) + if err != nil { + return "" + } + return strings.Replace(name, "/", "", -1) +} + +func (n *ClNode) GetPeerUrl() (string, error) { + p2pKeys, err := n.API.MustReadP2PKeys() + if err != nil { + return "", err + } + p2pId := p2pKeys.Data[0].Attributes.PeerID + + return fmt.Sprintf("%s@%s:%d", p2pId, n.GetContainerName(), 6690), nil +} + +func (n *ClNode) GetNodeCSAKeys() (*client.CSAKeys, error) { + csaKeys, _, err := n.API.ReadCSAKeys() + if err != nil { + return nil, err + } + return csaKeys, err +} + +func (n *ClNode) ChainlinkNodeAddress() (common.Address, error) { + addr, err := n.API.PrimaryEthAddress() + if err != nil { + return common.Address{}, err + } + return common.HexToAddress(addr), nil +} + +func (n *ClNode) Fund(evmClient blockchain.EVMClient, amount *big.Float) error { + toAddress, err := n.API.PrimaryEthAddress() + if err != nil { + return err + } + gasEstimates, err := evmClient.EstimateGas(ethereum.CallMsg{}) + if err != nil { + return err + } + return evmClient.Fund(toAddress, amount, gasEstimates) +} + +func (n *ClNode) StartContainer() error { + err := n.PostgresDb.StartContainer() + if err != nil { + return err + } + nodeSecretsToml, err := templates.NodeSecretsTemplate{ + PgDbName: n.PostgresDb.DbName, + PgHost: n.PostgresDb.ContainerName, + PgPort: n.PostgresDb.Port, + PgPassword: n.PostgresDb.Password, + }.String() + if err != nil { + return err + } + n.NodeSecretsConfigTOML = nodeSecretsToml + cReq, err := n.getContainerRequest() + if err != nil { + return err + } + container, err := tc.GenericContainer(context.Background(), tc.GenericContainerRequest{ + ContainerRequest: *cReq, + Started: true, + Reuse: true, + }) + if err != nil { + return errors.Wrap(err, ErrStartCLNodeContainer) + } + if n.lw != nil { + if err := n.lw.ConnectContainer(context.Background(), container, "cl-node", true); err != nil { + return err + } + } + clEndpoint, err := container.Endpoint(context.Background(), "http") + if err != nil { + return err + } + ip, err := container.ContainerIP(context.Background()) + if err != nil { + return err + } + log.Info().Str("containerName", n.ContainerName). + Str("clEndpoint", clEndpoint). + Str("clInternalIP", ip). + Msg("Started Chainlink Node container") + clClient, err := client.NewChainlinkClient(&client.ChainlinkConfig{ + URL: clEndpoint, + Email: "local@local.com", + Password: "localdevpassword", + InternalIP: ip, + }) + if err != nil { + return errors.Wrap(err, ErrConnectNodeClient) + } + + clClient.Config.InternalIP = n.ContainerName + n.Container = container + n.API = clClient + + return nil +} + +func (n *ClNode) getContainerRequest() ( + *tc.ContainerRequest, error) { + configFile, err := os.CreateTemp("", "node_config") + if err != nil { + return nil, err + } + data, err := toml.Marshal(n.NodeConfig) + if err != nil { + return nil, err + } + _, err = configFile.WriteString(string(data)) + if err != nil { + return nil, err + } + secretsFile, err := os.CreateTemp("", "node_secrets") + if err != nil { + return nil, err + } + _, err = secretsFile.WriteString(n.NodeSecretsConfigTOML) + if err != nil { + return nil, err + } + + adminCreds := "local@local.com\nlocaldevpassword" + adminCredsFile, err := os.CreateTemp("", "admin_creds") + if err != nil { + return nil, err + } + _, err = adminCredsFile.WriteString(adminCreds) + if err != nil { + return nil, err + } + + apiCreds := "local@local.com\nlocaldevpassword" + apiCredsFile, err := os.CreateTemp("", "api_creds") + if err != nil { + return nil, err + } + _, err = apiCredsFile.WriteString(apiCreds) + if err != nil { + return nil, err + } + + configPath := "/home/cl-node-config.toml" + secretsPath := "/home/cl-node-secrets.toml" + adminCredsPath := "/home/admin-credentials.txt" + apiCredsPath := "/home/api-credentials.txt" + + image, ok := os.LookupEnv("CHAINLINK_IMAGE") + if !ok { + return nil, errors.New("CHAINLINK_IMAGE env must be set") + } + tag, ok := os.LookupEnv("CHAINLINK_VERSION") + if !ok { + return nil, errors.New("CHAINLINK_VERSION env must be set") + } + + return &tc.ContainerRequest{ + Name: n.ContainerName, + Image: fmt.Sprintf("%s:%s", image, tag), + ExposedPorts: []string{"6688/tcp"}, + Entrypoint: []string{"chainlink", + "-c", configPath, + "-s", secretsPath, + "node", "start", "-d", + "-p", adminCredsPath, + "-a", apiCredsPath, + }, + Networks: n.Networks, + WaitingFor: tcwait.ForHTTP("/health"). + WithPort("6688/tcp"). + WithStartupTimeout(90 * time.Second). + WithPollInterval(1 * time.Second), + Files: []tc.ContainerFile{ + { + HostFilePath: configFile.Name(), + ContainerFilePath: configPath, + FileMode: 0644, + }, + { + HostFilePath: secretsFile.Name(), + ContainerFilePath: secretsPath, + FileMode: 0644, + }, + { + HostFilePath: adminCredsFile.Name(), + ContainerFilePath: adminCredsPath, + FileMode: 0644, + }, + { + HostFilePath: apiCredsFile.Name(), + ContainerFilePath: apiCredsPath, + FileMode: 0644, + }, + }, + }, nil +} + +func GetOracleIdentities(chainlinkNodes []*ClNode) ([]int, []confighelper.OracleIdentityExtra) { + S := make([]int, len(chainlinkNodes)) + oracleIdentities := make([]confighelper.OracleIdentityExtra, len(chainlinkNodes)) + sharedSecretEncryptionPublicKeys := make([]ocrtypes.ConfigEncryptionPublicKey, len(chainlinkNodes)) + var wg sync.WaitGroup + for i, cl := range chainlinkNodes { + wg.Add(1) + go func(i int, cl *ClNode) error { + defer wg.Done() + + ocr2Keys, err := cl.API.MustReadOCR2Keys() + if err != nil { + return err + } + var ocr2Config client.OCR2KeyAttributes + for _, key := range ocr2Keys.Data { + if key.Attributes.ChainType == string(chaintype.EVM) { + ocr2Config = key.Attributes + break + } + } + + keys, err := cl.API.MustReadP2PKeys() + if err != nil { + return err + } + p2pKeyID := keys.Data[0].Attributes.PeerID + + offchainPkBytes, err := hex.DecodeString(strings.TrimPrefix(ocr2Config.OffChainPublicKey, "ocr2off_evm_")) + if err != nil { + return err + } + + offchainPkBytesFixed := [ed25519.PublicKeySize]byte{} + copy(offchainPkBytesFixed[:], offchainPkBytes) + if err != nil { + return err + } + + configPkBytes, err := hex.DecodeString(strings.TrimPrefix(ocr2Config.ConfigPublicKey, "ocr2cfg_evm_")) + if err != nil { + return err + } + + configPkBytesFixed := [ed25519.PublicKeySize]byte{} + copy(configPkBytesFixed[:], configPkBytes) + if err != nil { + return err + } + + onchainPkBytes, err := hex.DecodeString(strings.TrimPrefix(ocr2Config.OnChainPublicKey, "ocr2on_evm_")) + if err != nil { + return err + } + + csaKeys, _, err := cl.API.ReadCSAKeys() + if err != nil { + return err + } + + sharedSecretEncryptionPublicKeys[i] = configPkBytesFixed + oracleIdentities[i] = confighelper.OracleIdentityExtra{ + OracleIdentity: confighelper.OracleIdentity{ + OnchainPublicKey: onchainPkBytes, + OffchainPublicKey: offchainPkBytesFixed, + PeerID: p2pKeyID, + TransmitAccount: ocrtypes.Account(csaKeys.Data[0].ID), + }, + ConfigEncryptionPublicKey: configPkBytesFixed, + } + S[i] = 1 + + return nil + }(i, cl) + } + wg.Wait() + + return S, oracleIdentities +} diff --git a/integration-tests/docker/test_env/env_component.go b/integration-tests/docker/test_env/env_component.go new file mode 100644 index 00000000000..e6f6fc4b8a6 --- /dev/null +++ b/integration-tests/docker/test_env/env_component.go @@ -0,0 +1,21 @@ +package test_env + +import ( + tc "github.com/testcontainers/testcontainers-go" +) + +type EnvComponent struct { + ContainerName string + Container tc.Container + Networks []string +} + +type EnvComponentOption = func(c *EnvComponent) + +func WithContainerName(name string) EnvComponentOption { + return func(c *EnvComponent) { + if name != "" { + c.ContainerName = name + } + } +} diff --git a/integration-tests/docker/test_env/geth.go b/integration-tests/docker/test_env/geth.go new file mode 100644 index 00000000000..764f7acf418 --- /dev/null +++ b/integration-tests/docker/test_env/geth.go @@ -0,0 +1,233 @@ +package test_env + +import ( + "context" + "fmt" + "os" + "time" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/google/uuid" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + tc "github.com/testcontainers/testcontainers-go" + tcwait "github.com/testcontainers/testcontainers-go/wait" + + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + + "github.com/smartcontractkit/chainlink/integration-tests/utils/templates" +) + +const ( + // RootFundingAddr is the static key that hardhat is using + // https://hardhat.org/hardhat-runner/docs/getting-started + // if you need more keys, keep them compatible, so we can swap Geth to Ganache/Hardhat in the future + RootFundingAddr = `0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266` + RootFundingWallet = `{"address":"f39fd6e51aad88f6f4ce6ab8827279cfffb92266","crypto":{"cipher":"aes-128-ctr","ciphertext":"c36afd6e60b82d6844530bd6ab44dbc3b85a53e826c3a7f6fc6a75ce38c1e4c6","cipherparams":{"iv":"f69d2bb8cd0cb6274535656553b61806"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"80d5f5e38ba175b6b89acfc8ea62a6f163970504af301292377ff7baafedab53"},"mac":"f2ecec2c4d05aacc10eba5235354c2fcc3776824f81ec6de98022f704efbf065"},"id":"e5c124e9-e280-4b10-a27b-d7f3e516b408","version":3}` +) + +type Geth struct { + EnvComponent + ExternalHttpUrl string + InternalHttpUrl string + ExternalWsUrl string + InternalWsUrl string +} + +func NewGeth(networks []string, opts ...EnvComponentOption) *Geth { + g := &Geth{ + EnvComponent: EnvComponent{ + ContainerName: fmt.Sprintf("%s-%s", "geth", uuid.NewString()[0:8]), + Networks: networks, + }, + } + for _, opt := range opts { + opt(&g.EnvComponent) + } + return g +} + +func (g *Geth) StartContainer() (blockchain.EVMNetwork, InternalDockerUrls, error) { + r, _, _, err := g.getGethContainerRequest(g.Networks) + if err != nil { + return blockchain.EVMNetwork{}, InternalDockerUrls{}, err + } + ct, err := tc.GenericContainer(context.Background(), + tc.GenericContainerRequest{ + ContainerRequest: *r, + Started: true, + Reuse: true, + }) + if err != nil { + return blockchain.EVMNetwork{}, InternalDockerUrls{}, errors.Wrapf(err, "cannot start geth container") + } + host, err := ct.Host(context.Background()) + if err != nil { + return blockchain.EVMNetwork{}, InternalDockerUrls{}, err + } + httpPort, err := ct.MappedPort(context.Background(), "8544/tcp") + if err != nil { + return blockchain.EVMNetwork{}, InternalDockerUrls{}, err + } + wsPort, err := ct.MappedPort(context.Background(), "8545/tcp") + if err != nil { + return blockchain.EVMNetwork{}, InternalDockerUrls{}, err + } + + g.Container = ct + g.ExternalHttpUrl = fmt.Sprintf("http://%s:%s", host, httpPort.Port()) + g.InternalHttpUrl = fmt.Sprintf("http://%s:8544", g.ContainerName) + g.ExternalWsUrl = fmt.Sprintf("ws://%s:%s", host, wsPort.Port()) + g.InternalWsUrl = fmt.Sprintf("ws://%s:8545", g.ContainerName) + + networkConfig := blockchain.SimulatedEVMNetwork + networkConfig.Name = "geth" + networkConfig.URLs = []string{g.ExternalWsUrl} + networkConfig.HTTPURLs = []string{g.ExternalHttpUrl} + + internalDockerUrls := InternalDockerUrls{ + HttpUrl: g.InternalHttpUrl, + WsUrl: g.InternalWsUrl, + } + + log.Info().Str("containerName", g.ContainerName). + Str("internalHttpUrl", g.InternalHttpUrl). + Str("externalHttpUrl", g.ExternalHttpUrl). + Str("externalWsUrl", g.ExternalWsUrl). + Str("internalWsUrl", g.InternalWsUrl). + Msg("Started Geth container") + + return networkConfig, internalDockerUrls, nil +} + +func (g *Geth) getGethContainerRequest(networks []string) (*tc.ContainerRequest, *keystore.KeyStore, *accounts.Account, error) { + chainId := "1337" + blocktime := "1" + + initScriptFile, err := os.CreateTemp("", "init_script") + if err != nil { + return nil, nil, nil, err + } + _, err = initScriptFile.WriteString(templates.InitGethScript) + if err != nil { + return nil, nil, nil, err + } + keystoreDir, err := os.MkdirTemp("", "keystore") + if err != nil { + return nil, nil, nil, err + } + // Create keystore and ethereum account + ks := keystore.NewKeyStore(keystoreDir, keystore.StandardScryptN, keystore.StandardScryptP) + account, err := ks.NewAccount("") + if err != nil { + return nil, ks, &account, err + } + genesisJsonStr, err := templates.GenesisJsonTemplate{ + ChainId: chainId, + AccountAddr: account.Address.Hex(), + }.String() + if err != nil { + return nil, ks, &account, err + } + genesisFile, err := os.CreateTemp("", "genesis_json") + if err != nil { + return nil, ks, &account, err + } + _, err = genesisFile.WriteString(genesisJsonStr) + if err != nil { + return nil, ks, &account, err + } + key1File, err := os.CreateTemp(keystoreDir, "key1") + if err != nil { + return nil, ks, &account, err + } + _, err = key1File.WriteString(RootFundingWallet) + if err != nil { + return nil, ks, &account, err + } + configDir, err := os.MkdirTemp("", "config") + if err != nil { + return nil, ks, &account, err + } + err = os.WriteFile(configDir+"/password.txt", []byte(""), 0600) + if err != nil { + return nil, ks, &account, err + } + + return &tc.ContainerRequest{ + Name: g.ContainerName, + AlwaysPullImage: true, + Image: "ethereum/client-go:stable", + ExposedPorts: []string{"8544/tcp", "8545/tcp"}, + Networks: networks, + WaitingFor: tcwait.ForLog("Chain head was updated"). + WithStartupTimeout(120 * time.Second). + WithPollInterval(1 * time.Second), + Entrypoint: []string{"sh", "./root/init.sh", + "--dev", + "--password", "/root/config/password.txt", + "--datadir", + "/root/.ethereum/devchain", + "--unlock", + RootFundingAddr, + "--mine", + "--miner.etherbase", + RootFundingAddr, + "--ipcdisable", + "--http", + "--http.vhosts", + "*", + "--http.addr", + "0.0.0.0", + "--http.port=8544", + "--ws", + "--ws.origins", + "*", + "--ws.addr", + "0.0.0.0", + "--ws.port=8545", + "--graphql", + "-graphql.corsdomain", + "*", + "--allow-insecure-unlock", + "--rpc.allow-unprotected-txs", + "--http.api", + "eth,web3,debug", + "--http.corsdomain", + "*", + "--vmdebug", + fmt.Sprintf("--networkid=%s", chainId), + "--rpc.txfeecap", + "0", + "--dev.period", + blocktime, + }, + Files: []tc.ContainerFile{ + { + HostFilePath: initScriptFile.Name(), + ContainerFilePath: "/root/init.sh", + FileMode: 0644, + }, + { + HostFilePath: genesisFile.Name(), + ContainerFilePath: "/root/genesis.json", + FileMode: 0644, + }, + }, + Mounts: tc.ContainerMounts{ + tc.ContainerMount{ + Source: tc.GenericBindMountSource{ + HostPath: keystoreDir, + }, + Target: "/root/.ethereum/devchain/keystore/", + }, + tc.ContainerMount{ + Source: tc.GenericBindMountSource{ + HostPath: configDir, + }, + Target: "/root/config/", + }, + }, + }, ks, &account, nil +} diff --git a/integration-tests/docker/test_env/mockserver.go b/integration-tests/docker/test_env/mockserver.go new file mode 100644 index 00000000000..8a8f966678c --- /dev/null +++ b/integration-tests/docker/test_env/mockserver.go @@ -0,0 +1,106 @@ +package test_env + +import ( + "context" + "fmt" + "net/url" + "strings" + "time" + + "github.com/google/uuid" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + tc "github.com/testcontainers/testcontainers-go" + tcwait "github.com/testcontainers/testcontainers-go/wait" + + ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" +) + +type MockServer struct { + EnvComponent + Client *ctfClient.MockserverClient + Endpoint string + InternalEndpoint string + EAMockUrls []*url.URL +} + +func NewMockServer(networks []string, opts ...EnvComponentOption) *MockServer { + ms := &MockServer{ + EnvComponent: EnvComponent{ + ContainerName: fmt.Sprintf("%s-%s", "mockserver", uuid.NewString()[0:8]), + Networks: networks, + }, + } + for _, opt := range opts { + opt(&ms.EnvComponent) + } + return ms +} + +func (ms *MockServer) SetExternalAdapterMocks(count int) error { + for i := 0; i < count; i++ { + path := fmt.Sprintf("/ea-%d", i) + err := ms.Client.SetRandomValuePath(path) + if err != nil { + return err + } + cName, err := ms.Container.Name(context.Background()) + if err != nil { + return err + } + cName = strings.Replace(cName, "/", "", -1) + eaUrl, err := url.Parse(fmt.Sprintf("http://%s:%s%s", + cName, "1080", path)) + if err != nil { + return err + } + ms.EAMockUrls = append(ms.EAMockUrls, eaUrl) + } + return nil +} + +func (ms *MockServer) StartContainer() error { + c, err := tc.GenericContainer(context.Background(), tc.GenericContainerRequest{ + ContainerRequest: ms.getContainerRequest(), + Started: true, + Reuse: true, + }) + if err != nil { + return errors.Wrapf(err, "cannot start MockServer container") + } + ms.Container = c + endpoint, err := c.Endpoint(context.Background(), "http") + if err != nil { + return err + } + log.Info().Any("endpoint", endpoint).Str("containerName", ms.ContainerName). + Msgf("Started MockServer container") + ms.Endpoint = endpoint + ms.InternalEndpoint = fmt.Sprintf("http://%s:%s", ms.ContainerName, "1080") + + client := ctfClient.NewMockserverClient(&ctfClient.MockserverConfig{ + LocalURL: endpoint, + ClusterURL: ms.InternalEndpoint, + }) + if err != nil { + return errors.Wrapf(err, "cannot connect to MockServer client") + } + ms.Client = client + + return nil +} + +func (ms *MockServer) getContainerRequest() tc.ContainerRequest { + return tc.ContainerRequest{ + Name: ms.ContainerName, + Image: "mockserver/mockserver:5.15.0", + ExposedPorts: []string{"1080/tcp"}, + Env: map[string]string{ + "SERVER_PORT": "1080", + }, + Networks: ms.Networks, + WaitingFor: tcwait.ForLog("INFO 1080 started on port: 1080"). + WithStartupTimeout(30 * time.Second). + WithPollInterval(100 * time.Millisecond), + } +} diff --git a/integration-tests/docker/test_env/postgres.go b/integration-tests/docker/test_env/postgres.go new file mode 100644 index 00000000000..64b48235989 --- /dev/null +++ b/integration-tests/docker/test_env/postgres.go @@ -0,0 +1,83 @@ +package test_env + +import ( + "context" + "fmt" + "time" + + "github.com/google/uuid" + "github.com/rs/zerolog/log" + tc "github.com/testcontainers/testcontainers-go" + tcwait "github.com/testcontainers/testcontainers-go/wait" +) + +type PostgresDb struct { + EnvComponent + User string + Password string + DbName string + Port string +} + +type PostgresDbOption = func(c *PostgresDb) + +// Sets custom container name if name is not empty +func WithPostgresDbContainerName(name string) PostgresDbOption { + return func(c *PostgresDb) { + if name != "" { + c.ContainerName = name + } + } +} + +func NewPostgresDb(networks []string, opts ...PostgresDbOption) *PostgresDb { + pg := &PostgresDb{ + EnvComponent: EnvComponent{ + ContainerName: fmt.Sprintf("%s-%s", "postgres-db", uuid.NewString()[0:8]), + Networks: networks, + }, + User: "postgres", + Password: "mysecretpassword", + DbName: "testdb", + Port: "5432", + } + for _, opt := range opts { + opt(pg) + } + return pg +} + +func (pg *PostgresDb) StartContainer() error { + req := pg.getContainerRequest() + c, err := tc.GenericContainer(context.Background(), tc.GenericContainerRequest{ + ContainerRequest: *req, + Started: true, + Reuse: true, + }) + if err != nil { + return err + } + pg.Container = c + + log.Info().Str("containerName", pg.ContainerName). + Msg("Started Postgres DB container") + + return nil +} + +func (pg *PostgresDb) getContainerRequest() *tc.ContainerRequest { + return &tc.ContainerRequest{ + Name: pg.ContainerName, + Image: "postgres:15.3", + ExposedPorts: []string{fmt.Sprintf("%s/tcp", pg.Port)}, + Env: map[string]string{ + "POSTGRES_USER": pg.User, + "POSTGRES_DB": pg.DbName, + "POSTGRES_PASSWORD": pg.Password, + }, + Networks: pg.Networks, + WaitingFor: tcwait.ForExec([]string{"psql", "-h", "localhost", + "-U", pg.User, "-c", "select", "1", "-d", pg.DbName}). + WithStartupTimeout(10 * time.Second), + } +} diff --git a/integration-tests/docker/test_env/test_env.go b/integration-tests/docker/test_env/test_env.go new file mode 100644 index 00000000000..40e4c27bd2a --- /dev/null +++ b/integration-tests/docker/test_env/test_env.go @@ -0,0 +1,195 @@ +package test_env + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + tc "github.com/testcontainers/testcontainers-go" + "golang.org/x/sync/errgroup" + + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" + "github.com/smartcontractkit/chainlink-testing-framework/logwatch" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + + "github.com/smartcontractkit/chainlink/integration-tests/client" + "github.com/smartcontractkit/chainlink/integration-tests/contracts" + "github.com/smartcontractkit/chainlink/integration-tests/docker" + "github.com/smartcontractkit/chainlink/integration-tests/utils" +) + +var ( + ErrFundCLNode = "failed to fund CL node" + ErrGetNodeCSAKeys = "failed get CL node CSA keys" +) + +type CLClusterTestEnv struct { + Cfg *TestEnvConfig + Network *tc.DockerNetwork + LogWatch *logwatch.LogWatch + + /* components */ + CLNodes []*ClNode + Geth *Geth // for tests using --dev networks + PrivateGethChain []test_env.PrivateGethChain // for tests using non-dev networks + MockServer *MockServer + EVMClient blockchain.EVMClient + ContractDeployer contracts.ContractDeployer + ContractLoader contracts.ContractLoader +} + +func NewTestEnv() (*CLClusterTestEnv, error) { + utils.SetupCoreDockerEnvLogger() + network, err := docker.CreateNetwork() + if err != nil { + return nil, err + } + networks := []string{network.Name} + return &CLClusterTestEnv{ + Network: network, + Geth: NewGeth(networks), + MockServer: NewMockServer(networks), + }, nil +} + +func NewTestEnvFromCfg(cfg *TestEnvConfig) (*CLClusterTestEnv, error) { + utils.SetupCoreDockerEnvLogger() + network, err := docker.CreateNetwork() + if err != nil { + return nil, err + } + networks := []string{network.Name} + log.Info().Interface("Cfg", cfg).Send() + return &CLClusterTestEnv{ + Cfg: cfg, + Network: network, + Geth: NewGeth(networks, WithContainerName(cfg.Geth.ContainerName)), + MockServer: NewMockServer(networks, WithContainerName(cfg.MockServer.ContainerName)), + }, nil +} + +func (te *CLClusterTestEnv) ParallelTransactions(enabled bool) { + te.EVMClient.ParallelTransactions(enabled) +} + +func (te *CLClusterTestEnv) WithPrivateGethChain(evmNetworks []blockchain.EVMNetwork) *CLClusterTestEnv { + var chains []test_env.PrivateGethChain + for _, evmNetwork := range evmNetworks { + n := evmNetwork + chains = append(chains, test_env.NewPrivateGethChain(&n, []string{te.Network.Name})) + } + te.PrivateGethChain = chains + return te +} + +func (te *CLClusterTestEnv) StartPrivateGethChain() error { + for _, chain := range te.PrivateGethChain { + err := chain.PrimaryNode.Start() + if err != nil { + return err + } + err = chain.PrimaryNode.ConnectToClient() + if err != nil { + return err + } + } + return nil +} + +func (te *CLClusterTestEnv) StartGeth() (blockchain.EVMNetwork, InternalDockerUrls, error) { + return te.Geth.StartContainer() +} + +func (te *CLClusterTestEnv) StartMockServer() error { + return te.MockServer.StartContainer() +} + +func (te *CLClusterTestEnv) GetAPIs() []*client.ChainlinkClient { + clients := make([]*client.ChainlinkClient, 0) + for _, c := range te.CLNodes { + clients = append(clients, c.API) + } + return clients +} + +// StartClNodes start one bootstrap node and {count} OCR nodes +func (te *CLClusterTestEnv) StartClNodes(nodeConfig *chainlink.Config, count int) error { + eg := &errgroup.Group{} + nodes := make(chan *ClNode, count) + + // Start nodes + for i := 0; i < count; i++ { + nodeIndex := i + eg.Go(func() error { + var nodeContainerName, dbContainerName string + if te.Cfg != nil { + nodeContainerName = te.Cfg.Nodes[nodeIndex].NodeContainerName + dbContainerName = te.Cfg.Nodes[nodeIndex].DbContainerName + } + n := NewClNode([]string{te.Network.Name}, nodeConfig, + WithNodeContainerName(nodeContainerName), + WithDbContainerName(dbContainerName), + ) + err := n.StartContainer() + if err != nil { + return err + } + nodes <- n + return nil + }) + } + + if err := eg.Wait(); err != nil { + return err + } + close(nodes) + + for node := range nodes { + te.CLNodes = append(te.CLNodes, node) + } + + return nil +} + +// ChainlinkNodeAddresses will return all the on-chain wallet addresses for a set of Chainlink nodes +func (te *CLClusterTestEnv) ChainlinkNodeAddresses() ([]common.Address, error) { + addresses := make([]common.Address, 0) + for _, n := range te.CLNodes { + primaryAddress, err := n.ChainlinkNodeAddress() + if err != nil { + return nil, err + } + addresses = append(addresses, primaryAddress) + } + return addresses, nil +} + +// FundChainlinkNodes will fund all the provided Chainlink nodes with a set amount of native currency +func (te *CLClusterTestEnv) FundChainlinkNodes(amount *big.Float) error { + for _, cl := range te.CLNodes { + if err := cl.Fund(te.EVMClient, amount); err != nil { + return errors.Wrap(err, ErrFundCLNode) + } + } + return te.EVMClient.WaitForEvents() +} + +func (te *CLClusterTestEnv) GetNodeCSAKeys() ([]string, error) { + var keys []string + for _, n := range te.CLNodes { + csaKeys, err := n.GetNodeCSAKeys() + if err != nil { + return nil, errors.Wrap(err, ErrGetNodeCSAKeys) + } + keys = append(keys, csaKeys.Data[0].ID) + } + return keys, nil +} + +func (te *CLClusterTestEnv) Terminate() error { + // TESTCONTAINERS_RYUK_DISABLED=false by default so ryuk will remove all + // the containers and the Network + return nil +} diff --git a/integration-tests/docker/test_env/test_env_builder.go b/integration-tests/docker/test_env/test_env_builder.go new file mode 100644 index 00000000000..04b9f44f3f7 --- /dev/null +++ b/integration-tests/docker/test_env/test_env_builder.go @@ -0,0 +1,240 @@ +package test_env + +import ( + "math/big" + "os" + + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink-testing-framework/logwatch" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + + "github.com/smartcontractkit/chainlink/integration-tests/contracts" + "github.com/smartcontractkit/chainlink/integration-tests/networks" + "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" +) + +type CLTestEnvBuilder struct { + hasLogWatch bool + hasGeth bool + hasMockServer bool + hasForwarders bool + clNodeConfig *chainlink.Config + nonDevGethNetworks []blockchain.EVMNetwork + clNodesCount int + externalAdapterCount int + customNodeCsaKeys []string + defaultNodeCsaKeys []string + + /* funding */ + ETHFunds *big.Float +} + +type InternalDockerUrls struct { + HttpUrl string + WsUrl string +} + +func NewCLTestEnvBuilder() *CLTestEnvBuilder { + return &CLTestEnvBuilder{ + externalAdapterCount: 1, + } +} + +func (b *CLTestEnvBuilder) WithLogWatcher() *CLTestEnvBuilder { + b.hasLogWatch = true + return b +} + +func (b *CLTestEnvBuilder) WithCLNodes(clNodesCount int) *CLTestEnvBuilder { + b.clNodesCount = clNodesCount + return b +} + +func (b *CLTestEnvBuilder) WithForwarders() *CLTestEnvBuilder { + b.hasForwarders = true + return b +} + +func (b *CLTestEnvBuilder) WithFunding(eth *big.Float) *CLTestEnvBuilder { + b.ETHFunds = eth + return b +} + +func (b *CLTestEnvBuilder) WithGeth() *CLTestEnvBuilder { + b.hasGeth = true + return b +} + +func (b *CLTestEnvBuilder) WithPrivateGethChains(evmNetworks []blockchain.EVMNetwork) *CLTestEnvBuilder { + b.nonDevGethNetworks = evmNetworks + return b +} + +func (b *CLTestEnvBuilder) WithCLNodeConfig(cfg *chainlink.Config) *CLTestEnvBuilder { + b.clNodeConfig = cfg + return b +} + +func (b *CLTestEnvBuilder) WithMockServer(externalAdapterCount int) *CLTestEnvBuilder { + b.hasMockServer = true + b.externalAdapterCount = externalAdapterCount + return b +} + +func (b *CLTestEnvBuilder) Build() (*CLClusterTestEnv, error) { + envConfigPath, isSet := os.LookupEnv("TEST_ENV_CONFIG_PATH") + if isSet { + cfg, err := NewTestEnvConfigFromFile(envConfigPath) + if err != nil { + return nil, err + } + _ = os.Setenv("TESTCONTAINERS_RYUK_DISABLED", "true") + return b.buildNewEnv(cfg) + } + return b.buildNewEnv(nil) +} + +func (b *CLTestEnvBuilder) buildNewEnv(cfg *TestEnvConfig) (*CLClusterTestEnv, error) { + log.Info(). + Bool("hasGeth", b.hasGeth). + Bool("hasMockServer", b.hasMockServer). + Int("externalAdapterCount", b.externalAdapterCount). + Int("clNodesCount", b.clNodesCount). + Strs("customNodeCsaKeys", b.customNodeCsaKeys). + Strs("defaultNodeCsaKeys", b.defaultNodeCsaKeys). + Msg("Building CL cluster test environment..") + + var te *CLClusterTestEnv + var err error + if cfg != nil { + te, err = NewTestEnvFromCfg(cfg) + if err != nil { + return nil, err + } + } else { + te, err = NewTestEnv() + if err != nil { + return nil, err + } + } + + if b.hasLogWatch { + te.LogWatch, err = logwatch.NewLogWatch(nil, nil) + if err != nil { + return nil, err + } + } + + if b.hasMockServer { + err = te.StartMockServer() + if err != nil { + return nil, err + } + err = te.MockServer.SetExternalAdapterMocks(b.externalAdapterCount) + if err != nil { + return nil, err + } + } + if b.nonDevGethNetworks != nil { + te.WithPrivateGethChain(b.nonDevGethNetworks) + err := te.StartPrivateGethChain() + if err != nil { + return te, err + } + var nonDevGethNetworks []blockchain.EVMNetwork + for i, n := range te.PrivateGethChain { + nonDevGethNetworks = append(nonDevGethNetworks, *n.NetworkConfig) + nonDevGethNetworks[i].URLs = []string{n.PrimaryNode.InternalWsUrl} + nonDevGethNetworks[i].HTTPURLs = []string{n.PrimaryNode.InternalHttpUrl} + } + if nonDevGethNetworks == nil { + return nil, errors.New("cannot create nodes with custom config without nonDevGethNetworks") + } + + err = te.StartClNodes(b.clNodeConfig, b.clNodesCount) + if err != nil { + return nil, err + } + return te, nil + } + networkConfig := networks.SelectedNetwork + var internalDockerUrls InternalDockerUrls + if b.hasGeth && networkConfig.Simulated { + networkConfig, internalDockerUrls, err = te.StartGeth() + if err != nil { + return nil, err + } + + } + + bc, err := blockchain.NewEVMClientFromNetwork(networkConfig) + if err != nil { + return nil, err + } + + te.EVMClient = bc + + cd, err := contracts.NewContractDeployer(bc) + if err != nil { + return nil, err + } + te.ContractDeployer = cd + + cl, err := contracts.NewContractLoader(bc) + if err != nil { + return nil, err + } + te.ContractLoader = cl + + var nodeCsaKeys []string + + // Start Chainlink Nodes + if b.clNodesCount > 0 { + var cfg *chainlink.Config + if b.clNodeConfig != nil { + cfg = b.clNodeConfig + } else { + cfg = node.NewConfig(node.BaseConf, + node.WithOCR1(), + node.WithP2Pv1(), + ) + } + //node.SetDefaultSimulatedGeth(cfg, te.Geth.InternalWsUrl, te.Geth.InternalHttpUrl, b.hasForwarders) + + var httpUrls []string + var wsUrls []string + if networkConfig.Simulated { + httpUrls = []string{internalDockerUrls.HttpUrl} + wsUrls = []string{internalDockerUrls.WsUrl} + } else { + httpUrls = networkConfig.HTTPURLs + wsUrls = networkConfig.URLs + } + + node.SetChainConfig(cfg, wsUrls, httpUrls, networkConfig, b.hasForwarders) + + err := te.StartClNodes(cfg, b.clNodesCount) + if err != nil { + return nil, err + } + + nodeCsaKeys, err = te.GetNodeCSAKeys() + if err != nil { + return nil, err + } + b.defaultNodeCsaKeys = nodeCsaKeys + } + + if b.hasGeth && b.clNodesCount > 0 && b.ETHFunds != nil { + te.ParallelTransactions(true) + defer te.ParallelTransactions(false) + if err := te.FundChainlinkNodes(b.ETHFunds); err != nil { + return nil, err + } + } + + return te, nil +} diff --git a/integration-tests/docker/test_env/test_env_config.go b/integration-tests/docker/test_env/test_env_config.go new file mode 100644 index 00000000000..da38575a86a --- /dev/null +++ b/integration-tests/docker/test_env/test_env_config.go @@ -0,0 +1,42 @@ +package test_env + +import ( + "encoding/json" + + env "github.com/smartcontractkit/chainlink/integration-tests/types/envcommon" +) + +type TestEnvConfig struct { + Networks []string `json:"networks"` + Geth GethConfig `json:"geth"` + MockServer MockServerConfig `json:"mockserver"` + Nodes []ClNodeConfig `json:"nodes"` +} + +type MockServerConfig struct { + ContainerName string `json:"container_name"` + EAMockUrls []string `json:"external_adapters_mock_urls"` +} + +type GethConfig struct { + ContainerName string `json:"container_name"` +} + +type ClNodeConfig struct { + NodeContainerName string `json:"container_name"` + DbContainerName string `json:"db_container_name"` +} + +func NewTestEnvConfigFromFile(path string) (*TestEnvConfig, error) { + c := &TestEnvConfig{} + err := env.ParseJSONFile(path, c) + if err != nil { + return nil, err + } + return c, nil +} + +func (c *TestEnvConfig) Json() string { + b, _ := json.Marshal(c) + return string(b) +} diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 106b5386532..9ad8b7164ce 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -6,6 +6,7 @@ go 1.20 replace github.com/smartcontractkit/chainlink/v2 => ../ require ( + github.com/K-Phoen/grabana v0.21.17 github.com/cli/go-gh/v2 v2.0.0 github.com/ethereum/go-ethereum v1.12.0 github.com/go-resty/resty/v2 v2.7.0 @@ -14,38 +15,61 @@ require ( github.com/lib/pq v1.10.9 github.com/manifoldco/promptui v0.9.0 github.com/onsi/gomega v1.27.8 + github.com/pelletier/go-toml/v2 v2.0.9 github.com/pkg/errors v0.9.1 - github.com/rs/zerolog v1.29.1 + github.com/rs/zerolog v1.30.0 github.com/slack-go/slack v0.12.2 - github.com/smartcontractkit/chainlink-env v0.35.0 - github.com/smartcontractkit/chainlink-testing-framework v1.14.0 + github.com/smartcontractkit/chainlink-env v0.36.0 + github.com/smartcontractkit/chainlink-testing-framework v1.16.0 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 - github.com/smartcontractkit/libocr v0.0.0-20230724105022-c5e49b4195ac - github.com/smartcontractkit/ocr2keepers v1.0.0-alpha.0 - github.com/smartcontractkit/ocr2vrf v0.0.0-20230616201444-d8b4222aff3c + github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 + github.com/smartcontractkit/ocr2keepers v0.7.17 + github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 + github.com/smartcontractkit/wasp v0.3.0 + github.com/spf13/cobra v1.6.1 github.com/stretchr/testify v1.8.4 + github.com/testcontainers/testcontainers-go v0.23.0 github.com/umbracle/ethgo v0.1.3 go.dedis.ch/kyber/v3 v3.1.0 - go.uber.org/zap v1.24.0 + go.uber.org/zap v1.25.0 golang.org/x/sync v0.3.0 gopkg.in/guregu/null.v4 v4.0.0 ) +// Pin K8s versions as their updates are highly disruptive and go mod keeps wanting to update them +replace ( + k8s.io/api => k8s.io/api v0.25.11 + k8s.io/client-go => k8s.io/client-go v0.25.11 + k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20230303024457-afdc3dddf62d +) + require ( contrib.go.opencensus.io/exporter/stackdriver v0.13.5 // indirect + cosmossdk.io/api v0.3.1 // indirect + cosmossdk.io/core v0.5.1 // indirect + cosmossdk.io/depinject v1.0.0-alpha.3 // indirect cosmossdk.io/errors v1.0.0 // indirect cosmossdk.io/math v1.0.1 // indirect + dario.cat/mergo v1.0.0 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect + github.com/CosmWasm/wasmd v0.40.1 // indirect + github.com/CosmWasm/wasmvm v1.2.4 // indirect github.com/DataDog/zstd v1.5.2 // indirect + github.com/K-Phoen/sdk v0.12.2 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect - github.com/OneOfOne/xxhash v1.2.6 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect github.com/VictoriaMetrics/fastcache v1.10.0 // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect + github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect + github.com/armon/go-metrics v0.4.1 // indirect + github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect + github.com/avast/retry-go/v4 v4.3.4 // indirect + github.com/aws/aws-sdk-go v1.44.276 // indirect github.com/aws/constructs-go/constructs/v10 v10.1.255 // indirect github.com/aws/jsii-runtime-go v1.75.0 // indirect github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 // indirect @@ -55,8 +79,12 @@ require ( github.com/blendle/zapdriver v1.3.1 // indirect github.com/btcsuite/btcd v0.23.4 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect + github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect github.com/bytedance/sonic v1.9.1 // indirect + github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee // indirect github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.7.5 // indirect + github.com/cenkalti/backoff v2.2.1+incompatible // indirect + github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect @@ -71,30 +99,43 @@ require ( github.com/cometbft/cometbft v0.37.2 // indirect github.com/cometbft/cometbft-db v0.7.0 // indirect github.com/confio/ics23/go v0.9.0 // indirect + github.com/containerd/containerd v1.7.3 // indirect + github.com/coreos/go-semver v0.3.0 // indirect + github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect github.com/cosmos/cosmos-sdk v0.47.4 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogoproto v1.4.10 // indirect + github.com/cosmos/iavl v0.20.0 // indirect + github.com/cosmos/ibc-go/v7 v7.0.1 // indirect + github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab // indirect github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect + github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/danieljoos/wincred v1.1.2 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/deckarep/golang-set/v2 v2.3.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/dennwc/varint v1.0.0 // indirect github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 // indirect github.com/dgraph-io/badger/v2 v2.2007.4 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect + github.com/docker/distribution v2.8.2+incompatible // indirect + github.com/docker/docker v24.0.5+incompatible // indirect + github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.5.0 // indirect - github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/edsrzf/mmap-go v1.1.0 // indirect + github.com/emicklei/go-restful/v3 v3.10.1 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect github.com/fatih/camelcase v1.0.0 // indirect github.com/fatih/color v1.15.0 // indirect + github.com/felixge/httpsnoop v1.0.3 // indirect github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fvbommel/sortorder v1.0.2 // indirect @@ -115,17 +156,28 @@ require ( github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-openapi/analysis v0.21.4 // indirect + github.com/go-openapi/errors v0.20.3 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/loads v0.21.2 // indirect + github.com/go-openapi/spec v0.20.8 // indirect + github.com/go-openapi/strfmt v0.21.7 // indirect github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-openapi/validate v0.22.1 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.14.0 // indirect github.com/go-stack/stack v1.8.1 // indirect + github.com/go-webauthn/revoke v0.1.9 // indirect + github.com/go-webauthn/webauthn v0.8.2 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gofrs/flock v0.8.1 // indirect + github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.3 // indirect + github.com/gogo/status v1.1.1 // indirect + github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/glog v1.1.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect @@ -134,33 +186,51 @@ require ( github.com/google/gnostic v0.6.9 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/go-querystring v1.1.0 // indirect + github.com/google/go-tpm v0.3.3 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/gorilla/context v1.1.1 // indirect + github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/securecookie v1.1.1 // indirect github.com/gorilla/sessions v1.2.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect + github.com/gosimple/slug v1.13.1 // indirect + github.com/gosimple/unidecode v1.0.1 // indirect + github.com/grafana/dskit v0.0.0-20230201083518-528d8a7d52f2 // indirect + github.com/grafana/loki v1.6.2-0.20230403212622-90888a0cc737 // indirect + github.com/grafana/loki/pkg/push v0.0.0-20230127102416-571f88bc5765 // indirect + github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect + github.com/hashicorp/consul/api v1.21.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-hclog v1.4.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-hclog v1.5.0 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-msgpack v0.5.5 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-plugin v1.4.10 // indirect + github.com/hashicorp/go-rootcerts v1.0.2 // indirect + github.com/hashicorp/go-sockaddr v1.0.2 // indirect github.com/hashicorp/golang-lru v0.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/hashicorp/memberlist v0.5.0 // indirect + github.com/hashicorp/serf v0.10.1 // indirect github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce // indirect github.com/hdevalence/ed25519consensus v0.1.0 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/uint256 v1.2.2 // indirect + github.com/huandu/skiplist v1.2.0 // indirect github.com/huin/goupnp v1.0.3 // indirect - github.com/imdario/mergo v0.3.15 // indirect + github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/go-cid v0.0.7 // indirect github.com/ipfs/go-datastore v0.4.5 // indirect @@ -179,12 +249,14 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect github.com/jmoiron/sqlx v1.3.5 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.16.3 // indirect + github.com/julienschmidt/httprouter v1.3.0 // indirect + github.com/klauspost/compress v1.16.7 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/koron/go-ssdp v0.0.2 // indirect github.com/kr/pretty v0.3.1 // indirect @@ -237,17 +309,22 @@ require ( github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/miekg/dns v1.1.54 // indirect github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect - github.com/minio/sha256-simd v0.1.1 // indirect + github.com/minio/sha256-simd v1.0.0 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/moby/patternmatcher v0.5.0 // indirect github.com/moby/spdystream v0.2.0 // indirect - github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect + github.com/moby/sys/sequential v0.5.0 // indirect + github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect + github.com/morikuni/aec v1.0.0 // indirect github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/mtibben/percent v0.2.1 // indirect @@ -262,50 +339,71 @@ require ( github.com/multiformats/go-multistream v0.2.2 // indirect github.com/multiformats/go-varint v0.0.6 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect + github.com/mwitkow/grpc-proxy v0.0.0-20230212185441-f345521cb9c9 // indirect github.com/oklog/run v1.1.0 // indirect + github.com/oklog/ulid v1.3.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0-rc4 // indirect + github.com/opencontainers/runc v1.1.7 // indirect + github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e // indirect + github.com/opentracing-contrib/go-stdlib v1.0.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect + github.com/patrickmn/go-cache v2.1.0+incompatible // indirect github.com/pelletier/go-toml v1.9.5 // indirect - github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect + github.com/prometheus/alertmanager v0.25.0 // indirect github.com/prometheus/client_golang v1.16.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/common/sigv4 v0.1.0 // indirect + github.com/prometheus/exporter-toolkit v0.10.0 // indirect github.com/prometheus/procfs v0.11.0 // indirect + github.com/prometheus/prometheus v0.45.0 // indirect github.com/pyroscope-io/client v0.7.1 // indirect - github.com/pyroscope-io/godeltaprof v0.1.0 // indirect + github.com/pyroscope-io/godeltaprof v0.1.2 // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/russross/blackfriday v1.6.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/scylladb/go-reflectx v1.0.1 // indirect + github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect + github.com/sercand/kuberesolver v2.4.0+incompatible // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.22.12 // indirect github.com/shopspring/decimal v1.3.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 // indirect - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230620171700-bbcb3a99b7d3 // indirect + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230824124058-9b063c470048 // indirect + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230824125819-215fd09979a2 // indirect + github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230802143301-165000751a85 // indirect + github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230802150127-d2c95679d61a // indirect github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb // indirect + github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230823081604-f2a0e6b108bb // indirect + github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230823081604-f2a0e6b108bb // indirect github.com/smartcontractkit/wsrpc v0.7.2 // indirect github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.9.3 // indirect github.com/spf13/cast v1.5.1 // indirect - github.com/spf13/cobra v1.6.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.15.0 // indirect github.com/status-im/keycard-go v0.2.0 // indirect + github.com/stretchr/objx v0.5.0 // indirect github.com/subosito/gotenv v1.4.2 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 // indirect github.com/theodesp/go-heaps v0.0.0-20190520121037-88e35354fe0a // indirect + github.com/tidwall/btree v1.6.0 // indirect github.com/tidwall/gjson v1.14.4 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect @@ -313,9 +411,13 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/tyler-smith/go-bip39 v1.1.0 // indirect + github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect + github.com/uber/jaeger-lib v2.4.1+incompatible // indirect github.com/ugorji/go/codec v1.2.11 // indirect github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 // indirect github.com/valyala/fastjson v1.4.1 // indirect + github.com/weaveworks/common v0.0.0-20221201103051-7c2720a9024d // indirect + github.com/weaveworks/promrus v1.2.0 // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect github.com/x448/float16 v0.8.4 // indirect @@ -326,25 +428,32 @@ require ( github.com/zondax/ledger-go v0.14.1 // indirect go.dedis.ch/fixbuf v1.0.3 // indirect go.etcd.io/bbolt v1.3.7 // indirect + go.etcd.io/etcd/api/v3 v3.5.7 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.7 // indirect + go.etcd.io/etcd/client/v3 v3.5.7 // indirect + go.mongodb.org/mongo-driver v1.11.3 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 // indirect go.opentelemetry.io/otel v1.16.0 // indirect go.opentelemetry.io/otel/metric v1.16.0 // indirect go.opentelemetry.io/otel/sdk v1.16.0 // indirect go.opentelemetry.io/otel/trace v1.16.0 // indirect go.starlark.net v0.0.0-20220817180228-f738f5508c12 // indirect go.uber.org/atomic v1.11.0 // indirect + go.uber.org/goleak v1.2.1 // indirect go.uber.org/multierr v1.11.0 // indirect + go.uber.org/ratelimit v0.2.0 // indirect golang.org/x/arch v0.4.0 // indirect - golang.org/x/crypto v0.11.0 // indirect - golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb // indirect + golang.org/x/crypto v0.12.0 // indirect + golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.12.0 // indirect + golang.org/x/net v0.14.0 // indirect golang.org/x/oauth2 v0.10.0 // indirect - golang.org/x/sys v0.10.0 // indirect - golang.org/x/term v0.10.0 // indirect - golang.org/x/text v0.11.0 // indirect + golang.org/x/sys v0.11.0 // indirect + golang.org/x/term v0.11.0 // indirect + golang.org/x/text v0.12.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.11.0 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect @@ -353,27 +462,29 @@ require ( google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect - google.golang.org/grpc v1.56.2 // indirect + google.golang.org/grpc v1.57.0 // indirect google.golang.org/protobuf v1.31.0 // indirect + gopkg.in/guregu/null.v2 v2.1.2 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.25.11 // indirect + k8s.io/api v0.26.2 // indirect k8s.io/apiextensions-apiserver v0.25.3 // indirect - k8s.io/apimachinery v0.25.11 // indirect + k8s.io/apimachinery v0.26.2 // indirect k8s.io/cli-runtime v0.25.11 // indirect - k8s.io/client-go v0.25.11 // indirect - k8s.io/component-base v0.25.11 // indirect - k8s.io/klog/v2 v2.80.1 // indirect - k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect + k8s.io/client-go v0.26.2 // indirect + k8s.io/component-base v0.26.2 // indirect + k8s.io/klog/v2 v2.90.1 // indirect + k8s.io/kube-openapi v0.0.0-20230303024457-afdc3dddf62d // indirect k8s.io/kubectl v0.25.11 // indirect - k8s.io/utils v0.0.0-20221107191617-1a15be271d1d // indirect + k8s.io/utils v0.0.0-20230308161112-d77c459e9343 // indirect + nhooyr.io/websocket v1.8.7 // indirect pgregory.net/rapid v0.5.5 // indirect sigs.k8s.io/controller-runtime v0.13.0 // indirect - sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/kustomize/api v0.12.1 // indirect sigs.k8s.io/kustomize/kyaml v0.13.9 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect @@ -385,9 +496,17 @@ replace ( // See https://github.com/ugorji/go/issues/279 github.com/btcsuite/btcd => github.com/btcsuite/btcd v0.22.1 + github.com/go-kit/log => github.com/go-kit/log v0.2.1 + // replicating the replace directive on cosmos SDK github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 // until merged upstream: https://github.com/hashicorp/go-plugin/pull/257 - github.com/hashicorp/go-plugin => github.com/jmank88/go-plugin v0.0.0-20230604120638-7bb12ec27e75 + github.com/hashicorp/go-plugin => github.com/smartcontractkit/go-plugin v0.0.0-20230605132010-0f4d515d1472 + + // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 + github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f + + github.com/prometheus/prometheus => github.com/prometheus/prometheus v0.43.1-0.20230327151049-211ae4f1f0a2 + github.com/sercand/kuberesolver v2.4.0+incompatible => github.com/sercand/kuberesolver/v5 v5.1.0 ) diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 9bbc38d3ec1..187291d8510 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -18,54 +18,547 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= +cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= +cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= +cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= +cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= +cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= cloud.google.com/go v0.110.4 h1:1JYyxKMN9hd5dR2MYTPWkGUgcoxVVhg0LKNKEo0qvmk= +cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= +cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= +cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= +cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= +cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= +cloud.google.com/go/accesscontextmanager v1.6.0/go.mod h1:8XCvZWfYw3K/ji0iVnp+6pu7huxoQTLmxAbVjbloTtM= +cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= +cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= +cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= +cloud.google.com/go/aiplatform v1.35.0/go.mod h1:7MFT/vCaOyZT/4IIFfxH4ErVg/4ku6lKv3w0+tFTgXQ= +cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= +cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/analytics v0.18.0/go.mod h1:ZkeHGQlcIPkw0R/GW+boWHhCOR43xz9RN/jn7WcqfIE= +cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= +cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= +cloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8= +cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= +cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= +cloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8= +cloud.google.com/go/apigeeregistry v0.4.0/go.mod h1:EUG4PGcsZvxOXAdyEghIdXwAEi/4MEaoqLMLDMIwKXY= +cloud.google.com/go/apigeeregistry v0.5.0/go.mod h1:YR5+s0BVNZfVOUkMa5pAR2xGd0A473vA5M7j247o1wM= +cloud.google.com/go/apikeys v0.4.0/go.mod h1:XATS/yqZbaBK0HOssf+ALHp8jAlNHUgyfprvNcBIszU= +cloud.google.com/go/apikeys v0.5.0/go.mod h1:5aQfwY4D+ewMMWScd3hm2en3hCj+BROlyrt3ytS7KLI= +cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno= +cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= +cloud.google.com/go/appengine v1.6.0/go.mod h1:hg6i0J/BD2cKmDJbaFSYHFyZkgBEfQrDg/X0V5fJn84= +cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= +cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k= +cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= +cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= +cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= +cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= +cloud.google.com/go/artifactregistry v1.11.2/go.mod h1:nLZns771ZGAwVLzTX/7Al6R9ehma4WUEhZGWV6CeQNQ= +cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= +cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= +cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= +cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ= +cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= +cloud.google.com/go/asset v1.11.1/go.mod h1:fSwLhbRvC9p9CXQHJ3BgFeQNM4c9x10lqlrdEUYXlJo= +cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= +cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= +cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= +cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= +cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= +cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E= +cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= +cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= +cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= +cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= +cloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU= +cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= +cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= +cloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss= +cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= +cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= +cloud.google.com/go/batch v0.7.0/go.mod h1:vLZN95s6teRUqRQ4s3RLDsH8PvboqBK+rn1oevL159g= +cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= +cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= +cloud.google.com/go/beyondcorp v0.4.0/go.mod h1:3ApA0mbhHx6YImmuubf5pyW8srKnCEPON32/5hj+RmM= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= +cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= +cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= +cloud.google.com/go/bigquery v1.48.0/go.mod h1:QAwSz+ipNgfL5jxiaK7weyOhzdoAy1zFm0Nf1fysJac= +cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= +cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= +cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= +cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= +cloud.google.com/go/billing v1.12.0/go.mod h1:yKrZio/eu+okO/2McZEbch17O5CB5NpZhhXG6Z766ss= +cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= +cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= +cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= +cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= +cloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q= +cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= +cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= +cloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8= +cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= +cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= +cloud.google.com/go/channel v1.11.0/go.mod h1:IdtI0uWGqhEeatSB62VOoJ8FSUhJ9/+iGkJVqp74CGE= +cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= +cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= +cloud.google.com/go/cloudbuild v1.7.0/go.mod h1:zb5tWh2XI6lR9zQmsm1VRA+7OCuve5d8S+zJUul8KTg= +cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= +cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= +cloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA= +cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= +cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= +cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= +cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= +cloud.google.com/go/cloudtasks v1.9.0/go.mod h1:w+EyLsVkLWHcOaqNEyvcKAsWp9p29dL6uL9Nst1cI7Y= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= +cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= +cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= +cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= +cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= +cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg= +cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= +cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= +cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w= +cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= +cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= +cloud.google.com/go/container v1.13.1/go.mod h1:6wgbMPeQRw9rSnKBCAJXnds3Pzj03C4JHamr8asWKy4= +cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= +cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= +cloud.google.com/go/containeranalysis v0.7.0/go.mod h1:9aUL+/vZ55P2CXfuZjS4UjQ9AgXoSw8Ts6lemfmxBxI= +cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= +cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= +cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= +cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE= +cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= +cloud.google.com/go/datacatalog v1.8.1/go.mod h1:RJ58z4rMp3gvETA465Vg+ag8BGgBdnRPEMMSTr5Uv+M= +cloud.google.com/go/datacatalog v1.12.0/go.mod h1:CWae8rFkfp6LzLumKOnmVh4+Zle4A3NXLzVJ1d1mRm0= +cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= +cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE= +cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= +cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= +cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= +cloud.google.com/go/dataform v0.6.0/go.mod h1:QPflImQy33e29VuapFdf19oPbE4aYTJxr31OAPV+ulA= +cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= +cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= +cloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8= +cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= +cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM= +cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= +cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= +cloud.google.com/go/dataplex v1.5.2/go.mod h1:cVMgQHsmfRoI5KFYq4JtIBEUbYwc3c7tXmIDhRmNNVQ= +cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= +cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= +cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4= +cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= +cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= +cloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= +cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= +cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= +cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= +cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= +cloud.google.com/go/datastream v1.6.0/go.mod h1:6LQSuswqLa7S4rPAOZFVjHIG3wJIjZcZrw8JDEDJuIs= +cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= +cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= +cloud.google.com/go/deploy v1.6.0/go.mod h1:f9PTHehG/DjCom3QH0cntOVRm93uGBDt2vKzAPwpXQI= +cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= +cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= +cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= +cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek= +cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= +cloud.google.com/go/dialogflow v1.29.0/go.mod h1:b+2bzMe+k1s9V+F2jbJwpHPzrnIyHihAdRFMtn2WXuM= +cloud.google.com/go/dialogflow v1.31.0/go.mod h1:cuoUccuL1Z+HADhyIA7dci3N5zUssgpBJmCzI6fNRB4= +cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= +cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= +cloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4= +cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= +cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= +cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= +cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= +cloud.google.com/go/documentai v1.16.0/go.mod h1:o0o0DLTEZ+YnJZ+J4wNfTxmDVyrkzFvttBXXtYRMHkM= +cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= +cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE= +cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= +cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/edgecontainer v0.3.0/go.mod h1:FLDpP4nykgwwIfcLt6zInhprzw0lEi2P1fjO6Ie0qbc= +cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= +cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= +cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= +cloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M= +cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= +cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= +cloud.google.com/go/eventarc v1.10.0/go.mod h1:u3R35tmZ9HvswGRBnF48IlYgYeBcPUCjkr4BTdem2Kw= +cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= +cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= +cloud.google.com/go/filestore v1.5.0/go.mod h1:FqBXDWBp4YLHqRnVGveOkHDf8svj9r5+mUDLupOWEDs= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= +cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= +cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= +cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= +cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= +cloud.google.com/go/functions v1.10.0/go.mod h1:0D3hEOe3DbEvCXtYOZHQZmD+SzYsi1YbI7dGvHfldXw= +cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= +cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= +cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= +cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= +cloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0= +cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= +cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= +cloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg= +cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= +cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw= +cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= +cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +cloud.google.com/go/gkehub v0.11.0/go.mod h1:JOWHlmN+GHyIbuWQPl47/C2RFhnFKH38jH9Ascu3n0E= +cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= +cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= +cloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y= +cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= +cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= +cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= +cloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo= +cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= +cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= +cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= +cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= +cloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY= +cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= +cloud.google.com/go/iam v1.1.0 h1:67gSqaPukx7O8WLLHMa0PNs3EBGd2eE4d+psbO/CO94= +cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= +cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= +cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk= +cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= +cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= +cloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4= +cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= +cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= +cloud.google.com/go/iot v1.5.0/go.mod h1:mpz5259PDl3XJthEmh9+ap0affn/MqNSP4My77Qql9o= +cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= +cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= +cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= +cloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w= +cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= +cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= +cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= +cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= +cloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY= +cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= +cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= +cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo= +cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= +cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M= +cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= +cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= +cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= +cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= +cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= +cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA= +cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= +cloud.google.com/go/maps v0.6.0/go.mod h1:o6DAMMfb+aINHz/p/jbcY+mYeXBoZoxTfdSQ8VAJaCw= +cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= +cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I= +cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= +cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= +cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= +cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= +cloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM= +cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= +cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= +cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= +cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= +cloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo= +cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= +cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= +cloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w= +cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= +cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= +cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= +cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= +cloud.google.com/go/networkconnectivity v1.10.0/go.mod h1:UP4O4sWXJG13AqrTdQCD9TnLGEbtNRqjuaaA7bNjF5E= +cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= +cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= +cloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY= +cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= +cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/networksecurity v0.7.0/go.mod h1:mAnzoxx/8TBSyXEeESMy9OOYwo1v+gZ5eMRnsT5bC8k= +cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= +cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= +cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= +cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= +cloud.google.com/go/notebooks v1.7.0/go.mod h1:PVlaDGfJgj1fl1S3dUwhFMXFgfYGhYQt2164xOMONmE= +cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= +cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= +cloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI= +cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= +cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= +cloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ= +cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= +cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= +cloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc= +cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= +cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= +cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= +cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= +cloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw= +cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= +cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= +cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= +cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= +cloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs= +cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= +cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk= +cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= +cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= +cloud.google.com/go/policytroubleshooter v1.5.0/go.mod h1:Rz1WfV+1oIpPdN2VvvuboLVRsB1Hclg3CKQ53j9l8vw= +cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= +cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= +cloud.google.com/go/privatecatalog v0.7.0/go.mod h1:2s5ssIFO69F5csTXcwBP7NPFTZvps26xGzvQ2PQaBYg= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= +cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= +cloud.google.com/go/pubsub v1.28.0/go.mod h1:vuXFpwaVoIPQMGXqRyUQigu/AX1S3IWugR9xznmcXX8= +cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= +cloud.google.com/go/pubsublite v1.6.0/go.mod h1:1eFCS0U11xlOuMFV/0iBqw3zP12kddMeCbj/F3FSj9k= +cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= +cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= +cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= +cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= +cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE= +cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= +cloud.google.com/go/recaptchaenterprise/v2 v2.6.0/go.mod h1:RPauz9jeLtB3JVzg6nCbe12qNoaa8pXc4d/YukAmcnA= +cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= +cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac= +cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= +cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= +cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= +cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= +cloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ= +cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= +cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= +cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= +cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= +cloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ= +cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= +cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= +cloud.google.com/go/resourcemanager v1.5.0/go.mod h1:eQoXNAiAvCf5PXxWxXjhKQoTMaUSNrEfg+6qdf/wots= +cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= +cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= +cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA= +cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= +cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= +cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= +cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= +cloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14= +cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= +cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= +cloud.google.com/go/run v0.8.0/go.mod h1:VniEnuBwqjigv0A7ONfQUaEItaiCRVujlMqerPPiktM= +cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= +cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= +cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= +cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= +cloud.google.com/go/scheduler v1.8.0/go.mod h1:TCET+Y5Gp1YgHT8py4nlg2Sew8nUHMqcpousDgXJVQc= +cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= +cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= +cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= +cloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU= +cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= +cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= +cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= +cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q= +cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= +cloud.google.com/go/security v1.12.0/go.mod h1:rV6EhrpbNHrrxqlvW0BWAIawFWq3X90SduMJdFwtLB8= +cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= +cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= +cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= +cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= +cloud.google.com/go/securitycenter v1.18.1/go.mod h1:0/25gAzCM/9OL9vVx4ChPeM/+DlfGQJDwBy/UC8AKK0= +cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= +cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= +cloud.google.com/go/servicecontrol v1.11.0/go.mod h1:kFmTzYzTUIuZs0ycVqRHNaNhgR+UMUpw9n02l/pY+mc= +cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= +cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= +cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4= +cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= +cloud.google.com/go/servicedirectory v1.8.0/go.mod h1:srXodfhY1GFIPvltunswqXpVxFPpZjf8nkKQT7XcXaY= +cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= +cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= +cloud.google.com/go/servicemanagement v1.6.0/go.mod h1:aWns7EeeCOtGEX4OvZUWCCJONRZeFKiptqKf1D0l/Jc= +cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E= +cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= +cloud.google.com/go/serviceusage v1.5.0/go.mod h1:w8U1JvqUqwJNPEOTQjrMHkw3IaIFLoLsPLvsE3xueec= +cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= +cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= +cloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A= +cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= +cloud.google.com/go/spanner v1.44.0/go.mod h1:G8XIgYdOK+Fbcpbs7p2fiprDw4CaZX63whnSMLVBxjk= +cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= +cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= +cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= +cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= +cloud.google.com/go/speech v1.14.1/go.mod h1:gEosVRPJ9waG7zqqnsHpYTOoAS4KouMRLDFMekpJ0J0= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= +cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= +cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y= +cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM= +cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= +cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= +cloud.google.com/go/storagetransfer v1.7.0/go.mod h1:8Giuj1QNb1kfLAiWM1bN6dHzfdlDAVC9rv9abHot2W4= +cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= +cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= +cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= +cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= +cloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c= +cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= +cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= +cloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc= +cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= +cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= +cloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM= +cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= +cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= +cloud.google.com/go/trace v1.8.0/go.mod h1:zH7vcsbAhklH8hWFig58HvxcxyQbaIqMarMg9hn5ECA= +cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= +cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= +cloud.google.com/go/translate v1.6.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= +cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= +cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= +cloud.google.com/go/video v1.13.0/go.mod h1:ulzkYlYgCp15N2AokzKjy7MQ9ejuynOJdf1tR5lGthk= +cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= +cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= +cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= +cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= +cloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU= +cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= +cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= +cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= +cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY= +cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= +cloud.google.com/go/vision/v2 v2.6.0/go.mod h1:158Hes0MvOS9Z/bDMSFpjwsUrZ5fPrdwuyyvKSGAGMY= +cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= +cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= +cloud.google.com/go/vmmigration v1.5.0/go.mod h1:E4YQ8q7/4W9gobHjQg4JJSgXXSgY21nA5r8swQV+Xxc= +cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= +cloud.google.com/go/vmwareengine v0.2.2/go.mod h1:sKdctNJxb3KLZkE/6Oui94iw/xs9PRNC2wnNLXsHvH8= +cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= +cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= +cloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes= +cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= +cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= +cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= +cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= +cloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg= +cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= +cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= +cloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng= +cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= +cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= +cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= +cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= +cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= contrib.go.opencensus.io/exporter/stackdriver v0.12.6/go.mod h1:8x999/OcIPy5ivx/wDiV7Gx4D+VUPODf0mWRGRc5kSk= contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= contrib.go.opencensus.io/exporter/stackdriver v0.13.5 h1:TNaexHK16gPUoc7uzELKOU7JULqccn1NDuqUxmxSqfo= contrib.go.opencensus.io/exporter/stackdriver v0.13.5/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE= +cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= +cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= +cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= cosmossdk.io/errors v1.0.0 h1:nxF07lmlBbB8NKQhtJ+sJm6ef5uV1XkvPXG2bUntb04= cosmossdk.io/errors v1.0.0/go.mod h1:+hJZLuhdDE0pYN8HkOrVNwrIOYvUGnn6+4fjnJs/oV0= +cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca h1:msenprh2BLLRwNT7zN56TbBHOGk/7ARQckXHxXyvjoQ= cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= +cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= +gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= +git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo87o= github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic= github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI= github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE= github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/azure-sdk-for-go v65.0.0+incompatible h1:HzKLt3kIwMm4KeJYTdx9EbjRYTySD/t8i1Ee/W5EGXw= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= +github.com/Azure/go-autorest/autorest v0.11.28 h1:ndAExarwr5Y+GaHE6VCaY1kyS/HwwGGyuimVhWsHOEM= +github.com/Azure/go-autorest/autorest/adal v0.9.22 h1:/GblQdIudfEM3AWWZ0mrYJQSd7JS4S/Mbzh6F0ov0Xc= +github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= +github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk= +github.com/Azure/go-autorest/autorest/validation v0.3.1 h1:AgyqjAd94fwNAoTjl/WQXg4VvFeRFpO+UhNyRXqF1ac= +github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= +github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= @@ -74,13 +567,22 @@ github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1: github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= github.com/CosmWasm/wasmd v0.40.1 h1:LxbO78t/6S8TkeQlUrJ0m5O87HtAwLx4RGHq3rdrOEU= +github.com/CosmWasm/wasmd v0.40.1/go.mod h1:6EOwnv7MpuFaEqxcUOdFV9i4yvrdOciaY6VQ1o7A3yg= github.com/CosmWasm/wasmvm v1.2.4 h1:6OfeZuEcEH/9iqwrg2pkeVtDCkMoj9U6PpKtcrCyVrQ= +github.com/CosmWasm/wasmvm v1.2.4/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Depado/ginprom v1.7.11 h1:qOhxW/NJZkNkkG4TQrzAZklX8SUTjTfLA73zIUNIpww= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= +github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= +github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/K-Phoen/grabana v0.21.17 h1:mO/9DvJWC/qpTF/X5jQDm5eKgCBaCGypP/tEfXAvKfg= +github.com/K-Phoen/grabana v0.21.17/go.mod h1:vbASQt9UiQhX4lC3/opLpJMJ8m+hsTUU2FwkQMytHK4= +github.com/K-Phoen/sdk v0.12.2 h1:0QofDlKE+lloyBOzhjEEMW21061zts/WIpfpQ5NLLAs= +github.com/K-Phoen/sdk v0.12.2/go.mod h1:qmM0wO23CtoDux528MXPpYvS4XkRWkWX6rvX9Za8EVU= github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= @@ -88,36 +590,61 @@ github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0 github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/hcsshim v0.10.0-rc.8 h1:YSZVvlIIDD1UxQpJp0h+dnpLUw+TrY0cx8obKsp3bek= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.6 h1:U68crOE3y3MPttCMQGywZOLrTeF5HHJ3/vDBCJn9/bA= -github.com/OneOfOne/xxhash v1.2.6/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/VictoriaMetrics/fastcache v1.10.0 h1:5hDJnLsKLpnUEToub7ETuRu8RCkb40woBZAUiKonXzY= github.com/VictoriaMetrics/fastcache v1.10.0/go.mod h1:tjiYeEfYXCqacuvYw/7UoDIeJaNxq6132xHICNP77w8= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= +github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= +github.com/alecthomas/kingpin/v2 v2.3.1/go.mod h1:oYL5vtsvEHZGHxU7DMp32Dvx+qL+ptGn6lWaot2vCNE= +github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 h1:MzBOUgng9orim59UnfUTLRjMpd09C5uEVQ6RPGeCaVI= github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= +github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= -github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/avast/retry-go/v4 v4.3.4 h1:pHLkL7jvCvP317I8Ge+Km2Yhntv3SdkJm7uekkqbKhM= +github.com/avast/retry-go/v4 v4.3.4/go.mod h1:rv+Nla6Vk3/ilU0H51VHddWHiwimzX66yZ0JT6T+UvE= github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/aws/aws-sdk-go v1.44.276 h1:ywPlx9C5Yc482dUgAZ9bHpQ6onVvJvYE9FJWsNDCEy0= +github.com/aws/aws-sdk-go v1.44.276/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/constructs-go/constructs/v10 v10.1.255 h1:5hARfEmhBqHSTQf/C3QLA3sWOxO2Dfja0iA1W7ZcI7g= github.com/aws/constructs-go/constructs/v10 v10.1.255/go.mod h1:DCdBSjN04Ck2pajCacTD4RKFqSA7Utya8d62XreYctI= github.com/aws/jsii-runtime-go v1.75.0 h1:NhpUfyiL7/wsRuUekFsz8FFBCYLfPD/l61kKg9kL/a4= @@ -132,12 +659,15 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= +github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= @@ -158,11 +688,17 @@ github.com/bxcodec/faker v2.0.1+incompatible h1:P0KUpUw5w6WJXwrPfv35oc91i4d8nf40 github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= +github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee h1:BnPxIde0gjtTnc9Er7cxvBk8DHLWhEux0SxayC8dP6I= +github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M= github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.7.5 h1:rvc39Ol6z3MvaBzXkxFC6Nfsnixq/dRypushKDd7Nc0= github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.7.5/go.mod h1:R/pdNYDYFQk+tuuOo7QES1kkv6OLmp5ze2XBZQIVffM= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= @@ -186,6 +722,8 @@ github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObk github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/cli/go-gh/v2 v2.0.0 h1:JAgQY7VNHletsO0Eqr+/PzF7fF5QEjhY2t2+Tev3vmk= github.com/cli/go-gh/v2 v2.0.0/go.mod h1:2/ox3Dnc8wDBT5bnTAH1aKGy6Qt1ztlFBe10EufnvoA= github.com/cli/safeexec v1.0.0 h1:0VngyaIyqACHdcMNWfo6+KdUYnqEr2Sg+bSP1pdF+dI= @@ -195,10 +733,21 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= +github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA= github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= @@ -210,14 +759,18 @@ github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 h1:ytcWPaNPhNoG github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811/go.mod h1:Nb5lgvnQ2+oGlE/EyZy4+2/CxRh9KfvCXnag1vtpxVM= github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +github.com/coinbase/rosetta-sdk-go/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONNbHU7MuEHboiFuA= github.com/cometbft/cometbft v0.37.2 h1:XB0yyHGT0lwmJlFmM4+rsRnczPlHoAKFX6K8Zgc2/Jc= github.com/cometbft/cometbft v0.37.2/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= -github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= +github.com/containerd/containerd v1.7.3 h1:cKwYKkP1eTj54bP3wCdXXBymmKRQMrWjkLSWZZJDa8o= +github.com/containerd/containerd v1.7.3/go.mod h1:32FOM4/O0RkNg7AjQj3hDzN9cUGtu+HMvaKUNiqCZB8= +github.com/containerd/continuity v0.4.1 h1:wQnVrjIyQ8vhU2sgOiL5T07jo+ouqc2bnKsv5/EqGhU= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -227,6 +780,8 @@ github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmf github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.4.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= @@ -242,26 +797,36 @@ github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiK github.com/cosmos/gogoproto v1.4.10 h1:QH/yT8X+c0F4ZDacDv3z+xE3WU1P1Z3wQoLMBRJoKuI= github.com/cosmos/gogoproto v1.4.10/go.mod h1:3aAZzeRWpAwr+SS/LLkICX2/kDFyaYVzckBDzygIxek= github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= +github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= github.com/cosmos/ibc-go/v7 v7.0.1 h1:NIBNRWjlOoFvFQu1ZlgwkaSeHO5avf4C1YQiWegt8jw= +github.com/cosmos/ibc-go/v7 v7.0.1/go.mod h1:vEaapV6nuLPQlS+g8IKmxMo6auPi0i7HMv1PhViht/E= github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab h1:I9ialKTQo7248V827Bba4OuKPmk+FPzmTVHsLXaIJWw= +github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab/go.mod h1:2CwqasX5dSD7Hbp/9b6lhK6BwoBDCBldx7gPKRukR60= github.com/cosmos/ledger-cosmos-go v0.12.1 h1:sMBxza5p/rNK/06nBSNmsI/WDqI0pVJFVNihy1Y984w= github.com/cosmos/ledger-cosmos-go v0.12.1/go.mod h1:dhO6kj+Y+AHIOgAe4L9HL/6NDdyyth4q238I9yFpD2g= +github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzUGSKFTcM= +github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= +github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creachadair/taskgroup v0.4.2 h1:jsBLdAJE42asreGss2xZGZ8fJra7WtwnHWeJFxv2Li8= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= -github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= +github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= +github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= github.com/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e h1:5jVSh2l/ho6ajWhSPNN84eHEdq3dp0T7+f6r3Tc6hsk= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= @@ -271,6 +836,9 @@ github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5il github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE= +github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA= +github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/dfuse-io/logging v0.0.0-20201110202154-26697de88c79/go.mod h1:V+ED4kT/t/lKtH99JQmKIb0v9WL3VaYkJ36CfHlVECI= github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 h1:CuJS05R9jmNlUK8GOxrEELPbfXm0EuGh/30LjkjN5vo= github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70/go.mod h1:EoK/8RFbMEteaCaz89uessDTnCWjbbcr+DXcBh4el5o= @@ -290,8 +858,13 @@ github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUn github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/digitalocean/godo v1.97.0 h1:p9w1yCcWMZcxFSLPToNGXA96WfUVLXqoHti6GzVomL4= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= +github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v24.0.5+incompatible h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY= +github.com/docker/docker v24.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= @@ -300,10 +873,12 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= +github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ= +github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= -github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= -github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= +github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -311,7 +886,15 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= +github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI= +github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f h1:7T++XKzy4xg7PKy+bM+Sa9/oe1OC88yz2hXQUISoXfA= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= +github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= +github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/go-ethereum v1.12.0 h1:bdnhLPtqETd4m3mS8BGMNvBTf36bO5bx/hxE2zljOa0= @@ -335,11 +918,15 @@ github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYF github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= +github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 h1:u/UEqS66A5ckRmS4yNpjmVH56sVtS/RfclBAYocb4as= github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -356,6 +943,7 @@ github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9 github.com/gagliardetto/binary v0.6.1/go.mod h1:aOfYkc20U0deHaHn/LVZXiqlkDbFAX0FpTlDhsXa0S0= github.com/gagliardetto/binary v0.7.1 h1:6ggDQ26vR+4xEvl/S13NcdLK3MUCi4oSy73pS9aI1cI= github.com/gagliardetto/binary v0.7.1/go.mod h1:aOfYkc20U0deHaHn/LVZXiqlkDbFAX0FpTlDhsXa0S0= +github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= github.com/gagliardetto/gofuzz v1.2.2/go.mod h1:bkH/3hYLZrMLbfYWA0pWzXmi5TTRZnu4pMGZBkqMKvY= github.com/gagliardetto/solana-go v1.4.1-0.20220428092759-5250b4abbb27 h1:q2IztKyRQUxJ6abXRsawaBtvDFvM+szj4jDqV4od1gs= github.com/gagliardetto/solana-go v1.4.1-0.20220428092759-5250b4abbb27/go.mod h1:NFuoDwHPvw858ZMHUJr6bkhN8qHt4x6e+U3EYHxAwNY= @@ -378,24 +966,32 @@ github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NB github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= +github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= +github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= +github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -408,17 +1004,52 @@ github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= +github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= +github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= +github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= +github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= +github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= +github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro= +github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw= +github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= +github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= +github.com/go-openapi/spec v0.20.8 h1:ubHmXNY3FCIOinT8RNrrPfGc9t7I1qhPtdOGoG2AxRU= +github.com/go-openapi/spec v0.20.8/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= +github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= +github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= +github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= +github.com/go-openapi/strfmt v0.21.7 h1:rspiXgNWgeUzhjo1YU01do6qsahtJNByjLVbPLNHb8k= +github.com/go-openapi/strfmt v0.21.7/go.mod h1:adeGTkxE44sPyLk0JV235VQAO/ZXUr8KAzYjclFs3ew= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= +github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= +github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= +github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= @@ -433,10 +1064,41 @@ github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEe github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho= github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-webauthn/revoke v0.1.9 h1:gSJ1ckA9VaKA2GN4Ukp+kiGTk1/EXtaDb1YE8RknbS0= +github.com/go-webauthn/revoke v0.1.9/go.mod h1:j6WKPnv0HovtEs++paan9g3ar46gm1NarktkXBaPR+w= github.com/go-webauthn/webauthn v0.8.2 h1:8KLIbpldjz9KVGHfqEgJNbkhd7bbRXhNw4QWFJE15oA= +github.com/go-webauthn/webauthn v0.8.2/go.mod h1:d+ezx/jMCNDiqSMzOchuynKb9CVU1NM9BumOnokfcVQ= +github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg= +github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= +github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= +github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= +github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= +github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= +github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= +github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= +github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= +github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= +github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= +github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= +github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= +github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= +github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= +github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= +github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= @@ -447,13 +1109,19 @@ github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI= github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= +github.com/gogo/status v1.0.3/go.mod h1:SavQ51ycCLnc7dGyJxp8YAmudx8xqiVrRf+6IXRsugc= github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/gogo/status v1.1.1 h1:DuHXlSFHNKqTQ+/ACf5Vs6r4X/dH2EgIzR9Vr+H65kg= +github.com/gogo/status v1.1.1/go.mod h1:jpG3dM5QPcqu19Hg8lkUhBFBa3TcLs1DG7+2Jqci7oU= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -469,7 +1137,9 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -486,10 +1156,12 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= @@ -499,6 +1171,7 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -514,12 +1187,18 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/go-tpm v0.1.2-0.20190725015402-ae6dd98980d4/go.mod h1:H9HbmUG2YgV/PHITkO7p6wxEEj/v5nlsVWIwumwH2NI= +github.com/google/go-tpm v0.3.0/go.mod h1:iVLWvrPp/bHeEkxTFi9WG6K9w0iy2yIszHwZGHPbzAw= github.com/google/go-tpm v0.3.3 h1:P/ZFNBZYXRxc+z7i5uyd8VP7MaDteuLZInzrH2idRGo= +github.com/google/go-tpm v0.3.3/go.mod h1:9Hyn3rgnzWF9XBWVk6ml6A6hNkbWjNFlDQL51BeghL4= +github.com/google/go-tpm-tools v0.0.0-20190906225433-1614c142f845/go.mod h1:AVfHadzbdzHo54inR2x1v640jdi1YSi3NauM2DUsxk0= +github.com/google/go-tpm-tools v0.2.0/go.mod h1:npUd03rQ60lxN7tzeBJreG38RvWwme2N1reF/eeiBk4= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= @@ -531,6 +1210,9 @@ github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -541,10 +1223,16 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -552,29 +1240,63 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= +github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= +github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= +github.com/googleapis/gax-go/v2 v2.11.0 h1:9V9PWXEsWnPpQhu/PeQIkS4eGzMlTLGgt80cUUI8Ki4= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gophercloud/gophercloud v1.2.0 h1:1oXyj4g54KBg/kFtCdMM6jtxSzeIyg8wv4z1HoGPp1E= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/rpc v1.2.0/go.mod h1:V4h9r+4sF5HnzqbwIez0fKSpANP0zlYd3qR7p36jkTQ= github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI= github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gosimple/slug v1.13.1 h1:bQ+kpX9Qa6tHRaK+fZR0A0M2Kd7Pa5eHPPsb1JpHD+Q= +github.com/gosimple/slug v1.13.1/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ= +github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6T/o= +github.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc= +github.com/grafana/dskit v0.0.0-20230201083518-528d8a7d52f2 h1:IOks+FXJ6iO/pfbaVEf4efNw+YzYBYNCkCabyrbkFTM= +github.com/grafana/dskit v0.0.0-20230201083518-528d8a7d52f2/go.mod h1:zj+5BNZAVmQafV583uLTAOzRr963KPdEm4d6NPmtbwg= +github.com/grafana/loki v1.6.2-0.20230403212622-90888a0cc737 h1:o45+fZAYRtTjx+9fFml9LZxsCmLX65l39eWDgvdkIr0= +github.com/grafana/loki v1.6.2-0.20230403212622-90888a0cc737/go.mod h1:kxNnWCr4EMobhndjy7a2Qpm7jkLPnJW2ariYvY77hLE= +github.com/grafana/loki/pkg/push v0.0.0-20230127102416-571f88bc5765 h1:VXitROTlmZtLzvokNe8ZbUKpmwldM4Hy1zdNRO32jKU= +github.com/grafana/loki/pkg/push v0.0.0-20230127102416-571f88bc5765/go.mod h1:DhJMrd2QInI/1CNtTN43BZuTmkccdizW1jZ+F6aHkhY= +github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww= +github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug= github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0 h1:mdLirNAJBxnGgyB6pjZLcs6ue/6eZGBui6gXspfq4ks= github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0/go.mod h1:kdXbOySqcQeTxiqglW7aahTmWZy3Pgi6SYL36yvKeyA= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 h1:o95KDiV/b1xdkumY5YbLR0/n2+wBxUpgf3HgfKgTyLI= @@ -583,6 +1305,9 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= +github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= @@ -593,27 +1318,47 @@ github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIv github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/api v1.21.0 h1:WMR2JiyuaQWRAMFaOGiYfY4Q4HRpyYRe/oYQofjyduM= +github.com/hashicorp/consul/api v1.21.0/go.mod h1:f8zVJwBcLdr1IQnfdfszjUM0xzp31Zl3bpws3pL9uFM= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.13.1 h1:EygWVWWMczTzXGpO93awkHFzfUka6hLYJ0qhETd+6lY= +github.com/hashicorp/cronexpr v1.1.1 h1:NJZDd87hGXjoZBdvyCF9mX4DCq5Wy7+A/w+A7q0wn6c= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-hclog v1.4.0 h1:ctuWFGrhFha8BnnzxqeRGidlEcQkDyL5u8J8t5eA11I= -github.com/hashicorp/go-hclog v1.4.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-getter v1.7.1 h1:SWiSWN/42qdpR0MdhaOc/bLR48PLuP1ZQtYLRlM69uY= +github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= +github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= +github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -625,33 +1370,46 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= +github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= +github.com/hashicorp/nomad/api v0.0.0-20230308192510-48e7d70fcd4b h1:EkuSTU8c/63q4LMayj8ilgg/4I5PXDFVcnqKfs9qcwI= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= +github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce h1:7UnVY3T/ZnHUrfviiAgIUjg2PXxsQfs5bphsG8F7Keo= github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hdevalence/ed25519consensus v0.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7HsjsjeEZ6auqU= github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= github.com/henvic/httpretty v0.0.6 h1:JdzGzKZBajBfnvlMALXXMVQWxWMF/ofTy8C3/OSUTxs= +github.com/hetznercloud/hcloud-go v1.41.0 h1:KJGFRRc68QiVu4PrEP5BmCQVveCP2CM26UGQUKGpIUs= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.2 h1:TXKcSGc2WaxPD2+bmzAsVthL4+pEN0YwXcL5qED83vk= github.com/holiman/uint256 v1.2.2/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= +github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw= +github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= -github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= +github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/ionos-cloud/sdk-go/v6 v6.1.4 h1:BJHhFA8Q1SZC7VOXqKKr2BV2ysQ2/4hlk1e4hZte7GY= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= @@ -764,13 +1522,16 @@ github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0 github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= -github.com/jmank88/go-plugin v0.0.0-20230604120638-7bb12ec27e75 h1:KYTOmcwuezD27O7vNF15lj8H7imCBMXCq1RzCdj4e3A= -github.com/jmank88/go-plugin v0.0.0-20230604120638-7bb12ec27e75/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -780,37 +1541,52 @@ github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= +github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= +github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= -github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= github.com/koron/go-ssdp v0.0.2 h1:fL3wAoyT6hXHQlORyXUW4Q23kkQpJRgEAYcZB5BR71o= github.com/koron/go-ssdp v0.0.2/go.mod h1:XoLfkAiA2KeZsYh4DbHxD7h3nR2AZNqVQOa+LJuqPYs= @@ -832,6 +1608,7 @@ github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awS github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a h1:dHCfT5W7gghzPtfsW488uPmEOm85wewI+ypUwibyTdU= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -1047,20 +1824,29 @@ github.com/libp2p/go-yamux/v2 v2.0.0 h1:vSGhAy5u6iHBq11ZDcyHH4Blcf9xlBhT4WQDoOE9 github.com/libp2p/go-yamux/v2 v2.0.0/go.mod h1:NVWira5+sVUIU6tu1JWvaRn1dRnG+cawOJiflsAM+7U= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= +github.com/linode/linodego v1.14.1 h1:uGxQyy0BidoEpLGdvfi4cPgEW+0YUFsEGrLEhcTfjNc= github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f h1:tVvGiZQFjOXP+9YyGqSA6jE55x1XVxmoPYudncxrZ8U= +github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -1088,6 +1874,7 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -1098,39 +1885,55 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= +github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= +github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= +github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= +github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo= +github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI= -github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= +github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= +github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -1140,6 +1943,9 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 h1:mPMvm6X6tf4w8y7j9YIt6V9jfWhL6QlbEc7CCmeQlWk= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1/go.mod h1:ye2e/VUEtE2BHE+G/QcKkcLQVAEJoYRFj5VUOQatCRE= github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= @@ -1210,6 +2016,7 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= @@ -1222,6 +2029,7 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= +github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= @@ -1247,25 +2055,43 @@ github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9 github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/image-spec v1.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= +github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= github.com/opencontainers/runc v1.1.7 h1:y2EZDS8sNng4Ksf0GUYNhKbTShZJPJg1FiXJNH/uoCk= +github.com/opencontainers/runc v1.1.7/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50= +github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02/go.mod h1:JNdpVEzCpXBgIiv4ds+TzhN1hrtxq6ClLrTlT9OQRSc= +github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e h1:4cPxUYdgaGzZIT5/j0IfqOrrXmq6bG8AwvwisMXpdrg= +github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e/go.mod h1:DYR5Eij8rJl8h7gblRrOZ8g0kW1umSpKqYIBTgeDtLo= +github.com/opentracing-contrib/go-stdlib v0.0.0-20190519235532-cf7a6c988dc9/go.mod h1:PLldrQSroqzH70Xl+1DQcGnefIbqsKR7UDaiux3zV+w= +github.com/opentracing-contrib/go-stdlib v1.0.0 h1:TBS7YuVotp8myLon4Pv7BtCBzOTo1DeZCld0Z63mW2w= +github.com/opentracing-contrib/go-stdlib v1.0.0/go.mod h1:qtI1ogk+2JhVPIXVc6q+NHziSmy2W5GbdQZFUHADCBU= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= +github.com/ovh/go-ovh v1.3.0 h1:mvZaddk4E4kLcXhzb+cxBsMPYp2pHqiQpWYkInsuZPQ= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= -github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0= +github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 h1:hDSdbBuw3Lefr6R18ax0tZ2BJeNB3NehB3trOwYBsdU= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= +github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= +github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= +github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -1273,40 +2099,79 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/pressly/goose/v3 v3.5.3 h1:lIQIIXVbdO2RuQtJBS1e7MZjKEk0demVWt6i0YPiOrg= +github.com/pressly/goose/v3 v3.15.0 h1:6tY5aDqFknY6VZkorFGgZtWygodZQxfmmEF4rqyJW9k= +github.com/prometheus/alertmanager v0.25.0 h1:vbXKUR6PYRiZPRIKfmXaG+dmCKG52RtPL4Btl8hQGvg= +github.com/prometheus/alertmanager v0.25.0/go.mod h1:MEZ3rFVHqKZsw7IcNS/m4AWZeXThmJhumpiWR4eHU/w= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4= +github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI= +github.com/prometheus/exporter-toolkit v0.8.2/go.mod h1:00shzmJL7KxcsabLWcONwpyNEuWhREOnFqZW7vadFS0= +github.com/prometheus/exporter-toolkit v0.10.0 h1:yOAzZTi4M22ZzVxD+fhy1URTuNRj/36uQJJ5S8IPza8= +github.com/prometheus/exporter-toolkit v0.10.0/go.mod h1:+sVFzuvV5JDyw+Ih6p3zFxZNVnKQa3x5qPmDSiPu4ZY= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk= github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= -github.com/prometheus/prometheus v0.45.0 h1:O/uG+Nw4kNxx/jDPxmjsSDd+9Ohql6E7ZSY1x5x/0KI= +github.com/prometheus/prometheus v0.43.1-0.20230327151049-211ae4f1f0a2 h1:i5hmbBzR+VeL5pPl1ZncsJ1bpg3SO66bwkE1msJBsMA= +github.com/prometheus/prometheus v0.43.1-0.20230327151049-211ae4f1f0a2/go.mod h1:Mm42Acga98xgA+u5yTaC3ki3i0rJEJWFpbdHN7q2trk= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/pyroscope-io/client v0.7.1 h1:yFRhj3vbgjBxehvxQmedmUWJQ4CAfCHhn+itPsuWsHw= github.com/pyroscope-io/client v0.7.1/go.mod h1:4h21iOU4pUOq0prKyDlvYRL+SCKsBc5wKiEtV+rJGqU= -github.com/pyroscope-io/godeltaprof v0.1.0 h1:UBqtjt0yZi4jTxqZmLAs34XG6ycS3vUTlhEUSq4NHLE= -github.com/pyroscope-io/godeltaprof v0.1.0/go.mod h1:psMITXp90+8pFenXkKIpNhrfmI9saQnPbba27VIaiQE= +github.com/pyroscope-io/godeltaprof v0.1.2 h1:MdlEmYELd5w+lvIzmZvXGNMVzW2Qc9jDMuJaPOR75g4= +github.com/pyroscope-io/godeltaprof v0.1.2/go.mod h1:psMITXp90+8pFenXkKIpNhrfmI9saQnPbba27VIaiQE= +github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= +github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -1314,34 +2179,42 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= +github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= -github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc= -github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU= +github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= +github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= +github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.14 h1:yFl3jyaSVLNYXlnNYM5z2pagEk1dYQhfr1p20T1NyKY= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/scylladb/go-reflectx v1.0.1 h1:b917wZM7189pZdlND9PbIJ6NQxfDPfBvUaQ7cjj1iZQ= github.com/scylladb/go-reflectx v1.0.1/go.mod h1:rWnOfDIRWBGN0miMLIcoPt/Dhi2doCMZqwMCJ3KupFc= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sercand/kuberesolver/v5 v5.1.0 h1:YLqreB1vUFbZHSidcqI5ChMp+RIRmop0brQOeUFWiRw= +github.com/sercand/kuberesolver/v5 v5.1.0/go.mod h1:Fs1KbKhVRnB2aDWN12NjKCB+RgYMWZJ294T3BtmVCpQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= @@ -1354,33 +2227,46 @@ github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5g github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ= github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumvbfM1u/etVq42Afwq/jtNSBSOA8n5jntnNPo= github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230725012331-9007d9fb0d7b h1:vh4N/K+TMG8oV7L2i4U8q5aMjlVgf5M8TAZJCsXUh4U= -github.com/smartcontractkit/chainlink-env v0.35.0 h1:bjF+OOqWJUEIGmoiOZ6k1D4q6J6S/MqD269m37u0Ub8= -github.com/smartcontractkit/chainlink-env v0.35.0/go.mod h1:hMOkTDW5k0C5B5lup1+xpPiZQPkq84YGLuFDVdTKU7A= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230620171700-bbcb3a99b7d3 h1:rlNWHk15A2im/e9U95q4AkHZk5Wbc77lpx6ys4kUyCE= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230620171700-bbcb3a99b7d3/go.mod h1:MfZBUifutkv3aK7abyw5YmTJbqt8iFwcQDFikrxC/uI= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230612131011-369bfb503592 h1:3Ul/LkULxrolCVguHUFnWJamgUDsSGISlm/DzclstmE= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230622060316-7ce48476dd7d h1:4jSCp6i/p/EIaAkYQDxPK8nXDuv0fBXzKIcVYzetCoI= -github.com/smartcontractkit/chainlink-testing-framework v1.14.0 h1:XJSE2xnXCij1Pdnykg1YUeFwfuaDQmpiMHQmygf2xYk= -github.com/smartcontractkit/chainlink-testing-framework v1.14.0/go.mod h1:Wio/JS9GuEAWOI0k46sUs4+/wLMZnZKz9IwCpdV/miY= -github.com/smartcontractkit/libocr v0.0.0-20230724105022-c5e49b4195ac h1:ugouvLyN5D2AeztWrByENx08cx0phkxxvfP+AkBv3NI= -github.com/smartcontractkit/libocr v0.0.0-20230724105022-c5e49b4195ac/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= -github.com/smartcontractkit/ocr2keepers v1.0.0-alpha.0 h1:zkXsh4MAARNXqUlsMPBzVtFVV7SN93SxQ3KfCicnans= -github.com/smartcontractkit/ocr2keepers v1.0.0-alpha.0/go.mod h1:13Q6zuYWLByKXzzcSoi7L01bT8OzxM//XgMZQeCZVP0= -github.com/smartcontractkit/ocr2vrf v0.0.0-20230616201444-d8b4222aff3c h1:BX1ibMdGE2QdD8rJEI5nxE4jA6v2bf7LULrSbDrNM+A= -github.com/smartcontractkit/ocr2vrf v0.0.0-20230616201444-d8b4222aff3c/go.mod h1:AT1OrDDOCd8vzmMsCnA70N+tZdq9AbdZAiAw+gQq260= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230824124058-9b063c470048 h1:OHj8qzXajBAIT9TBnHN5LVGoCxvso/4JgCeg/l76Tgk= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230824124058-9b063c470048/go.mod h1:xMwqRdj5vqYhCJXgKVqvyAwdcqM6ZAEhnwEQ4Khsop8= +github.com/smartcontractkit/chainlink-env v0.36.0 h1:CFOjs0c0y3lrHi/fl5qseCH9EQa5W/6CFyOvmhe2VnA= +github.com/smartcontractkit/chainlink-env v0.36.0/go.mod h1:NbRExHmJGnKSYXmvNuJx5VErSx26GtE1AEN/CRzYOg8= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230824125819-215fd09979a2 h1:z9PIgm0klhunwPy+KZYR4E9vCpjgJaMOyQRLCYgfoLk= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230824125819-215fd09979a2/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230802143301-165000751a85 h1:/fm02hYSUdhbSh7xPn7os9yHj7dnl8aLs2+nFXPiB4g= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230802143301-165000751a85/go.mod h1:H3/j2l84FsxYevCLNERdVasI7FVr+t2mkpv+BCJLSVw= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230802150127-d2c95679d61a h1:b3rjvZLpTV45TmCV+ALX+EDDslf91pnDUugP54Lu9FA= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230802150127-d2c95679d61a/go.mod h1:LL+FLf10gOUHrF3aUsRGEZlT/w8DaW5T/eEo/54W68c= +github.com/smartcontractkit/chainlink-testing-framework v1.16.0 h1:jLpqwqaTpJXQvTJ1IXTomcCToOdrSCe4+IGcLXGsmD0= +github.com/smartcontractkit/chainlink-testing-framework v1.16.0/go.mod h1:t6FJX3akEfAO31p96ru0ilNPfE9P2UshUlXTIkI58LM= +github.com/smartcontractkit/go-plugin v0.0.0-20230605132010-0f4d515d1472 h1:x3kNwgFlDmbE/n0gTSRMt9GBDfsfGrs4X9b9arPZtFI= +github.com/smartcontractkit/go-plugin v0.0.0-20230605132010-0f4d515d1472/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0= +github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= +github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= +github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 h1:rzbqGoScs9VHGnyCKF7AoQEuUfwJnzcKmGIfaczeanA= +github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= +github.com/smartcontractkit/ocr2keepers v0.7.17 h1:847GG2SHyHIPc3yu+dhB+1HfeLRhSjyiKnhw3umpoJw= +github.com/smartcontractkit/ocr2keepers v0.7.17/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0= +github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 h1:NwC3SOc25noBTe1KUQjt45fyTIuInhoE2UfgcHAdihM= +github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687/go.mod h1:YYZq52t4wcHoMQeITksYsorD+tZcOyuVU5+lvot3VFM= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb h1:OMaBUb4X9IFPLbGbCHsMU+kw/BPCrewaVwWGIBc0I4A= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb/go.mod h1:HNUu4cJekUdsJbwRBCiOybtkPJEfGRELQPe2tkoDEyk= -github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230616141813-ca0ecf03ca5c h1:B7jWegIHCHXY32qWGwlNalrJYSz4uZh5zAgd2rQ3Iyc= -github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230625174811-4934857d1c4a h1:/ZJnNxcdJ75yDJHnKMjd3G9oZ6lcQRvFUdmiR2DPAgQ= +github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230823081604-f2a0e6b108bb h1:xNLGJcARfz9HCUKla6wH0gmwsG1/FTAWWeOplW2J72A= +github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230823081604-f2a0e6b108bb/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= +github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230823081604-f2a0e6b108bb h1:jyhgdafuZsex+kEHDIgq8o8wuVoPTr9wsGmuBtcFbEk= +github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230823081604-f2a0e6b108bb/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw= +github.com/smartcontractkit/wasp v0.3.0 h1:mueeLvpb6HyGNwILxCOKShDR6q18plQn7Gb1j3G/Qkk= +github.com/smartcontractkit/wasp v0.3.0/go.mod h1:skquNdMbKxIrHi5O8Kyukf66AaaXuEpEEaSTxfHbhak= github.com/smartcontractkit/wsrpc v0.7.2 h1:iBXzMeg7vc5YoezIQBq896y25BARw7OKbhrb6vPbtRQ= github.com/smartcontractkit/wsrpc v0.7.2/go.mod h1:sj7QX2NQibhkhxTfs3KOhAj/5xwgqMipTvJVSssT9i0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -1394,12 +2280,17 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk= github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= @@ -1410,6 +2301,7 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= @@ -1435,7 +2327,6 @@ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1F github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= @@ -1453,15 +2344,19 @@ github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 h1:3SNcvBmEPE1YlB github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0= github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE= github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU= +github.com/testcontainers/testcontainers-go v0.23.0 h1:ERYTSikX01QczBLPZpqsETTBO7lInqEP349phDOVJVs= +github.com/testcontainers/testcontainers-go v0.23.0/go.mod h1:3gzuZfb7T9qfcH2pHpV4RLlWrPjeWNQah6XlYQ32c4I= github.com/theodesp/go-heaps v0.0.0-20190520121037-88e35354fe0a h1:YuO+afVc3eqrjiCUizNCxI53bl/BnPiVwXqLzqYTqgU= github.com/theodesp/go-heaps v0.0.0-20190520121037-88e35354fe0a/go.mod h1:/sfW47zCZp9FrtGcWyo1VjbgDaodxX9ovZvgLb/MxaA= github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e h1:BuzhfgfWQbX0dWzYzT1zsORLnHRv3bcRcsaUk0VmXA8= github.com/tidwall/btree v1.6.0 h1:LDZfKfQIBHGHWSwckhXI0RPSXzlo+KYdjK7FWSqOzzg= +github.com/tidwall/btree v1.6.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= github.com/tidwall/gjson v1.9.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= @@ -1470,23 +2365,31 @@ github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +github.com/uber/jaeger-client-go v2.28.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= +github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= +github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= github.com/ulule/limiter/v3 v3.11.2 h1:P4yOrxoEMJbOTfRJR2OzjL90oflzYPPmWg+dvwN2tHA= github.com/umbracle/ethgo v0.1.3 h1:s8D7Rmphnt71zuqrgsGTMS5gTNbueGO1zKLh7qsFzTM= github.com/umbracle/ethgo v0.1.3/go.mod h1:g9zclCLixH8liBI27Py82klDkW7Oo33AxUOr+M9lzrU= github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 h1:10Nbw6cACsnQm7r34zlpJky+IzxVLRk6MKTS2d3Vp0E= github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722/go.mod h1:c8J0h9aULj2i3umrfyestM6jCq0LK0U6ly6bWy96nd4= github.com/unrolled/secure v1.13.0 h1:sdr3Phw2+f8Px8HE5sd1EHdj1aV3yUwed/uZXChLFsk= -github.com/urfave/cli v1.22.13 h1:wsLILXG8qCJNse/qAgLNf23737Cx05GflHg/PJGe1Ok= +github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bCzK15ozrqo2sZxkh0FHynJZOTVoV6Q= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= @@ -1496,6 +2399,11 @@ github.com/valyala/fastjson v1.4.1/go.mod h1:nV6MsjxL2IMJQUoHDIrjEI7oLyeqK6aBD7E github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs= +github.com/weaveworks/common v0.0.0-20221201103051-7c2720a9024d h1:9Z/HiqeGN+LOnmotAMpFEQjuXZ4AGAVFG0rC1laP5Go= +github.com/weaveworks/common v0.0.0-20221201103051-7c2720a9024d/go.mod h1:Fnq3+U51tMkPRMC6Wr7zKGUeFFYX4YjNrNK50iU0fcE= +github.com/weaveworks/promrus v1.2.0 h1:jOLf6pe6/vss4qGHjXmGz4oDJQA+AOCqEL3FvvZGz7M= +github.com/weaveworks/promrus v1.2.0/go.mod h1:SaE82+OJ91yqjrE1rsvBWVzNZKcHYFtMUyS1+Ogs/KA= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= @@ -1507,15 +2415,22 @@ github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go. github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= +github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= +github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk= github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= @@ -1524,11 +2439,14 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= @@ -1547,6 +2465,17 @@ go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYr go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.etcd.io/etcd/api/v3 v3.5.7 h1:sbcmosSVesNrWOJ58ZQFitHMdncusIifYcrBfwrlJSY= +go.etcd.io/etcd/api/v3 v3.5.7/go.mod h1:9qew1gCdDDLu+VwmeG+iFpL+QlpHTo7iubavdVDgCAA= +go.etcd.io/etcd/client/pkg/v3 v3.5.7 h1:y3kf5Gbp4e4q7egZdn5T7W9TSHUvkClN6u+Rq9mEOmg= +go.etcd.io/etcd/client/pkg/v3 v3.5.7/go.mod h1:o0Abi1MK86iad3YrWhgUsbGx1pmTS+hrORWc2CamuhY= +go.etcd.io/etcd/client/v3 v3.5.7 h1:u/OhpiuCgYY8awOHlhIhmGIGpxfBU/GZBUP3m/3/Iz4= +go.etcd.io/etcd/client/v3 v3.5.7/go.mod h1:sOWmj9DZUMyAngS7QQwCyAXXAL6WhgTOPLNS/NabQgw= +go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= +go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= +go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= +go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y= +go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= @@ -1554,10 +2483,13 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 h1:ZOLJc06r4CB42laIXg/7udr0pbZyuAihN10A/XuiQRY= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0/go.mod h1:5z+/ZWJQKXa9YT34fQNx5K8Hd1EoIhvtUygUQPqEOgQ= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 h1:pginetY7+onl4qN1vl0xW/V/v6OBZ0vVdH+esuJgvmM= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0/go.mod h1:XiYsayHc36K3EByOO6nbAXnAWbrUxdjUROCEeeROOH8= go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= @@ -1567,11 +2499,14 @@ go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.starlark.net v0.0.0-20220817180228-f738f5508c12 h1:xOBJXWGEDwU5xSDxH6macxO11Us0AH2fTa9rmsbbF7g= go.starlark.net v0.0.0-20220817180228-f738f5508c12/go.mod h1:VZcBMdr3cT3PnBoWunTabuSEXwVAH+ZJ5zxfs3AdASk= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= 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= @@ -1579,6 +2514,7 @@ go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0 go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -1595,8 +2531,9 @@ go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= +go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.4.0 h1:A8WCeEWhLwPBKNbFi5Wv5UTCBx5zzubnXDlMOFAzFMc= golang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= @@ -1608,6 +2545,7 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -1616,11 +2554,13 @@ golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -1635,23 +2575,41 @@ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20221012134737-56aed061732a/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb h1:xIApU0ow1zwMa2uL1VDNeQlNVFTWMQxZUZCMDy0Q4Us= -golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw= +golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1676,7 +2634,12 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1696,12 +2659,15 @@ golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1724,20 +2690,45 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1747,13 +2738,33 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= +golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1761,7 +2772,11 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1782,10 +2797,12 @@ golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1794,6 +2811,7 @@ golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1801,6 +2819,7 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1815,6 +2834,8 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1824,46 +2845,82 @@ golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210629170331-7dc0b73dc9fb/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= -golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1873,36 +2930,50 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181130052023-1c3d964395ce/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1940,6 +3011,7 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -1947,9 +3019,16 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 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.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1958,11 +3037,23 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= +gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= +gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= gonum.org/v1/gonum v0.13.0 h1:a0T3bh+7fhRyqeNbiC3qVHYmkiQgit3wnNan/2c0HMM= gonum.org/v1/gonum v0.13.0/go.mod h1:/WPYRckkfWrhWefxyYTfrTtQR0KH4iyHNuzxqXAKyAU= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= +gonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1983,6 +3074,43 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513 google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= +google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= +google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= +google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= +google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= +google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= +google.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= +google.golang.org/api v0.126.0 h1:q4GJq+cAdMAC7XP7njvQ4tvohGLiSlytuL4BQxbIZ+o= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2017,6 +3145,7 @@ google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -2033,9 +3162,97 @@ google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= +google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= +google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= +google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= +google.golang.org/genproto v0.0.0-20221109142239-94d6d90a7d66/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221201204527-e3fa12d562f3/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= +google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230112194545-e10362b5ecf9/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230113154510-dbe35b8444a5/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230127162408-596548ed4efa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= +google.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 h1:Au6te5hbKUV8pIYWHqOUZ1pva5qK/rwbIhoXEUB9Lu8= google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y= google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529 h1:s5YSX+ZH5b5vS9rnpGymvIyMpLRJizowqDlOuyjXnTk= @@ -2045,6 +3262,7 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go. google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= @@ -2064,11 +3282,31 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI= -google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= +google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/grpc/examples v0.0.0-20210424002626-9572fd6faeae/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -2083,12 +3321,16 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -2097,6 +3339,7 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/guregu/null.v2 v2.1.2 h1:YOuepWdYqGnrenzPyMi+ybCjeDzjdazynbwsXXOk4i8= +gopkg.in/guregu/null.v2 v2.1.2/go.mod h1:XORrx8tyS5ZDcyUboCIxQtta/Aujk/6pfWrn9Xe33mU= gopkg.in/guregu/null.v4 v4.0.0 h1:1Wm3S1WEA2I26Kq+6vcW+w0gcDo44YKYD7YIEJNHDjg= gopkg.in/guregu/null.v4 v4.0.0/go.mod h1:YoQhUrADuG3i9WqesrCmpNRwm1ypAgSHYqoOcTu/JrI= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= @@ -2121,18 +3364,19 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -2141,26 +3385,63 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= k8s.io/api v0.25.11 h1:4mjYDfE3yp22jrytjH0knwgzjXKkxHX4D01ZCAazvZM= k8s.io/api v0.25.11/go.mod h1:bK4UvD4bthtutNlvensrfBX21PRQ/vs2cIYggHkOOAo= k8s.io/apiextensions-apiserver v0.25.3 h1:bfI4KS31w2f9WM1KLGwnwuVlW3RSRPuIsfNF/3HzR0k= k8s.io/apiextensions-apiserver v0.25.3/go.mod h1:ZJqwpCkxIx9itilmZek7JgfUAM0dnTsA48I4krPqRmo= -k8s.io/apimachinery v0.25.11 h1:2EhfdrSAMvBxsswvOGCEymKk4ZnHZkranuZqdR0rsO4= -k8s.io/apimachinery v0.25.11/go.mod h1:IFwbcNi3gKkfDhuy0VYu3+BwbxbiIov3p6FR8ge1Epc= +k8s.io/apimachinery v0.26.2 h1:da1u3D5wfR5u2RpLhE/ZtZS2P7QvDgLZTi9wrNZl/tQ= +k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= k8s.io/cli-runtime v0.25.11 h1:GE2yNZm1tN+MJtw1SGMOLesLF7Kp7NVAVqRSTbXfu4o= k8s.io/cli-runtime v0.25.11/go.mod h1:r/nEINuHVEpgGhcd2WamU7hD1t/lMnSz8XM44Autltc= k8s.io/client-go v0.25.11 h1:DJQ141UsbNRI6wYSlcYLP5J5BW5Wq7Bgm42Ztq2SW70= k8s.io/client-go v0.25.11/go.mod h1:41Xs7p1SfhoReUnmjjYCfCNWFiq4xSkexwJfbxF2F7A= -k8s.io/component-base v0.25.11 h1:3QmISCE9n9CJkVpTA4spQO1IZCrLlOwbKdzSN9dqZZA= -k8s.io/component-base v0.25.11/go.mod h1:wFR4pfB+xTc6FBak+RoWRNeTmelGE4XWJP/xVOvn3vM= -k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= -k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= -k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= +k8s.io/component-base v0.26.2 h1:IfWgCGUDzrD6wLLgXEstJKYZKAFS2kO+rBRi0p3LqcI= +k8s.io/component-base v0.26.2/go.mod h1:DxbuIe9M3IZPRxPIzhch2m1eT7uFrSBJUBuVCQEBivs= +k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= +k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20230303024457-afdc3dddf62d h1:VcFq5n7wCJB2FQMCIHfC+f+jNcGgNMar1uKd6rVlifU= +k8s.io/kube-openapi v0.0.0-20230303024457-afdc3dddf62d/go.mod h1:y5VtZWM9sHHc2ZodIH/6SHzXj+TPU5USoA8lcIeKEKY= k8s.io/kubectl v0.25.11 h1:6bsft5Gan6BCvQ7cJbDRFjTm4Zfq8GuUYpsWAdVngYE= k8s.io/kubectl v0.25.11/go.mod h1:8mIfgkFgT+yJ8/TlmPW1qoRh46H2si9q5nW8id7i9iM= -k8s.io/utils v0.0.0-20221107191617-1a15be271d1d h1:0Smp/HP1OH4Rvhe+4B8nWGERtlqAGSftbSbbmm45oFs= -k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20230308161112-d77c459e9343 h1:m7tbIjXGcGIAtpmQr7/NAi7RsWoW3E7Zcm4jI1HicTc= +k8s.io/utils v0.0.0-20230308161112-d77c459e9343/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= +modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= +modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws= +modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo= +modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= +modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= +modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= +modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A= +modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU= +modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= +modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= +modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0= +modernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s= +modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= +modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= +modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= +modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= +modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= +modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= +modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= +nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= @@ -2169,8 +3450,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= -sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= -sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/kustomize/api v0.12.1 h1:7YM7gW3kYBwtKvoY216ZzY+8hM+lV53LUayghNRJ0vM= sigs.k8s.io/kustomize/api v0.12.1/go.mod h1:y3JUhimkZkR6sbLNwfJHxvo1TCLwuwm14sCYnkH6S1s= sigs.k8s.io/kustomize/kyaml v0.13.9 h1:Qz53EAaFFANyNgyOEJbT/yoIHygK40/ZcvU3rgry2Tk= diff --git a/integration-tests/load/README.md b/integration-tests/load/README.md new file mode 100644 index 00000000000..1ed1ee8b94e --- /dev/null +++ b/integration-tests/load/README.md @@ -0,0 +1,63 @@ +## Performance tests for CL jobs + +This folder container performance e2e tests for different job types, currently implemented: +- VRFv2 + +All the tests have 4 groups: +- one product soak +- one product load +- multiple product instances soak +- multiple product instances load + +When you develop an e2e performance suite for a new product you can implement the tests one by one to answer the questions: + +What are performance characteristics of a one instance of a product (jobs + contracts): +- is our product stable at all, no memory leaks, no flaking performance under some RPS? (test #1) +- what are the limits for one product instance, figuring out the max/optimal performance params by increasing RPS and varying configuration (test #2) +- update test #1 with optimal params and workload to constantly run in CI + +What are performance and capacity characteristics of Chainlink node(s) that run multiple products of the same type simultaneously: +- how many products of the same type we can run at once at a stable load with optimal configuration? (test #3) +- what are the limits if we add more and more products of the same type, each product have a stable RPS, we vary only amount of products +- update test #3 with optimal params and workload to constantly run in CI + +Implementing test #1 is **mandatory** for each product. +Tests #2,#3,#4 are optional if you need to figure out your product scaling or node/cluster capacity. + + +## Usage +``` +export LOKI_TOKEN=... +export LOKI_URL=... + +go test -v -run TestVRFV2Load/vrfv2_soak_test +``` + +### Dashboards +Each product has its own generated dashboard in `cmd/dashboard.go` + +Deploying dashboard: +``` +export GRAFANA_URL=... +export GRAFANA_TOKEN=... +export DATA_SOURCE_NAME=grafanacloud-logs +export DASHBOARD_FOLDER=LoadTests +export DASHBOARD_NAME=${JobTypeName, for example WaspVRFv2} + +go run dashboard.go +``` + +### Assertions + +You can implement your product requirements assertions in `onchain_monitoring.go`. For Chainlink products (VRF/OCR/Keepers/Automation) it's easier to assert on-chain part + +If you need to assert some metrics in `Prometheus/Loki`, here is an [example](https://github.com/smartcontractkit/wasp/blob/master/examples/alerts/main_test.go#L88) + +Do not mix workload logic with assertions, separate them. + +### Implementation +To implement a standard e2e performance suite for a new product please look at `gun.go` and `vu.go`. + +Gun should be working with one instance of your product. + +VU(Virtual user) creates a new instance of your product and works with it in `Call()` \ No newline at end of file diff --git a/integration-tests/load/functions/README.md b/integration-tests/load/functions/README.md new file mode 100644 index 00000000000..ec94b9ded0a --- /dev/null +++ b/integration-tests/load/functions/README.md @@ -0,0 +1,22 @@ +### Functions Load tests + +## Usage +``` +export LOKI_TOKEN=... +export LOKI_URL=... + +go test -v -run TestFunctionsLoad/functions_soak_test +``` + +### Dashboards + +Deploying dashboard: +``` +export GRAFANA_URL=... +export GRAFANA_TOKEN=... +export DATA_SOURCE_NAME=... +export DASHBOARD_FOLDER=LoadTests +export DASHBOARD_NAME=FunctionsV1 + +go run dashboard.go +``` \ No newline at end of file diff --git a/integration-tests/load/functions/cmd/dashboard.go b/integration-tests/load/functions/cmd/dashboard.go new file mode 100644 index 00000000000..6414759e672 --- /dev/null +++ b/integration-tests/load/functions/cmd/dashboard.go @@ -0,0 +1,34 @@ +package main + +import ( + "github.com/K-Phoen/grabana/dashboard" + "github.com/K-Phoen/grabana/logs" + "github.com/K-Phoen/grabana/row" + "github.com/smartcontractkit/wasp" +) + +func main() { + lokiDS := "grafanacloud-logs" + d, err := wasp.NewDashboard(nil, + []dashboard.Option{ + dashboard.Row("DON logs (errors)", + row.Collapse(), + row.WithLogs( + "DON logs", + logs.DataSource(lokiDS), + logs.Span(12), + logs.Height("300px"), + logs.Transparent(), + logs.WithLokiTarget(` + { cluster="staging-us-west-2-main", app=~"clc-ocr2-dr-matic-testnet" } | json | level="error" + `), + )), + }, + ) + if err != nil { + panic(err) + } + if _, err := d.Deploy(); err != nil { + panic(err) + } +} diff --git a/integration-tests/load/functions/config.go b/integration-tests/load/functions/config.go new file mode 100644 index 00000000000..baba37d2c82 --- /dev/null +++ b/integration-tests/load/functions/config.go @@ -0,0 +1,80 @@ +package loadfunctions + +import ( + "github.com/pelletier/go-toml/v2" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + "github.com/smartcontractkit/chainlink/v2/core/store/models" + "math/big" + "os" +) + +const ( + DefaultConfigFilename = "config.toml" + + ErrReadPerfConfig = "failed to read TOML config for performance tests" + ErrUnmarshalPerfConfig = "failed to unmarshal TOML config for performance tests" +) + +type PerformanceConfig struct { + Soak *Soak `toml:"Soak"` + Load *Load `toml:"Load"` + SoakVolume *SoakVolume `toml:"SoakVolume"` + LoadVolume *LoadVolume `toml:"LoadVolume"` + Common *Common `toml:"Common"` +} + +type Common struct { + Funding + LINKTokenAddr string `toml:"link_token_addr"` + Coordinator string `toml:"coordinator_addr"` + Router string `toml:"router_addr"` + LoadTestClient string `toml:"client_example_addr"` + SubscriptionID uint64 `toml:"subscription_id"` + DONID string `toml:"don_id"` +} + +type Funding struct { + NodeFunds *big.Float `toml:"node_funds"` + SubFunds *big.Int `toml:"sub_funds"` +} + +type Soak struct { + RPS int64 `toml:"rps"` + Duration *models.Duration `toml:"duration"` +} + +type SoakVolume struct { + Products int64 `toml:"products"` + Pace *models.Duration `toml:"pace"` + Duration *models.Duration `toml:"duration"` +} + +type Load struct { + RPSFrom int64 `toml:"rps_from"` + RPSIncrease int64 `toml:"rps_increase"` + RPSSteps int `toml:"rps_steps"` + Duration *models.Duration `toml:"duration"` +} + +type LoadVolume struct { + ProductsFrom int64 `toml:"products_from"` + ProductsIncrease int64 `toml:"products_increase"` + ProductsSteps int `toml:"products_steps"` + Pace *models.Duration `toml:"pace"` + Duration *models.Duration `toml:"duration"` +} + +func ReadConfig() (*PerformanceConfig, error) { + var cfg *PerformanceConfig + d, err := os.ReadFile(DefaultConfigFilename) + if err != nil { + return nil, errors.Wrap(err, ErrReadPerfConfig) + } + err = toml.Unmarshal(d, &cfg) + if err != nil { + return nil, errors.Wrap(err, ErrUnmarshalPerfConfig) + } + log.Debug().Interface("PerformanceConfig", cfg).Msg("Parsed performance config") + return cfg, nil +} diff --git a/integration-tests/load/functions/config.toml b/integration-tests/load/functions/config.toml new file mode 100644 index 00000000000..14cedcd9a5d --- /dev/null +++ b/integration-tests/load/functions/config.toml @@ -0,0 +1,34 @@ +[Soak] +rps = 1 +duration = "1h" + +[Load] +rps_from = 1 +rps_increase = 1 +rps_steps = 10 +duration = "3m" + +[SoakVolume] +products = 5 +pace = "1s" +duration = "3m" + +[LoadVolume] +products_from = 1 +products_increase = 1 +products_steps = 10 +pace = "1s" +duration = "3m" + +[Common] +# Polygon Mumbai only for now +link_token_addr = "0x326C977E6efc84E512bB9C30f76E30c160eD06FB" +coordinator_addr = "0x69b4C680209737B877c93327fC2144ec39eaC423" +router_addr = "0xa4Ac8b863A6b4fB064B6bdF87aD61d389d97748d" +client_example_addr = "0x2720cC3a112d33B5C1D40270f7c7BE7CADec1690" +don_id = "functions_staging_mumbai" +# comment it to automatically create and fund a new one +subscription_id = 48 +# not used until we have full DON setup +# node_funds = 10 +sub_funds = 7 \ No newline at end of file diff --git a/integration-tests/load/functions/functions_test.go b/integration-tests/load/functions/functions_test.go new file mode 100644 index 00000000000..656c3b80ec1 --- /dev/null +++ b/integration-tests/load/functions/functions_test.go @@ -0,0 +1,62 @@ +package loadfunctions + +import ( + "github.com/smartcontractkit/wasp" + "github.com/stretchr/testify/require" + "testing" + "time" +) + +func TestFunctionsLoad(t *testing.T) { + cfg, err := ReadConfig() + require.NoError(t, err) + env, functionContracts, err := SetupLocalLoadTestEnv(cfg) + require.NoError(t, err) + env.ParallelTransactions(true) + + labels := map[string]string{ + "branch": "functions_healthcheck", + "commit": "functions_healthcheck", + } + + singleFeedConfig := &wasp.Config{ + T: t, + LoadType: wasp.RPS, + GenName: "gun", + CallTimeout: 2 * time.Minute, + Gun: NewSingleFunctionCallGun( + functionContracts, + "const response = await Functions.makeHttpRequest({ url: 'http://dummyjson.com/products/1' }); return Functions.encodeUint256(response.data.id)", + []byte{}, + []string{}, + cfg.Common.SubscriptionID, + StringToByte32(cfg.Common.DONID), + ), + Labels: labels, + LokiConfig: wasp.NewEnvLokiConfig(), + } + + t.Run("functions soak test", func(t *testing.T) { + singleFeedConfig.Schedule = wasp.Plain( + cfg.Soak.RPS, + cfg.Soak.Duration.Duration(), + ) + _, err := wasp.NewProfile(). + Add(wasp.NewGenerator(singleFeedConfig)). + Run(true) + require.NoError(t, err) + }) + + t.Run("functions load test", func(t *testing.T) { + singleFeedConfig.Schedule = wasp.Steps( + cfg.Load.RPSFrom, + cfg.Load.RPSIncrease, + cfg.Load.RPSSteps, + cfg.Load.Duration.Duration(), + ) + _, err = wasp.NewProfile(). + Add(wasp.NewGenerator(singleFeedConfig)). + Run(true) + require.NoError(t, err) + }) +} diff --git a/integration-tests/load/functions/gun.go b/integration-tests/load/functions/gun.go new file mode 100644 index 00000000000..358e0acb986 --- /dev/null +++ b/integration-tests/load/functions/gun.go @@ -0,0 +1,36 @@ +package loadfunctions + +import ( + "github.com/smartcontractkit/wasp" +) + +/* SingleFunctionCallGun is a gun that constantly requests randomness for one feed */ + +type SingleFunctionCallGun struct { + contracts *Contracts + source string + encryptedSecretsReferences []byte + args []string + subscriptionId uint64 + jobId [32]byte +} + +func NewSingleFunctionCallGun(contracts *Contracts, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) *SingleFunctionCallGun { + return &SingleFunctionCallGun{ + contracts: contracts, + source: source, + encryptedSecretsReferences: encryptedSecretsReferences, + args: args, + subscriptionId: subscriptionId, + jobId: jobId, + } +} + +// Call implements example gun call, assertions on response bodies should be done here +func (m *SingleFunctionCallGun) Call(l *wasp.Generator) *wasp.CallResult { + err := m.contracts.LoadTestClient.SendRequest(m.source, m.encryptedSecretsReferences, m.args, m.subscriptionId, m.jobId) + if err != nil { + return &wasp.CallResult{Error: err.Error(), Failed: true} + } + return &wasp.CallResult{} +} diff --git a/integration-tests/load/functions/setup.go b/integration-tests/load/functions/setup.go new file mode 100644 index 00000000000..cd8038c41ba --- /dev/null +++ b/integration-tests/load/functions/setup.go @@ -0,0 +1,64 @@ +package loadfunctions + +import ( + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + "github.com/smartcontractkit/chainlink/integration-tests/contracts" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + chainlinkutils "github.com/smartcontractkit/chainlink/v2/core/utils" + "math/big" +) + +type Contracts struct { + LinkToken contracts.LinkToken + Coordinator contracts.FunctionsCoordinator + Router contracts.FunctionsRouter + LoadTestClient contracts.FunctionsLoadTestClient +} + +func SetupLocalLoadTestEnv(cfg *PerformanceConfig) (*test_env.CLClusterTestEnv, *Contracts, error) { + env, err := test_env.NewCLTestEnvBuilder(). + Build() + if err != nil { + return env, nil, err + } + env.EVMClient.GetNonceSetting() + lt, err := env.ContractLoader.LoadLINKToken(cfg.Common.LINKTokenAddr) + if err != nil { + return env, nil, err + } + coord, err := env.ContractLoader.LoadFunctionsCoordinator(cfg.Common.Coordinator) + if err != nil { + return env, nil, err + } + router, err := env.ContractLoader.LoadFunctionsRouter(cfg.Common.Router) + if err != nil { + return env, nil, err + } + loadTestClient, err := env.ContractLoader.LoadFunctionsLoadTestClient(cfg.Common.LoadTestClient) + if err != nil { + return env, nil, err + } + if cfg.Common.SubscriptionID == 0 { + log.Info().Msg("Creating new subscription") + subID, err := router.CreateSubscriptionWithConsumer(loadTestClient.Address()) + if err != nil { + return env, nil, errors.Wrap(err, "failed to create a new subscription") + } + encodedSubId, err := chainlinkutils.ABIEncode(`[{"type":"uint64"}]`, subID) + if err != nil { + return env, nil, errors.Wrap(err, "failed to encode subscription ID for funding") + } + _, err = lt.TransferAndCall(router.Address(), big.NewInt(0).Mul(cfg.Common.Funding.SubFunds, big.NewInt(1e18)), encodedSubId) + if err != nil { + return env, nil, errors.Wrap(err, "failed to transferAndCall router, LINK funding") + } + cfg.Common.SubscriptionID = subID + } + return env, &Contracts{ + LinkToken: lt, + Coordinator: coord, + Router: router, + LoadTestClient: loadTestClient, + }, nil +} diff --git a/integration-tests/load/functions/util.go b/integration-tests/load/functions/util.go new file mode 100644 index 00000000000..d5a4a2d6061 --- /dev/null +++ b/integration-tests/load/functions/util.go @@ -0,0 +1,15 @@ +package loadfunctions + +// StringToByte32 transforms a single string into a [32]byte value +func StringToByte32(s string) [32]byte { + var result [32]byte + + for i, ch := range []byte(s) { + if i > 31 { + break + } + result[i] = ch + } + + return result +} diff --git a/integration-tests/load/vrfv2/README.md b/integration-tests/load/vrfv2/README.md new file mode 100644 index 00000000000..4b00d4ad0d2 --- /dev/null +++ b/integration-tests/load/vrfv2/README.md @@ -0,0 +1,22 @@ +### VRFv2 Load tests + +## Usage +``` +export LOKI_TOKEN=... +export LOKI_URL=... + +go test -v -run TestVRFV2Load/vrfv2_soak_test +``` + +### Dashboards + +Deploying dashboard: +``` +export GRAFANA_URL=... +export GRAFANA_TOKEN=... +export DATA_SOURCE_NAME=grafanacloud-logs +export DASHBOARD_FOLDER=LoadTests +export DASHBOARD_NAME=${JobTypeName, for example WaspVRFv2} + +go run dashboard.go +``` \ No newline at end of file diff --git a/integration-tests/load/vrfv2/cmd/dashboard.go b/integration-tests/load/vrfv2/cmd/dashboard.go new file mode 100644 index 00000000000..f7e29bd7d75 --- /dev/null +++ b/integration-tests/load/vrfv2/cmd/dashboard.go @@ -0,0 +1,98 @@ +package main + +import ( + "github.com/K-Phoen/grabana/dashboard" + "github.com/K-Phoen/grabana/logs" + "github.com/K-Phoen/grabana/row" + "github.com/K-Phoen/grabana/target/prometheus" + "github.com/K-Phoen/grabana/timeseries" + "github.com/K-Phoen/grabana/timeseries/axis" + "github.com/smartcontractkit/wasp" +) + +func main() { + lokiDS := "grafanacloud-logs" + d, err := wasp.NewDashboard(nil, + []dashboard.Option{ + dashboard.Row("LoadContractMetrics", + row.WithTimeSeries( + "RequestCount + FulfilmentCount", + timeseries.Span(12), + timeseries.Height("300px"), + timeseries.DataSource(lokiDS), + timeseries.Axis( + axis.Unit("Requests"), + ), + timeseries.WithPrometheusTarget( + ` + last_over_time({type="vrfv2_contracts_load_summary", go_test_name=~"${go_test_name:pipe}", branch=~"${branch:pipe}", commit=~"${commit:pipe}", gen_name=~"${gen_name:pipe}"} + | json + | unwrap RequestCount [$__interval]) by (node_id, go_test_name, gen_name) + `, prometheus.Legend("{{go_test_name}} requests"), + ), + timeseries.WithPrometheusTarget( + ` + last_over_time({type="vrfv2_contracts_load_summary", go_test_name=~"${go_test_name:pipe}", branch=~"${branch:pipe}", commit=~"${commit:pipe}", gen_name=~"${gen_name:pipe}"} + | json + | unwrap FulfilmentCount [$__interval]) by (node_id, go_test_name, gen_name) + `, prometheus.Legend("{{go_test_name}} fulfillments"), + ), + ), + row.WithTimeSeries( + "Fulfillment time (blocks)", + timeseries.Span(12), + timeseries.Height("300px"), + timeseries.DataSource(lokiDS), + timeseries.Axis( + axis.Unit("Blocks"), + ), + timeseries.WithPrometheusTarget( + ` + last_over_time({type="vrfv2_contracts_load_summary", go_test_name=~"${go_test_name:pipe}", branch=~"${branch:pipe}", commit=~"${commit:pipe}", gen_name=~"${gen_name:pipe}"} + | json + | unwrap AverageFulfillmentInMillions [$__interval]) by (node_id, go_test_name, gen_name) / 1e6 + `, prometheus.Legend("{{go_test_name}} avg"), + ), + timeseries.WithPrometheusTarget( + ` + last_over_time({type="vrfv2_contracts_load_summary", go_test_name=~"${go_test_name:pipe}", branch=~"${branch:pipe}", commit=~"${commit:pipe}", gen_name=~"${gen_name:pipe}"} + | json + | unwrap SlowestFulfillment [$__interval]) by (node_id, go_test_name, gen_name) + `, prometheus.Legend("{{go_test_name}} slowest"), + ), + timeseries.WithPrometheusTarget( + ` + last_over_time({type="vrfv2_contracts_load_summary", go_test_name=~"${go_test_name:pipe}", branch=~"${branch:pipe}", commit=~"${commit:pipe}", gen_name=~"${gen_name:pipe}"} + | json + | unwrap FastestFulfillment [$__interval]) by (node_id, go_test_name, gen_name) + `, prometheus.Legend("{{go_test_name}} fastest"), + ), + ), + ), + dashboard.Row("CL nodes logs", + row.Collapse(), + row.WithLogs( + "CL nodes logs", + logs.DataSource(lokiDS), + logs.Span(12), + logs.Height("300px"), + logs.Transparent(), + logs.WithLokiTarget(` + {type="log_watch"} + `), + )), + }, + ) + if err != nil { + panic(err) + } + // set env vars + //export GRAFANA_URL=... + //export GRAFANA_TOKEN=... + //export DATA_SOURCE_NAME=Loki + //export DASHBOARD_FOLDER=LoadTests + //export DASHBOARD_NAME=WaspVRFv2 + if _, err := d.Deploy(); err != nil { + panic(err) + } +} diff --git a/integration-tests/load/vrfv2/config.go b/integration-tests/load/vrfv2/config.go new file mode 100644 index 00000000000..ee5f3ff80dd --- /dev/null +++ b/integration-tests/load/vrfv2/config.go @@ -0,0 +1,74 @@ +package loadvrfv2 + +import ( + "github.com/pelletier/go-toml/v2" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + "github.com/smartcontractkit/chainlink/v2/core/store/models" + "math/big" + "os" +) + +const ( + DefaultConfigFilename = "config.toml" + + ErrReadPerfConfig = "failed to read TOML config for performance tests" + ErrUnmarshalPerfConfig = "failed to unmarshal TOML config for performance tests" +) + +type PerformanceConfig struct { + Soak *Soak `toml:"Soak"` + Load *Load `toml:"Load"` + SoakVolume *SoakVolume `toml:"SoakVolume"` + LoadVolume *LoadVolume `toml:"LoadVolume"` + Common *Common `toml:"Common"` +} + +type Common struct { + Funding +} + +type Funding struct { + NodeFunds *big.Float `toml:"node_funds"` + SubFunds *big.Int `toml:"sub_funds"` +} + +type Soak struct { + RPS int64 `toml:"rps"` + Duration *models.Duration `toml:"duration"` +} + +type SoakVolume struct { + Products int64 `toml:"products"` + Pace *models.Duration `toml:"pace"` + Duration *models.Duration `toml:"duration"` +} + +type Load struct { + RPSFrom int64 `toml:"rps_from"` + RPSIncrease int64 `toml:"rps_increase"` + RPSSteps int `toml:"rps_steps"` + Duration *models.Duration `toml:"duration"` +} + +type LoadVolume struct { + ProductsFrom int64 `toml:"products_from"` + ProductsIncrease int64 `toml:"products_increase"` + ProductsSteps int `toml:"products_steps"` + Pace *models.Duration `toml:"pace"` + Duration *models.Duration `toml:"duration"` +} + +func ReadConfig() (*PerformanceConfig, error) { + var cfg *PerformanceConfig + d, err := os.ReadFile(DefaultConfigFilename) + if err != nil { + return nil, errors.Wrap(err, ErrReadPerfConfig) + } + err = toml.Unmarshal(d, &cfg) + if err != nil { + return nil, errors.Wrap(err, ErrUnmarshalPerfConfig) + } + log.Debug().Interface("PerformanceConfig", cfg).Msg("Parsed performance config") + return cfg, nil +} diff --git a/integration-tests/load/vrfv2/config.toml b/integration-tests/load/vrfv2/config.toml new file mode 100644 index 00000000000..8917db88cc2 --- /dev/null +++ b/integration-tests/load/vrfv2/config.toml @@ -0,0 +1,27 @@ +# testing one product (jobs + contracts) by varying RPS +[Soak] +rps = 1 +duration = "3m" + +[Load] +rps_from = 1 +rps_increase = 1 +rps_steps = 10 +duration = "3m" + +# testing multiple products (jobs + contracts) by varying instances, deploying more of the same type with stable RPS for each product +[SoakVolume] +products = 5 +pace = "1s" +duration = "3m" + +[LoadVolume] +products_from = 1 +products_increase = 1 +products_steps = 10 +pace = "1s" +duration = "3m" + +[Common] +node_funds = 10 +sub_funds = 100 \ No newline at end of file diff --git a/integration-tests/load/vrfv2/gun.go b/integration-tests/load/vrfv2/gun.go new file mode 100644 index 00000000000..d6a8977738b --- /dev/null +++ b/integration-tests/load/vrfv2/gun.go @@ -0,0 +1,37 @@ +package loadvrfv2 + +import ( + "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2_actions" + vrfConst "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2_actions/vrfv2_constants" + "github.com/smartcontractkit/wasp" +) + +/* SingleHashGun is a gun that constantly requests randomness for one feed */ + +type SingleHashGun struct { + contracts *vrfv2_actions.VRFV2Contracts + keyHash [32]byte +} + +func SingleFeedGun(contracts *vrfv2_actions.VRFV2Contracts, keyHash [32]byte) *SingleHashGun { + return &SingleHashGun{ + contracts: contracts, + keyHash: keyHash, + } +} + +// Call implements example gun call, assertions on response bodies should be done here +func (m *SingleHashGun) Call(l *wasp.Generator) *wasp.CallResult { + err := m.contracts.LoadTestConsumer.RequestRandomness( + m.keyHash, + vrfConst.SubID, + vrfConst.MinimumConfirmations, + vrfConst.CallbackGasLimit, + vrfConst.NumberOfWords, + vrfConst.RandomnessRequestCountPerRequest, + ) + if err != nil { + return &wasp.CallResult{Error: err.Error(), Failed: true} + } + return &wasp.CallResult{} +} diff --git a/integration-tests/load/vrfv2/onchain_monitoring.go b/integration-tests/load/vrfv2/onchain_monitoring.go new file mode 100644 index 00000000000..b4503d27fad --- /dev/null +++ b/integration-tests/load/vrfv2/onchain_monitoring.go @@ -0,0 +1,46 @@ +package loadvrfv2 + +import ( + "context" + "github.com/rs/zerolog/log" + "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2_actions" + "github.com/smartcontractkit/wasp" + "testing" + "time" +) + +/* Monitors on-chain stats of LoadConsumer and pushes them to Loki every second */ + +const ( + LokiTypeLabel = "vrfv2_contracts_load_summary" + ErrMetrics = "failed to get VRFv2 load test metrics" + ErrLokiClient = "failed to create Loki client for monitoring" + ErrLokiPush = "failed to push monitoring metrics to Loki" +) + +func MonitorLoadStats(t *testing.T, vrfv2Contracts *vrfv2_actions.VRFV2Contracts, labels map[string]string) { + go func() { + updatedLabels := make(map[string]string) + for k, v := range labels { + updatedLabels[k] = v + } + updatedLabels["type"] = LokiTypeLabel + updatedLabels["go_test_name"] = t.Name() + updatedLabels["gen_name"] = "performance" + lc, err := wasp.NewLokiClient(wasp.NewEnvLokiConfig()) + if err != nil { + log.Error().Err(err).Msg(ErrLokiClient) + return + } + for { + time.Sleep(1 * time.Second) + metrics, err := vrfv2Contracts.LoadTestConsumer.GetLoadTestMetrics(context.Background()) + if err != nil { + log.Error().Err(err).Msg(ErrMetrics) + } + if err := lc.HandleStruct(wasp.LabelsMapToModel(updatedLabels), time.Now(), metrics); err != nil { + log.Error().Err(err).Msg(ErrLokiPush) + } + } + }() +} diff --git a/integration-tests/load/vrfv2/vrfv2_test.go b/integration-tests/load/vrfv2/vrfv2_test.go new file mode 100644 index 00000000000..97a455dc714 --- /dev/null +++ b/integration-tests/load/vrfv2/vrfv2_test.go @@ -0,0 +1,92 @@ +package loadvrfv2 + +import ( + "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2_actions" + "github.com/smartcontractkit/wasp" + "github.com/stretchr/testify/require" + "testing" +) + +func TestVRFV2Load(t *testing.T) { + cfg, err := ReadConfig() + require.NoError(t, err) + env, vrfv2Contracts, key, err := vrfv2_actions.SetupLocalLoadTestEnv(cfg.Common.NodeFunds, cfg.Common.SubFunds) + require.NoError(t, err) + + labels := map[string]string{ + "branch": "vrfv2_healthcheck", + "commit": "vrfv2_healthcheck", + } + + singleFeedConfig := &wasp.Config{ + T: t, + LoadType: wasp.RPS, + GenName: "gun", + Gun: SingleFeedGun(vrfv2Contracts, key), + Labels: labels, + LokiConfig: wasp.NewEnvLokiConfig(), + } + + multiFeedConfig := &wasp.Config{ + T: t, + LoadType: wasp.VU, + GenName: "vu", + VU: NewJobVolumeVU(cfg.SoakVolume.Pace.Duration(), 1, env.GetAPIs(), env.EVMClient, vrfv2Contracts), + Labels: labels, + LokiConfig: wasp.NewEnvLokiConfig(), + } + + MonitorLoadStats(t, vrfv2Contracts, labels) + + // is our "job" stable at all, no memory leaks, no flaking performance under some RPS? + t.Run("vrfv2 soak test", func(t *testing.T) { + singleFeedConfig.Schedule = wasp.Plain( + cfg.Soak.RPS, + cfg.Soak.Duration.Duration(), + ) + _, err := wasp.NewProfile(). + Add(wasp.NewGenerator(singleFeedConfig)). + Run(true) + require.NoError(t, err) + }) + + // what are the limits for one "job", figuring out the max/optimal performance params by increasing RPS and varying configuration + t.Run("vrfv2 load test", func(t *testing.T) { + singleFeedConfig.Schedule = wasp.Steps( + cfg.Load.RPSFrom, + cfg.Load.RPSIncrease, + cfg.Load.RPSSteps, + cfg.Load.Duration.Duration(), + ) + _, err = wasp.NewProfile(). + Add(wasp.NewGenerator(singleFeedConfig)). + Run(true) + require.NoError(t, err) + }) + + // how many "jobs" of the same type we can run at once at a stable load with optimal configuration? + t.Run("vrfv2 volume soak test", func(t *testing.T) { + multiFeedConfig.Schedule = wasp.Plain( + cfg.SoakVolume.Products, + cfg.SoakVolume.Duration.Duration(), + ) + _, err = wasp.NewProfile(). + Add(wasp.NewGenerator(multiFeedConfig)). + Run(true) + require.NoError(t, err) + }) + + // what are the limits if we add more and more "jobs/products" of the same type, each "job" have a stable RPS we vary only amount of jobs + t.Run("vrfv2 volume load test", func(t *testing.T) { + multiFeedConfig.Schedule = wasp.Steps( + cfg.LoadVolume.ProductsFrom, + cfg.LoadVolume.ProductsIncrease, + cfg.LoadVolume.ProductsSteps, + cfg.LoadVolume.Duration.Duration(), + ) + _, err = wasp.NewProfile(). + Add(wasp.NewGenerator(multiFeedConfig)). + Run(true) + require.NoError(t, err) + }) +} diff --git a/integration-tests/load/vrfv2/vu.go b/integration-tests/load/vrfv2/vu.go new file mode 100644 index 00000000000..df05a9168e2 --- /dev/null +++ b/integration-tests/load/vrfv2/vu.go @@ -0,0 +1,92 @@ +package loadvrfv2 + +import ( + "github.com/pkg/errors" + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2_actions" + vrfConst "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2_actions/vrfv2_constants" + "github.com/smartcontractkit/chainlink/integration-tests/client" + "github.com/smartcontractkit/wasp" + "time" +) + +/* JobVolumeVU is a "virtual user" that creates a VRFv2 job and constantly requesting new randomness only for this job instance */ + +type JobVolumeVU struct { + pace time.Duration + minIncomingConfirmations uint16 + nodes []*client.ChainlinkClient + bc blockchain.EVMClient + contracts *vrfv2_actions.VRFV2Contracts + jobs []vrfv2_actions.VRFV2JobInfo + keyHash [32]byte + stop chan struct{} +} + +func NewJobVolumeVU( + pace time.Duration, + confirmations uint16, + nodes []*client.ChainlinkClient, + bc blockchain.EVMClient, + contracts *vrfv2_actions.VRFV2Contracts, +) *JobVolumeVU { + return &JobVolumeVU{ + pace: pace, + minIncomingConfirmations: confirmations, + nodes: nodes, + bc: bc, + contracts: contracts, + stop: make(chan struct{}, 1), + } +} + +func (m *JobVolumeVU) Clone(_ *wasp.Generator) wasp.VirtualUser { + return &JobVolumeVU{ + pace: m.pace, + minIncomingConfirmations: m.minIncomingConfirmations, + nodes: m.nodes, + bc: m.bc, + contracts: m.contracts, + stop: make(chan struct{}, 1), + } +} + +func (m *JobVolumeVU) Setup(_ *wasp.Generator) error { + jobs, err := vrfv2_actions.CreateVRFV2Jobs(m.nodes, m.contracts.Coordinator, m.bc, m.minIncomingConfirmations) + if err != nil { + return errors.Wrap(err, "failed to create VRFv2 jobs in setup") + } + m.jobs = jobs + m.keyHash = jobs[0].KeyHash + return nil +} + +func (m *JobVolumeVU) Teardown(_ *wasp.Generator) error { + return nil +} + +func (m *JobVolumeVU) Call(l *wasp.Generator) { + time.Sleep(m.pace) + tn := time.Now() + err := m.contracts.LoadTestConsumer.RequestRandomness( + m.keyHash, + vrfConst.SubID, + vrfConst.MinimumConfirmations, + vrfConst.CallbackGasLimit, + vrfConst.NumberOfWords, + vrfConst.RandomnessRequestCountPerRequest, + ) + if err != nil { + l.ResponsesChan <- &wasp.CallResult{Duration: time.Since(tn), Error: err.Error(), Failed: true} + return + } + l.ResponsesChan <- &wasp.CallResult{Duration: time.Since(tn)} +} + +func (m *JobVolumeVU) Stop(_ *wasp.Generator) { + m.stop <- struct{}{} +} + +func (m *JobVolumeVU) StopChan() chan struct{} { + return m.stop +} diff --git a/integration-tests/migration/upgrade_version_test.go b/integration-tests/migration/upgrade_version_test.go index b9c3ff01756..1f90bd123eb 100644 --- a/integration-tests/migration/upgrade_version_test.go +++ b/integration-tests/migration/upgrade_version_test.go @@ -1,78 +1,37 @@ package migration import ( - "fmt" - "strings" "testing" - "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" - - "github.com/smartcontractkit/chainlink-env/environment" - "github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink/integration-tests/actions" - "github.com/smartcontractkit/chainlink/integration-tests/client" - "github.com/smartcontractkit/chainlink/integration-tests/config" - "github.com/smartcontractkit/chainlink/integration-tests/networks" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + "os" ) func TestVersionUpgrade(t *testing.T) { t.Parallel() - testEnvironment, testNetwork := setupUpgradeTest(t) - if testEnvironment.WillUseRemoteRunner() { - return - } + env, err := test_env.NewCLTestEnvBuilder(). + WithGeth(). + WithCLNodes(1). + Build() + require.NoError(t, err) upgradeImage, err := utils.GetEnv("UPGRADE_IMAGE") require.NoError(t, err, "Error getting upgrade image") upgradeVersion, err := utils.GetEnv("UPGRADE_VERSION") require.NoError(t, err, "Error getting upgrade version") - chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment) - require.NoError(t, err, "Connecting to blockchain nodes shouldn't fail") - chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment) - require.NoError(t, err, "Connecting to chainlink nodes shouldn't fail") - - t.Cleanup(func() { - err := actions.TeardownSuite(t, testEnvironment, utils.ProjectRoot, chainlinkNodes, nil, zapcore.ErrorLevel, chainClient) - require.NoError(t, err, "Error tearing down environment") - }) - - err = actions.UpgradeChainlinkNodeVersions(testEnvironment, upgradeImage, upgradeVersion, chainlinkNodes[0]) - require.NoError(t, err, "Upgrading chainlink nodes shouldn't fail") -} - -func setupUpgradeTest(t *testing.T) ( - testEnvironment *environment.Environment, - testNetwork blockchain.EVMNetwork, -) { - testNetwork = networks.SelectedNetwork - evmConfig := ethereum.New(nil) - if !testNetwork.Simulated { - evmConfig = ethereum.New(ðereum.Props{ - NetworkName: testNetwork.Name, - Simulated: testNetwork.Simulated, - WsURLs: testNetwork.URLs, - }) - } - charts, err := chainlink.NewDeployment(1, map[string]any{ - "toml": client.AddNetworksConfig(config.BaseOCRP2PV1Config, testNetwork), - "db": map[string]any{ - "stateful": true, - }, - }) - require.NoError(t, err, "Error creating chainlink deployments") - testEnvironment = environment.New(&environment.Config{ - NamespacePrefix: fmt.Sprintf("upgrade-version-%s", strings.ReplaceAll(strings.ToLower(testNetwork.Name), " ", "-")), - Test: t, - }). - AddHelm(evmConfig). - AddHelmCharts(charts) - err = testEnvironment.Run() - require.NoError(t, err, "Error launching test environment") - return testEnvironment, testNetwork + _ = os.Setenv("CHAINLINK_IMAGE", upgradeImage) + _ = os.Setenv("CHAINLINK_VERSION", upgradeVersion) + + // just restarting CL container with the same name, DB is still the same + // + // [Database] + // MigrateOnStartup = true + // + // by default + err = env.CLNodes[0].Restart(env.CLNodes[0].NodeConfig) + require.NoError(t, err) } diff --git a/integration-tests/networks/known_networks.go b/integration-tests/networks/known_networks.go index a047ad024f5..2886f6c359d 100644 --- a/integration-tests/networks/known_networks.go +++ b/integration-tests/networks/known_networks.go @@ -8,6 +8,7 @@ import ( "time" "github.com/rs/zerolog/log" + "github.com/smartcontractkit/chainlink-testing-framework/utils" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" @@ -59,6 +60,7 @@ var ( Timeout: blockchain.JSONStrDuration{Duration: 2 * time.Minute}, MinimumConfirmations: 1, GasEstimationBuffer: 10000, + DefaultGasLimit: 6000000, } // SimulatedEVM_NON_DEV_2 represents a simulated network with chain id 2337 which can be used to deploy a non-dev geth node @@ -69,7 +71,7 @@ var ( ClientImplementation: blockchain.EthereumClientImplementation, ChainID: 2337, PrivateKeys: []string{ - "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", + "59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d", }, URLs: []string{"ws://dest-chain-ethereum-geth:8546"}, HTTPURLs: []string{"http://dest-chain-ethereum-geth:8544"}, @@ -77,6 +79,7 @@ var ( Timeout: blockchain.JSONStrDuration{Duration: 2 * time.Minute}, MinimumConfirmations: 1, GasEstimationBuffer: 10000, + DefaultGasLimit: 6000000, } SimulatedEVMNonDev = blockchain.EVMNetwork{ @@ -106,6 +109,8 @@ var ( Timeout: blockchain.JSONStrDuration{Duration: 5 * time.Minute}, MinimumConfirmations: 1, GasEstimationBuffer: 0, + FinalityTag: true, + DefaultGasLimit: 6000000, } // sepoliaTestnet https://sepolia.dev/ @@ -119,6 +124,8 @@ var ( Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, MinimumConfirmations: 1, GasEstimationBuffer: 1000, + FinalityTag: true, + DefaultGasLimit: 6000000, } // goerliTestnet https://goerli.net/ @@ -132,6 +139,8 @@ var ( Timeout: blockchain.JSONStrDuration{Duration: 5 * time.Minute}, MinimumConfirmations: 1, GasEstimationBuffer: 1000, + FinalityTag: true, + DefaultGasLimit: 6000000, } KlaytnMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{ @@ -194,6 +203,8 @@ var ( Timeout: blockchain.JSONStrDuration{Duration: 2 * time.Minute}, MinimumConfirmations: 0, GasEstimationBuffer: 0, + FinalityTag: true, + DefaultGasLimit: 100000000, } // arbitrumGoerli https://developer.offchainlabs.com/docs/public_chains @@ -207,6 +218,8 @@ var ( Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, MinimumConfirmations: 0, GasEstimationBuffer: 0, + FinalityTag: true, + DefaultGasLimit: 100000000, } OptimismMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{ @@ -219,6 +232,8 @@ var ( Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, MinimumConfirmations: 1, GasEstimationBuffer: 0, + FinalityTag: true, + DefaultGasLimit: 6000000, } // optimismGoerli https://dev.optimism.io/kovan-to-goerli/ @@ -232,6 +247,8 @@ var ( Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, MinimumConfirmations: 1, GasEstimationBuffer: 0, + FinalityTag: true, + DefaultGasLimit: 6000000, } RSKMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{ @@ -269,6 +286,8 @@ var ( Timeout: blockchain.JSONStrDuration{Duration: 2 * time.Minute}, MinimumConfirmations: 1, GasEstimationBuffer: 0, + FinalityDepth: 550, + DefaultGasLimit: 6000000, } // PolygonMumbai https://mumbai.polygonscan.com/ @@ -282,6 +301,8 @@ var ( Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, MinimumConfirmations: 1, GasEstimationBuffer: 1000, + FinalityDepth: 550, + DefaultGasLimit: 6000000, } AvalancheMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{ @@ -294,6 +315,8 @@ var ( Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, MinimumConfirmations: 1, GasEstimationBuffer: 0, + FinalityDepth: 35, + DefaultGasLimit: 6000000, } AvalancheFuji = blockchain.EVMNetwork{ @@ -306,6 +329,8 @@ var ( Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, MinimumConfirmations: 1, GasEstimationBuffer: 1000, + FinalityDepth: 35, + DefaultGasLimit: 6000000, } Quorum = blockchain.EVMNetwork{ @@ -344,6 +369,28 @@ var ( GasEstimationBuffer: 1000, } + ScrollSepolia = blockchain.EVMNetwork{ + Name: "Scroll Sepolia", + ClientImplementation: blockchain.ScrollClientImplementation, + ChainID: 534351, + Simulated: false, + ChainlinkTransactionLimit: 5000, + Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, + MinimumConfirmations: 1, + GasEstimationBuffer: 0, + } + + ScrollMainnet = blockchain.EVMNetwork{ + Name: "Scroll Mainnet", + ClientImplementation: blockchain.ScrollClientImplementation, + ChainID: 534352, + Simulated: false, + ChainlinkTransactionLimit: 5000, + Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, + MinimumConfirmations: 1, + GasEstimationBuffer: 0, + } + CeloMainnet = blockchain.EVMNetwork{ Name: "Celo", ClientImplementation: blockchain.CeloClientImplementation, @@ -367,6 +414,30 @@ var ( GasEstimationBuffer: 0, } + BSCTestnet blockchain.EVMNetwork = blockchain.EVMNetwork{ + Name: "BSC Testnet", + SupportsEIP1559: true, + ClientImplementation: blockchain.BSCClientImplementation, + ChainID: 97, + Simulated: false, + ChainlinkTransactionLimit: 5000, + Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, + MinimumConfirmations: 3, + GasEstimationBuffer: 0, + } + + BSCMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{ + Name: "BSC Mainnet", + SupportsEIP1559: true, + ClientImplementation: blockchain.BSCClientImplementation, + ChainID: 56, + Simulated: false, + ChainlinkTransactionLimit: 5000, + Timeout: blockchain.JSONStrDuration{Duration: time.Minute}, + MinimumConfirmations: 3, + GasEstimationBuffer: 0, + } + MappedNetworks = map[string]blockchain.EVMNetwork{ "SIMULATED": SimulatedEVM, "SIMULATED_1": SimulatedEVMNonDev1, @@ -393,7 +464,11 @@ var ( "AVALANCHE_FUJI": AvalancheFuji, "AVALANCHE_MAINNET": AvalancheMainnet, "QUORUM": Quorum, + "SCROLL_SEPOLIA": ScrollSepolia, + "SCROLL_MAINNET": ScrollMainnet, "BASE_MAINNET": BaseMainnet, + "BSC_TESTNET": BSCTestnet, + "BSC_MAINNET": BSCMainnet, } ) @@ -471,7 +546,7 @@ func setURLs(prefix string, network *blockchain.EVMNetwork) { httpURLs := strings.Split(httpEnvURLs, ",") network.URLs = wsURLs network.HTTPURLs = httpURLs - log.Info().Interface(wsEnvVar, wsURLs).Interface(httpEnvVar, httpURLs).Msg("Read network URLs") + log.Info().Msg("Read network URLs") } // setKeys sets a network's private key(s) based on env vars @@ -498,5 +573,5 @@ func setKeys(prefix string, network *blockchain.EVMNetwork) { } keys := strings.Split(keysEnv, ",") network.PrivateKeys = keys - log.Info().Interface(envVar, keys).Msg("Read network Keys") + log.Info().Msg("Read network Keys") } diff --git a/integration-tests/performance/cron_test.go b/integration-tests/performance/cron_test.go index 0833b270ad4..933014a1698 100644 --- a/integration-tests/performance/cron_test.go +++ b/integration-tests/performance/cron_test.go @@ -36,7 +36,7 @@ func TestMain(m *testing.M) { func CleanupPerformanceTest( t *testing.T, testEnvironment *environment.Environment, - chainlinkNodes []*client.Chainlink, + chainlinkNodes []*client.ChainlinkK8sClient, testReporter testreporters.ChainlinkProfileTestReporter, chainClient blockchain.EVMClient, ) { @@ -61,8 +61,8 @@ func TestCronPerformance(t *testing.T) { err = mockServer.SetValuePath("/variable", 5) require.NoError(t, err, "Setting value path in mockserver shouldn't fail") - profileFunction := func(chainlinkNode *client.Chainlink) { - if chainlinkNode != chainlinkNodes[len(chainlinkNodes)-1] { + profileFunction := func(chainlinkNode *client.ChainlinkClient) { + if chainlinkNode != chainlinkNodes[len(chainlinkNodes)-1].ChainlinkClient { // Not the last node, hence not all nodes started profiling yet. return } @@ -96,7 +96,7 @@ func TestCronPerformance(t *testing.T) { profileTest := testsetups.NewChainlinkProfileTest(testsetups.ChainlinkProfileTestInputs{ ProfileFunction: profileFunction, ProfileDuration: 30 * time.Second, - ChainlinkNodes: []*client.Chainlink{chainlinkNode}, + ChainlinkNodes: []*client.ChainlinkK8sClient{chainlinkNode}, }) // Register cleanup for any test t.Cleanup(func() { diff --git a/integration-tests/performance/directrequest_test.go b/integration-tests/performance/directrequest_test.go index f5fe04576a7..47a16de1091 100644 --- a/integration-tests/performance/directrequest_test.go +++ b/integration-tests/performance/directrequest_test.go @@ -87,8 +87,8 @@ func TestDirectRequestPerformance(t *testing.T) { }) require.NoError(t, err, "Creating direct_request job shouldn't fail") - profileFunction := func(chainlinkNode *client.Chainlink) { - if chainlinkNode != chainlinkNodes[len(chainlinkNodes)-1] { + profileFunction := func(chainlinkNode *client.ChainlinkClient) { + if chainlinkNode != chainlinkNodes[len(chainlinkNodes)-1].ChainlinkClient { // Not the last node, hence not all nodes started profiling yet. return } diff --git a/integration-tests/performance/flux_test.go b/integration-tests/performance/flux_test.go index 0838ccae3bb..ecacce90ca7 100644 --- a/integration-tests/performance/flux_test.go +++ b/integration-tests/performance/flux_test.go @@ -109,8 +109,8 @@ func TestFluxPerformance(t *testing.T) { require.NoError(t, err, "Creating flux job shouldn't fail for node %d", i+1) } - profileFunction := func(chainlinkNode *client.Chainlink) { - if chainlinkNode != chainlinkNodes[len(chainlinkNodes)-1] { + profileFunction := func(chainlinkNode *client.ChainlinkClient) { + if chainlinkNode != chainlinkNodes[len(chainlinkNodes)-1].ChainlinkClient { // Not the last node, hence not all nodes started profiling yet. return } diff --git a/integration-tests/performance/keeper_test.go b/integration-tests/performance/keeper_test.go index 0f900c63dd6..346f0897d47 100644 --- a/integration-tests/performance/keeper_test.go +++ b/integration-tests/performance/keeper_test.go @@ -62,8 +62,8 @@ func TestKeeperPerformance(t *testing.T) { ) gom := gomega.NewGomegaWithT(t) - profileFunction := func(chainlinkNode *client.Chainlink) { - if chainlinkNode != chainlinkNodes[len(chainlinkNodes)-1] { + profileFunction := func(chainlinkNode *client.ChainlinkClient) { + if chainlinkNode != chainlinkNodes[len(chainlinkNodes)-1].ChainlinkClient { // Not the last node, hence not all nodes started profiling yet. return } @@ -130,7 +130,7 @@ func setupKeeperTest( ) ( *environment.Environment, blockchain.EVMClient, - []*client.Chainlink, + []*client.ChainlinkK8sClient, contracts.ContractDeployer, contracts.LinkToken, ) { diff --git a/integration-tests/performance/ocr_test.go b/integration-tests/performance/ocr_test.go index 713767fe7a8..25791161bc2 100644 --- a/integration-tests/performance/ocr_test.go +++ b/integration-tests/performance/ocr_test.go @@ -56,7 +56,7 @@ func TestOCRBasic(t *testing.T) { err = chainClient.WaitForEvents() require.NoError(t, err, "Error waiting for events") - profileFunction := func(chainlinkNode *client.Chainlink) { + profileFunction := func(chainlinkNode *client.ChainlinkClient) { err = actions.CreateOCRJobs(ocrInstances, bootstrapNode, workerNodes, 5, mockServer) require.NoError(t, err) err = actions.StartNewRound(1, ocrInstances, chainClient) diff --git a/integration-tests/performance/vrf_test.go b/integration-tests/performance/vrf_test.go index c14df261d14..2074eecaf78 100644 --- a/integration-tests/performance/vrf_test.go +++ b/integration-tests/performance/vrf_test.go @@ -62,7 +62,7 @@ func TestVRFBasic(t *testing.T) { err = chainClient.WaitForEvents() require.NoError(t, err, "Waiting for event subscriptions in nodes shouldn't fail") - profileFunction := func(chainlinkNode *client.Chainlink) { + profileFunction := func(chainlinkNode *client.ChainlinkClient) { nodeKey, err := chainlinkNode.MustCreateVRFKey() require.NoError(t, err, "Creating VRF key shouldn't fail") l.Debug().Interface("Key JSON", nodeKey).Msg("Created proving key") diff --git a/integration-tests/reorg/automation_reorg_test.go b/integration-tests/reorg/automation_reorg_test.go index a26e0f37f2a..cfc6a2b2968 100644 --- a/integration-tests/reorg/automation_reorg_test.go +++ b/integration-tests/reorg/automation_reorg_test.go @@ -178,7 +178,7 @@ func TestAutomationReorg(t *testing.T) { chainClient, ) - actions.CreateOCRKeeperJobs(t, chainlinkNodes, registry.Address(), network.ChainID, 0) + actions.CreateOCRKeeperJobs(t, chainlinkNodes, registry.Address(), network.ChainID, 0, ethereum.RegistryVersion_2_0) nodesWithoutBootstrap := chainlinkNodes[1:] ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, defaultOCRRegistryConfig, registrar.Address(), 5*time.Second) require.NoError(t, err, "OCR2 config should be built successfully") @@ -186,17 +186,7 @@ func TestAutomationReorg(t *testing.T) { require.NoError(t, err, "Registry config should be be set successfully") require.NoError(t, chainClient.WaitForEvents(), "Waiting for config to be set") - consumers, upkeepIDs := actions.DeployConsumers( - t, - registry, - registrar, - linkToken, - contractDeployer, - chainClient, - numberOfUpkeeps, - big.NewInt(defaultLinkFunds), - defaultUpkeepGasLimit, - ) + consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, false) l.Info().Msg("Waiting for all upkeeps to be performed") diff --git a/integration-tests/reorg/reorg_test.go b/integration-tests/reorg/reorg_test.go index cf124c36887..d6ac5ce1cf1 100644 --- a/integration-tests/reorg/reorg_test.go +++ b/integration-tests/reorg/reorg_test.go @@ -23,15 +23,34 @@ import ( ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" "github.com/smartcontractkit/chainlink-testing-framework/utils" + "context" + "github.com/onsi/gomega" + "github.com/rs/zerolog/log" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" + "github.com/smartcontractkit/chainlink/integration-tests/networks" +) + +const ( + baseDRTOML = ` +[Feature] +LogPoller = true +` + networkDRTOML = ` +Enabled = true +FinalityDepth = %s +LogPollInterval = '1s' + +[EVM.HeadTracker] +HistoryDepth = %s +` ) const ( EVMFinalityDepth = "200" EVMTrackerHistoryDepth = "400" - reorgBlocks = 50 + reorgBlocks = 10 minIncomingConfirmations = "200" timeout = "15m" interval = "2s" @@ -59,7 +78,7 @@ func TestMain(m *testing.M) { func CleanupReorgTest( t *testing.T, testEnvironment *environment.Environment, - chainlinkNodes []*client.Chainlink, + chainlinkNodes []*client.ChainlinkK8sClient, chainClient blockchain.EVMClient, ) { if chainClient != nil { @@ -102,14 +121,10 @@ func TestDirectRequestReorg(t *testing.T) { // related https://app.shortcut.com/chainlinklabs/story/38295/creating-an-evm-chain-via-cli-or-api-immediately-polling-the-nodes-and-returning-an-error // node must work and reconnect even if network is not working time.Sleep(90 * time.Second) + activeEVMNetwork = networks.SimulatedEVMNonDev + netCfg := fmt.Sprintf(networkDRTOML, EVMFinalityDepth, EVMTrackerHistoryDepth) chainlinkDeployment, err := chainlink.NewDeployment(1, map[string]interface{}{ - "env": map[string]interface{}{ - "eth_url": "ws://geth-ethereum-geth:8546", - "eth_http_url": "http://geth-ethereum-geth:8544", - "eth_chain_id": "1337", - "ETH_FINALITY_DEPTH": EVMFinalityDepth, - "ETH_HEAD_TRACKER_HISTORY_DEPTH": EVMTrackerHistoryDepth, - }, + "toml": client.AddNetworkDetailedConfig(baseDRTOML, netCfg, activeEVMNetwork), }) require.NoError(t, err, "Error building Chainlink deployment") err = testEnvironment.AddHelmCharts(chainlinkDeployment).Run() @@ -154,11 +169,11 @@ func TestDirectRequestReorg(t *testing.T) { err = chainlinkNodes[0].MustCreateBridge(&bta) require.NoError(t, err, "Creating bridge shouldn't fail") - os := &client.DirectRequestTxPipelineSpec{ + drps := &client.DirectRequestTxPipelineSpec{ BridgeTypeAttributes: bta, DataPath: "data,result", } - ost, err := os.String() + ost, err := drps.String() require.NoError(t, err, "Building observation source spec shouldn't fail") _, err = chainlinkNodes[0].MustCreateJob(&client.DirectRequestJobSpec{ @@ -199,4 +214,13 @@ func TestDirectRequestReorg(t *testing.T) { err = rc.WaitDepthReached() require.NoError(t, err, "Error waiting for depth to be reached") + + gom := gomega.NewGomegaWithT(t) + gom.Eventually(func(g gomega.Gomega) { + d, err := consumer.Data(context.Background()) + g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Getting data from consumer contract shouldn't fail") + g.Expect(d).ShouldNot(gomega.BeNil(), "Expected the initial on chain data to be nil") + log.Debug().Int64("Data", d.Int64()).Msg("Found on chain") + g.Expect(d.Int64()).Should(gomega.BeNumerically("==", 5), "Expected the on-chain data to be 5, but found %d", d.Int64()) + }, timeout, interval).Should(gomega.Succeed()) } diff --git a/integration-tests/scripts/entrypoint b/integration-tests/scripts/entrypoint index 858a3d83b8d..3955023685d 100755 --- a/integration-tests/scripts/entrypoint +++ b/integration-tests/scripts/entrypoint @@ -2,7 +2,7 @@ # Runs tests for a specific product -set -ex +set -x # get this scripts directory SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) @@ -17,6 +17,14 @@ cd "$SCRIPT_DIR"/../ || exit 1 # run the tests ./${SUITE}.test -test.v -test.count 1 ${ARGS} -test.run ^${TEST_NAME}$ +exit_code=$? + +echo "Test exit code: ${exit_code}" + +if [ $exit_code -eq 2 ]; then # 2 is the code for an interrupted test, we only want to restart the test when the test is interrupted + exit 1 # Exiting with non-zero status to trigger pod restart +fi + # Sleep for the amount of time provided by the POST_RUN_SLEEP env var upload_to_slack() { curl -F file=@$1 -F "initial_comment=$2" -F channels=${SLACK_CHANNEL} -H "Authorization: Bearer ${SLACK_API_KEY}" https://slack.com/api/files.upload diff --git a/integration-tests/smoke/README.md b/integration-tests/smoke/README.md new file mode 100644 index 00000000000..1dedc4e3840 --- /dev/null +++ b/integration-tests/smoke/README.md @@ -0,0 +1,69 @@ +## Smoke tests (local environments) + +These products are using local `testcontainers-go` environments: +- RunLog (Direct request) +- Cron +- Flux +- VRFv1 +- VRFv2 + +### Usage +``` +go test -v -run ${TestName} +``` +### Re-using environments +Configuration is still WIP, but you can make your environment re-usable by providing JSON config. + +Create `test_env.json` in the same dir +``` +export TEST_ENV_CONFIG_PATH=test_env.json +``` + +Here is an example for 3 nodes cluster +``` +{ + "networks": [ + "epic" + ], + "mockserver": { + "container_name": "mockserver", + "external_adapters_mock_urls": [ + "/epico1" + ] + }, + "geth": { + "container_name": "geth" + }, + "nodes": [ + { + "container_name": "cl-node-0", + "db_container_name": "cl-db-0" + }, + { + "container_name": "cl-node-1", + "db_container_name": "cl-db-1" + }, + { + "container_name": "cl-node-2", + "db_container_name": "cl-db-2" + } + ] +} +``` + +### Running against Live Testnets + +``` +SELECTED_NETWORKS= \ +_KEYS= \ +_URLS= \ +_HTTP_URLS= \ +go test -v -run ${TestName} +``` + + + +### Debugging CL client API calls +``` +export CL_CLIENT_DEBUG=true +``` \ No newline at end of file diff --git a/integration-tests/smoke/automation_test.go b/integration-tests/smoke/automation_test.go index fa8a18d1d8b..ab757afe87a 100644 --- a/integration-tests/smoke/automation_test.go +++ b/integration-tests/smoke/automation_test.go @@ -18,8 +18,6 @@ import ( "github.com/smartcontractkit/chainlink-env/logging" "github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink" eth "github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver" - mockservercfg "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver-cfg" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils" @@ -103,101 +101,132 @@ func TestAutomationBasic(t *testing.T) { func SetupAutomationBasic(t *testing.T, nodeUpgrade bool) { t.Parallel() l := utils.GetTestLogger(t) - var ( - upgradeImage string - upgradeVersion string - err error - testName = "basic-upkeep" - ) - if nodeUpgrade { - upgradeImage, err = utils.GetEnv("UPGRADE_IMAGE") - require.NoError(t, err, "Error getting upgrade image") - upgradeVersion, err = utils.GetEnv("UPGRADE_VERSION") - require.NoError(t, err, "Error getting upgrade version") - testName = "node-upgrade" - } - chainClient, chainlinkNodes, contractDeployer, linkToken, registry, registrar, onlyStartRunner, testEnv := setupAutomationTest( - t, testName, ethereum.RegistryVersion_2_0, defaultOCRRegistryConfig, nodeUpgrade, - ) - if onlyStartRunner { - return - } - consumers, upkeepIDs := actions.DeployConsumers( - t, - registry, - registrar, - linkToken, - contractDeployer, - chainClient, - defaultAmountOfUpkeeps, - big.NewInt(automationDefaultLinkFunds), - automationDefaultUpkeepGasLimit, - ) + registryVersions := map[string]ethereum.KeeperRegistryVersion{ + "registry_2_0": ethereum.RegistryVersion_2_0, + "registry_2_1_conditional": ethereum.RegistryVersion_2_1, + "registry_2_1_logtrigger": ethereum.RegistryVersion_2_1, + } - l.Info().Msg("Waiting for all upkeeps to be performed") - gom := gomega.NewGomegaWithT(t) - gom.Eventually(func(g gomega.Gomega) { - // Check if the upkeeps are performing multiple times by analyzing their counters and checking they are greater than 10 - for i := 0; i < len(upkeepIDs); i++ { - counter, err := consumers[i].Counter(context.Background()) - require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i) - expect := 5 - l.Info().Int64("Upkeeps Performed", counter.Int64()).Int("Upkeep ID", i).Msg("Number of upkeeps performed") - g.Expect(counter.Int64()).Should(gomega.BeNumerically(">=", int64(expect)), - "Expected consumer counter to be greater than %d, but got %d", expect, counter.Int64()) - } - }, "5m", "1s").Should(gomega.Succeed()) // ~1m for cluster setup, ~2m for performing each upkeep 5 times, ~2m buffer + for name, registryVersion := range registryVersions { + t.Run(name, func(t *testing.T) { + t.Parallel() + + var ( + upgradeImage string + upgradeVersion string + err error + testName = "basic-upkeep" + ) + if nodeUpgrade { + upgradeImage, err = utils.GetEnv("UPGRADE_IMAGE") + require.NoError(t, err, "Error getting upgrade image") + upgradeVersion, err = utils.GetEnv("UPGRADE_VERSION") + require.NoError(t, err, "Error getting upgrade version") + testName = "node-upgrade" + } + chainClient, chainlinkNodes, contractDeployer, linkToken, registry, registrar, onlyStartRunner, testEnv := setupAutomationTest( + t, testName, registryVersion, defaultOCRRegistryConfig, nodeUpgrade, + ) + if onlyStartRunner { + return + } + + // Use the name to determine if this is a log trigger or not + isLogTrigger := name == "registry_2_1_logtrigger" + + consumers, upkeepIDs := actions.DeployConsumers( + t, + registry, + registrar, + linkToken, + contractDeployer, + chainClient, + defaultAmountOfUpkeeps, + big.NewInt(automationDefaultLinkFunds), + automationDefaultUpkeepGasLimit, + isLogTrigger, + ) + + l.Info().Msg("Waiting for all upkeeps to be performed") + gom := gomega.NewGomegaWithT(t) + + // Wait for 30 seconds to allow everything to be ready before emitting logs + time.Sleep(30 * time.Second) + for i := 0; i < len(upkeepIDs); i++ { + err := consumers[i].Start() + if err != nil { + return + } + } - if nodeUpgrade { - expect := 5 - // Upgrade the nodes one at a time and check that the upkeeps are still being performed - for i := 0; i < 5; i++ { - actions.UpgradeChainlinkNodeVersions(testEnv, upgradeImage, upgradeVersion, chainlinkNodes[i]) - time.Sleep(time.Second * 10) - expect = expect + 5 + startTime := time.Now() + // TODO Tune this timeout window after stress testing gom.Eventually(func(g gomega.Gomega) { - // Check if the upkeeps are performing multiple times by analyzing their counters and checking they are increasing by 5 in each step within 5 minutes + // Check if the upkeeps are performing multiple times by analyzing their counters for i := 0; i < len(upkeepIDs); i++ { counter, err := consumers[i].Counter(context.Background()) require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i) - l.Info().Int64("Upkeeps Performed", counter.Int64()).Int("Upkeep ID", i).Msg("Number of upkeeps performed") + expect := 5 + l.Info().Int64("Upkeeps Performed", counter.Int64()).Int("Upkeep Index", i).Msg("Number of upkeeps performed") g.Expect(counter.Int64()).Should(gomega.BeNumerically(">=", int64(expect)), "Expected consumer counter to be greater than %d, but got %d", expect, counter.Int64()) } - }, "5m", "1s").Should(gomega.Succeed()) - } - } + }, "5m", "1s").Should(gomega.Succeed()) // ~1m for cluster setup, ~2m for performing each upkeep 5 times, ~2m buffer + + l.Info().Msgf("Total time taken to get 5 performs for each upkeep: %s", time.Since(startTime)) + + if nodeUpgrade { + expect := 5 + // Upgrade the nodes one at a time and check that the upkeeps are still being performed + for i := 0; i < 5; i++ { + actions.UpgradeChainlinkNodeVersions(testEnv, upgradeImage, upgradeVersion, chainlinkNodes[i]) + time.Sleep(time.Second * 10) + expect = expect + 5 + gom.Eventually(func(g gomega.Gomega) { + // Check if the upkeeps are performing multiple times by analyzing their counters and checking they are increasing by 5 in each step within 5 minutes + for i := 0; i < len(upkeepIDs); i++ { + counter, err := consumers[i].Counter(context.Background()) + require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i) + l.Info().Int64("Upkeeps Performed", counter.Int64()).Int("Upkeep ID", i).Msg("Number of upkeeps performed") + g.Expect(counter.Int64()).Should(gomega.BeNumerically(">=", int64(expect)), + "Expected consumer counter to be greater than %d, but got %d", expect, counter.Int64()) + } + }, "5m", "1s").Should(gomega.Succeed()) + } + } - // Cancel all the registered upkeeps via the registry - for i := 0; i < len(upkeepIDs); i++ { - err := registry.CancelUpkeep(upkeepIDs[i]) - require.NoError(t, err, "Could not cancel upkeep at index %d", i) - } + // Cancel all the registered upkeeps via the registry + for i := 0; i < len(upkeepIDs); i++ { + err := registry.CancelUpkeep(upkeepIDs[i]) + require.NoError(t, err, "Could not cancel upkeep at index %d", i) + } - err = chainClient.WaitForEvents() - require.NoError(t, err, "Error encountered when waiting for upkeeps to be cancelled") + err = chainClient.WaitForEvents() + require.NoError(t, err, "Error encountered when waiting for upkeeps to be cancelled") - var countersAfterCancellation = make([]*big.Int, len(upkeepIDs)) + var countersAfterCancellation = make([]*big.Int, len(upkeepIDs)) - for i := 0; i < len(upkeepIDs); i++ { - // Obtain the amount of times the upkeep has been executed so far - countersAfterCancellation[i], err = consumers[i].Counter(context.Background()) - require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i) - l.Info().Int64("Upkeep Count", countersAfterCancellation[i].Int64()).Int("Upkeep Index", i).Msg("Cancelled upkeep") - } + for i := 0; i < len(upkeepIDs); i++ { + // Obtain the amount of times the upkeep has been executed so far + countersAfterCancellation[i], err = consumers[i].Counter(context.Background()) + require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i) + l.Info().Int64("Upkeep Count", countersAfterCancellation[i].Int64()).Int("Upkeep Index", i).Msg("Cancelled upkeep") + } - l.Info().Msg("Making sure the counter stays consistent") - gom.Consistently(func(g gomega.Gomega) { - for i := 0; i < len(upkeepIDs); i++ { - // Expect the counter to remain constant (At most increase by 1 to account for stale performs) because the upkeep was cancelled - latestCounter, err := consumers[i].Counter(context.Background()) - g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i) - g.Expect(latestCounter.Int64()).Should(gomega.BeNumerically("<=", countersAfterCancellation[i].Int64()+1), - "Expected consumer counter to remain less than or equal to %d, but got %d", - countersAfterCancellation[i].Int64()+1, latestCounter.Int64()) - } - }, "1m", "1s").Should(gomega.Succeed()) + l.Info().Msg("Making sure the counter stays consistent") + gom.Consistently(func(g gomega.Gomega) { + for i := 0; i < len(upkeepIDs); i++ { + // Expect the counter to remain constant (At most increase by 1 to account for stale performs) because the upkeep was cancelled + latestCounter, err := consumers[i].Counter(context.Background()) + g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i) + g.Expect(latestCounter.Int64()).Should(gomega.BeNumerically("<=", countersAfterCancellation[i].Int64()+1), + "Expected consumer counter to remain less than or equal to %d, but got %d", + countersAfterCancellation[i].Int64()+1, latestCounter.Int64()) + } + }, "1m", "1s").Should(gomega.Succeed()) + }) + } } func TestAutomationAddFunds(t *testing.T) { @@ -210,17 +239,7 @@ func TestAutomationAddFunds(t *testing.T) { return } - consumers, upkeepIDs := actions.DeployConsumers( - t, - registry, - registrar, - linkToken, - contractDeployer, - chainClient, - defaultAmountOfUpkeeps, - big.NewInt(1), - automationDefaultUpkeepGasLimit, - ) + consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, defaultAmountOfUpkeeps, big.NewInt(1), automationDefaultUpkeepGasLimit, false) gom := gomega.NewGomegaWithT(t) // Since the upkeep is currently underfunded, check that it doesn't get executed @@ -263,17 +282,7 @@ func TestAutomationPauseUnPause(t *testing.T) { return } - consumers, upkeepIDs := actions.DeployConsumers( - t, - registry, - registrar, - linkToken, - contractDeployer, - chainClient, - defaultAmountOfUpkeeps, - big.NewInt(automationDefaultLinkFunds), - automationDefaultUpkeepGasLimit, - ) + consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false) gom := gomega.NewGomegaWithT(t) gom.Eventually(func(g gomega.Gomega) { @@ -347,17 +356,7 @@ func TestAutomationRegisterUpkeep(t *testing.T) { return } - consumers, upkeepIDs := actions.DeployConsumers( - t, - registry, - registrar, - linkToken, - contractDeployer, - chainClient, - defaultAmountOfUpkeeps, - big.NewInt(automationDefaultLinkFunds), - automationDefaultUpkeepGasLimit, - ) + consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false) var initialCounters = make([]*big.Int, len(upkeepIDs)) gom := gomega.NewGomegaWithT(t) @@ -420,17 +419,7 @@ func TestAutomationPauseRegistry(t *testing.T) { return } - consumers, upkeepIDs := actions.DeployConsumers( - t, - registry, - registrar, - linkToken, - contractDeployer, - chainClient, - defaultAmountOfUpkeeps, - big.NewInt(automationDefaultLinkFunds), - automationDefaultUpkeepGasLimit, - ) + consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false) gom := gomega.NewGomegaWithT(t) // Observe that the upkeeps which are initially registered are performing @@ -479,17 +468,7 @@ func TestAutomationKeeperNodesDown(t *testing.T) { return } - consumers, upkeepIDs := actions.DeployConsumers( - t, - registry, - registrar, - linkToken, - contractDeployer, - chainClient, - defaultAmountOfUpkeeps, - big.NewInt(automationDefaultLinkFunds), - automationDefaultUpkeepGasLimit, - ) + consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false) gom := gomega.NewGomegaWithT(t) nodesWithoutBootstrap := chainlinkNodes[1:] @@ -785,7 +764,7 @@ func setupAutomationTest( statefulDb bool, ) ( chainClient blockchain.EVMClient, - chainlinkNodes []*client.Chainlink, + chainlinkNodes []*client.ChainlinkK8sClient, contractDeployer contracts.ContractDeployer, linkToken contracts.LinkToken, registry contracts.KeeperRegistry, @@ -793,6 +772,9 @@ func setupAutomationTest( onlyStartRunner bool, testEnvironment *environment.Environment, ) { + // Add registry version to config + registryConfig.RegistryVersion = registryVersion + network := networks.SelectedNetwork evmConfig := eth.New(nil) if !network.Simulated { @@ -816,8 +798,6 @@ func setupAutomationTest( NamespacePrefix: fmt.Sprintf("smoke-automation-%s-%s", testName, strings.ReplaceAll(strings.ToLower(network.Name), " ", "-")), Test: t, }). - AddHelm(mockservercfg.New(nil)). - AddHelm(mockserver.New(nil)). AddHelm(evmConfig). AddHelmCharts(cd) err = testEnvironment.Run() @@ -852,7 +832,7 @@ func setupAutomationTest( chainClient, ) - actions.CreateOCRKeeperJobs(t, chainlinkNodes, registry.Address(), network.ChainID, 0) + actions.CreateOCRKeeperJobs(t, chainlinkNodes, registry.Address(), network.ChainID, 0, registryVersion) nodesWithoutBootstrap := chainlinkNodes[1:] ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, registryConfig, registrar.Address(), 5*time.Second) require.NoError(t, err, "Error building OCR config vars") diff --git a/integration-tests/smoke/cron_test.go b/integration-tests/smoke/cron_test.go index d11007e1f66..30eadb8f16b 100644 --- a/integration-tests/smoke/cron_test.go +++ b/integration-tests/smoke/cron_test.go @@ -2,56 +2,35 @@ package smoke import ( "fmt" - "strings" - "testing" - "github.com/google/uuid" "github.com/onsi/gomega" - "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" - - "github.com/smartcontractkit/chainlink-env/environment" - "github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver" - mockservercfg "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver-cfg" - ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" - "github.com/smartcontractkit/chainlink-testing-framework/utils" - - "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" - "github.com/smartcontractkit/chainlink/integration-tests/networks" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + "github.com/stretchr/testify/require" + "testing" ) func TestCronBasic(t *testing.T) { t.Parallel() - testEnvironment := setupCronTest(t) - if testEnvironment.WillUseRemoteRunner() { - return - } - chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment) - require.NoError(t, err, "Connecting to chainlink nodes shouldn't fail") - mockServer, err := ctfClient.ConnectMockServer(testEnvironment) - require.NoError(t, err, "Creating mockserver client shouldn't fail") - chainlinkNode := chainlinkNodes[0] - err = mockServer.SetValuePath("/variable", 5) + env, err := test_env.NewCLTestEnvBuilder(). + WithGeth(). + WithMockServer(1). + WithCLNodes(1). + Build() + require.NoError(t, err) + err = env.MockServer.Client.SetValuePath("/variable", 5) require.NoError(t, err, "Setting value path in mockserver shouldn't fail") - // Register cleanup for any test - t.Cleanup(func() { - err := actions.TeardownSuite(t, testEnvironment, utils.ProjectRoot, chainlinkNodes, nil, zapcore.ErrorLevel, nil) - require.NoError(t, err, "Error tearing down environment") - }) bta := &client.BridgeTypeAttributes{ - Name: fmt.Sprintf("variable-%s", uuid.New().String()), - URL: fmt.Sprintf("%s/variable", mockServer.Config.ClusterURL), + Name: fmt.Sprintf("variable-%s", uuid.NewString()), + URL: fmt.Sprintf("%s/variable", env.MockServer.InternalEndpoint), RequestData: "{}", } - err = chainlinkNode.MustCreateBridge(bta) + err = env.CLNodes[0].API.MustCreateBridge(bta) require.NoError(t, err, "Creating bridge in chainlink node shouldn't fail") - job, err := chainlinkNode.MustCreateJob(&client.CronJobSpec{ + job, err := env.CLNodes[0].API.MustCreateJob(&client.CronJobSpec{ Schedule: "CRON_TZ=UTC * * * * * *", ObservationSource: client.ObservationSourceSpecBridge(bta), }) @@ -59,7 +38,7 @@ func TestCronBasic(t *testing.T) { gom := gomega.NewGomegaWithT(t) gom.Eventually(func(g gomega.Gomega) { - jobRuns, err := chainlinkNode.MustReadRunsByJob(job.Data.ID) + jobRuns, err := env.CLNodes[0].API.MustReadRunsByJob(job.Data.ID) g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Reading Job run data shouldn't fail") g.Expect(len(jobRuns.Data)).Should(gomega.BeNumerically(">=", 5), "Expected number of job runs to be greater than 5, but got %d", len(jobRuns.Data)) @@ -67,32 +46,5 @@ func TestCronBasic(t *testing.T) { for _, jr := range jobRuns.Data { g.Expect(jr.Attributes.Errors).Should(gomega.Equal([]interface{}{nil}), "Job run %s shouldn't have errors", jr.ID) } - }, "2m", "1s").Should(gomega.Succeed()) -} - -func setupCronTest(t *testing.T) (testEnvironment *environment.Environment) { - network := networks.SelectedNetwork - evmConfig := ethereum.New(nil) - if !network.Simulated { - evmConfig = ethereum.New(ðereum.Props{ - NetworkName: network.Name, - Simulated: network.Simulated, - WsURLs: network.URLs, - }) - } - cd, err := chainlink.NewDeployment(1, map[string]interface{}{ - "toml": client.AddNetworksConfig("", network), - }) - require.NoError(t, err, "Error creating chainlink deployment") - testEnvironment = environment.New(&environment.Config{ - NamespacePrefix: fmt.Sprintf("smoke-cron-%s", strings.ReplaceAll(strings.ToLower(network.Name), " ", "-")), - Test: t, - }). - AddHelm(mockservercfg.New(nil)). - AddHelm(mockserver.New(nil)). - AddHelm(evmConfig). - AddHelmCharts(cd) - err = testEnvironment.Run() - require.NoError(t, err, "Error launching test environment") - return testEnvironment + }, "20m", "3s").Should(gomega.Succeed()) } diff --git a/integration-tests/smoke/flux_test.go b/integration-tests/smoke/flux_test.go index b13b078a47d..da06fc4b57a 100644 --- a/integration-tests/smoke/flux_test.go +++ b/integration-tests/smoke/flux_test.go @@ -3,79 +3,56 @@ package smoke import ( "context" "fmt" - "math/big" - "strings" - "testing" - "time" - "github.com/ethereum/go-ethereum/common" "github.com/google/uuid" - "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" - - "github.com/smartcontractkit/chainlink-env/environment" - "github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver" - mockservercfg "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver-cfg" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" "github.com/smartcontractkit/chainlink-testing-framework/utils" - "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" - "github.com/smartcontractkit/chainlink/integration-tests/networks" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + "github.com/stretchr/testify/require" + "math/big" + "strings" + "testing" + "time" ) func TestFluxBasic(t *testing.T) { t.Parallel() l := utils.GetTestLogger(t) - testEnvironment, testNetwork := setupFluxTest(t) - if testEnvironment.WillUseRemoteRunner() { - return - } - - chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment) - require.NoError(t, err, "Connecting to blockchain nodes shouldn't fail") - contractDeployer, err := contracts.NewContractDeployer(chainClient) - require.NoError(t, err, "Deploying contracts shouldn't fail") - chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment) - require.NoError(t, err, "Connecting to chainlink nodes shouldn't fail") - nodeAddresses, err := actions.ChainlinkNodeAddresses(chainlinkNodes) - require.NoError(t, err, "Retreiving on-chain wallet addresses for chainlink nodes shouldn't fail") - mockServer, err := ctfClient.ConnectMockServer(testEnvironment) - require.NoError(t, err, "Creating mock server client shouldn't fail") - // Register cleanup - t.Cleanup(func() { - err := actions.TeardownSuite(t, testEnvironment, utils.ProjectRoot, chainlinkNodes, nil, zapcore.ErrorLevel, chainClient) - require.NoError(t, err, "Error tearing down environment") - }) - - chainClient.ParallelTransactions(true) - adapterUUID := uuid.New().String() + env, err := test_env.NewCLTestEnvBuilder(). + WithGeth(). + WithMockServer(1). + WithCLNodes(3). + Build() + require.NoError(t, err) + nodeAddresses, err := env.ChainlinkNodeAddresses() + require.NoError(t, err, "Retrieving on-chain wallet addresses for chainlink nodes shouldn't fail") + env.EVMClient.ParallelTransactions(true) + + adapterUUID := uuid.NewString() adapterPath := fmt.Sprintf("/variable-%s", adapterUUID) - err = mockServer.SetValuePath(adapterPath, 1e5) + err = env.MockServer.Client.SetValuePath(adapterPath, 1e5) require.NoError(t, err, "Setting mockserver value path shouldn't fail") - linkToken, err := contractDeployer.DeployLinkTokenContract() + lt, err := actions.DeployLINKToken(env.ContractDeployer) require.NoError(t, err, "Deploying Link Token Contract shouldn't fail") - fluxInstance, err := contractDeployer.DeployFluxAggregatorContract(linkToken.Address(), contracts.DefaultFluxAggregatorOptions()) + fluxInstance, err := env.ContractDeployer.DeployFluxAggregatorContract(lt.Address(), contracts.DefaultFluxAggregatorOptions()) require.NoError(t, err, "Deploying Flux Aggregator Contract shouldn't fail") - err = chainClient.WaitForEvents() + err = env.EVMClient.WaitForEvents() require.NoError(t, err, "Failed waiting for deployment of flux aggregator contract") - err = linkToken.Transfer(fluxInstance.Address(), big.NewInt(1e18)) + err = lt.Transfer(fluxInstance.Address(), big.NewInt(1e18)) require.NoError(t, err, "Funding Flux Aggregator Contract shouldn't fail") - err = chainClient.WaitForEvents() + err = env.EVMClient.WaitForEvents() require.NoError(t, err, "Failed waiting for funding of flux aggregator contract") err = fluxInstance.UpdateAvailableFunds() require.NoError(t, err, "Updating the available funds on the Flux Aggregator Contract shouldn't fail") - err = actions.FundChainlinkNodes(chainlinkNodes, chainClient, big.NewFloat(.02)) - require.NoError(t, err, "Funding chainlink nodes with ETH shouldn't fail") + err = env.FundChainlinkNodes(big.NewFloat(1)) + require.NoError(t, err, "Failed to fund the nodes") err = fluxInstance.SetOracles( contracts.FluxAggregatorSetOraclesOptions{ @@ -87,19 +64,21 @@ func TestFluxBasic(t *testing.T) { RestartDelayRounds: 0, }) require.NoError(t, err, "Setting oracle options in the Flux Aggregator contract shouldn't fail") - err = chainClient.WaitForEvents() + + err = env.EVMClient.WaitForEvents() require.NoError(t, err, "Waiting for event subscriptions in nodes shouldn't fail") oracles, err := fluxInstance.GetOracles(context.Background()) require.NoError(t, err, "Getting oracle details from the Flux aggregator contract shouldn't fail") l.Info().Str("Oracles", strings.Join(oracles, ",")).Msg("Oracles set") - adapterFullURL := fmt.Sprintf("%s%s", mockServer.Config.ClusterURL, adapterPath) + adapterFullURL := fmt.Sprintf("%s%s", env.MockServer.Client.Config.ClusterURL, adapterPath) + l.Info().Str("AdapterFullURL", adapterFullURL).Send() bta := &client.BridgeTypeAttributes{ Name: fmt.Sprintf("variable-%s", adapterUUID), URL: adapterFullURL, } - for i, n := range chainlinkNodes { - err = n.MustCreateBridge(bta) + for i, n := range env.CLNodes { + err = n.API.MustCreateBridge(bta) require.NoError(t, err, "Creating bridge shouldn't fail for node %d", i+1) fluxSpec := &client.FluxMonitorJobSpec{ @@ -111,19 +90,18 @@ func TestFluxBasic(t *testing.T) { IdleTimerDisabled: true, ObservationSource: client.ObservationSourceSpecBridge(bta), } - _, err = n.MustCreateJob(fluxSpec) + _, err = n.API.MustCreateJob(fluxSpec) require.NoError(t, err, "Creating flux job shouldn't fail for node %d", i+1) } // initial value set is performed before jobs creation - fluxRoundTimeout := 2 * time.Minute + fluxRoundTimeout := 1 * time.Minute fluxRound := contracts.NewFluxAggregatorRoundConfirmer(fluxInstance, big.NewInt(1), fluxRoundTimeout) - chainClient.AddHeaderEventSubscription(fluxInstance.Address(), fluxRound) - err = chainClient.WaitForEvents() + env.EVMClient.AddHeaderEventSubscription(fluxInstance.Address(), fluxRound) + err = env.EVMClient.WaitForEvents() require.NoError(t, err, "Waiting for event subscriptions in nodes shouldn't fail") data, err := fluxInstance.GetContractData(context.Background()) require.NoError(t, err, "Getting contract data from flux aggregator contract shouldn't fail") - l.Info().Interface("Data", data).Msg("Round data") require.Equal(t, int64(1e5), data.LatestRoundData.Answer.Int64(), "Expected latest round answer to be %d, but found %d", int64(1e5), data.LatestRoundData.Answer.Int64()) require.Equal(t, int64(1), data.LatestRoundData.RoundId.Int64(), @@ -136,10 +114,10 @@ func TestFluxBasic(t *testing.T) { "Expected allocated funds to be %d, but found %d", int64(3), data.AllocatedFunds.Int64()) fluxRound = contracts.NewFluxAggregatorRoundConfirmer(fluxInstance, big.NewInt(2), fluxRoundTimeout) - chainClient.AddHeaderEventSubscription(fluxInstance.Address(), fluxRound) - err = mockServer.SetValuePath(adapterPath, 1e10) + env.EVMClient.AddHeaderEventSubscription(fluxInstance.Address(), fluxRound) + err = env.MockServer.Client.SetValuePath(adapterPath, 1e10) require.NoError(t, err, "Setting value path in mock server shouldn't fail") - err = chainClient.WaitForEvents() + err = env.EVMClient.WaitForEvents() require.NoError(t, err, "Waiting for event subscriptions in nodes shouldn't fail") data, err = fluxInstance.GetContractData(context.Background()) require.NoError(t, err, "Getting contract data from flux aggregator contract shouldn't fail") @@ -159,32 +137,3 @@ func TestFluxBasic(t *testing.T) { "Expected flux aggregator contract's withdrawable payment to be %d, but found %d", int64(2), payment.Int64()) } } - -func setupFluxTest(t *testing.T) (testEnvironment *environment.Environment, testNetwork blockchain.EVMNetwork) { - testNetwork = networks.SelectedNetwork - evmConf := ethereum.New(nil) - if !testNetwork.Simulated { - evmConf = ethereum.New(ðereum.Props{ - NetworkName: testNetwork.Name, - Simulated: testNetwork.Simulated, - WsURLs: testNetwork.URLs, - }) - } - baseTOML := `[OCR] -Enabled = true` - cd, err := chainlink.NewDeployment(3, map[string]interface{}{ - "toml": client.AddNetworksConfig(baseTOML, testNetwork), - }) - require.NoError(t, err, "Error creating chainlink deployment") - testEnvironment = environment.New(&environment.Config{ - NamespacePrefix: fmt.Sprintf("smoke-flux-%s", strings.ReplaceAll(strings.ToLower(testNetwork.Name), " ", "-")), - Test: t, - }). - AddHelm(mockservercfg.New(nil)). - AddHelm(mockserver.New(nil)). - AddHelm(evmConf). - AddHelmCharts(cd) - err = testEnvironment.Run() - require.NoError(t, err, "Error running test environment") - return testEnvironment, testNetwork -} diff --git a/integration-tests/smoke/forwarder_ocr_test.go b/integration-tests/smoke/forwarder_ocr_test.go index bbcaedc9f10..0b58be41d74 100644 --- a/integration-tests/smoke/forwarder_ocr_test.go +++ b/integration-tests/smoke/forwarder_ocr_test.go @@ -1,139 +1,81 @@ package smoke import ( - "context" - "fmt" "math/big" - "strings" "testing" + "context" "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" - - "github.com/smartcontractkit/chainlink-env/environment" - "github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver" - mockservercfg "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver-cfg" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" - "github.com/smartcontractkit/chainlink-testing-framework/utils" - "github.com/smartcontractkit/chainlink/integration-tests/actions" - "github.com/smartcontractkit/chainlink/integration-tests/client" - "github.com/smartcontractkit/chainlink/integration-tests/contracts" - "github.com/smartcontractkit/chainlink/integration-tests/networks" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + "github.com/stretchr/testify/require" ) func TestForwarderOCRBasic(t *testing.T) { t.Parallel() - testEnvironment, testNetwork := setupForwarderOCRTest(t) - if testEnvironment.WillUseRemoteRunner() { - return - } + env, err := test_env.NewCLTestEnvBuilder(). + WithGeth(). + WithMockServer(1). + WithForwarders(). + WithCLNodes(6). + WithFunding(big.NewFloat(10)). + Build() + require.NoError(t, err) + env.ParallelTransactions(true) - chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment) - require.NoError(t, err, "Connecting to blockchain nodes shouldn't fail") - contractDeployer, err := contracts.NewContractDeployer(chainClient) - require.NoError(t, err, "Deploying contracts shouldn't fail") - contractLoader, err := contracts.NewContractLoader(chainClient) - require.NoError(t, err, "Loading contracts shouldn't fail") - chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment) - require.NoError(t, err, "Connecting to chainlink nodes shouldn't fail") - bootstrapNode, workerNodes := chainlinkNodes[0], chainlinkNodes[1:] - workerNodeAddresses, err := actions.ChainlinkNodeAddresses(workerNodes) - require.NoError(t, err, "Retreiving on-chain wallet addresses for chainlink nodes shouldn't fail") - mockServer, err := ctfClient.ConnectMockServer(testEnvironment) - require.NoError(t, err, "Creating mockserver clients shouldn't fail") + nodeClients := env.GetAPIs() + bootstrapNode, workerNodes := nodeClients[0], nodeClients[1:] - t.Cleanup(func() { - err := actions.TeardownSuite(t, testEnvironment, utils.ProjectRoot, chainlinkNodes, nil, zapcore.ErrorLevel, chainClient) - require.NoError(t, err, "Error tearing down environment") - }) - chainClient.ParallelTransactions(true) + workerNodeAddresses, err := actions.ChainlinkNodeAddressesLocal(workerNodes) + require.NoError(t, err, "Retreiving on-chain wallet addresses for chainlink nodes shouldn't fail") - linkTokenContract, err := contractDeployer.DeployLinkTokenContract() + linkTokenContract, err := env.ContractDeployer.DeployLinkTokenContract() require.NoError(t, err, "Deploying Link Token Contract shouldn't fail") - err = actions.FundChainlinkNodes(workerNodes, chainClient, big.NewFloat(.05)) + err = actions.FundChainlinkNodesLocal(workerNodes, env.EVMClient, big.NewFloat(.05)) require.NoError(t, err, "Error funding Chainlink nodes") operators, authorizedForwarders, _ := actions.DeployForwarderContracts( - t, contractDeployer, linkTokenContract, chainClient, len(workerNodes), + t, env.ContractDeployer, linkTokenContract, env.EVMClient, len(workerNodes), ) for i := range workerNodes { actions.AcceptAuthorizedReceiversOperator( - t, operators[i], authorizedForwarders[i], []common.Address{workerNodeAddresses[i]}, chainClient, contractLoader, + t, operators[i], authorizedForwarders[i], []common.Address{workerNodeAddresses[i]}, env.EVMClient, env.ContractLoader, ) require.NoError(t, err, "Accepting Authorize Receivers on Operator shouldn't fail") - actions.TrackForwarder(t, chainClient, authorizedForwarders[i], workerNodes[i]) - err = chainClient.WaitForEvents() + err = actions.TrackForwarderLocal(env.EVMClient, authorizedForwarders[i], workerNodes[i]) + require.NoError(t, err) + err = env.EVMClient.WaitForEvents() } - ocrInstances := actions.DeployOCRContractsForwarderFlow( - t, 1, linkTokenContract, contractDeployer, workerNodes, authorizedForwarders, chainClient, + ocrInstances, err := actions.DeployOCRContractsForwarderFlowLocal( + 1, + linkTokenContract, + env.ContractDeployer, + workerNodes, + authorizedForwarders, + env.EVMClient, ) - err = chainClient.WaitForEvents() - require.NoError(t, err, "Error waiting for events") - actions.CreateOCRJobsWithForwarder(t, ocrInstances, bootstrapNode, workerNodes, 5, mockServer) - err = actions.StartNewRound(1, ocrInstances, chainClient) + err = actions.CreateOCRJobsWithForwarderLocal(ocrInstances, bootstrapNode, workerNodes, 5, env.MockServer.Client) + require.NoError(t, err, "failed to setup forwarder jobs") + err = actions.StartNewRound(1, ocrInstances, env.EVMClient) require.NoError(t, err) - err = chainClient.WaitForEvents() + err = env.EVMClient.WaitForEvents() require.NoError(t, err, "Error waiting for events") + //time.Sleep(999 * time.Second) answer, err := ocrInstances[0].GetLatestAnswer(context.Background()) require.NoError(t, err, "Getting latest answer from OCR contract shouldn't fail") require.Equal(t, int64(5), answer.Int64(), "Expected latest answer from OCR contract to be 5 but got %d", answer.Int64()) - err = actions.SetAllAdapterResponsesToTheSameValue(10, ocrInstances, workerNodes, mockServer) + err = actions.SetAllAdapterResponsesToTheSameValueLocal(10, ocrInstances, workerNodes, env.MockServer.Client) require.NoError(t, err) - err = actions.StartNewRound(2, ocrInstances, chainClient) + err = actions.StartNewRound(2, ocrInstances, env.EVMClient) require.NoError(t, err) - err = chainClient.WaitForEvents() + err = env.EVMClient.WaitForEvents() require.NoError(t, err, "Error waiting for events") answer, err = ocrInstances[0].GetLatestAnswer(context.Background()) require.NoError(t, err, "Error getting latest OCR answer") require.Equal(t, int64(10), answer.Int64(), "Expected latest answer from OCR contract to be 10 but got %d", answer.Int64()) } - -func setupForwarderOCRTest(t *testing.T) (testEnvironment *environment.Environment, testNetwork blockchain.EVMNetwork) { - testNetwork = networks.SelectedNetwork - evmConfig := ethereum.New(nil) - if !testNetwork.Simulated { - evmConfig = ethereum.New(ðereum.Props{ - NetworkName: testNetwork.Name, - Simulated: testNetwork.Simulated, - WsURLs: testNetwork.URLs, - }) - } - baseTOML := `[OCR] -Enabled = true - -[Feature] -LogPoller = true - -[P2P] -[P2P.V1] -Enabled = true -ListenIP = '0.0.0.0' -ListenPort = 6690` - networkDetailTOML := `[EVM.Transactions] -ForwardersEnabled = true` - cd, err := chainlink.NewDeployment(6, map[string]interface{}{ - "toml": client.AddNetworkDetailedConfig(baseTOML, networkDetailTOML, testNetwork), - }) - require.NoError(t, err, "Error creating chainlink deployment") - testEnvironment = environment.New(&environment.Config{ - NamespacePrefix: fmt.Sprintf("smoke-ocr-forwarder-%s", strings.ReplaceAll(strings.ToLower(testNetwork.Name), " ", "-")), - Test: t, - }). - AddHelm(mockservercfg.New(nil)). - AddHelm(mockserver.New(nil)). - AddHelm(evmConfig). - AddHelmCharts(cd) - err = testEnvironment.Run() - require.NoError(t, err, "Error running test environment") - return testEnvironment, testNetwork -} diff --git a/integration-tests/smoke/forwarders_ocr2_test.go b/integration-tests/smoke/forwarders_ocr2_test.go index 2674067cf8b..cb6a3f0556d 100644 --- a/integration-tests/smoke/forwarders_ocr2_test.go +++ b/integration-tests/smoke/forwarders_ocr2_test.go @@ -9,60 +9,50 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" - - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" - "github.com/smartcontractkit/chainlink-testing-framework/utils" "github.com/smartcontractkit/chainlink/integration-tests/actions" - "github.com/smartcontractkit/chainlink/integration-tests/client" - "github.com/smartcontractkit/chainlink/integration-tests/contracts" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" ) func TestForwarderOCR2Basic(t *testing.T) { t.Parallel() - testEnvironment, testNetwork := setupOCR2Test(t, true) - if testEnvironment.WillUseRemoteRunner() { - return - } + env, err := test_env.NewCLTestEnvBuilder(). + WithGeth(). + WithMockServer(1). + WithCLNodeConfig(node.NewConfig(node.BaseConf, + node.WithOCR2(), + node.WithP2Pv2(), + )). + WithForwarders(). + WithCLNodes(6). + WithFunding(big.NewFloat(10)). + Build() + require.NoError(t, err) + env.ParallelTransactions(true) + + nodeClients := env.GetAPIs() + bootstrapNode, workerNodes := nodeClients[0], nodeClients[1:] - chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment) - require.NoError(t, err, "Connecting to blockchain nodes shouldn't fail") - contractDeployer, err := contracts.NewContractDeployer(chainClient) - require.NoError(t, err, "Deploying contracts shouldn't fail") - contractLoader, err := contracts.NewContractLoader(chainClient) - require.NoError(t, err, "Loading contracts shouldn't fail") - - chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment) - require.NoError(t, err, "Connecting to chainlink nodes shouldn't fail") - bootstrapNode, workerNodes := chainlinkNodes[0], chainlinkNodes[1:] - workerNodeAddresses, err := actions.ChainlinkNodeAddresses(workerNodes) + workerNodeAddresses, err := actions.ChainlinkNodeAddressesLocal(workerNodes) require.NoError(t, err, "Retreiving on-chain wallet addresses for chainlink nodes shouldn't fail") - mockServer, err := ctfClient.ConnectMockServer(testEnvironment) - require.NoError(t, err, "Creating mockserver clients shouldn't fail") - t.Cleanup(func() { - err := actions.TeardownSuite(t, testEnvironment, utils.ProjectRoot, chainlinkNodes, nil, zapcore.ErrorLevel, chainClient) - require.NoError(t, err, "Error tearing down environment") - }) - chainClient.ParallelTransactions(true) - - linkTokenContract, err := contractDeployer.DeployLinkTokenContract() + + linkTokenContract, err := env.ContractDeployer.DeployLinkTokenContract() require.NoError(t, err, "Deploying Link Token Contract shouldn't fail") - err = actions.FundChainlinkNodes(workerNodes, chainClient, big.NewFloat(.05)) + err = actions.FundChainlinkNodesLocal(workerNodes, env.EVMClient, big.NewFloat(.05)) require.NoError(t, err, "Error funding Chainlink nodes") operators, authorizedForwarders, _ := actions.DeployForwarderContracts( - t, contractDeployer, linkTokenContract, chainClient, len(workerNodes), + t, env.ContractDeployer, linkTokenContract, env.EVMClient, len(workerNodes), ) for i := range workerNodes { - actions.AcceptAuthorizedReceiversOperator(t, operators[i], authorizedForwarders[i], []common.Address{workerNodeAddresses[i]}, chainClient, contractLoader) + actions.AcceptAuthorizedReceiversOperator(t, operators[i], authorizedForwarders[i], []common.Address{workerNodeAddresses[i]}, env.EVMClient, env.ContractLoader) require.NoError(t, err, "Accepting Authorized Receivers on Operator shouldn't fail") - actions.TrackForwarder(t, chainClient, authorizedForwarders[i], workerNodes[i]) - err = chainClient.WaitForEvents() - + err = actions.TrackForwarderLocal(env.EVMClient, authorizedForwarders[i], workerNodes[i]) + require.NoError(t, err, "failed to track forwarders") + err = env.EVMClient.WaitForEvents() require.NoError(t, err, "Error waiting for events") } @@ -72,25 +62,24 @@ func TestForwarderOCR2Basic(t *testing.T) { transmitters = append(transmitters, forwarderCommonAddress.Hex()) } - ocrInstances, err := actions.DeployOCRv2Contracts(1, linkTokenContract, contractDeployer, transmitters, chainClient) - + ocrInstances, err := actions.DeployOCRv2Contracts(1, linkTokenContract, env.ContractDeployer, transmitters, env.EVMClient) require.NoError(t, err, "Error deploying OCRv2 contracts with forwarders") - err = chainClient.WaitForEvents() + err = env.EVMClient.WaitForEvents() require.NoError(t, err, "Error waiting for events") - err = actions.CreateOCRv2Jobs(ocrInstances, bootstrapNode, workerNodes, mockServer, "ocr2", 5, chainClient.GetChainID().Uint64(), true) + err = actions.CreateOCRv2JobsLocal(ocrInstances, bootstrapNode, workerNodes, env.MockServer.Client, "ocr2", 5, env.EVMClient.GetChainID().Uint64(), true) require.NoError(t, err, "Error creating OCRv2 jobs with forwarders") - err = chainClient.WaitForEvents() + err = env.EVMClient.WaitForEvents() require.NoError(t, err, "Error waiting for events") - ocrv2Config, err := actions.BuildMedianOCR2Config(workerNodes) + ocrv2Config, err := actions.BuildMedianOCR2ConfigLocal(workerNodes) require.NoError(t, err, "Error building OCRv2 config") ocrv2Config.Transmitters = authorizedForwarders - err = actions.ConfigureOCRv2AggregatorContracts(chainClient, ocrv2Config, ocrInstances) + err = actions.ConfigureOCRv2AggregatorContracts(env.EVMClient, ocrv2Config, ocrInstances) require.NoError(t, err, "Error configuring OCRv2 aggregator contracts") - err = actions.StartNewOCR2Round(1, ocrInstances, chainClient, time.Minute*10) + err = actions.StartNewOCR2Round(1, ocrInstances, env.EVMClient, time.Minute*10) require.NoError(t, err) answer, err := ocrInstances[0].GetLatestAnswer(context.Background()) @@ -99,9 +88,9 @@ func TestForwarderOCR2Basic(t *testing.T) { for i := 2; i <= 3; i++ { ocrRoundVal := (5 + i) % 10 - err = mockServer.SetValuePath("ocr2", ocrRoundVal) + err = env.MockServer.Client.SetValuePath("ocr2", ocrRoundVal) require.NoError(t, err) - err = actions.StartNewOCR2Round(int64(i), ocrInstances, chainClient, time.Minute*10) + err = actions.StartNewOCR2Round(int64(i), ocrInstances, env.EVMClient, time.Minute*10) require.NoError(t, err) answer, err = ocrInstances[0].GetLatestAnswer(context.Background()) diff --git a/integration-tests/smoke/keeper_test.go b/integration-tests/smoke/keeper_test.go index e328bf8481d..00cbe07eb0f 100644 --- a/integration-tests/smoke/keeper_test.go +++ b/integration-tests/smoke/keeper_test.go @@ -5,19 +5,13 @@ import ( "fmt" "math/big" "strconv" - "strings" "testing" + "time" "github.com/ethereum/go-ethereum/common" "github.com/onsi/gomega" "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" - "github.com/smartcontractkit/chainlink-env/environment" - "github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink" - eth "github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver" - mockservercfg "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver-cfg" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils" @@ -25,7 +19,9 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" - "github.com/smartcontractkit/chainlink/integration-tests/networks" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" + "github.com/smartcontractkit/chainlink/v2/core/store/models" ) const ( @@ -34,21 +30,9 @@ const ( keeperDefaultUpkeepsToDeploy = 10 numUpkeepsAllowedForStragglingTxs = 6 keeperExpectedData = "abcdef" - keeperBaseTOML = `[Keeper] - TurnLookBack = 0 - - [Keeper.Registry] - SyncInterval = '5s' - PerformGasOverhead = 150_000` ) var ( - keeperEnvVars = map[string]any{ - "KEEPER_TURN_LOOK_BACK": "0", - "KEEPER_REGISTRY_SYNC_INTERVAL": "5s", - "KEEPER_REGISTRY_PERFORM_GAS_OVERHEAD": "150000", - } - keeperDefaultRegistryConfig = contracts.KeeperRegistrySettings{ PaymentPremiumPPB: uint32(200000000), FlatFeeMicroLINK: uint32(0), @@ -92,21 +76,16 @@ var ( func TestKeeperBasicSmoke(t *testing.T) { t.Parallel() l := utils.GetTestLogger(t) - registryVersions := map[string]ethereum.KeeperRegistryVersion{ - "registry_1_1": ethereum.RegistryVersion_1_1, - "registry_1_2": ethereum.RegistryVersion_1_2, - "registry_1_3": ethereum.RegistryVersion_1_3, + registryVersions := []ethereum.KeeperRegistryVersion{ + ethereum.RegistryVersion_1_1, + ethereum.RegistryVersion_1_2, + ethereum.RegistryVersion_1_3, } - for n, rv := range registryVersions { - name := n - registryVersion := rv - t.Run(name, func(t *testing.T) { - t.Parallel() - chainClient, chainlinkNodes, contractDeployer, linkToken, onlyStartRunner := setupKeeperTest(t, "basic-smoke") - if onlyStartRunner { - return - } + chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t) + + for _, registryVersion := range registryVersions { + t.Run(fmt.Sprintf("registry_1_%d", registryVersion), func(t *testing.T) { registry, _, consumers, upkeepIDs := actions.DeployKeeperContracts( t, registryVersion, @@ -120,11 +99,12 @@ func TestKeeperBasicSmoke(t *testing.T) { ) gom := gomega.NewGomegaWithT(t) - actions.CreateKeeperJobs(t, chainlinkNodes, registry, contracts.OCRv2Config{}) - err := chainClient.WaitForEvents() + _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{}) + require.NoError(t, err, "Error creating keeper jobs") + err = chainClient.WaitForEvents() require.NoError(t, err, "Error creating keeper jobs") - gom.Eventually(func(g gomega.Gomega) { + gom.Eventually(func(g gomega.Gomega) error { // Check if the upkeeps are performing multiple times by analysing their counters and checking they are greater than 10 for i := 0; i < len(upkeepIDs); i++ { counter, err := consumers[i].Counter(context.Background()) @@ -133,6 +113,7 @@ func TestKeeperBasicSmoke(t *testing.T) { "Expected consumer counter to be greater than 10, but got %d", counter.Int64()) l.Info().Int64("Upkeep counter", counter.Int64()).Msg("Number of upkeeps performed") } + return nil }, "5m", "1s").Should(gomega.Succeed()) // Cancel all the registered upkeeps via the registry @@ -157,7 +138,7 @@ func TestKeeperBasicSmoke(t *testing.T) { for i := 0; i < len(upkeepIDs); i++ { // Expect the counter to remain constant because the upkeep was cancelled, so it shouldn't increase anymore latestCounter, err := consumers[i].Counter(context.Background()) - require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i) + g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i) g.Expect(latestCounter.Int64()).Should(gomega.Equal(countersAfterCancellation[i].Int64()), "Expected consumer counter to remain constant at %d, but got %d", countersAfterCancellation[i].Int64(), latestCounter.Int64()) @@ -170,21 +151,16 @@ func TestKeeperBasicSmoke(t *testing.T) { func TestKeeperBlockCountPerTurn(t *testing.T) { t.Parallel() l := utils.GetTestLogger(t) - registryVersions := map[string]ethereum.KeeperRegistryVersion{ - "registry_1_1": ethereum.RegistryVersion_1_1, - "registry_1_2": ethereum.RegistryVersion_1_2, - "registry_1_3": ethereum.RegistryVersion_1_3, + registryVersions := []ethereum.KeeperRegistryVersion{ + ethereum.RegistryVersion_1_1, + ethereum.RegistryVersion_1_2, + ethereum.RegistryVersion_1_3, } - for n, rv := range registryVersions { - name := n - registryVersion := rv - t.Run(name, func(t *testing.T) { - t.Parallel() - chainClient, chainlinkNodes, contractDeployer, linkToken, onlyStartRunner := setupKeeperTest(t, "bcpt") - if onlyStartRunner { - return - } + chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t) + + for _, registryVersion := range registryVersions { + t.Run(fmt.Sprintf("registry_1_%d", registryVersion), func(t *testing.T) { registry, _, consumers, upkeepIDs := actions.DeployKeeperContracts( t, registryVersion, @@ -198,15 +174,16 @@ func TestKeeperBlockCountPerTurn(t *testing.T) { ) gom := gomega.NewGomegaWithT(t) - actions.CreateKeeperJobs(t, chainlinkNodes, registry, contracts.OCRv2Config{}) - err := chainClient.WaitForEvents() + _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{}) + require.NoError(t, err, "Error creating keeper jobs") + err = chainClient.WaitForEvents() require.NoError(t, err, "Error creating keeper jobs") keepersPerformed := make([]string, 0) upkeepID := upkeepIDs[0] // Wait for upkeep to be performed twice by different keepers (buddies) - gom.Eventually(func(g gomega.Gomega) { + gom.Eventually(func(g gomega.Gomega) error { counter, err := consumers[0].Counter(context.Background()) g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's counter shouldn't fail") l.Info().Int64("Upkeep counter", counter.Int64()).Msg("Number of upkeeps performed") @@ -221,9 +198,10 @@ func TestKeeperBlockCountPerTurn(t *testing.T) { l.Info().Str("keeper", latestKeeper).Msg("New keeper performed upkeep") keepersPerformed = append(keepersPerformed, latestKeeper) + return nil }, "1m", "1s").Should(gomega.Succeed()) - gom.Eventually(func(g gomega.Gomega) { + gom.Eventually(func(g gomega.Gomega) error { upkeepInfo, err := registry.GetUpkeepInfo(context.Background(), upkeepID) g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Registry's getUpkeep shouldn't fail") @@ -233,6 +211,7 @@ func TestKeeperBlockCountPerTurn(t *testing.T) { l.Info().Str("Keeper", latestKeeper).Msg("New keeper performed upkeep") keepersPerformed = append(keepersPerformed, latestKeeper) + return nil }, "1m", "1s").Should(gomega.Succeed()) // Expect no new keepers to perform for a while @@ -252,7 +231,7 @@ func TestKeeperBlockCountPerTurn(t *testing.T) { require.NoError(t, err, "Error waiting for set config tx") // Expect a new keeper to perform - gom.Eventually(func(g gomega.Gomega) { + gom.Eventually(func(g gomega.Gomega) error { counter, err := consumers[0].Counter(context.Background()) g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's counter shouldn't fail") l.Info().Int64("Upkeep counter", counter.Int64()).Msg("Num upkeeps performed") @@ -267,6 +246,7 @@ func TestKeeperBlockCountPerTurn(t *testing.T) { l.Info().Str("keeper", latestKeeper).Msg("New keeper performed upkeep") keepersPerformed = append(keepersPerformed, latestKeeper) + return nil }, "1m", "1s").Should(gomega.Succeed()) }) } @@ -274,20 +254,15 @@ func TestKeeperBlockCountPerTurn(t *testing.T) { func TestKeeperSimulation(t *testing.T) { t.Parallel() - registryVersions := map[string]ethereum.KeeperRegistryVersion{ - "registry_1_2": ethereum.RegistryVersion_1_2, - "registry_1_3": ethereum.RegistryVersion_1_3, + registryVersions := []ethereum.KeeperRegistryVersion{ + ethereum.RegistryVersion_1_2, + ethereum.RegistryVersion_1_3, } - for n, rv := range registryVersions { - name := n - registryVersion := rv - t.Run(name, func(t *testing.T) { - t.Parallel() - chainClient, chainlinkNodes, contractDeployer, linkToken, onlyStartRunner := setupKeeperTest(t, "simulation") - if onlyStartRunner { - return - } + chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t) + + for _, registryVersion := range registryVersions { + t.Run(fmt.Sprintf("registry_1_%d", registryVersion), func(t *testing.T) { registry, _, consumersPerformance, upkeepIDs := actions.DeployPerformanceKeeperContracts( t, registryVersion, @@ -305,8 +280,9 @@ func TestKeeperSimulation(t *testing.T) { ) gom := gomega.NewGomegaWithT(t) - actions.CreateKeeperJobs(t, chainlinkNodes, registry, contracts.OCRv2Config{}) - err := chainClient.WaitForEvents() + _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{}) + require.NoError(t, err, "Error creating keeper jobs") + err = chainClient.WaitForEvents() require.NoError(t, err, "Error creating keeper jobs") consumerPerformance := consumersPerformance[0] @@ -335,12 +311,13 @@ func TestKeeperSimulation(t *testing.T) { require.NoError(t, err, "Error waiting to set PerformGasToBurn") // Upkeep should now start performing - gom.Eventually(func(g gomega.Gomega) { + gom.Eventually(func(g gomega.Gomega) error { cnt, err := consumerPerformance.GetUpkeepCount(context.Background()) g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's Counter shouldn't fail") g.Expect(cnt.Int64()).Should(gomega.BeNumerically(">", int64(0)), "Expected consumer counter to be greater than 0, but got %d", cnt.Int64(), ) + return nil }, "1m", "1s").Should(gomega.Succeed()) }) } @@ -349,20 +326,14 @@ func TestKeeperSimulation(t *testing.T) { func TestKeeperCheckPerformGasLimit(t *testing.T) { t.Parallel() l := utils.GetTestLogger(t) - registryVersions := map[string]ethereum.KeeperRegistryVersion{ - "registry_1_2": ethereum.RegistryVersion_1_2, - "registry_1_3": ethereum.RegistryVersion_1_3, + registryVersions := []ethereum.KeeperRegistryVersion{ + ethereum.RegistryVersion_1_2, + ethereum.RegistryVersion_1_3, } - for n, rv := range registryVersions { - name := n - registryVersion := rv - t.Run(name, func(t *testing.T) { - t.Parallel() - chainClient, chainlinkNodes, contractDeployer, linkToken, onlyStartRunner := setupKeeperTest(t, "gas-limit") - if onlyStartRunner { - return - } + for _, registryVersion := range registryVersions { + t.Run(fmt.Sprintf("registry_1_%d", registryVersion), func(t *testing.T) { + chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t) registry, _, consumersPerformance, upkeepIDs := actions.DeployPerformanceKeeperContracts( t, registryVersion, @@ -380,8 +351,9 @@ func TestKeeperCheckPerformGasLimit(t *testing.T) { ) gom := gomega.NewGomegaWithT(t) - actions.CreateKeeperJobs(t, chainlinkNodes, registry, contracts.OCRv2Config{}) - err := chainClient.WaitForEvents() + _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{}) + require.NoError(t, err, "Error creating keeper jobs") + err = chainClient.WaitForEvents() require.NoError(t, err, "Error creating keeper jobs") consumerPerformance := consumersPerformance[0] @@ -404,12 +376,13 @@ func TestKeeperCheckPerformGasLimit(t *testing.T) { require.NoError(t, err, "Error waiting for SetUpkeepGasLimit tx") // Upkeep should now start performing - gom.Eventually(func(g gomega.Gomega) { + gom.Eventually(func(g gomega.Gomega) error { cnt, err := consumerPerformance.GetUpkeepCount(context.Background()) g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's counter shouldn't fail") g.Expect(cnt.Int64()).Should(gomega.BeNumerically(">", int64(0)), "Expected consumer counter to be greater than 0, but got %d", cnt.Int64(), ) + return nil }, "1m", "1s").Should(gomega.Succeed()) // Now increase the checkGasBurn on consumer, upkeep should stop performing @@ -463,21 +436,16 @@ func TestKeeperCheckPerformGasLimit(t *testing.T) { func TestKeeperRegisterUpkeep(t *testing.T) { t.Parallel() l := utils.GetTestLogger(t) - registryVersions := map[string]ethereum.KeeperRegistryVersion{ - "registry_1_1": ethereum.RegistryVersion_1_1, - "registry_1_2": ethereum.RegistryVersion_1_2, - "registry_1_3": ethereum.RegistryVersion_1_3, + registryVersions := []ethereum.KeeperRegistryVersion{ + ethereum.RegistryVersion_1_1, + ethereum.RegistryVersion_1_2, + ethereum.RegistryVersion_1_3, } - for n, rv := range registryVersions { - name := n - registryVersion := rv - t.Run(name, func(t *testing.T) { - t.Parallel() - chainClient, chainlinkNodes, contractDeployer, linkToken, onlyStartRunner := setupKeeperTest(t, "register-upkeep") - if onlyStartRunner { - return - } + chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t) + + for _, registryVersion := range registryVersions { + t.Run(fmt.Sprintf("registry_1_%d", registryVersion), func(t *testing.T) { registry, registrar, consumers, upkeepIDs := actions.DeployKeeperContracts( t, registryVersion, @@ -491,15 +459,16 @@ func TestKeeperRegisterUpkeep(t *testing.T) { ) gom := gomega.NewGomegaWithT(t) - actions.CreateKeeperJobs(t, chainlinkNodes, registry, contracts.OCRv2Config{}) - err := chainClient.WaitForEvents() + _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{}) + require.NoError(t, err, "Error creating keeper jobs") + err = chainClient.WaitForEvents() require.NoError(t, err, "Error creating keeper jobs") var initialCounters = make([]*big.Int, len(upkeepIDs)) // Observe that the upkeeps which are initially registered are performing and // store the value of their initial counters in order to compare later on that the value increased. - gom.Eventually(func(g gomega.Gomega) { + gom.Eventually(func(g gomega.Gomega) error { for i := 0; i < len(upkeepIDs); i++ { counter, err := consumers[i].Counter(context.Background()) initialCounters[i] = counter @@ -512,6 +481,7 @@ func TestKeeperRegisterUpkeep(t *testing.T) { Int("Upkeep ID", i). Msg("Number of upkeeps performed") } + return nil }, "1m", "1s").Should(gomega.Succeed()) newConsumers, _ := actions.RegisterNewUpkeeps(t, contractDeployer, chainClient, linkToken, @@ -521,15 +491,16 @@ func TestKeeperRegisterUpkeep(t *testing.T) { newUpkeep := newConsumers[0] // Test that the newly registered upkeep is also performing. - gom.Eventually(func(g gomega.Gomega) { + gom.Eventually(func(g gomega.Gomega) error { counter, err := newUpkeep.Counter(context.Background()) g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling newly deployed upkeep's counter shouldn't fail") g.Expect(counter.Int64()).Should(gomega.BeNumerically(">", int64(0)), "Expected newly registered upkeep's counter to be greater than 0, but got %d", counter.Int64()) l.Info().Msg("Newly registered upkeeps performed " + strconv.Itoa(int(counter.Int64())) + " times") + return nil }, "1m", "1s").Should(gomega.Succeed()) - gom.Eventually(func(g gomega.Gomega) { + gom.Eventually(func(g gomega.Gomega) error { for i := 0; i < len(upkeepIDs); i++ { currentCounter, err := consumers[i].Counter(context.Background()) g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's counter shouldn't fail") @@ -544,6 +515,7 @@ func TestKeeperRegisterUpkeep(t *testing.T) { "Expected counter to have increased from initial value of %s, but got %s", initialCounters[i], currentCounter) } + return nil }, "1m", "1s").Should(gomega.Succeed()) }) } @@ -551,21 +523,16 @@ func TestKeeperRegisterUpkeep(t *testing.T) { func TestKeeperAddFunds(t *testing.T) { t.Parallel() - registryVersions := map[string]ethereum.KeeperRegistryVersion{ - "registry_1_1": ethereum.RegistryVersion_1_1, - "registry_1_2": ethereum.RegistryVersion_1_2, - "registry_1_3": ethereum.RegistryVersion_1_3, + registryVersions := []ethereum.KeeperRegistryVersion{ + ethereum.RegistryVersion_1_1, + ethereum.RegistryVersion_1_2, + ethereum.RegistryVersion_1_3, } - for n, rv := range registryVersions { - name := n - registryVersion := rv - t.Run(name, func(t *testing.T) { - t.Parallel() - chainClient, chainlinkNodes, contractDeployer, linkToken, onlyStartRunner := setupKeeperTest(t, "add-funds") - if onlyStartRunner { - return - } + chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t) + + for _, registryVersion := range registryVersions { + t.Run(fmt.Sprintf("registry_1_%d", registryVersion), func(t *testing.T) { registry, _, consumers, upkeepIDs := actions.DeployKeeperContracts( t, registryVersion, @@ -579,8 +546,9 @@ func TestKeeperAddFunds(t *testing.T) { ) gom := gomega.NewGomegaWithT(t) - actions.CreateKeeperJobs(t, chainlinkNodes, registry, contracts.OCRv2Config{}) - err := chainClient.WaitForEvents() + _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{}) + require.NoError(t, err, "Error creating keeper jobs") + err = chainClient.WaitForEvents() require.NoError(t, err, "Error creating keeper jobs") // Since the upkeep is currently underfunded, check that it doesn't get executed @@ -617,21 +585,16 @@ func TestKeeperAddFunds(t *testing.T) { func TestKeeperRemove(t *testing.T) { t.Parallel() l := utils.GetTestLogger(t) - registryVersions := map[string]ethereum.KeeperRegistryVersion{ - "registry_1_1": ethereum.RegistryVersion_1_1, - "registry_1_2": ethereum.RegistryVersion_1_2, - "registry_1_3": ethereum.RegistryVersion_1_3, + registryVersions := []ethereum.KeeperRegistryVersion{ + ethereum.RegistryVersion_1_1, + ethereum.RegistryVersion_1_2, + ethereum.RegistryVersion_1_3, } - for n, rv := range registryVersions { - name := n - registryVersion := rv - t.Run(name, func(t *testing.T) { - t.Parallel() - chainClient, chainlinkNodes, contractDeployer, linkToken, onlyStartRunner := setupKeeperTest(t, "remove") - if onlyStartRunner { - return - } + chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t) + + for _, registryVersion := range registryVersions { + t.Run(fmt.Sprintf("registry_1_%d", registryVersion), func(t *testing.T) { registry, _, consumers, upkeepIDs := actions.DeployKeeperContracts( t, registryVersion, @@ -645,13 +608,14 @@ func TestKeeperRemove(t *testing.T) { ) gom := gomega.NewGomegaWithT(t) - actions.CreateKeeperJobs(t, chainlinkNodes, registry, contracts.OCRv2Config{}) - err := chainClient.WaitForEvents() + _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{}) + require.NoError(t, err, "Error creating keeper jobs") + err = chainClient.WaitForEvents() require.NoError(t, err, "Error creating keeper jobs") var initialCounters = make([]*big.Int, len(upkeepIDs)) // Make sure the upkeeps are running before we remove a keeper - gom.Eventually(func(g gomega.Gomega) { + gom.Eventually(func(g gomega.Gomega) error { for upkeepID := 0; upkeepID < len(upkeepIDs); upkeepID++ { counter, err := consumers[upkeepID].Counter(context.Background()) initialCounters[upkeepID] = counter @@ -659,6 +623,7 @@ func TestKeeperRemove(t *testing.T) { " for upkeep with ID "+strconv.Itoa(upkeepID)) g.Expect(counter.Cmp(big.NewInt(0)) == 1, "Expected consumer counter to be greater than 0, but got %s", counter) } + return nil }, "1m", "1s").Should(gomega.Succeed()) keepers, err := registry.GetKeeperList(context.Background()) @@ -682,13 +647,14 @@ func TestKeeperRemove(t *testing.T) { l.Info().Msg("Successfully removed keeper at address " + keepers[0] + " from the list of Keepers") // The upkeeps should still perform and their counters should have increased compared to the first check - gom.Eventually(func(g gomega.Gomega) { + gom.Eventually(func(g gomega.Gomega) error { for i := 0; i < len(upkeepIDs); i++ { counter, err := consumers[i].Counter(context.Background()) g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i) g.Expect(counter.Cmp(initialCounters[i]) == 1, "Expected consumer counter to be greater "+ "than initial counter which was %s, but got %s", initialCounters[i], counter) } + return nil }, "1m", "1s").Should(gomega.Succeed()) }) } @@ -696,20 +662,15 @@ func TestKeeperRemove(t *testing.T) { func TestKeeperPauseRegistry(t *testing.T) { t.Parallel() - registryVersions := map[string]ethereum.KeeperRegistryVersion{ - "registry_1_2": ethereum.RegistryVersion_1_2, - "registry_1_3": ethereum.RegistryVersion_1_3, + registryVersions := []ethereum.KeeperRegistryVersion{ + ethereum.RegistryVersion_1_2, + ethereum.RegistryVersion_1_3, } - for n, rv := range registryVersions { - name := n - registryVersion := rv - t.Run(name, func(t *testing.T) { - t.Parallel() - chainClient, chainlinkNodes, contractDeployer, linkToken, onlyStartRunner := setupKeeperTest(t, "pause-registry") - if onlyStartRunner { - return - } + chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t) + + for _, registryVersion := range registryVersions { + t.Run(fmt.Sprintf("registry_1_%d", registryVersion), func(t *testing.T) { registry, _, consumers, upkeepIDs := actions.DeployKeeperContracts( t, registryVersion, @@ -723,18 +684,20 @@ func TestKeeperPauseRegistry(t *testing.T) { ) gom := gomega.NewGomegaWithT(t) - actions.CreateKeeperJobs(t, chainlinkNodes, registry, contracts.OCRv2Config{}) - err := chainClient.WaitForEvents() + _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{}) + require.NoError(t, err, "Error creating keeper jobs") + err = chainClient.WaitForEvents() require.NoError(t, err, "Error creating keeper jobs") // Observe that the upkeeps which are initially registered are performing - gom.Eventually(func(g gomega.Gomega) { + gom.Eventually(func(g gomega.Gomega) error { for i := 0; i < len(upkeepIDs); i++ { counter, err := consumers[i].Counter(context.Background()) g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i) g.Expect(counter.Int64()).Should(gomega.BeNumerically(">", int64(0)), "Expected consumer counter to be greater than 0, but got %d") } + return nil }, "1m", "1s").Should(gomega.Succeed()) // Pause the registry @@ -767,10 +730,7 @@ func TestKeeperPauseRegistry(t *testing.T) { func TestKeeperMigrateRegistry(t *testing.T) { t.Parallel() - chainClient, chainlinkNodes, contractDeployer, linkToken, onlyStartRunner := setupKeeperTest(t, "migrate-registry") - if onlyStartRunner { - return - } + chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t) registry, _, consumers, upkeepIDs := actions.DeployKeeperContracts( t, ethereum.RegistryVersion_1_2, @@ -784,8 +744,9 @@ func TestKeeperMigrateRegistry(t *testing.T) { ) gom := gomega.NewGomegaWithT(t) - actions.CreateKeeperJobs(t, chainlinkNodes, registry, contracts.OCRv2Config{}) - err := chainClient.WaitForEvents() + _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{}) + require.NoError(t, err, "Error creating keeper jobs") + err = chainClient.WaitForEvents() require.NoError(t, err, "Error creating keeper jobs") // Deploy the second registry, second registrar, and the same number of upkeeps as the first one @@ -802,7 +763,8 @@ func TestKeeperMigrateRegistry(t *testing.T) { ) // Set the jobs for the second registry - actions.CreateKeeperJobs(t, chainlinkNodes, secondRegistry, contracts.OCRv2Config{}) + _, err = actions.CreateKeeperJobsLocal(chainlinkNodes, secondRegistry, contracts.OCRv2Config{}) + require.NoError(t, err, "Error creating keeper jobs") err = chainClient.WaitForEvents() require.NoError(t, err, "Error creating keeper jobs") @@ -814,11 +776,12 @@ func TestKeeperMigrateRegistry(t *testing.T) { require.NoError(t, err, "Error waiting to set permissions") // Check that the first upkeep from the first registry is performing (before being migrated) - gom.Eventually(func(g gomega.Gomega) { + gom.Eventually(func(g gomega.Gomega) error { counterBeforeMigration, err := consumers[0].Counter(context.Background()) g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's counter shouldn't fail") g.Expect(counterBeforeMigration.Int64()).Should(gomega.BeNumerically(">", int64(0)), "Expected consumer counter to be greater than 0, but got %s", counterBeforeMigration) + return nil }, "1m", "1s").Should(gomega.Succeed()) // Migrate the upkeep with index 0 from the first to the second registry @@ -837,32 +800,27 @@ func TestKeeperMigrateRegistry(t *testing.T) { require.NoError(t, err, "Error calling consumer's counter") // Check that once we migrated the upkeep, the counter has increased - gom.Eventually(func(g gomega.Gomega) { + gom.Eventually(func(g gomega.Gomega) error { currentCounter, err := consumers[0].Counter(context.Background()) g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's counter shouldn't fail") g.Expect(currentCounter.Int64()).Should(gomega.BeNumerically(">", counterAfterMigration.Int64()), "Expected counter to have increased, but stayed constant at %s", counterAfterMigration) + return nil }, "1m", "1s").Should(gomega.Succeed()) } func TestKeeperNodeDown(t *testing.T) { t.Parallel() l := utils.GetTestLogger(t) - registryVersions := map[string]ethereum.KeeperRegistryVersion{ - "registry_1_1": ethereum.RegistryVersion_1_1, - "registry_1_2": ethereum.RegistryVersion_1_2, - "registry_1_3": ethereum.RegistryVersion_1_3, + registryVersions := []ethereum.KeeperRegistryVersion{ + ethereum.RegistryVersion_1_1, + ethereum.RegistryVersion_1_2, + ethereum.RegistryVersion_1_3, } - for n, rv := range registryVersions { - name := n - registryVersion := rv - t.Run(name, func(t *testing.T) { - t.Parallel() - chainClient, chainlinkNodes, contractDeployer, linkToken, onlyStartRunner := setupKeeperTest(t, "node-down") - if onlyStartRunner { - return - } + for _, registryVersion := range registryVersions { + t.Run(fmt.Sprintf("registry_1_%d", registryVersion), func(t *testing.T) { + chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t) registry, _, consumers, upkeepIDs := actions.DeployKeeperContracts( t, registryVersion, @@ -876,14 +834,15 @@ func TestKeeperNodeDown(t *testing.T) { ) gom := gomega.NewGomegaWithT(t) - actions.CreateKeeperJobs(t, chainlinkNodes, registry, contracts.OCRv2Config{}) - err := chainClient.WaitForEvents() + jobs, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{}) + require.NoError(t, err, "Error creating keeper jobs") + err = chainClient.WaitForEvents() require.NoError(t, err, "Error creating keeper jobs") var initialCounters = make([]*big.Int, len(upkeepIDs)) // Watch upkeeps being performed and store their counters in order to compare them later in the test - gom.Eventually(func(g gomega.Gomega) { + gom.Eventually(func(g gomega.Gomega) error { for i := 0; i < len(upkeepIDs); i++ { counter, err := consumers[i].Counter(context.Background()) initialCounters[i] = counter @@ -891,12 +850,13 @@ func TestKeeperNodeDown(t *testing.T) { g.Expect(counter.Int64()).Should(gomega.BeNumerically(">", int64(0)), "Expected consumer counter to be greater than 0, but got %d", counter.Int64()) } + return nil }, "1m", "1s").Should(gomega.Succeed()) // Take down half of the Keeper nodes by deleting the Keeper job registered above (after registry deployment) firstHalfToTakeDown := chainlinkNodes[:len(chainlinkNodes)/2+1] for i, nodeToTakeDown := range firstHalfToTakeDown { - err = nodeToTakeDown.MustDeleteJob("1") + err = nodeToTakeDown.MustDeleteJob(jobs[0].Data.ID) require.NoError(t, err, "Error deleting job from node %d", i) err = chainClient.WaitForEvents() require.NoError(t, err, "Error waiting for events") @@ -904,7 +864,7 @@ func TestKeeperNodeDown(t *testing.T) { l.Info().Msg("Successfully managed to take down the first half of the nodes") // Assert that upkeeps are still performed and their counters have increased - gom.Eventually(func(g gomega.Gomega) { + gom.Eventually(func(g gomega.Gomega) error { for i := 0; i < len(upkeepIDs); i++ { currentCounter, err := consumers[i].Counter(context.Background()) g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i) @@ -912,12 +872,17 @@ func TestKeeperNodeDown(t *testing.T) { "Expected counter to have increased from initial value of %s, but got %s", initialCounters[i], currentCounter) } + return nil }, "3m", "1s").Should(gomega.Succeed()) // Take down the other half of the Keeper nodes - secondHalfToTakeDown := chainlinkNodes[len(chainlinkNodes)/2+1:] + nodesAndJobs := []nodeAndJob{} + for i, n := range chainlinkNodes { + nodesAndJobs = append(nodesAndJobs, nodeAndJob{node: n, job: jobs[i]}) + } + secondHalfToTakeDown := nodesAndJobs[len(nodesAndJobs)/2+1:] for i, nodeToTakeDown := range secondHalfToTakeDown { - err = nodeToTakeDown.MustDeleteJob("1") + err = nodeToTakeDown.node.MustDeleteJob(nodeToTakeDown.job.Data.ID) require.NoError(t, err, "Error deleting job from node %d", i) err = chainClient.WaitForEvents() require.NoError(t, err, "Error waiting for events") @@ -953,13 +918,15 @@ func TestKeeperNodeDown(t *testing.T) { } } +type nodeAndJob struct { + node *client.ChainlinkClient + job *client.Job +} + func TestKeeperPauseUnPauseUpkeep(t *testing.T) { t.Parallel() l := utils.GetTestLogger(t) - chainClient, chainlinkNodes, contractDeployer, linkToken, onlyStartRunner := setupKeeperTest(t, "pause-upkeep") - if onlyStartRunner { - return - } + chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t) registry, _, consumers, upkeepIDs := actions.DeployKeeperContracts( t, ethereum.RegistryVersion_1_3, @@ -973,11 +940,12 @@ func TestKeeperPauseUnPauseUpkeep(t *testing.T) { ) gom := gomega.NewGomegaWithT(t) - actions.CreateKeeperJobs(t, chainlinkNodes, registry, contracts.OCRv2Config{}) - err := chainClient.WaitForEvents() + _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{}) + require.NoError(t, err, "Error creating keeper jobs") + err = chainClient.WaitForEvents() require.NoError(t, err, "Error creating keeper jobs") - gom.Eventually(func(g gomega.Gomega) { + gom.Eventually(func(g gomega.Gomega) error { // Check if the upkeeps are performing multiple times by analysing their counters and checking they are greater than 5 for i := 0; i < len(upkeepIDs); i++ { counter, err := consumers[i].Counter(context.Background()) @@ -986,6 +954,7 @@ func TestKeeperPauseUnPauseUpkeep(t *testing.T) { "Expected consumer counter to be greater than 5, but got %d", counter.Int64()) l.Info().Int64("Upkeep counter", counter.Int64()).Msg("Number of upkeeps performed") } + return nil }, "3m", "1s").Should(gomega.Succeed()) // pause all the registered upkeeps via the registry @@ -1030,7 +999,7 @@ func TestKeeperPauseUnPauseUpkeep(t *testing.T) { err = chainClient.WaitForEvents() require.NoError(t, err, "Error waiting to un-pause upkeeps") - gom.Eventually(func(g gomega.Gomega) { + gom.Eventually(func(g gomega.Gomega) error { // Check if the upkeeps are performing multiple times by analysing their counters and checking they are greater than 5 + numbers of performing before pause for i := 0; i < len(upkeepIDs); i++ { counter, err := consumers[i].Counter(context.Background()) @@ -1040,16 +1009,14 @@ func TestKeeperPauseUnPauseUpkeep(t *testing.T) { "Expected consumer counter to be greater than %d, but got %d", int64(5)+countersAfterPause[i].Int64(), counter.Int64()) l.Info().Int64("Upkeeps", counter.Int64()).Msg("Upkeeps Performed") } + return nil }, "3m", "1s").Should(gomega.Succeed()) } func TestKeeperUpdateCheckData(t *testing.T) { t.Parallel() l := utils.GetTestLogger(t) - chainClient, chainlinkNodes, contractDeployer, linkToken, onlyStartRunner := setupKeeperTest(t, "pause-upkeep") - if onlyStartRunner { - return - } + chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t) registry, _, performDataChecker, upkeepIDs := actions.DeployPerformDataCheckerContracts( t, ethereum.RegistryVersion_1_3, @@ -1064,8 +1031,9 @@ func TestKeeperUpdateCheckData(t *testing.T) { ) gom := gomega.NewGomegaWithT(t) - actions.CreateKeeperJobs(t, chainlinkNodes, registry, contracts.OCRv2Config{}) - err := chainClient.WaitForEvents() + _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{}) + require.NoError(t, err, "Error creating keeper jobs") + err = chainClient.WaitForEvents() require.NoError(t, err, "Error creating keeper jobs") gom.Consistently(func(g gomega.Gomega) { @@ -1094,7 +1062,7 @@ func TestKeeperUpdateCheckData(t *testing.T) { require.Equal(t, []byte(keeperExpectedData), upkeep.CheckData, "Check data not as expected") } - gom.Eventually(func(g gomega.Gomega) { + gom.Eventually(func(g gomega.Gomega) error { // Check if the upkeeps are performing multiple times by analysing their counters and checking they are greater than 5 for i := 0; i < len(upkeepIDs); i++ { counter, err := performDataChecker[i].Counter(context.Background()) @@ -1103,71 +1071,41 @@ func TestKeeperUpdateCheckData(t *testing.T) { "Expected perform data checker counter to be greater than 5, but got %d", counter.Int64()) l.Info().Int64("Upkeep perform data checker", counter.Int64()).Msg("Number of upkeeps performed") } + return nil }, "3m", "1s").Should(gomega.Succeed()) } -func setupKeeperTest( - t *testing.T, - testName string, -) ( - chainClient blockchain.EVMClient, - chainlinkNodes []*client.Chainlink, - contractDeployer contracts.ContractDeployer, - linkToken contracts.LinkToken, - onlyStartRunner bool, +func setupKeeperTest(t *testing.T) ( + blockchain.EVMClient, + []*client.ChainlinkClient, + contracts.ContractDeployer, + contracts.LinkToken, + *test_env.CLClusterTestEnv, ) { - network := networks.SelectedNetwork - evmConfig := eth.New(nil) - if !network.Simulated { - evmConfig = eth.New(ð.Props{ - NetworkName: network.Name, - Simulated: network.Simulated, - WsURLs: network.URLs, - }) - } - - chainlinkChart, err := chainlink.NewDeployment(5, map[string]interface{}{ - "toml": client.AddNetworksConfig(keeperBaseTOML, network), - }) - require.NoError(t, err, "Error creating chainlink deployment") - - networkName := strings.ReplaceAll(strings.ToLower(network.Name), " ", "-") - testEnvironment := environment.New( - &environment.Config{ - NamespacePrefix: fmt.Sprintf("smoke-keeper-%s-%s", testName, networkName), - Test: t, - }). - AddHelm(mockservercfg.New(nil)). - AddHelm(mockserver.New(nil)). - AddHelm(evmConfig). - AddHelmCharts(chainlinkChart) - err = testEnvironment.Run() + clNodeConfig := node.NewConfig(node.BaseConf) + turnLookBack := int64(0) + syncInterval := models.MustMakeDuration(5 * time.Second) + performGasOverhead := uint32(150000) + clNodeConfig.Keeper.TurnLookBack = &turnLookBack + clNodeConfig.Keeper.Registry.SyncInterval = &syncInterval + clNodeConfig.Keeper.Registry.PerformGasOverhead = &performGasOverhead + + env, err := test_env.NewCLTestEnvBuilder(). + WithGeth(). + WithMockServer(1). + WithCLNodes(5). + WithCLNodeConfig(clNodeConfig). + WithFunding(big.NewFloat(.5)). + Build() require.NoError(t, err, "Error deploying test environment") - onlyStartRunner = testEnvironment.WillUseRemoteRunner() - if !onlyStartRunner { - chainClient, err = blockchain.NewEVMClient(network, testEnvironment) - require.NoError(t, err, "Connecting to blockchain nodes shouldn't fail") - contractDeployer, err = contracts.NewContractDeployer(chainClient) - require.NoError(t, err, "Deploying contracts shouldn't fail") - chainlinkNodes, err = client.ConnectChainlinkNodes(testEnvironment) - require.NoError(t, err, "Connecting to chainlink nodes shouldn't fail") - chainClient.ParallelTransactions(true) - - // Register cleanup for any test - t.Cleanup(func() { - err := actions.TeardownSuite(t, testEnvironment, utils.ProjectRoot, chainlinkNodes, nil, zapcore.ErrorLevel, chainClient) - require.NoError(t, err, "Error tearing down environment") - }) - err = actions.FundChainlinkNodes(chainlinkNodes, chainClient, big.NewFloat(.5)) - require.NoError(t, err, "Funding Chainlink nodes shouldn't fail") + env.ParallelTransactions(true) - linkToken, err = contractDeployer.DeployLinkTokenContract() - require.NoError(t, err, "Deploying Link Token Contract shouldn't fail") + linkTokenContract, err := env.ContractDeployer.DeployLinkTokenContract() + require.NoError(t, err, "Deploying Link Token Contract shouldn't fail") - err = chainClient.WaitForEvents() - require.NoError(t, err, "Error waiting for events") - } + err = env.EVMClient.WaitForEvents() + require.NoError(t, err, "Error waiting for events") - return chainClient, chainlinkNodes, contractDeployer, linkToken, onlyStartRunner + return env.EVMClient, env.GetAPIs(), env.ContractDeployer, linkTokenContract, env } diff --git a/integration-tests/smoke/ocr2_test.go b/integration-tests/smoke/ocr2_test.go index a9f374c607a..7dd0b23223c 100644 --- a/integration-tests/smoke/ocr2_test.go +++ b/integration-tests/smoke/ocr2_test.go @@ -4,56 +4,47 @@ import ( "context" "fmt" "math/big" - "strings" "testing" "time" - "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" - "github.com/smartcontractkit/chainlink-env/environment" "github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink" "github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum" "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver" mockservercfg "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver-cfg" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" - "github.com/smartcontractkit/chainlink-testing-framework/utils" - "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/config" - "github.com/smartcontractkit/chainlink/integration-tests/contracts" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" "github.com/smartcontractkit/chainlink/integration-tests/networks" + "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" + "github.com/stretchr/testify/require" + "strings" ) // Tests a basic OCRv2 median feed func TestOCRv2Basic(t *testing.T) { - testEnvironment, testNetwork := setupOCR2Test(t, false) - if testEnvironment.WillUseRemoteRunner() { - return - } + env, err := test_env.NewCLTestEnvBuilder(). + WithGeth(). + WithMockServer(1). + WithCLNodeConfig(node.NewConfig(node.BaseConf, + node.WithOCR2(), + node.WithP2Pv2(), + )). + WithCLNodes(6). + WithFunding(big.NewFloat(10)). + Build() + require.NoError(t, err) + env.ParallelTransactions(true) - chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment) - require.NoError(t, err, "Connecting to blockchain nodes shouldn't fail") - contractDeployer, err := contracts.NewContractDeployer(chainClient) - require.NoError(t, err, "Deploying contracts shouldn't fail") - - chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment) - require.NoError(t, err, "Connecting to chainlink nodes shouldn't fail") - bootstrapNode, workerNodes := chainlinkNodes[0], chainlinkNodes[1:] - mockServer, err := ctfClient.ConnectMockServer(testEnvironment) - require.NoError(t, err, "Creating mockserver clients shouldn't fail") - t.Cleanup(func() { - err := actions.TeardownSuite(t, testEnvironment, utils.ProjectRoot, chainlinkNodes, nil, zapcore.ErrorLevel, chainClient) - require.NoError(t, err, "Error tearing down environment") - }) - chainClient.ParallelTransactions(true) + nodeClients := env.GetAPIs() + bootstrapNode, workerNodes := nodeClients[0], nodeClients[1:] - linkToken, err := contractDeployer.DeployLinkTokenContract() + linkToken, err := env.ContractDeployer.DeployLinkTokenContract() require.NoError(t, err, "Deploying Link Token Contract shouldn't fail") - err = actions.FundChainlinkNodes(workerNodes, chainClient, big.NewFloat(.05)) + err = actions.FundChainlinkNodesLocal(workerNodes, env.EVMClient, big.NewFloat(.05)) require.NoError(t, err, "Error funding Chainlink nodes") // Gather transmitters @@ -66,19 +57,19 @@ func TestOCRv2Basic(t *testing.T) { transmitters = append(transmitters, addr) } - aggregatorContracts, err := actions.DeployOCRv2Contracts(1, linkToken, contractDeployer, transmitters, chainClient) + aggregatorContracts, err := actions.DeployOCRv2Contracts(1, linkToken, env.ContractDeployer, transmitters, env.EVMClient) require.NoError(t, err, "Error deploying OCRv2 aggregator contracts") - err = actions.CreateOCRv2Jobs(aggregatorContracts, bootstrapNode, workerNodes, mockServer, "ocr2", 5, chainClient.GetChainID().Uint64(), false) + err = actions.CreateOCRv2JobsLocal(aggregatorContracts, bootstrapNode, workerNodes, env.MockServer.Client, "ocr2", 5, env.EVMClient.GetChainID().Uint64(), false) require.NoError(t, err, "Error creating OCRv2 jobs") - ocrv2Config, err := actions.BuildMedianOCR2Config(workerNodes) + ocrv2Config, err := actions.BuildMedianOCR2ConfigLocal(workerNodes) require.NoError(t, err, "Error building OCRv2 config") - err = actions.ConfigureOCRv2AggregatorContracts(chainClient, ocrv2Config, aggregatorContracts) + err = actions.ConfigureOCRv2AggregatorContracts(env.EVMClient, ocrv2Config, aggregatorContracts) require.NoError(t, err, "Error configuring OCRv2 aggregator contracts") - err = actions.StartNewOCR2Round(1, aggregatorContracts, chainClient, time.Minute*5) + err = actions.StartNewOCR2Round(1, aggregatorContracts, env.EVMClient, time.Minute*5) require.NoError(t, err, "Error starting new OCR2 round") roundData, err := aggregatorContracts[0].GetRound(context.Background(), big.NewInt(1)) require.NoError(t, err, "Getting latest answer from OCR contract shouldn't fail") @@ -87,9 +78,9 @@ func TestOCRv2Basic(t *testing.T) { roundData.Answer.Int64(), ) - err = mockServer.SetValuePath("ocr2", 10) + err = env.MockServer.Client.SetValuePath("ocr2", 10) require.NoError(t, err) - err = actions.StartNewOCR2Round(2, aggregatorContracts, chainClient, time.Minute*5) + err = actions.StartNewOCR2Round(2, aggregatorContracts, env.EVMClient, time.Minute*5) require.NoError(t, err) roundData, err = aggregatorContracts[0].GetRound(context.Background(), big.NewInt(2)) diff --git a/integration-tests/smoke/ocr_test.go b/integration-tests/smoke/ocr_test.go index 59bbdac6688..1ae52ade305 100644 --- a/integration-tests/smoke/ocr_test.go +++ b/integration-tests/smoke/ocr_test.go @@ -1,112 +1,56 @@ package smoke import ( - "context" - "fmt" - "math/big" - "strings" "testing" - "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" - - "github.com/smartcontractkit/chainlink-env/environment" - "github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver" - mockservercfg "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver-cfg" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" - "github.com/smartcontractkit/chainlink-testing-framework/utils" - + "context" "github.com/smartcontractkit/chainlink/integration-tests/actions" - "github.com/smartcontractkit/chainlink/integration-tests/client" - "github.com/smartcontractkit/chainlink/integration-tests/config" - "github.com/smartcontractkit/chainlink/integration-tests/contracts" - "github.com/smartcontractkit/chainlink/integration-tests/networks" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + "github.com/stretchr/testify/require" + "math/big" ) func TestOCRBasic(t *testing.T) { t.Parallel() - testEnvironment, testNetwork := setupOCRTest(t) - if testEnvironment.WillUseRemoteRunner() { - return - } - - chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment) - require.NoError(t, err, "Connecting to blockchain nodes shouldn't fail") - contractDeployer, err := contracts.NewContractDeployer(chainClient) - require.NoError(t, err, "Deploying contracts shouldn't fail") - - chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment) - require.NoError(t, err, "Connecting to chainlink nodes shouldn't fail") - bootstrapNode, workerNodes := chainlinkNodes[0], chainlinkNodes[1:] - mockServer, err := ctfClient.ConnectMockServer(testEnvironment) - require.NoError(t, err, "Creating mockserver clients shouldn't fail") + env, err := test_env.NewCLTestEnvBuilder(). + WithGeth(). + WithMockServer(1). + WithCLNodes(6). + WithFunding(big.NewFloat(10)). + Build() + require.NoError(t, err) + env.ParallelTransactions(true) - t.Cleanup(func() { - err := actions.TeardownSuite(t, testEnvironment, utils.ProjectRoot, chainlinkNodes, nil, zapcore.ErrorLevel, chainClient) - require.NoError(t, err, "Error tearing down environment") - }) - chainClient.ParallelTransactions(true) + nodeClients := env.GetAPIs() + bootstrapNode, workerNodes := nodeClients[0], nodeClients[1:] - linkTokenContract, err := contractDeployer.DeployLinkTokenContract() + linkTokenContract, err := env.ContractDeployer.DeployLinkTokenContract() require.NoError(t, err, "Deploying Link Token Contract shouldn't fail") - err = actions.FundChainlinkNodes(workerNodes, chainClient, big.NewFloat(.05)) + err = actions.FundChainlinkNodesLocal(workerNodes, env.EVMClient, big.NewFloat(.05)) require.NoError(t, err, "Error funding Chainlink nodes") - ocrInstances, err := actions.DeployOCRContracts(1, linkTokenContract, contractDeployer, bootstrapNode, workerNodes, chainClient) + ocrInstances, err := actions.DeployOCRContractsLocal(1, linkTokenContract, env.ContractDeployer, workerNodes, env.EVMClient) require.NoError(t, err) - err = chainClient.WaitForEvents() + err = env.EVMClient.WaitForEvents() require.NoError(t, err, "Error waiting for events") - err = actions.CreateOCRJobs(ocrInstances, bootstrapNode, workerNodes, 5, mockServer) + err = actions.CreateOCRJobsLocal(ocrInstances, bootstrapNode, workerNodes, 5, env.MockServer.Client) require.NoError(t, err) - err = actions.StartNewRound(1, ocrInstances, chainClient) + + _ = actions.StartNewRound(1, ocrInstances, env.EVMClient) require.NoError(t, err) answer, err := ocrInstances[0].GetLatestAnswer(context.Background()) require.NoError(t, err, "Getting latest answer from OCR contract shouldn't fail") require.Equal(t, int64(5), answer.Int64(), "Expected latest answer from OCR contract to be 5 but got %d", answer.Int64()) - err = actions.SetAllAdapterResponsesToTheSameValue(10, ocrInstances, workerNodes, mockServer) + err = actions.SetAllAdapterResponsesToTheSameValueLocal(10, ocrInstances, workerNodes, env.MockServer.Client) require.NoError(t, err) - err = actions.StartNewRound(2, ocrInstances, chainClient) + err = actions.StartNewRound(2, ocrInstances, env.EVMClient) require.NoError(t, err) answer, err = ocrInstances[0].GetLatestAnswer(context.Background()) require.NoError(t, err, "Error getting latest OCR answer") require.Equal(t, int64(10), answer.Int64(), "Expected latest answer from OCR contract to be 10 but got %d", answer.Int64()) } - -func setupOCRTest(t *testing.T) ( - testEnvironment *environment.Environment, - testNetwork blockchain.EVMNetwork, -) { - testNetwork = networks.SelectedNetwork - evmConfig := ethereum.New(nil) - if !testNetwork.Simulated { - evmConfig = ethereum.New(ðereum.Props{ - NetworkName: testNetwork.Name, - Simulated: testNetwork.Simulated, - WsURLs: testNetwork.URLs, - }) - } - chainlinkChart, err := chainlink.NewDeployment(6, map[string]interface{}{ - "toml": client.AddNetworksConfig(config.BaseOCRP2PV1Config, testNetwork), - }) - require.NoError(t, err, "Error creating chainlink deployment") - - testEnvironment = environment.New(&environment.Config{ - NamespacePrefix: fmt.Sprintf("smoke-ocr-%s", strings.ReplaceAll(strings.ToLower(testNetwork.Name), " ", "-")), - Test: t, - }). - AddHelm(mockservercfg.New(nil)). - AddHelm(mockserver.New(nil)). - AddHelm(evmConfig). - AddHelmCharts(chainlinkChart) - err = testEnvironment.Run() - require.NoError(t, err, "Error running test environment") - return testEnvironment, testNetwork -} diff --git a/integration-tests/smoke/runlog_test.go b/integration-tests/smoke/runlog_test.go index 63147763b41..d40d5677fde 100644 --- a/integration-tests/smoke/runlog_test.go +++ b/integration-tests/smoke/runlog_test.go @@ -3,75 +3,49 @@ package smoke import ( "context" "fmt" - "math/big" - "strings" - "testing" - "github.com/google/uuid" "github.com/onsi/gomega" - "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" - - "github.com/smartcontractkit/chainlink-env/environment" - "github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver" - mockservercfg "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver-cfg" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" "github.com/smartcontractkit/chainlink-testing-framework/utils" - - "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" - "github.com/smartcontractkit/chainlink/integration-tests/contracts" - "github.com/smartcontractkit/chainlink/integration-tests/networks" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + "github.com/stretchr/testify/require" + "math/big" + "strings" + "testing" ) func TestRunLogBasic(t *testing.T) { t.Parallel() l := utils.GetTestLogger(t) - testEnvironment, testNetwork := setupRunLogTest(t) - if testEnvironment.WillUseRemoteRunner() { - return - } - - chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment) - require.NoError(t, err, "Connecting to blockchain nodes shouldn't fail") - contractDeployer, err := contracts.NewContractDeployer(chainClient) - require.NoError(t, err, "Deploying contracts shouldn't fail") - chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment) - require.NoError(t, err, "Connecting to chainlink nodes shouldn't fail") - t.Cleanup(func() { - err := actions.TeardownSuite(t, testEnvironment, utils.ProjectRoot, chainlinkNodes, nil, zapcore.ErrorLevel, chainClient) - require.NoError(t, err, "Error tearing down environment") - }) - - mockServer, err := ctfClient.ConnectMockServer(testEnvironment) - require.NoError(t, err, "Error connecting to mockserver") - err = actions.FundChainlinkNodes(chainlinkNodes, chainClient, big.NewFloat(.01)) - require.NoError(t, err, "Funding chainlink nodes with ETH shouldn't fail") - - lt, err := contractDeployer.DeployLinkTokenContract() + env, err := test_env.NewCLTestEnvBuilder(). + WithGeth(). + WithMockServer(1). + WithCLNodes(1). + WithFunding(big.NewFloat(1)). + Build() + require.NoError(t, err) + + lt, err := env.ContractDeployer.DeployLinkTokenContract() require.NoError(t, err, "Deploying Link Token Contract shouldn't fail") - oracle, err := contractDeployer.DeployOracle(lt.Address()) + oracle, err := env.ContractDeployer.DeployOracle(lt.Address()) require.NoError(t, err, "Deploying Oracle Contract shouldn't fail") - consumer, err := contractDeployer.DeployAPIConsumer(lt.Address()) + consumer, err := env.ContractDeployer.DeployAPIConsumer(lt.Address()) require.NoError(t, err, "Deploying Consumer Contract shouldn't fail") - err = chainClient.SetDefaultWallet(0) + err = env.EVMClient.SetDefaultWallet(0) require.NoError(t, err, "Setting default wallet shouldn't fail") err = lt.Transfer(consumer.Address(), big.NewInt(2e18)) require.NoError(t, err, "Transferring %d to consumer contract shouldn't fail", big.NewInt(2e18)) - err = mockServer.SetValuePath("/variable", 5) + err = env.MockServer.Client.SetValuePath("/variable", 5) require.NoError(t, err, "Setting mockserver value path shouldn't fail") jobUUID := uuid.New() bta := client.BridgeTypeAttributes{ Name: fmt.Sprintf("five-%s", jobUUID.String()), - URL: fmt.Sprintf("%s/variable", mockServer.Config.ClusterURL), + URL: fmt.Sprintf("%s/variable", env.MockServer.Client.Config.ClusterURL), } - err = chainlinkNodes[0].MustCreateBridge(&bta) + err = env.CLNodes[0].API.MustCreateBridge(&bta) require.NoError(t, err, "Creating bridge shouldn't fail") os := &client.DirectRequestTxPipelineSpec{ @@ -81,8 +55,8 @@ func TestRunLogBasic(t *testing.T) { ost, err := os.String() require.NoError(t, err, "Building observation source spec shouldn't fail") - _, err = chainlinkNodes[0].MustCreateJob(&client.DirectRequestJobSpec{ - Name: "direct_request", + _, err = env.CLNodes[0].API.MustCreateJob(&client.DirectRequestJobSpec{ + Name: fmt.Sprintf("direct-request-%s", uuid.NewString()), MinIncomingConfirmations: "1", ContractAddress: oracle.Address(), ExternalJobID: jobUUID.String(), @@ -97,7 +71,7 @@ func TestRunLogBasic(t *testing.T) { oracle.Address(), jobID, big.NewInt(1e18), - fmt.Sprintf("%s/variable", mockServer.Config.ClusterURL), + fmt.Sprintf("%s/variable", env.MockServer.Client.Config.ClusterURL), "data,result", big.NewInt(100), ) @@ -112,30 +86,3 @@ func TestRunLogBasic(t *testing.T) { g.Expect(d.Int64()).Should(gomega.BeNumerically("==", 5), "Expected the on-chain data to be 5, but found %d", d.Int64()) }, "2m", "1s").Should(gomega.Succeed()) } - -func setupRunLogTest(t *testing.T) (testEnvironment *environment.Environment, testNetwork blockchain.EVMNetwork) { - testNetwork = networks.SelectedNetwork - evmConfig := ethereum.New(nil) - if !testNetwork.Simulated { - evmConfig = ethereum.New(ðereum.Props{ - NetworkName: testNetwork.Name, - Simulated: testNetwork.Simulated, - WsURLs: testNetwork.URLs, - }) - } - cd, err := chainlink.NewDeployment(1, map[string]interface{}{ - "toml": client.AddNetworksConfig("", testNetwork), - }) - require.NoError(t, err, "Error creating chainlink deployment") - testEnvironment = environment.New(&environment.Config{ - NamespacePrefix: fmt.Sprintf("smoke-runlog-%s", strings.ReplaceAll(strings.ToLower(testNetwork.Name), " ", "-")), - Test: t, - }). - AddHelm(mockservercfg.New(nil)). - AddHelm(mockserver.New(nil)). - AddHelm(evmConfig). - AddHelmCharts(cd) - err = testEnvironment.Run() - require.NoError(t, err, "Error running test environment") - return testEnvironment, testNetwork -} diff --git a/integration-tests/smoke/vrf_test.go b/integration-tests/smoke/vrf_test.go index 232cb719d25..2f3a8bb40f5 100644 --- a/integration-tests/smoke/vrf_test.go +++ b/integration-tests/smoke/vrf_test.go @@ -3,83 +3,57 @@ package smoke import ( "context" "fmt" - "math/big" - "strings" - "testing" - "time" - "github.com/google/uuid" "github.com/onsi/gomega" - "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" - - "github.com/smartcontractkit/chainlink-env/environment" - "github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils" - "github.com/smartcontractkit/chainlink/integration-tests/actions" + "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv1" "github.com/smartcontractkit/chainlink/integration-tests/client" - "github.com/smartcontractkit/chainlink/integration-tests/contracts" - "github.com/smartcontractkit/chainlink/integration-tests/networks" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + "github.com/stretchr/testify/require" + "math/big" + "testing" + "time" ) func TestVRFBasic(t *testing.T) { t.Parallel() l := utils.GetTestLogger(t) - testEnvironment, testNetwork := setupVRFTest(t) - if testEnvironment.WillUseRemoteRunner() { - return - } - - chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment) - require.NoError(t, err, "Connecting client shouldn't fail") - cd, err := contracts.NewContractDeployer(chainClient) - require.NoError(t, err, "Deploying contracts shouldn't fail") - chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment) - require.NoError(t, err, "Connecting to chainlink nodes shouldn't fail") - t.Cleanup(func() { - err := actions.TeardownSuite(t, testEnvironment, utils.ProjectRoot, chainlinkNodes, nil, zapcore.ErrorLevel, chainClient) - require.NoError(t, err, "Error tearing down environment") - }) - chainClient.ParallelTransactions(true) - - err = actions.FundChainlinkNodes(chainlinkNodes, chainClient, big.NewFloat(.01)) - require.NoError(t, err, "Funding chainlink nodes with ETH shouldn't fail") - - lt, err := cd.DeployLinkTokenContract() + env, err := test_env.NewCLTestEnvBuilder(). + WithGeth(). + WithMockServer(1). + WithCLNodes(1). + WithFunding(big.NewFloat(1)). + Build() + require.NoError(t, err) + env.ParallelTransactions(true) + + lt, err := actions.DeployLINKToken(env.ContractDeployer) require.NoError(t, err, "Deploying Link Token Contract shouldn't fail") - bhs, err := cd.DeployBlockhashStore() - require.NoError(t, err, "Deploying Blockhash store shouldn't fail") - coordinator, err := cd.DeployVRFCoordinator(lt.Address(), bhs.Address()) - require.NoError(t, err, "Deploying VRF coordinator shouldn't fail") - consumer, err := cd.DeployVRFConsumer(lt.Address(), coordinator.Address()) - require.NoError(t, err, "Deploying VRF consumer contract shouldn't fail") - err = chainClient.WaitForEvents() - require.NoError(t, err, "Failed to wait for VRF setup contracts to deploy") + contracts, err := vrfv1.DeployVRFContracts(env.ContractDeployer, env.EVMClient, lt) + require.NoError(t, err, "Deploying VRF Contracts shouldn't fail") - err = lt.Transfer(consumer.Address(), big.NewInt(2e18)) + err = lt.Transfer(contracts.Consumer.Address(), big.NewInt(2e18)) require.NoError(t, err, "Funding consumer contract shouldn't fail") - _, err = cd.DeployVRFContract() + _, err = env.ContractDeployer.DeployVRFContract() require.NoError(t, err, "Deploying VRF contract shouldn't fail") - err = chainClient.WaitForEvents() + err = env.EVMClient.WaitForEvents() require.NoError(t, err, "Waiting for event subscriptions in nodes shouldn't fail") - for _, n := range chainlinkNodes { - nodeKey, err := n.MustCreateVRFKey() + for _, n := range env.CLNodes { + nodeKey, err := n.API.MustCreateVRFKey() require.NoError(t, err, "Creating VRF key shouldn't fail") l.Debug().Interface("Key JSON", nodeKey).Msg("Created proving key") pubKeyCompressed := nodeKey.Data.ID jobUUID := uuid.New() os := &client.VRFTxPipelineSpec{ - Address: coordinator.Address(), + Address: contracts.Coordinator.Address(), } ost, err := os.String() require.NoError(t, err, "Building observation source spec shouldn't fail") - job, err := n.MustCreateJob(&client.VRFJobSpec{ + job, err := n.API.MustCreateJob(&client.VRFJobSpec{ Name: fmt.Sprintf("vrf-%s", jobUUID), - CoordinatorAddress: coordinator.Address(), + CoordinatorAddress: contracts.Coordinator.Address(), MinIncomingConfirmations: 1, PublicKey: pubKeyCompressed, ExternalJobID: jobUUID.String(), @@ -87,11 +61,11 @@ func TestVRFBasic(t *testing.T) { }) require.NoError(t, err, "Creating VRF Job shouldn't fail") - oracleAddr, err := n.PrimaryEthAddress() + oracleAddr, err := n.API.PrimaryEthAddress() require.NoError(t, err, "Getting primary ETH address of chainlink node shouldn't fail") provingKey, err := actions.EncodeOnChainVRFProvingKey(*nodeKey) require.NoError(t, err, "Encoding on-chain VRF Proving key shouldn't fail") - err = coordinator.RegisterProvingKey( + err = contracts.Coordinator.RegisterProvingKey( big.NewInt(1), oracleAddr, provingKey, @@ -101,18 +75,18 @@ func TestVRFBasic(t *testing.T) { encodedProvingKeys := make([][2]*big.Int, 0) encodedProvingKeys = append(encodedProvingKeys, provingKey) - requestHash, err := coordinator.HashOfKey(context.Background(), encodedProvingKeys[0]) + requestHash, err := contracts.Coordinator.HashOfKey(context.Background(), encodedProvingKeys[0]) require.NoError(t, err, "Getting Hash of encoded proving keys shouldn't fail") - err = consumer.RequestRandomness(requestHash, big.NewInt(1)) + err = contracts.Consumer.RequestRandomness(requestHash, big.NewInt(1)) require.NoError(t, err, "Requesting randomness shouldn't fail") gom := gomega.NewGomegaWithT(t) timeout := time.Minute * 2 gom.Eventually(func(g gomega.Gomega) { - jobRuns, err := chainlinkNodes[0].MustReadRunsByJob(job.Data.ID) + jobRuns, err := env.CLNodes[0].API.MustReadRunsByJob(job.Data.ID) g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Job execution shouldn't fail") - out, err := consumer.RandomnessOutput(context.Background()) + out, err := contracts.Consumer.RandomnessOutput(context.Background()) g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Getting the randomness output of the consumer shouldn't fail") // Checks that the job has actually run g.Expect(len(jobRuns.Data)).Should(gomega.BeNumerically(">=", 1), @@ -127,28 +101,3 @@ func TestVRFBasic(t *testing.T) { }, timeout, "1s").Should(gomega.Succeed()) } } - -func setupVRFTest(t *testing.T) (testEnvironment *environment.Environment, testNetwork blockchain.EVMNetwork) { - testNetwork = networks.SelectedNetwork - evmConfig := ethereum.New(nil) - if !testNetwork.Simulated { - evmConfig = ethereum.New(ðereum.Props{ - NetworkName: testNetwork.Name, - Simulated: testNetwork.Simulated, - WsURLs: testNetwork.URLs, - }) - } - cd, err := chainlink.NewDeployment(1, map[string]interface{}{ - "toml": client.AddNetworksConfig("", testNetwork), - }) - require.NoError(t, err, "Error creating chainlink deployment") - testEnvironment = environment.New(&environment.Config{ - NamespacePrefix: fmt.Sprintf("smoke-vrf-%s", strings.ReplaceAll(strings.ToLower(testNetwork.Name), " ", "-")), - Test: t, - }). - AddHelm(evmConfig). - AddHelmCharts(cd) - err = testEnvironment.Run() - require.NoError(t, err, "Error running test environment") - return testEnvironment, testNetwork -} diff --git a/integration-tests/smoke/vrfv2_test.go b/integration-tests/smoke/vrfv2_test.go index db1255aebeb..ed9b9f16318 100644 --- a/integration-tests/smoke/vrfv2_test.go +++ b/integration-tests/smoke/vrfv2_test.go @@ -7,91 +7,83 @@ import ( "time" "github.com/onsi/gomega" - "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" - - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2_actions" - "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2_actions/vrfv2_constants" - "github.com/smartcontractkit/chainlink/integration-tests/client" - "github.com/smartcontractkit/chainlink/integration-tests/config" - "github.com/smartcontractkit/chainlink/integration-tests/contracts" - "github.com/smartcontractkit/chainlink/integration-tests/networks" + vrfConst "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2_actions/vrfv2_constants" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" ) func TestVRFv2Basic(t *testing.T) { - t.Parallel() l := utils.GetTestLogger(t) - testNetwork := networks.SelectedNetwork - testEnvironment := vrfv2_actions.SetupVRFV2Environment( - t, - testNetwork, - config.BaseVRFV2NetworkDetailTomlConfig, - "", - "smoke-vrfv2", - "", - time.Minute*20, - ) - if testEnvironment.WillUseRemoteRunner() { - return - } + env, err := test_env.NewCLTestEnvBuilder(). + WithGeth(). + WithCLNodes(1). + WithFunding(vrfConst.ChainlinkNodeFundingAmountEth). + Build() + require.NoError(t, err) + env.ParallelTransactions(true) - chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment) + mockFeed, err := actions.DeployMockETHLinkFeed(env.ContractDeployer, vrfConst.LinkEthFeedResponse) require.NoError(t, err) - contractDeployer, err := contracts.NewContractDeployer(chainClient) + lt, err := actions.DeployLINKToken(env.ContractDeployer) require.NoError(t, err) - chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment) + vrfv2Contracts, err := vrfv2_actions.DeployVRFV2Contracts(env.ContractDeployer, env.EVMClient, lt, mockFeed) require.NoError(t, err) - chainClient.ParallelTransactions(true) + err = env.EVMClient.WaitForEvents() + require.NoError(t, err) - mockETHLINKFeed, err := contractDeployer.DeployMockETHLINKFeed(vrfv2_constants.LinkEthFeedResponse) + err = vrfv2Contracts.Coordinator.SetConfig( + vrfConst.MinimumConfirmations, + vrfConst.MaxGasLimitVRFCoordinatorConfig, + vrfConst.StalenessSeconds, + vrfConst.GasAfterPaymentCalculation, + vrfConst.LinkEthFeedResponse, + vrfConst.VRFCoordinatorV2FeeConfig, + ) require.NoError(t, err) - linkToken, err := contractDeployer.DeployLinkTokenContract() + err = env.EVMClient.WaitForEvents() require.NoError(t, err) - vrfV2Contracts, chainlinkNodesAfterRedeployment, vrfV2jobs, testEnvironmentAfterRedeployment := vrfv2_actions.SetupVRFV2Universe( - t, - linkToken, - mockETHLINKFeed, - contractDeployer, - chainClient, - chainlinkNodes, - testNetwork, - testEnvironment, - vrfv2_constants.ChainlinkNodeFundingAmountEth, - vrfv2_constants.VRFSubscriptionFundingAmountLink, - "smoke-vrfv2", - time.Minute*20, + err = vrfv2Contracts.Coordinator.CreateSubscription() + require.NoError(t, err) + err = env.EVMClient.WaitForEvents() + require.NoError(t, err) + + err = vrfv2Contracts.Coordinator.AddConsumer(vrfConst.SubID, vrfv2Contracts.LoadTestConsumer.Address()) + require.NoError(t, err) + + err = vrfv2_actions.FundVRFCoordinatorV2Subscription(lt, vrfv2Contracts.Coordinator, env.EVMClient, vrfConst.SubID, vrfConst.VRFSubscriptionFundingAmountLink) + require.NoError(t, err) + + vrfV2jobs, err := vrfv2_actions.CreateVRFV2Jobs(env.GetAPIs(), vrfv2Contracts.Coordinator, env.EVMClient, vrfConst.MinimumConfirmations) + require.NoError(t, err) + + // this part is here because VRFv2 can work with only a specific key + // [[EVM.KeySpecific]] + // Key = '...' + addr, err := env.CLNodes[0].API.PrimaryEthAddress() + require.NoError(t, err) + nodeConfig := node.NewConfig(env.CLNodes[0].NodeConfig, + node.WithVRFv2EVMEstimator(addr), ) + err = env.CLNodes[0].Restart(nodeConfig) + require.NoError(t, err) - consumerContract := vrfV2Contracts.LoadTestConsumer - - t.Cleanup(func() { - err := actions.TeardownSuite( - t, - testEnvironmentAfterRedeployment, - utils.ProjectRoot, - chainlinkNodesAfterRedeployment, - nil, - zapcore.ErrorLevel, - chainClient, - ) - require.NoError(t, err, "Error tearing down environment") - }) - - err = consumerContract.RequestRandomness( + // test and assert + err = vrfv2Contracts.LoadTestConsumer.RequestRandomness( vrfV2jobs[0].KeyHash, - vrfv2_constants.SubID, - vrfv2_constants.MinimumConfirmations, - vrfv2_constants.CallbackGasLimit, - vrfv2_constants.NumberOfWords, - vrfv2_constants.RandomnessRequestCountPerRequest, + vrfConst.SubID, + vrfConst.MinimumConfirmations, + vrfConst.CallbackGasLimit, + vrfConst.NumberOfWords, + vrfConst.RandomnessRequestCountPerRequest, ) require.NoError(t, err) @@ -99,21 +91,21 @@ func TestVRFv2Basic(t *testing.T) { timeout := time.Minute * 2 var lastRequestID *big.Int gom.Eventually(func(g gomega.Gomega) { - jobRuns, err := chainlinkNodesAfterRedeployment[0].MustReadRunsByJob(vrfV2jobs[0].Job.Data.ID) + jobRuns, err := env.CLNodes[0].API.MustReadRunsByJob(vrfV2jobs[0].Job.Data.ID) g.Expect(err).ShouldNot(gomega.HaveOccurred()) g.Expect(len(jobRuns.Data)).Should(gomega.BeNumerically("==", 1)) - lastRequestID, err = consumerContract.GetLastRequestId(context.Background()) + lastRequestID, err = vrfv2Contracts.LoadTestConsumer.GetLastRequestId(context.Background()) l.Debug().Interface("Last Request ID", lastRequestID).Msg("Last Request ID Received") g.Expect(err).ShouldNot(gomega.HaveOccurred()) - status, err := consumerContract.GetRequestStatus(context.Background(), lastRequestID) + status, err := vrfv2Contracts.LoadTestConsumer.GetRequestStatus(context.Background(), lastRequestID) g.Expect(err).ShouldNot(gomega.HaveOccurred()) g.Expect(status.Fulfilled).Should(gomega.BeTrue()) l.Debug().Interface("Fulfilment Status", status.Fulfilled).Msg("Random Words Request Fulfilment Status") g.Expect(err).ShouldNot(gomega.HaveOccurred()) for _, w := range status.RandomWords { - l.Debug().Uint64("Output", w.Uint64()).Msg("Randomness fulfilled") + l.Info().Uint64("Output", w.Uint64()).Msg("Randomness fulfilled") g.Expect(w.Uint64()).Should(gomega.BeNumerically(">", 0), "Expected the VRF job give an answer bigger than 0") } }, timeout, "1s").Should(gomega.Succeed()) diff --git a/integration-tests/soak/forwarder_ocr_test.go b/integration-tests/soak/forwarder_ocr_test.go index f2b3ec649f6..e8bcea0f5b8 100644 --- a/integration-tests/soak/forwarder_ocr_test.go +++ b/integration-tests/soak/forwarder_ocr_test.go @@ -1,106 +1,37 @@ package soak import ( - "fmt" - "math/big" - "os" - "strings" "testing" - "time" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-env/environment" - "github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver" - mockservercfg "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver-cfg" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils" "github.com/smartcontractkit/chainlink/integration-tests/actions" - "github.com/smartcontractkit/chainlink/integration-tests/client" - "github.com/smartcontractkit/chainlink/integration-tests/networks" "github.com/smartcontractkit/chainlink/integration-tests/testsetups" ) -func TestMain(m *testing.M) { - os.Exit(m.Run()) -} - func TestForwarderOCRSoak(t *testing.T) { l := utils.GetTestLogger(t) - testEnvironment, network := SetupForwarderOCRSoakEnv(t) - if testEnvironment.WillUseRemoteRunner() { + // Use this variable to pass in any custom EVM specific TOML values to your Chainlink nodes + customNetworkTOML := `[EVM.Transactions] +ForwardersEnabled = true` + // Uncomment below for debugging TOML issues on the node + // fmt.Println("Using Chainlink TOML\n---------------------") + // fmt.Println(client.AddNetworkDetailedConfig(config.BaseOCRP2PV1Config, customNetworkTOML, network)) + // fmt.Println("---------------------") + + ocrSoakTest, err := testsetups.NewOCRSoakTest(t, true) + require.NoError(t, err, "Error creating soak test") + ocrSoakTest.DeployEnvironment(customNetworkTOML) + if ocrSoakTest.Environment().WillUseRemoteRunner() { return } - - chainClient, err := blockchain.NewEVMClient(network, testEnvironment) - require.NoError(t, err, "Error connecting to blockchain") - ocrSoakTest := testsetups.NewOCRSoakTest(&testsetups.OCRSoakTestInputs{ - BlockchainClient: chainClient, - TestDuration: time.Minute * 15, - NumberOfContracts: 2, - ChainlinkNodeFunding: big.NewFloat(.1), - ExpectedRoundTime: time.Minute * 2, - TimeBetweenRounds: time.Minute * 1, - StartingAdapterValue: 5, - }) t.Cleanup(func() { - if err = actions.TeardownRemoteSuite(ocrSoakTest.TearDownVals(t)); err != nil { - l.Error().Err(err).Msg("Error when tearing down remote suite") + if err := actions.TeardownRemoteSuite(ocrSoakTest.TearDownVals(t)); err != nil { + l.Error().Err(err).Msg("Error tearing down environment") } }) - ocrSoakTest.OperatorForwarderFlow = true - ocrSoakTest.Setup(t, testEnvironment) - l.Info().Msg("Setup soak test") - ocrSoakTest.Run(t) -} - -func SetupForwarderOCRSoakEnv(t *testing.T) (*environment.Environment, blockchain.EVMNetwork) { - var ( - ocrForwarderBaseTOML = `[OCR] - Enabled = true - - [Feature] - LogPoller = true - - [P2P] - [P2P.V1] - Enabled = true - ListenIP = '0.0.0.0' - ListenPort = 6690` - - ocrForwarderNetworkDetailTOML = `[EVM.Transactions] - ForwardersEnabled = true` - ) - network := networks.SelectedNetwork // Environment currently being used to soak test on - - baseEnvironmentConfig := &environment.Config{ - TTL: time.Hour * 720, // 30 days, - NamespacePrefix: fmt.Sprintf( - "soak-forwarder-ocr-%s", - strings.ReplaceAll(strings.ToLower(network.Name), " ", "-"), - ), - Test: t, - } - - cd, err := chainlink.NewDeployment(6, map[string]interface{}{ - "toml": client.AddNetworkDetailedConfig(ocrForwarderBaseTOML, ocrForwarderNetworkDetailTOML, network), - }) - require.NoError(t, err, "Error creating chainlink deployment") - // Values you want each node to have the exact same of (e.g. eth_chain_id) - testEnvironment := environment.New(baseEnvironmentConfig). - AddHelm(mockservercfg.New(nil)). - AddHelm(mockserver.New(nil)). - AddHelm(ethereum.New(ðereum.Props{ - NetworkName: network.Name, - Simulated: network.Simulated, - WsURLs: network.URLs, - })). - AddHelmCharts(cd) - - err = testEnvironment.Run() - require.NoError(t, err, "Error launching test environment") - return testEnvironment, network + ocrSoakTest.Setup() + ocrSoakTest.Run() } diff --git a/integration-tests/soak/ocr_test.go b/integration-tests/soak/ocr_test.go index 27000cd10a8..c0fd0a4525f 100644 --- a/integration-tests/soak/ocr_test.go +++ b/integration-tests/soak/ocr_test.go @@ -1,123 +1,44 @@ package soak import ( - "fmt" - "math/big" - "os" - "strconv" - "strings" "testing" - "time" - "github.com/kelseyhightower/envconfig" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-env/environment" - "github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver" - mockservercfg "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver-cfg" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils" "github.com/smartcontractkit/chainlink/integration-tests/actions" - "github.com/smartcontractkit/chainlink/integration-tests/client" - "github.com/smartcontractkit/chainlink/integration-tests/config" - "github.com/smartcontractkit/chainlink/integration-tests/networks" "github.com/smartcontractkit/chainlink/integration-tests/testsetups" ) func TestOCRSoak(t *testing.T) { l := utils.GetTestLogger(t) - testEnvironment, network, testInputs := SetupOCRSoakEnv(t) - if testEnvironment.WillUseRemoteRunner() { - return - } - - chainClient, err := blockchain.NewEVMClient(network, testEnvironment) - require.NoError(t, err, "Error connecting to network") - - ocrSoakTest := testsetups.NewOCRSoakTest(&testsetups.OCRSoakTestInputs{ - BlockchainClient: chainClient, - TestDuration: testInputs.TestDuration, - NumberOfContracts: 2, - ChainlinkNodeFunding: big.NewFloat(testInputs.ChainlinkNodeFunding), - ExpectedRoundTime: time.Minute * 2, - TimeBetweenRounds: testInputs.TimeBetweenRounds, - StartingAdapterValue: 5, - }) - t.Cleanup(func() { - if err := actions.TeardownRemoteSuite(ocrSoakTest.TearDownVals(t)); err != nil { - l.Error().Err(err).Msg("Error tearing down environment") - } - }) - ocrSoakTest.Setup(t, testEnvironment) - l.Info().Msg("Set up soak test") - ocrSoakTest.Run(t) -} - -func SetupOCRSoakEnv(t *testing.T) (*environment.Environment, blockchain.EVMNetwork, OcrSoakInputs) { - var testInputs OcrSoakInputs - err := envconfig.Process("OCR", &testInputs) - require.NoError(t, err, "Error reading OCR soak test inputs") - testInputs.setForRemoteRunner() - network := networks.SelectedNetwork // Environment currently being used to soak test on - - baseEnvironmentConfig := &environment.Config{ - TTL: time.Hour * 720, // 30 days, - NamespacePrefix: fmt.Sprintf( - "soak-ocr-%s", - strings.ReplaceAll(strings.ToLower(network.Name), " ", "-"), - ), - Test: t, - } - // Use this variable to pass in any custom EVM specific TOML values to your Chainlink nodes customNetworkTOML := `` // Uncomment below for debugging TOML issues on the node // fmt.Println("Using Chainlink TOML\n---------------------") // fmt.Println(client.AddNetworkDetailedConfig(config.BaseOCRP2PV1Config, customNetworkTOML, network)) // fmt.Println("---------------------") - cd, err := chainlink.NewDeployment(6, map[string]any{ - "toml": client.AddNetworkDetailedConfig(config.BaseOCRP2PV1Config, customNetworkTOML, network), - "db": map[string]any{ - "stateful": true, // stateful DB by default for soak tests - }, - "chainlink": map[string]any{ - "p2p_port": "6690", - }, - }) - require.NoError(t, err, "Error creating chainlink deployment") - testEnvironment := environment.New(baseEnvironmentConfig). - AddHelm(mockservercfg.New(nil)). - AddHelm(mockserver.New(nil)). - AddHelm(ethereum.New(ðereum.Props{ - NetworkName: network.Name, - Simulated: network.Simulated, - WsURLs: network.URLs, - })). - AddHelmCharts(cd) - err = testEnvironment.Run() - require.NoError(t, err, "Error launching test environment") - return testEnvironment, network, testInputs -} -type OcrSoakInputs struct { - TestDuration time.Duration `envconfig:"TEST_DURATION" default:"15m"` - ChainlinkNodeFunding float64 `envconfig:"CHAINLINK_NODE_FUNDING" default:".1"` - TimeBetweenRounds time.Duration `envconfig:"TIME_BETWEEN_ROUNDS" default:"1m"` -} - -func (i OcrSoakInputs) setForRemoteRunner() { - os.Setenv("TEST_OCR_TEST_DURATION", i.TestDuration.String()) - os.Setenv("TEST_OCR_CHAINLINK_NODE_FUNDING", strconv.FormatFloat(i.ChainlinkNodeFunding, 'f', -1, 64)) - os.Setenv("TEST_OCR_TIME_BETWEEN_ROUNDS", i.TimeBetweenRounds.String()) - - selectedNetworks := strings.Split(os.Getenv("SELECTED_NETWORKS"), ",") - for _, networkPrefix := range selectedNetworks { - urlEnv := fmt.Sprintf("%s_URLS", networkPrefix) - httpEnv := fmt.Sprintf("%s_HTTP_URLS", networkPrefix) - os.Setenv(fmt.Sprintf("TEST_%s", urlEnv), os.Getenv(urlEnv)) - os.Setenv(fmt.Sprintf("TEST_%s", httpEnv), os.Getenv(httpEnv)) + ocrSoakTest, err := testsetups.NewOCRSoakTest(t, false) + require.NoError(t, err, "Error creating soak test") + if !ocrSoakTest.Interrupted() { + ocrSoakTest.DeployEnvironment(customNetworkTOML) + } + if ocrSoakTest.Environment().WillUseRemoteRunner() { + return + } + t.Cleanup(func() { + if err := actions.TeardownRemoteSuite(ocrSoakTest.TearDownVals(t)); err != nil { + l.Error().Err(err).Msg("Error tearing down environment") + } + }) + if ocrSoakTest.Interrupted() { + err = ocrSoakTest.LoadState() + require.NoError(t, err, "Error loading state") + ocrSoakTest.Resume() + } else { + ocrSoakTest.Setup() + ocrSoakTest.Run() } } diff --git a/integration-tests/soak/vrfv2_test.go b/integration-tests/soak/vrfv2_test.go deleted file mode 100644 index cc64474de90..00000000000 --- a/integration-tests/soak/vrfv2_test.go +++ /dev/null @@ -1,151 +0,0 @@ -package soak - -import ( - "fmt" - "math/big" - "testing" - "time" - - "github.com/kelseyhightower/envconfig" - "github.com/rs/zerolog" - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - "github.com/smartcontractkit/chainlink-testing-framework/utils" - - "github.com/smartcontractkit/chainlink/integration-tests/actions" - "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2_actions" - "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2_actions/vrfv2_constants" - "github.com/smartcontractkit/chainlink/integration-tests/client" - "github.com/smartcontractkit/chainlink/integration-tests/config" - "github.com/smartcontractkit/chainlink/integration-tests/contracts" - "github.com/smartcontractkit/chainlink/integration-tests/networks" - "github.com/smartcontractkit/chainlink/integration-tests/testsetups" -) - -func TestVRFV2Soak(t *testing.T) { - var testInputs testsetups.VRFV2SoakTestInputs - err := envconfig.Process("VRFV2", &testInputs) - require.NoError(t, err, "Error reading VRFV2 soak test inputs") - vrfSubscriptionFundingAmountInLink := testInputs.SubscriptionFunding - chainlinkNodeFundingAmountEth := testInputs.ChainlinkNodeFunding - randomnessRequestCountPerRequest := testInputs.RandomnessRequestCountPerRequest - - l := utils.GetTestLogger(t) - - testInputs.SetForRemoteRunner() - testNetwork := networks.SelectedNetwork // Environment currently being used to soak test on - - testEnvironment := vrfv2_actions.SetupVRFV2Environment( - t, - testNetwork, - config.BaseVRFV2NetworkDetailTomlConfig, - "", - "soak-vrfv2", - "", - //todo - what should be TTL for soak test? - time.Minute*60, - ) - if testEnvironment.WillUseRemoteRunner() { - return - } - - chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment) - require.NoError(t, err) - contractDeployer, err := contracts.NewContractDeployer(chainClient) - require.NoError(t, err) - chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment) - require.NoError(t, err) - chainClient.ParallelTransactions(true) - - mockETHLINKFeed, err := contractDeployer.DeployMockETHLINKFeed(vrfv2_constants.LinkEthFeedResponse) - require.NoError(t, err) - linkToken, err := contractDeployer.DeployLinkTokenContract() - require.NoError(t, err) - - vrfV2Contracts, chainlinkNodesAfterRedeployment, vrfV2jobs, _ := vrfv2_actions.SetupVRFV2Universe( - t, - linkToken, - mockETHLINKFeed, - contractDeployer, - chainClient, - chainlinkNodes, - testNetwork, - testEnvironment, - chainlinkNodeFundingAmountEth, - vrfSubscriptionFundingAmountInLink, - "soak-vrfv2", - time.Hour*1, - ) - - consumerContract := vrfV2Contracts.LoadTestConsumer - - vrfV2SoakTest := testsetups.NewVRFV2SoakTest(&testsetups.VRFV2SoakTestInputs{ - BlockchainClient: chainClient, - TestDuration: testInputs.TestDuration, - ChainlinkNodeFunding: chainlinkNodeFundingAmountEth, - SubscriptionFunding: vrfSubscriptionFundingAmountInLink, - StopTestOnError: testInputs.StopTestOnError, - RequestsPerMinute: testInputs.RequestsPerMinute, - ConsumerContract: consumerContract, - TestFunc: func(t *testsetups.VRFV2SoakTest, requestNumber int) error { - // request randomness - err = consumerContract.RequestRandomness( - vrfV2jobs[0].KeyHash, - vrfv2_constants.SubID, - vrfv2_constants.MinimumConfirmations, - vrfv2_constants.CallbackGasLimit, - vrfv2_constants.NumberOfWords, - uint16(randomnessRequestCountPerRequest), - ) - if err != nil { - return fmt.Errorf("error occurred Requesting Randomness, error: %w", err) - } - - l.Info(). - Int("Request Number", requestNumber). - Int("Randomness Request Count Per Request", randomnessRequestCountPerRequest). - Msg("Randomness requested") - - printDebugData(l, vrfV2Contracts, chainlinkNodesAfterRedeployment) - - return nil - }, - }, - chainlinkNodesAfterRedeployment) - - t.Cleanup(func() { - if err := actions.TeardownRemoteSuite(vrfV2SoakTest.TearDownVals(t)); err != nil { - l.Error().Err(err).Msg("Error tearing down environment") - } - }) - vrfV2SoakTest.Setup(t, testEnvironment) - l.Info().Msg("Set up soak test") - vrfV2SoakTest.Run(t) -} - -func printDebugData(l zerolog.Logger, vrfV2Contracts vrfv2_actions.VRFV2Contracts, chainlinkNodesAfterRedeployment []*client.Chainlink) { - subscription, err := vrfV2Contracts.Coordinator.GetSubscription(nil, vrfv2_constants.SubID) - if err != nil { - l.Error().Err(err). - Uint64("Subscription ID", vrfv2_constants.SubID). - Interface("Coordinator Address", vrfV2Contracts.Coordinator.Address()). - Msg("error occurred Getting Subscription Data from a Coordinator Contract") - } - l.Debug().Interface("Data", subscription).Uint64("Subscription ID", vrfv2_constants.SubID).Msg("Subscription Data") - remainingSubBalanceInLink := new(big.Float).Quo(new(big.Float).SetInt(subscription.Balance), big.NewFloat(1e18)) - l.Debug().Interface("Balance", remainingSubBalanceInLink).Msg("Remaining Balance in Link for a subscription") - nativeTokenPrimaryKey, err := chainlinkNodesAfterRedeployment[0].ReadPrimaryETHKey() - if err != nil { - l.Error().Err(err).Msg("error occurred reading Native Token Primary Key from Chainlink Node") - } - ethBalance, ok := new(big.Int).SetString(nativeTokenPrimaryKey.Attributes.ETHBalance, 10) - if !ok { - l.Error().Interface("Balance", nativeTokenPrimaryKey.Attributes.ETHBalance).Msg("error occurred converting Native Token Primary Key from Chainlink Node") - } - remainingNativeTokenPrimaryKeyBalanceInETH := new(big.Float).Quo(new(big.Float).SetInt(ethBalance), big.NewFloat(1e18)) - l.Debug(). - Interface("Balance", remainingNativeTokenPrimaryKeyBalanceInETH). - Interface("Key Address", nativeTokenPrimaryKey.Attributes.Address). - Msg("Remaining Balance for a Native Token Primary Key of Chainlink Node") -} diff --git a/integration-tests/testreporters/ocr.go b/integration-tests/testreporters/ocr.go index 818d4192e87..a04718ea228 100644 --- a/integration-tests/testreporters/ocr.go +++ b/integration-tests/testreporters/ocr.go @@ -19,7 +19,7 @@ import ( // OCRSoakTestReporter collates all OCRAnswerUpdated events into a single report type OCRSoakTestReporter struct { - TestDuration time.Duration + StartTime time.Time AnomaliesDetected bool anomalies [][]string @@ -34,37 +34,38 @@ type TimeLineEvent interface { CSV() [][]string } -// RPCIssue is a single RPC issue, either a disconnect or reconnect -type RPCIssue struct { - StartTime time.Time - Message string +// TestIssue is a single RPC issue, either a disconnect or reconnect +type TestIssue struct { + StartTime time.Time `toml:"startTime"` + Message string `toml:"message"` } -func (r *RPCIssue) Time() time.Time { +func (r *TestIssue) Time() time.Time { return r.StartTime } -func (r *RPCIssue) CSV() [][]string { - return [][]string{{r.StartTime.Format("2006-01-02 15:04:05.00 MST"), r.Message}} +func (r *TestIssue) CSV() [][]string { + return [][]string{{r.StartTime.Format("2006-01-02 15:04:05.00 MST"), "Test Issue!", r.Message}} } -// OCRTestState indicates that a round per contract should complete within this time with this answer -type OCRTestState struct { - StartTime time.Time - EndTime time.Time // Time when the round should end, only used for analysis - Answer int64 - anomalous bool - anomalies [][]string - FoundEvents map[string][]*FoundEvent // Address -> FoundEvents, possible to have multiple found events per round, and need to call it out - TimeLineEvents []TimeLineEvent +// OCRRoundState indicates that a round per contract should complete within this time with this answer +type OCRRoundState struct { + StartTime time.Time `toml:"startTime"` + EndTime time.Time `toml:"endTime"` // Time when the round should end, only used for analysis + Answer int64 `toml:"answer"` + Anomalous bool `toml:"anomalous"` // Whether the round was anomalous + FoundEvents map[string][]*FoundEvent `toml:"foundEvents"` // Address -> FoundEvents, possible to have multiple found events per round, and need to call it out + TimeLineEvents []TimeLineEvent `toml:"timeLineEvents"` + + anomalies [][]string } -func (e *OCRTestState) Time() time.Time { +func (e *OCRRoundState) Time() time.Time { return e.StartTime } // CSV returns a CSV representation of the test state and all events -func (e *OCRTestState) CSV() [][]string { +func (e *OCRRoundState) CSV() [][]string { rows := [][]string{{e.StartTime.Format("2006-01-02 15:04:05.00 MST"), fmt.Sprintf("Expecting new Answer: %d", e.Answer)}} for _, anomaly := range e.anomalies { rows = append(rows, anomaly) @@ -76,31 +77,31 @@ func (e *OCRTestState) CSV() [][]string { // 1. There is a FoundEvent for every address // 2. There is only one FoundEvent for every address // 3. The answer is correct -func (e *OCRTestState) Validate() bool { +func (e *OCRRoundState) Validate() bool { anomalies := [][]string{} for address, eventList := range e.FoundEvents { if len(eventList) == 0 { - e.anomalous = true + e.Anomalous = true anomalies = append(anomalies, []string{ - e.StartTime.Format("2006-01-02 15:04:05.00 MST"), fmt.Sprintf("No AnswerUpdated for address '%s'", address), + e.StartTime.Format("2006-01-02 15:04:05.00 MST"), "Anomaly Found!", fmt.Sprintf("No AnswerUpdated for address '%s'", address), }) } else if len(eventList) > 1 { - e.anomalous = true - anomalies = append(anomalies, []string{e.StartTime.Format("2006-01-02 15:04:05.00 MST"), + e.Anomalous = true + anomalies = append(anomalies, []string{e.StartTime.Format("2006-01-02 15:04:05.00 MST"), "Anomaly Found!", fmt.Sprintf("Multiple AnswerUpdated for address '%s', possible double-transmission", address)}, ) } else { event := eventList[0] if event.Answer != e.Answer { - e.anomalous = true - anomalies = append(e.anomalies, []string{e.StartTime.Format("2006-01-02 15:04:05.00 MST"), + e.Anomalous = true + anomalies = append(e.anomalies, []string{e.StartTime.Format("2006-01-02 15:04:05.00 MST"), "Anomaly Found!", fmt.Sprintf("FoundEvent for address '%s' has wrong answer '%d'", address, event.Answer)}, ) } } } e.anomalies = anomalies - return e.anomalous + return e.Anomalous } // FoundEvent is a single round update event @@ -128,7 +129,7 @@ func (a *FoundEvent) CSV() [][]string { } // RecordEvents takes in a list of test states and RPC issues, orders them, and records them in the timeline -func (o *OCRSoakTestReporter) RecordEvents(testStates []*OCRTestState, rpcIssues []*RPCIssue) { +func (o *OCRSoakTestReporter) RecordEvents(testStates []*OCRRoundState, testIssues []*TestIssue) { events := []TimeLineEvent{} for _, expectedEvent := range testStates { if expectedEvent.Validate() { @@ -138,11 +139,12 @@ func (o *OCRSoakTestReporter) RecordEvents(testStates []*OCRTestState, rpcIssues events = append(events, expectedEvent) events = append(events, expectedEvent.TimeLineEvents...) } - if len(rpcIssues) > 0 { + if len(testIssues) > 0 { o.AnomaliesDetected = true } - for _, rpcIssue := range rpcIssues { - events = append(events, rpcIssue) + for _, testIssue := range testIssues { + events = append(events, testIssue) + o.anomalies = append(o.anomalies, testIssue.CSV()...) } sort.Slice(events, func(i, j int) bool { return events[i].Time().Before(events[j].Time()) @@ -178,8 +180,10 @@ func (o *OCRSoakTestReporter) WriteReport(folderLocation string) error { err = ocrReportWriter.Write([]string{ "Namespace", o.namespace, + "Started At", + o.StartTime.Format("2006-01-02 15:04:05.00 MST"), "Test Duration", - o.TestDuration.String(), + time.Since(o.StartTime).String(), }) if err != nil { return err @@ -245,7 +249,7 @@ func (o *OCRSoakTestReporter) SendSlackNotification(t *testing.T, slackClient *s headerText = ":warning: OCR Soak Test Found Anomalies :warning:" } messageBlocks := testreporters.CommonSlackNotificationBlocks( - headerText, o.namespace, o.csvLocation, + headerText, fmt.Sprintf("%s | Test took: %s", o.namespace, time.Since(o.StartTime).Truncate(time.Second).String()), o.csvLocation, ) ts, err := testreporters.SendSlackMessage(slackClient, slack.MsgOptionBlocks(messageBlocks...)) if err != nil { diff --git a/integration-tests/testsetups/don_evm_chain.go b/integration-tests/testsetups/don_evm_chain.go index ec01d8e9784..a9e69b32f49 100644 --- a/integration-tests/testsetups/don_evm_chain.go +++ b/integration-tests/testsetups/don_evm_chain.go @@ -23,7 +23,7 @@ type DonChain struct { EVMNetwork *blockchain.EVMNetwork ContractDeployer contracts.ContractDeployer LinkTokenContract contracts.LinkToken - ChainlinkNodes []*client.Chainlink + ChainlinkNodes []*client.ChainlinkK8sClient Mockserver *ctfClient.MockserverClient } diff --git a/integration-tests/testsetups/keeper_benchmark.go b/integration-tests/testsetups/keeper_benchmark.go index 358a266c605..8bc11c43599 100644 --- a/integration-tests/testsetups/keeper_benchmark.go +++ b/integration-tests/testsetups/keeper_benchmark.go @@ -21,6 +21,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/blockchain" reportModel "github.com/smartcontractkit/chainlink-testing-framework/testreporters" "github.com/smartcontractkit/chainlink-testing-framework/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_1" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_2" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_3" @@ -45,7 +46,8 @@ type KeeperBenchmarkTest struct { upkeepIDs [][]*big.Int env *environment.Environment - chainlinkNodes []*client.Chainlink + namespace string + chainlinkNodes []*client.ChainlinkK8sClient chainClient blockchain.EVMClient contractDeployer contracts.ContractDeployer @@ -102,6 +104,7 @@ func (k *KeeperBenchmarkTest) Setup(t *testing.T, env *environment.Environment) k.TestReporter.Summary.StartTime = startTime.UnixMilli() k.ensureInputValues(t) k.env = env + k.namespace = k.env.Cfg.Namespace inputs := k.Inputs k.keeperRegistries = make([]contracts.KeeperRegistry, len(inputs.RegistryVersions)) @@ -238,7 +241,7 @@ func (k *KeeperBenchmarkTest) Run(t *testing.T) { // Send keeper jobs to registry and chainlink nodes if inputs.RegistryVersions[rIndex] == ethereum.RegistryVersion_2_0 { - actions.CreateOCRKeeperJobs(t, k.chainlinkNodes, k.keeperRegistries[rIndex].Address(), k.chainClient.GetChainID().Int64(), txKeyId) + actions.CreateOCRKeeperJobs(t, k.chainlinkNodes, k.keeperRegistries[rIndex].Address(), k.chainClient.GetChainID().Int64(), txKeyId, ethereum.RegistryVersion_2_0) err = k.keeperRegistries[rIndex].SetConfig(*inputs.KeeperRegistrySettings, ocrConfig) require.NoError(t, err, "Registry config should be be set successfully") // Give time for OCR nodes to bootstrap @@ -392,12 +395,12 @@ func (k *KeeperBenchmarkTest) subscribeToUpkeepPerformedEvent( // TearDownVals returns the networks that the test is running on func (k *KeeperBenchmarkTest) TearDownVals(t *testing.T) ( *testing.T, - *environment.Environment, - []*client.Chainlink, + string, + []*client.ChainlinkK8sClient, reportModel.TestReporter, blockchain.EVMClient, ) { - return t, k.env, k.chainlinkNodes, &k.TestReporter, k.chainClient + return t, k.namespace, k.chainlinkNodes, &k.TestReporter, k.chainClient } // ensureValues ensures that all values needed to run the test are present @@ -539,10 +542,7 @@ func (k *KeeperBenchmarkTest) DeployBenchmarkKeeperContracts( linkFunds = big.NewInt(0).Add(linkFunds, minLinkBalance) - upkeepIds := actions.RegisterUpkeepContractsWithCheckData( - t, k.linkToken, linkFunds, k.chainClient, uint32(upkeep.UpkeepGasLimit), registry, - registrar, upkeep.NumberOfUpkeeps, upkeepAddresses, checkData, - ) + upkeepIds := actions.RegisterUpkeepContractsWithCheckData(t, k.linkToken, linkFunds, k.chainClient, uint32(upkeep.UpkeepGasLimit), registry, registrar, upkeep.NumberOfUpkeeps, upkeepAddresses, checkData, false) k.keeperRegistries[index] = registry k.keeperRegistrars[index] = registrar diff --git a/integration-tests/testsetups/ocr.go b/integration-tests/testsetups/ocr.go index e4cf46fa02a..88f52fa16f3 100644 --- a/integration-tests/testsetups/ocr.go +++ b/integration-tests/testsetups/ocr.go @@ -3,19 +3,33 @@ package testsetups import ( "context" + "fmt" + "io/ioutil" "math/big" + "math/rand" + "os" + "os/signal" "sort" + "strconv" + "strings" + "syscall" "testing" "time" geth "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/kelseyhightower/envconfig" + "github.com/pelletier/go-toml/v2" "github.com/rs/zerolog" "github.com/rs/zerolog/log" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-env/environment" + "github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink" + "github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum" + "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver" + mockservercfg "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver-cfg" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" reportModel "github.com/smartcontractkit/chainlink-testing-framework/testreporters" @@ -24,27 +38,35 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" + "github.com/smartcontractkit/chainlink/integration-tests/config" "github.com/smartcontractkit/chainlink/integration-tests/contracts" + "github.com/smartcontractkit/chainlink/integration-tests/networks" "github.com/smartcontractkit/chainlink/integration-tests/testreporters" ) +const saveFileLocation = "/persistence/ocr-soak-test-state.toml" + // OCRSoakTest defines a typical OCR soak test type OCRSoakTest struct { Inputs *OCRSoakTestInputs TestReporter testreporters.OCRSoakTestReporter OperatorForwarderFlow bool - testEnvironment *environment.Environment - bootstrapNode *client.Chainlink - workerNodes []*client.Chainlink - chainClient blockchain.EVMClient - mockServer *ctfClient.MockserverClient - mockPath string - filterQuery geth.FilterQuery - - ocrTestStates []*testreporters.OCRTestState - rpcIssues []*testreporters.RPCIssue - combinedEvents [][]string + t *testing.T + startTime time.Time + timeLeft time.Duration + startingBlockNum uint64 + testEnvironment *environment.Environment + namespace string + log zerolog.Logger + bootstrapNode *client.ChainlinkK8sClient + workerNodes []*client.ChainlinkK8sClient + chainClient blockchain.EVMClient + mockServer *ctfClient.MockserverClient + filterQuery geth.FilterQuery + + ocrRoundStates []*testreporters.OCRRoundState + testIssues []*testreporters.TestIssue ocrInstances []contracts.OffchainAggregator ocrInstanceMap map[string]contracts.OffchainAggregator // address : instance @@ -52,75 +74,157 @@ type OCRSoakTest struct { // OCRSoakTestInputs define required inputs to run an OCR soak test type OCRSoakTestInputs struct { - BlockchainClient blockchain.EVMClient // Client for the test to connect to the blockchain with - TestDuration time.Duration // How long to run the test for - NumberOfContracts int // Number of OCR contracts to launch - ChainlinkNodeFunding *big.Float // Amount of ETH to fund each chainlink node with - ExpectedRoundTime time.Duration // How long each round is expected to take - TimeBetweenRounds time.Duration // How long to wait after a completed round to start a new one, set 0 for instant - StartingAdapterValue int + TestDuration time.Duration `envconfig:"TEST_DURATION" default:"15m"` // How long to run the test for + NumberOfContracts int `envconfig:"NUMBER_CONTRACTS" default:"2"` // Number of OCR contracts to launch + ChainlinkNodeFunding float64 `envconfig:"CHAINLINK_NODE_FUNDING" default:".1"` // Amount of native currency to fund each chainlink node with + bigChainlinkNodeFunding *big.Float // Convenience conversions for funding + TimeBetweenRounds time.Duration `envconfig:"TIME_BETWEEN_ROUNDS" default:"1m"` // How long to wait before starting a new round; controls frequency of rounds +} + +func (i OCRSoakTestInputs) setForRemoteRunner() { + os.Setenv("TEST_OCR_TEST_DURATION", i.TestDuration.String()) + os.Setenv("TEST_OCR_NUMBER_CONTRACTS", fmt.Sprint(i.NumberOfContracts)) + os.Setenv("TEST_OCR_CHAINLINK_NODE_FUNDING", strconv.FormatFloat(i.ChainlinkNodeFunding, 'f', -1, 64)) + os.Setenv("TEST_OCR_TIME_BETWEEN_ROUNDS", i.TimeBetweenRounds.String()) + + selectedNetworks := strings.Split(os.Getenv("SELECTED_NETWORKS"), ",") + for _, networkPrefix := range selectedNetworks { + urlEnv := fmt.Sprintf("%s_URLS", networkPrefix) + httpEnv := fmt.Sprintf("%s_HTTP_URLS", networkPrefix) + os.Setenv(fmt.Sprintf("TEST_%s", urlEnv), os.Getenv(urlEnv)) + os.Setenv(fmt.Sprintf("TEST_%s", httpEnv), os.Getenv(httpEnv)) + } } // NewOCRSoakTest creates a new OCR soak test to setup and run -func NewOCRSoakTest(inputs *OCRSoakTestInputs) *OCRSoakTest { - if inputs.StartingAdapterValue == 0 { - inputs.StartingAdapterValue = 5 +func NewOCRSoakTest(t *testing.T, forwarderFlow bool) (*OCRSoakTest, error) { + var testInputs OCRSoakTestInputs + err := envconfig.Process("OCR", &testInputs) + if err != nil { + return nil, err } - return &OCRSoakTest{ - Inputs: inputs, + testInputs.setForRemoteRunner() + + test := &OCRSoakTest{ + Inputs: &testInputs, + OperatorForwarderFlow: forwarderFlow, TestReporter: testreporters.OCRSoakTestReporter{ - TestDuration: inputs.TestDuration, + StartTime: time.Now(), }, - ocrTestStates: make([]*testreporters.OCRTestState, 0), - mockPath: "ocr", + t: t, + startTime: time.Now(), + timeLeft: testInputs.TestDuration, + log: utils.GetTestLogger(t), + ocrRoundStates: make([]*testreporters.OCRRoundState, 0), ocrInstanceMap: make(map[string]contracts.OffchainAggregator), } + test.ensureInputValues() + return test, nil } -// Setup sets up the test environment, deploying contracts and funding chainlink nodes -func (o *OCRSoakTest) Setup(t *testing.T, env *environment.Environment) { - l := utils.GetTestLogger(t) - o.ensureInputValues(t) - o.testEnvironment = env - var err error +// DeployEnvironment deploys the test environment, starting all Chainlink nodes and other components for the test +func (o *OCRSoakTest) DeployEnvironment(customChainlinkNetworkTOML string) { + network := networks.SelectedNetwork // Environment currently being used to soak test on + nsPre := "soak-ocr-" + if o.OperatorForwarderFlow { + nsPre = fmt.Sprintf("%sforwarder-", nsPre) + } + nsPre = fmt.Sprintf("%s%s", nsPre, strings.ReplaceAll(strings.ToLower(network.Name), " ", "-")) + baseEnvironmentConfig := &environment.Config{ + TTL: time.Hour * 720, // 30 days, + NamespacePrefix: nsPre, + Test: o.t, + } + cd, err := chainlink.NewDeployment(6, map[string]any{ + "toml": client.AddNetworkDetailedConfig(config.BaseOCRP2PV1Config, customChainlinkNetworkTOML, network), + "db": map[string]any{ + "stateful": true, // stateful DB by default for soak tests + }, + }) + require.NoError(o.t, err, "Error creating chainlink deployment") + testEnvironment := environment.New(baseEnvironmentConfig). + AddHelm(mockservercfg.New(nil)). + AddHelm(mockserver.New(nil)). + AddHelm(ethereum.New(ðereum.Props{ + NetworkName: network.Name, + Simulated: network.Simulated, + WsURLs: network.URLs, + })). + AddHelmCharts(cd) + err = testEnvironment.Run() + require.NoError(o.t, err, "Error launching test environment") + o.testEnvironment = testEnvironment + o.namespace = testEnvironment.Cfg.Namespace +} + +// LoadEnvironment loads an existing test environment using the provided URLs +func (o *OCRSoakTest) LoadEnvironment(chainlinkURLs []string, chainURL, mockServerURL string) { + var ( + network = networks.SelectedNetwork + err error + ) + o.chainClient, err = blockchain.ConnectEVMClient(network) + require.NoError(o.t, err, "Error connecting to EVM client") + chainlinkNodes, err := client.ConnectChainlinkNodeURLs(chainlinkURLs) + require.NoError(o.t, err, "Error connecting to chainlink nodes") + o.bootstrapNode, o.workerNodes = chainlinkNodes[0], chainlinkNodes[1:] + o.mockServer, err = ctfClient.ConnectMockServerURL(mockServerURL) + require.NoError(o.t, err, "Error connecting to mockserver") +} + +// Environment returns the full K8s test environment +func (o *OCRSoakTest) Environment() *environment.Environment { + return o.testEnvironment +} + +func (o *OCRSoakTest) Setup() { + var ( + err error + network = networks.SelectedNetwork + ) + + // Environment currently being used to soak test on // Make connections to soak test resources + o.chainClient, err = blockchain.NewEVMClient(network, o.testEnvironment) + require.NoError(o.t, err, "Error creating EVM client") contractDeployer, err := contracts.NewContractDeployer(o.chainClient) - require.NoError(t, err, "Deploying contracts shouldn't fail") - nodes, err := client.ConnectChainlinkNodes(env) - require.NoError(t, err, "Connecting to chainlink nodes shouldn't fail") + require.NoError(o.t, err, "Unable to create contract deployer") + require.NotNil(o.t, contractDeployer, "Contract deployer shouldn't be nil") + nodes, err := client.ConnectChainlinkNodes(o.testEnvironment) + require.NoError(o.t, err, "Connecting to chainlink nodes shouldn't fail") o.bootstrapNode, o.workerNodes = nodes[0], nodes[1:] - o.mockServer, err = ctfClient.ConnectMockServer(env) - require.NoError(t, err, "Creating mockserver clients shouldn't fail") + o.mockServer, err = ctfClient.ConnectMockServer(o.testEnvironment) + require.NoError(o.t, err, "Creating mockserver clients shouldn't fail") o.chainClient.ParallelTransactions(true) // Deploy LINK linkTokenContract, err := contractDeployer.DeployLinkTokenContract() - require.NoError(t, err, "Deploying Link Token Contract shouldn't fail") + require.NoError(o.t, err, "Deploying Link Token Contract shouldn't fail") // Fund Chainlink nodes, excluding the bootstrap node - err = actions.FundChainlinkNodes(o.workerNodes, o.chainClient, o.Inputs.ChainlinkNodeFunding) - require.NoError(t, err, "Error funding Chainlink nodes") + err = actions.FundChainlinkNodes(o.workerNodes, o.chainClient, o.Inputs.bigChainlinkNodeFunding) + require.NoError(o.t, err, "Error funding Chainlink nodes") if o.OperatorForwarderFlow { contractLoader, err := contracts.NewContractLoader(o.chainClient) - require.NoError(t, err, "Loading contracts shouldn't fail") + require.NoError(o.t, err, "Loading contracts shouldn't fail") operators, authorizedForwarders, _ := actions.DeployForwarderContracts( - t, contractDeployer, linkTokenContract, o.chainClient, len(o.workerNodes), + o.t, contractDeployer, linkTokenContract, o.chainClient, len(o.workerNodes), ) forwarderNodesAddresses, err := actions.ChainlinkNodeAddresses(o.workerNodes) - require.NoError(t, err, "Retreiving on-chain wallet addresses for chainlink nodes shouldn't fail") + require.NoError(o.t, err, "Retrieving on-chain wallet addresses for chainlink nodes shouldn't fail") for i := range o.workerNodes { actions.AcceptAuthorizedReceiversOperator( - t, operators[i], authorizedForwarders[i], []common.Address{forwarderNodesAddresses[i]}, o.chainClient, contractLoader, + o.t, operators[i], authorizedForwarders[i], []common.Address{forwarderNodesAddresses[i]}, o.chainClient, contractLoader, ) - require.NoError(t, err, "Accepting Authorize Receivers on Operator shouldn't fail") - actions.TrackForwarder(t, o.chainClient, authorizedForwarders[i], o.workerNodes[i]) + require.NoError(o.t, err, "Accepting Authorize Receivers on Operator shouldn't fail") + actions.TrackForwarder(o.t, o.chainClient, authorizedForwarders[i], o.workerNodes[i]) err = o.chainClient.WaitForEvents() } o.ocrInstances = actions.DeployOCRContractsForwarderFlow( - t, + o.t, o.Inputs.NumberOfContracts, linkTokenContract, contractDeployer, @@ -137,118 +241,295 @@ func (o *OCRSoakTest) Setup(t *testing.T, env *environment.Environment) { o.workerNodes, o.chainClient, ) - require.NoError(t, err) + require.NoError(o.t, err) } err = o.chainClient.WaitForEvents() - require.NoError(t, err, "Error waiting for OCR contracts to be deployed") + require.NoError(o.t, err, "Error waiting for OCR contracts to be deployed") for _, ocrInstance := range o.ocrInstances { o.ocrInstanceMap[ocrInstance.Address()] = ocrInstance } - l.Info().Msg("OCR Soak Test Setup Complete") + o.log.Info().Msg("OCR Soak Test Setup Complete") } // Run starts the OCR soak test -func (o *OCRSoakTest) Run(t *testing.T) { - l := utils.GetTestLogger(t) - +func (o *OCRSoakTest) Run() { ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) latestBlockNum, err := o.chainClient.LatestBlockNumber(ctx) cancel() - require.NoError(t, err, "Error getting current block number") + require.NoError(o.t, err, "Error getting current block number") + o.startingBlockNum = latestBlockNum + + startingValue := 5 + if o.OperatorForwarderFlow { + actions.CreateOCRJobsWithForwarder(o.t, o.ocrInstances, o.bootstrapNode, o.workerNodes, startingValue, o.mockServer) + } else { + err := actions.CreateOCRJobs(o.ocrInstances, o.bootstrapNode, o.workerNodes, startingValue, o.mockServer) + require.NoError(o.t, err, "Error creating OCR jobs") + } + + o.log.Info(). + Str("Test Duration", o.Inputs.TestDuration.Truncate(time.Second).String()). + Int("Number of OCR Contracts", len(o.ocrInstances)). + Msg("Starting OCR Soak Test") + + o.testLoop(o.Inputs.TestDuration, startingValue) +} + +// Networks returns the networks that the test is running on +func (o *OCRSoakTest) TearDownVals(t *testing.T) ( + *testing.T, + string, + []*client.ChainlinkK8sClient, + reportModel.TestReporter, + blockchain.EVMClient, +) { + return t, o.namespace, append(o.workerNodes, o.bootstrapNode), &o.TestReporter, o.chainClient +} + +// ********************* +// Recovery if the test is shut-down/rebalanced by K8s +// ********************* + +// OCRSoakTestState contains all the info needed by the test to recover from a K8s rebalance, assuming the test was in a running state +type OCRSoakTestState struct { + Namespace string `toml:"namespace"` + OCRRoundStates []*testreporters.OCRRoundState `toml:"ocrRoundStates"` + TestIssues []*testreporters.TestIssue `toml:"testIssues"` + StartingBlockNum uint64 `toml:"startingBlockNum"` + StartTime time.Time `toml:"startTime"` + TimeRunning time.Duration `toml:"timeRunning"` + TestDuration time.Duration `toml:"testDuration"` + OCRContractAddresses []string `toml:"ocrContractAddresses"` + + BootStrapNodeURL string `toml:"bootstrapNodeURL"` + WorkerNodeURLs []string `toml:"workerNodeURLs"` + ChainURL string `toml:"chainURL"` + MockServerURL string `toml:"mockServerURL"` +} + +// SaveState saves the current state of the test to a TOML file +func (o *OCRSoakTest) SaveState() error { + ocrAddresses := make([]string, len(o.ocrInstances)) + for i, ocrInstance := range o.ocrInstances { + ocrAddresses[i] = ocrInstance.Address() + } + workerNodeURLs := make([]string, len(o.workerNodes)) + for i, workerNode := range o.workerNodes { + workerNodeURLs[i] = workerNode.URL() + } + + testState := &OCRSoakTestState{ + Namespace: o.namespace, + OCRRoundStates: o.ocrRoundStates, + TestIssues: o.testIssues, + StartingBlockNum: o.startingBlockNum, + StartTime: o.startTime, + TimeRunning: time.Since(o.startTime), + TestDuration: o.Inputs.TestDuration, + OCRContractAddresses: ocrAddresses, + + ChainURL: o.chainClient.GetNetworkConfig().URL, + MockServerURL: "http://mockserver:1080", // TODO: Make this dynamic + BootStrapNodeURL: o.bootstrapNode.URL(), + WorkerNodeURLs: workerNodeURLs, + } + data, err := toml.Marshal(testState) + if err != nil { + return err + } + // #nosec G306 - let everyone read + if err = os.WriteFile(saveFileLocation, data, 0644); err != nil { + return err + } + fmt.Println("---Saved State---") + fmt.Println(saveFileLocation) + fmt.Println("-----------------") + fmt.Println(string(data)) + fmt.Println("-----------------") + return nil +} + +// LoadState loads the test state from a TOML file +func (o *OCRSoakTest) LoadState() error { + if !o.Interrupted() { + return fmt.Errorf("no save file found at '%s'", saveFileLocation) + } + + testState := &OCRSoakTestState{} + saveData, err := ioutil.ReadFile(saveFileLocation) + if err != nil { + return err + } + err = toml.Unmarshal(saveData, testState) + if err != nil { + return err + } + fmt.Println("---Loaded State---") + fmt.Println(saveFileLocation) + fmt.Println("------------------") + fmt.Println(string(saveData)) + fmt.Println("------------------") + + o.namespace = testState.Namespace + o.TestReporter = testreporters.OCRSoakTestReporter{ + StartTime: testState.StartTime, + } + o.ocrRoundStates = testState.OCRRoundStates + o.testIssues = testState.TestIssues + o.Inputs.TestDuration = testState.TestDuration + o.timeLeft = testState.TestDuration - testState.TimeRunning + o.startTime = testState.StartTime + o.startingBlockNum = testState.StartingBlockNum + + network := networks.SelectedNetwork + o.chainClient, err = blockchain.ConnectEVMClient(network) + if err != nil { + return err + } + contractDeployer, err := contracts.NewContractDeployer(o.chainClient) + if err != nil { + return err + } + o.bootstrapNode, err = client.ConnectChainlinkNodeURL(testState.BootStrapNodeURL) + if err != nil { + return err + } + o.workerNodes, err = client.ConnectChainlinkNodeURLs(testState.WorkerNodeURLs) + if err != nil { + return err + } + + o.ocrInstances = make([]contracts.OffchainAggregator, len(testState.OCRContractAddresses)) + for i, addr := range testState.OCRContractAddresses { + address := common.HexToAddress(addr) + instance, err := contractDeployer.LoadOffChainAggregator(&address) + if err != nil { + return err + } + o.ocrInstances[i] = instance + } + o.mockServer, err = ctfClient.ConnectMockServerURL(testState.MockServerURL) + if err != nil { + return err + } + + return err +} + +func (o *OCRSoakTest) Resume() { + o.testIssues = append(o.testIssues, &testreporters.TestIssue{ + StartTime: time.Now(), + Message: "Test Resumed", + }) + log.Info().Str("Time Left", o.Inputs.TestDuration.String()).Msg("Resuming OCR Soak Test") ocrAddresses := make([]common.Address, len(o.ocrInstances)) for i, ocrInstance := range o.ocrInstances { ocrAddresses[i] = common.HexToAddress(ocrInstance.Address()) } contractABI, err := offchainaggregator.OffchainAggregatorMetaData.GetAbi() - require.NoError(t, err, "Error retrieving OCR contract ABI") + require.NoError(o.t, err, "Error retrieving OCR contract ABI") o.filterQuery = geth.FilterQuery{ Addresses: ocrAddresses, Topics: [][]common.Hash{{contractABI.Events["AnswerUpdated"].ID}}, - FromBlock: big.NewInt(0).SetUint64(latestBlockNum), + FromBlock: big.NewInt(0).SetUint64(o.startingBlockNum), } - if o.OperatorForwarderFlow { - actions.CreateOCRJobsWithForwarder(t, o.ocrInstances, o.bootstrapNode, o.workerNodes, 5, o.mockServer) - } else { - err := actions.CreateOCRJobs(o.ocrInstances, o.bootstrapNode, o.workerNodes, 5, o.mockServer) - require.NoError(t, err, "Error creating OCR jobs") - } + startingValue := 5 + o.testLoop(o.timeLeft, startingValue) - l.Info(). - Str("Test Duration", o.Inputs.TestDuration.Truncate(time.Second).String()). - Int("Number of OCR Contracts", len(o.ocrInstances)). - Msg("Starting OCR Soak Test") + o.log.Info().Msg("Test Complete, collecting on-chain events") - testDuration := time.After(o.Inputs.TestDuration) + err = o.collectEvents() + log.Error().Err(err).Interface("Query", o.filterQuery).Msg("Error collecting on-chain events, expect malformed report") + o.TestReporter.RecordEvents(o.ocrRoundStates, o.testIssues) +} + +// Interrupted indicates whether the test was interrupted by something like a K8s rebalance or not +func (o *OCRSoakTest) Interrupted() bool { + _, err := os.Stat(saveFileLocation) + return err == nil +} + +// ********************* +// ****** Helpers ****** +// ********************* - // ********************* - // ***** Test Loop ***** - // ********************* - lastAdapterValue, currentAdapterValue := o.Inputs.StartingAdapterValue, o.Inputs.StartingAdapterValue*25 - newRoundTrigger := time.NewTimer(0) +// testLoop is the primary test loop that will trigger new rounds and watch events +func (o *OCRSoakTest) testLoop(testDuration time.Duration, newValue int) { + endTest := time.After(testDuration) + interruption := make(chan os.Signal, 1) + signal.Notify(interruption, os.Kill, os.Interrupt, syscall.SIGTERM) + lastValue := 0 + newRoundTrigger := time.NewTimer(0) // Want to trigger a new round ASAP defer newRoundTrigger.Stop() - err = o.observeOCREvents(l) - require.NoError(t, err, "Error subscribing to OCR events") + err := o.observeOCREvents() + require.NoError(o.t, err, "Error subscribing to OCR events") -testLoop: for { select { - case <-testDuration: - break testLoop + case <-interruption: + saveStart := time.Now() + o.log.Warn().Msg("Test interrupted, saving state before shut down") + o.testIssues = append(o.testIssues, &testreporters.TestIssue{ + StartTime: time.Now(), + Message: "Test Interrupted", + }) + if err := o.SaveState(); err != nil { + o.log.Error().Err(err).Msg("Error saving state") + } + log.Warn().Str("Time Taken", time.Since(saveStart).String()).Msg("Saved state") + os.Exit(2) // Exit with code 2 to indicate test was interrupted, not just a normal failure + case <-endTest: + return case <-newRoundTrigger.C: - lastAdapterValue, currentAdapterValue = currentAdapterValue, lastAdapterValue - err := o.triggerNewRound(t, currentAdapterValue) - + err := o.triggerNewRound(newValue) timerReset := o.Inputs.TimeBetweenRounds if err != nil { - l.Error().Err(err).Int("Seconds Waiting", 5).Msg("Error triggering new round, waiting and trying again") timerReset = time.Second * 5 + o.log.Error().Err(err). + Str("Waiting", timerReset.String()). + Msg("Error triggering new round, waiting and trying again. Possible connection issues with mockserver") } newRoundTrigger.Reset(timerReset) + + // Change value for the next round + newValue = rand.Intn(256) + 1 // #nosec G404 - not everything needs to be cryptographically secure + for newValue == lastValue { + newValue = rand.Intn(256) + 1 // #nosec G404 - kudos to you if you actually find a way to exploit this + } + lastValue = newValue case t := <-o.chainClient.ConnectionIssue(): - o.rpcIssues = append(o.rpcIssues, &testreporters.RPCIssue{ + o.testIssues = append(o.testIssues, &testreporters.TestIssue{ StartTime: t, Message: "RPC Connection Lost", }) case t := <-o.chainClient.ConnectionRestored(): - o.rpcIssues = append(o.rpcIssues, &testreporters.RPCIssue{ + o.testIssues = append(o.testIssues, &testreporters.TestIssue{ StartTime: t, Message: "RPC Connection Restored", }) } } - - l.Info().Msg("Test Complete, collecting on-chain events to be collected") - // Keep trying to collect events until we get them, no exceptions - timeout := time.Second * 5 - err = o.collectEvents(l, timeout) - for err != nil { - timeout *= 2 - err = o.collectEvents(l, timeout) - } - o.TestReporter.RecordEvents(o.ocrTestStates, o.rpcIssues) -} - -// Networks returns the networks that the test is running on -func (o *OCRSoakTest) TearDownVals(t *testing.T) ( - *testing.T, - *environment.Environment, - []*client.Chainlink, - reportModel.TestReporter, - blockchain.EVMClient, -) { - return t, o.testEnvironment, append(o.workerNodes, o.bootstrapNode), &o.TestReporter, o.chainClient } -// ********************* -// ****** Helpers ****** -// ********************* - // observeOCREvents subscribes to OCR events and logs them to the test logger // WARNING: Should only be used for observation and logging. This is not a reliable way to collect events. -func (o *OCRSoakTest) observeOCREvents(logger zerolog.Logger) error { +func (o *OCRSoakTest) observeOCREvents() error { + // set the filter query to listen for AnswerUpdated events on all OCR contracts + ocrAddresses := make([]common.Address, len(o.ocrInstances)) + for i, ocrInstance := range o.ocrInstances { + ocrAddresses[i] = common.HexToAddress(ocrInstance.Address()) + } + contractABI, err := offchainaggregator.OffchainAggregatorMetaData.GetAbi() + require.NoError(o.t, err, "Error retrieving OCR contract ABI") + o.filterQuery = geth.FilterQuery{ + Addresses: ocrAddresses, + Topics: [][]common.Hash{{contractABI.Events["AnswerUpdated"].ID}}, + FromBlock: big.NewInt(0).SetUint64(o.startingBlockNum), + } + eventLogs := make(chan types.Log) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -271,7 +552,7 @@ func (o *OCRSoakTest) observeOCREvents(logger zerolog.Logger) error { Msg("Error parsing event as AnswerUpdated") continue } - logger.Info(). + o.log.Info(). Str("Address", event.Address.Hex()). Uint64("Block Number", event.BlockNumber). Uint64("Round ID", answerUpdated.RoundId.Uint64()). @@ -279,7 +560,7 @@ func (o *OCRSoakTest) observeOCREvents(logger zerolog.Logger) error { Msg("Answer Updated Event") case err = <-eventSub.Err(): for err != nil { - logger.Trace(). + o.log.Trace(). Err(err). Interface("Query", o.filterQuery). Msg("Error while subscribed to OCR Logs. Resubscribing") @@ -294,72 +575,61 @@ func (o *OCRSoakTest) observeOCREvents(logger zerolog.Logger) error { } // triggers a new OCR round by setting a new mock adapter value -func (o *OCRSoakTest) triggerNewRound(t *testing.T, currentAdapterValue int) error { - l := utils.GetTestLogger(t) - - if len(o.ocrTestStates) > 0 { - o.ocrTestStates[len(o.ocrTestStates)-1].EndTime = time.Now() +func (o *OCRSoakTest) triggerNewRound(newValue int) error { + if len(o.ocrRoundStates) > 0 { + o.ocrRoundStates[len(o.ocrRoundStates)-1].EndTime = time.Now() } - var ( - err error - attemptCount = 5 - ) - - // It's possible the adapter is temporarily down, so we try a few times if we get errors - for attemptCount > 0 { - attemptCount-- - err = actions.SetAllAdapterResponsesToTheSameValue(currentAdapterValue, o.ocrInstances, o.workerNodes, o.mockServer) - if err == nil { - break - } - log.Warn().Err(err). - Int("Attempts left", attemptCount). - Msg("Error setting adapter responses, adapter possibly temporarily down, trying again") - } + err := actions.SetAllAdapterResponsesToTheSameValue(newValue, o.ocrInstances, o.workerNodes, o.mockServer) if err != nil { return err } - expectedState := &testreporters.OCRTestState{ + expectedState := &testreporters.OCRRoundState{ StartTime: time.Now(), - Answer: int64(currentAdapterValue), + Answer: int64(newValue), FoundEvents: make(map[string][]*testreporters.FoundEvent), } for _, ocrInstance := range o.ocrInstances { expectedState.FoundEvents[ocrInstance.Address()] = make([]*testreporters.FoundEvent, 0) } - o.ocrTestStates = append(o.ocrTestStates, expectedState) - l.Info(). - Int("Value", currentAdapterValue). + o.ocrRoundStates = append(o.ocrRoundStates, expectedState) + o.log.Info(). + Int("Value", newValue). Msg("Starting a New OCR Round") return nil } -func (o *OCRSoakTest) collectEvents(logger zerolog.Logger, timeout time.Duration) error { +func (o *OCRSoakTest) collectEvents() error { start := time.Now() - o.ocrTestStates[len(o.ocrTestStates)-1].EndTime = start // Set end time for last expected event - logger.Info().Msg("Collecting on-chain events") - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - contractEvents, err := o.chainClient.FilterLogs(ctx, o.filterQuery) - if err != nil { - log.Error(). - Err(err). - Str("Time", time.Since(start).String()). - Msg("Error collecting on-chain events") - return err + if len(o.ocrRoundStates) == 0 { + return fmt.Errorf("error collecting on-chain events, no rounds have been started") + } + o.ocrRoundStates[len(o.ocrRoundStates)-1].EndTime = start // Set end time for last expected event + o.log.Info().Msg("Collecting on-chain events") + + // We must retrieve the events, use exponential backoff for timeout to retry + var ( + contractEvents []types.Log + err error + timeout = time.Second * 15 + ) + for err != nil { + log.Info().Interface("Filter Query", o.filterQuery).Str("Timeout", timeout.String()).Msg("Retrieving on-chain events") + ctx, cancel := context.WithTimeout(context.Background(), timeout) + contractEvents, err = o.chainClient.FilterLogs(ctx, o.filterQuery) + cancel() + if err != nil { + log.Warn().Interface("Filter Query", o.filterQuery).Str("Timeout", timeout.String()).Msg("Error collecting on-chain events, trying again") + timeout *= 2 + } } sortedFoundEvents := make([]*testreporters.FoundEvent, 0) for _, event := range contractEvents { answerUpdated, err := o.ocrInstances[0].ParseEventAnswerUpdated(event) if err != nil { - log.Error(). - Err(err). - Str("Time", time.Since(start).String()). - Msg("Error collecting on-chain events") - return err + return fmt.Errorf("error parsing EventAnswerUpdated for event: %v, %w", event, err) } sortedFoundEvents = append(sortedFoundEvents, &testreporters.FoundEvent{ StartTime: time.Unix(answerUpdated.UpdatedAt.Int64(), 0), @@ -378,35 +648,43 @@ func (o *OCRSoakTest) collectEvents(logger zerolog.Logger, timeout time.Duration // Now match each found event with the expected event time frame expectedIndex := 0 for _, event := range sortedFoundEvents { - if !event.StartTime.Before(o.ocrTestStates[expectedIndex].EndTime) { + if !event.StartTime.Before(o.ocrRoundStates[expectedIndex].EndTime) { expectedIndex++ - if expectedIndex >= len(o.ocrTestStates) { - logger.Warn(). + if expectedIndex >= len(o.ocrRoundStates) { + o.log.Warn(). Str("Event Time", event.StartTime.String()). - Str("Expected End Time", o.ocrTestStates[expectedIndex].EndTime.String()). + Str("Expected End Time", o.ocrRoundStates[expectedIndex].EndTime.String()). Msg("Found events after last expected end time, adding event to that final report, things might be weird") } } - o.ocrTestStates[expectedIndex].FoundEvents[event.Address] = append(o.ocrTestStates[expectedIndex].FoundEvents[event.Address], event) - o.ocrTestStates[expectedIndex].TimeLineEvents = append(o.ocrTestStates[expectedIndex].TimeLineEvents, event) + o.ocrRoundStates[expectedIndex].FoundEvents[event.Address] = append(o.ocrRoundStates[expectedIndex].FoundEvents[event.Address], event) + o.ocrRoundStates[expectedIndex].TimeLineEvents = append(o.ocrRoundStates[expectedIndex].TimeLineEvents, event) } - logger.Info(). + o.log.Info(). Str("Time", time.Since(start).String()). Msg("Collected on-chain events") return nil } // ensureValues ensures that all values needed to run the test are present -func (o *OCRSoakTest) ensureInputValues(t *testing.T) { +func (o *OCRSoakTest) ensureInputValues() error { inputs := o.Inputs - require.NotNil(t, inputs.BlockchainClient, "Need a valid blockchain client to use for the test") - o.chainClient = inputs.BlockchainClient - require.GreaterOrEqual(t, inputs.NumberOfContracts, 1, "Expecting at least 1 OCR contract") - fund, _ := inputs.ChainlinkNodeFunding.Float64() - require.Greater(t, fund, 0.0, "Expecting non-zero chainlink node funding amount") - require.GreaterOrEqual(t, inputs.TestDuration, time.Minute*1, "Expected test duration to be more than a minute") - require.GreaterOrEqual(t, inputs.ExpectedRoundTime, time.Second, "Expected ExpectedRoundTime to be greater than 1 second") - require.NotNil(t, inputs.TimeBetweenRounds, "Expected TimeBetweenRounds to be set") - require.Less(t, inputs.TimeBetweenRounds, time.Hour, "TimeBetweenRounds must be less than 1 hour") + if inputs.NumberOfContracts <= 0 { + return fmt.Errorf("Number of OCR contracts must be greater than 0, found %d", inputs.NumberOfContracts) + } + if inputs.ChainlinkNodeFunding <= 0 { + return fmt.Errorf("Chainlink node funding must be greater than 0, found %f", inputs.ChainlinkNodeFunding) + } + if inputs.TestDuration <= time.Minute { + return fmt.Errorf("Test duration must be greater than 1 minute, found %s", inputs.TestDuration.String()) + } + if inputs.TimeBetweenRounds >= time.Hour { + return fmt.Errorf("Time between rounds must be less than 1 hour, found %s", inputs.TimeBetweenRounds.String()) + } + if inputs.TimeBetweenRounds < time.Second*30 { + return fmt.Errorf("Time between rounds must be greater or equal to 30 seconds, found %s", inputs.TimeBetweenRounds.String()) + } + o.Inputs.bigChainlinkNodeFunding = big.NewFloat(inputs.ChainlinkNodeFunding) + return nil } diff --git a/integration-tests/testsetups/profile.go b/integration-tests/testsetups/profile.go index 81acd2edaaa..6f978cdebee 100644 --- a/integration-tests/testsetups/profile.go +++ b/integration-tests/testsetups/profile.go @@ -25,9 +25,9 @@ type ChainlinkProfileTest struct { // ChainlinkProfileTestInputs are the inputs necessary to run a profiling tests type ChainlinkProfileTestInputs struct { - ProfileFunction func(*client.Chainlink) + ProfileFunction func(*client.ChainlinkClient) ProfileDuration time.Duration - ChainlinkNodes []*client.Chainlink + ChainlinkNodes []*client.ChainlinkK8sClient } // NewChainlinkProfileTest prepares a new keeper Chainlink profiling test to be run @@ -63,7 +63,7 @@ func (c *ChainlinkProfileTest) Run() { } // Networks returns the networks that the test is running on -func (c *ChainlinkProfileTest) TearDownVals() (*environment.Environment, []*client.Chainlink, reportModel.TestReporter, blockchain.EVMClient) { +func (c *ChainlinkProfileTest) TearDownVals() (*environment.Environment, []*client.ChainlinkK8sClient, reportModel.TestReporter, blockchain.EVMClient) { return c.env, c.Inputs.ChainlinkNodes, &c.TestReporter, c.c } diff --git a/integration-tests/testsetups/vrfv2.go b/integration-tests/testsetups/vrfv2.go index f50d1c5a43e..7afe9cf2cca 100644 --- a/integration-tests/testsetups/vrfv2.go +++ b/integration-tests/testsetups/vrfv2.go @@ -31,7 +31,8 @@ type VRFV2SoakTest struct { TestReporter testreporters.VRFV2SoakTestReporter testEnvironment *environment.Environment - ChainlinkNodes []*client.Chainlink + namespace string + ChainlinkNodes []*client.ChainlinkK8sClient chainClient blockchain.EVMClient DefaultNetwork blockchain.EVMClient @@ -59,7 +60,7 @@ type VRFV2SoakTestInputs struct { } // NewVRFV2SoakTest creates a new vrfv2 soak test to setup and run -func NewVRFV2SoakTest(inputs *VRFV2SoakTestInputs, chainlinkNodes []*client.Chainlink) *VRFV2SoakTest { +func NewVRFV2SoakTest(inputs *VRFV2SoakTestInputs, chainlinkNodes []*client.ChainlinkK8sClient) *VRFV2SoakTest { return &VRFV2SoakTest{ Inputs: inputs, TestReporter: testreporters.VRFV2SoakTestReporter{ @@ -73,6 +74,7 @@ func NewVRFV2SoakTest(inputs *VRFV2SoakTestInputs, chainlinkNodes []*client.Chai func (v *VRFV2SoakTest) Setup(t *testing.T, env *environment.Environment) { v.ensureInputValues(t) v.testEnvironment = env + v.namespace = v.testEnvironment.Cfg.Namespace v.chainClient.ParallelTransactions(true) } @@ -161,12 +163,12 @@ func requestAndValidate(t *VRFV2SoakTest, requestNumber int) { // Networks returns the networks that the test is running on func (v *VRFV2SoakTest) TearDownVals(t *testing.T) ( *testing.T, - *environment.Environment, - []*client.Chainlink, + string, + []*client.ChainlinkK8sClient, reportModel.TestReporter, blockchain.EVMClient, ) { - return t, v.testEnvironment, v.ChainlinkNodes, &v.TestReporter, v.chainClient + return t, v.namespace, v.ChainlinkNodes, &v.TestReporter, v.chainClient } // ensureValues ensures that all values needed to run the test are present diff --git a/integration-tests/types/config/node/core.go b/integration-tests/types/config/node/core.go new file mode 100644 index 00000000000..6968f3fadc4 --- /dev/null +++ b/integration-tests/types/config/node/core.go @@ -0,0 +1,241 @@ +package node + +import ( + "bytes" + "embed" + "fmt" + "math/big" + "net" + "path/filepath" + "time" + + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink/v2/core/assets" + evmcfg "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" + "github.com/smartcontractkit/chainlink/v2/core/config/toml" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" + "github.com/smartcontractkit/chainlink/v2/core/store/models" + "github.com/smartcontractkit/chainlink/v2/core/utils" + "github.com/smartcontractkit/chainlink/v2/core/utils/config" + + "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2_actions/vrfv2_constants" +) + +var ( + BaseConf = &chainlink.Config{ + Core: toml.Core{ + RootDir: ptr("/home/chainlink"), + Database: toml.Database{ + MaxIdleConns: ptr(int64(20)), + MaxOpenConns: ptr(int64(40)), + MigrateOnStartup: ptr(true), + }, + Log: toml.Log{ + Level: ptr(toml.LogLevel(zapcore.DebugLevel)), + JSONConsole: ptr(true), + File: toml.LogFile{ + MaxSize: ptr(utils.FileSize(0)), + }, + }, + WebServer: toml.WebServer{ + AllowOrigins: ptr("*"), + HTTPPort: ptr[uint16](6688), + SecureCookies: ptr(false), + SessionTimeout: models.MustNewDuration(time.Hour * 999), + TLS: toml.WebServerTLS{ + HTTPSPort: ptr[uint16](0), + }, + RateLimit: toml.WebServerRateLimit{ + Authenticated: ptr(int64(2000)), + Unauthenticated: ptr(int64(100)), + }, + }, + Feature: toml.Feature{ + LogPoller: ptr(true), + FeedsManager: ptr(true), + UICSAKeys: ptr(true), + }, + P2P: toml.P2P{}, + }, + } + //go:embed defaults/*.toml + defaultsFS embed.FS +) + +type NodeConfigOpt = func(c *chainlink.Config) + +func NewConfig(baseConf *chainlink.Config, opts ...NodeConfigOpt) *chainlink.Config { + for _, opt := range opts { + opt(baseConf) + } + return baseConf +} + +func NewConfigFromToml(tomlFile string, opts ...NodeConfigOpt) (*chainlink.Config, error) { + path := filepath.Join("defaults", tomlFile+".toml") + b, err := defaultsFS.ReadFile(path) + if err != nil { + return nil, err + } + var cfg chainlink.Config + err = config.DecodeTOML(bytes.NewReader(b), &cfg) + if err != nil { + return nil, err + } + for _, opt := range opts { + opt(&cfg) + } + return &cfg, err +} + +func WithOCR1() NodeConfigOpt { + return func(c *chainlink.Config) { + c.OCR = toml.OCR{ + Enabled: ptr(true), + } + } +} + +func WithOCR2() NodeConfigOpt { + return func(c *chainlink.Config) { + c.OCR2 = toml.OCR2{ + Enabled: ptr(true), + } + } +} + +func WithP2Pv1() NodeConfigOpt { + return func(c *chainlink.Config) { + c.P2P.V1 = toml.P2PV1{ + Enabled: ptr(true), + ListenIP: mustIP("0.0.0.0"), + ListenPort: ptr[uint16](6690), + } + } +} + +func WithP2Pv2() NodeConfigOpt { + return func(c *chainlink.Config) { + c.P2P.V2 = toml.P2PV2{ + Enabled: ptr(true), + ListenAddresses: &[]string{"0.0.0.0:6690"}, + } + } +} + +func SetChainConfig( + cfg *chainlink.Config, + wsUrls, + httpUrls []string, + chain blockchain.EVMNetwork, + forwarders bool, +) { + if cfg.EVM == nil { + var nodes []*evmcfg.Node + for i := range wsUrls { + node := evmcfg.Node{ + Name: ptr(fmt.Sprintf("node_%d_%s", i, chain.Name)), + WSURL: mustURL(wsUrls[i]), + HTTPURL: mustURL(httpUrls[i]), + SendOnly: ptr(false), + } + + nodes = append(nodes, &node) + } + var chainConfig evmcfg.Chain + if chain.Simulated { + chainConfig = evmcfg.Chain{ + AutoCreateKey: ptr(true), + FinalityDepth: ptr[uint32](1), + MinContractPayment: assets.NewLinkFromJuels(0), + } + } + cfg.EVM = evmcfg.EVMConfigs{ + { + ChainID: utils.NewBig(big.NewInt(chain.ChainID)), + Chain: chainConfig, + Nodes: nodes, + }, + } + if forwarders { + cfg.EVM[0].Transactions = evmcfg.Transactions{ + ForwardersEnabled: ptr(true), + } + } + } +} + +func WithPrivateEVMs(networks []blockchain.EVMNetwork) NodeConfigOpt { + var evmConfigs []*evmcfg.EVMConfig + for _, network := range networks { + evmConfigs = append(evmConfigs, &evmcfg.EVMConfig{ + ChainID: utils.NewBig(big.NewInt(network.ChainID)), + Chain: evmcfg.Chain{ + AutoCreateKey: ptr(true), + FinalityDepth: ptr[uint32](50), + MinContractPayment: assets.NewLinkFromJuels(0), + LogPollInterval: models.MustNewDuration(1 * time.Second), + HeadTracker: evmcfg.HeadTracker{ + HistoryDepth: ptr(uint32(100)), + }, + GasEstimator: evmcfg.GasEstimator{ + LimitDefault: ptr(uint32(6000000)), + PriceMax: assets.GWei(200), + FeeCapDefault: assets.GWei(200), + }, + }, + Nodes: []*evmcfg.Node{ + { + Name: ptr(network.Name), + WSURL: mustURL(network.URLs[0]), + HTTPURL: mustURL(network.HTTPURLs[0]), + SendOnly: ptr(false), + }, + }, + }) + } + return func(c *chainlink.Config) { + c.EVM = evmConfigs + } +} + +func WithVRFv2EVMEstimator(addr string) NodeConfigOpt { + est := assets.GWei(vrfv2_constants.MaxGasPriceGWei) + return func(c *chainlink.Config) { + c.EVM[0].KeySpecific = evmcfg.KeySpecificConfig{ + { + Key: ptr(ethkey.EIP55Address(addr)), + GasEstimator: evmcfg.KeySpecificGasEstimator{ + PriceMax: est, + }, + }, + } + c.EVM[0].Chain.GasEstimator = evmcfg.GasEstimator{ + LimitDefault: ptr[uint32](3500000), + } + c.EVM[0].Chain.Transactions = evmcfg.Transactions{ + MaxQueued: ptr[uint32](10000), + } + } +} + +func ptr[T any](t T) *T { return &t } + +func mustURL(s string) *models.URL { + var u models.URL + if err := u.UnmarshalText([]byte(s)); err != nil { + panic(err) + } + return &u +} + +func mustIP(s string) *net.IP { + var ip net.IP + if err := ip.UnmarshalText([]byte(s)); err != nil { + panic(err) + } + return &ip +} diff --git a/integration-tests/types/config/node/defaults/sample.toml b/integration-tests/types/config/node/defaults/sample.toml new file mode 100644 index 00000000000..3663998003c --- /dev/null +++ b/integration-tests/types/config/node/defaults/sample.toml @@ -0,0 +1,22 @@ +[Feature] +LogPoller = true + +[Database] +MaxIdleConns = 50 +MaxOpenConns = 50 + +[OCR2] +Enabled = true +DefaultTransactionQueueDepth = 0 + +[OCR] +Enabled = false +DefaultTransactionQueueDepth = 0 + +[P2P] +[P2P.V2] +Enabled = true +ListenAddresses = ['0.0.0.0:6690'] +AnnounceAddresses = ['0.0.0.0:6690'] +DeltaDial = '500ms' +DeltaReconcile = '5s' \ No newline at end of file diff --git a/integration-tests/types/envcommon/common.go b/integration-tests/types/envcommon/common.go new file mode 100644 index 00000000000..607c481f33f --- /dev/null +++ b/integration-tests/types/envcommon/common.go @@ -0,0 +1,21 @@ +package envcommon + +import ( + "encoding/json" + "io/ioutil" + "os" +) + +func ParseJSONFile(path string, v any) error { + jsonFile, err := os.Open(path) + if err != nil { + return err + } + defer jsonFile.Close() + b, _ := ioutil.ReadAll(jsonFile) + err = json.Unmarshal(b, v) + if err != nil { + return err + } + return nil +} diff --git a/integration-tests/types/types.go b/integration-tests/types/types.go new file mode 100644 index 00000000000..c45c39f480c --- /dev/null +++ b/integration-tests/types/types.go @@ -0,0 +1,52 @@ +package types + +import "github.com/ethereum/go-ethereum/common" + +type MercuryServerType string + +const ( + MS_WSRPC MercuryServerType = "wsrpc" + MS_WS MercuryServerType = "ws" + MS_REST MercuryServerType = "rest" + MS_ALL MercuryServerType = "all" +) + +type MercuryServerOpts struct { + Server struct { + DevMode bool + AutomaticMigrations bool + Service string + Port string + } + RPC struct { + PrivateKey string + NodePubKeys []string + Port string + } + Database struct { + Url string + WriterInstanceUrl string + EncryptionKey string + } + Bootstrap struct { + Username string + Password string + } + WSRPCUrlInternal string + WSRPCUrlExternal string +} + +type User struct { + Id string + Username string + Password string +} + +type MercuryOCRConfig struct { + Signers []common.Address + Transmitters [][32]byte + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte +} diff --git a/integration-tests/utils/cl_node_jobs.go b/integration-tests/utils/cl_node_jobs.go new file mode 100644 index 00000000000..16b0c167cfe --- /dev/null +++ b/integration-tests/utils/cl_node_jobs.go @@ -0,0 +1,128 @@ +package utils + +import ( + "bytes" + "fmt" + "net/url" + "text/template" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/google/uuid" + "github.com/lib/pq" + coreClient "github.com/smartcontractkit/chainlink/integration-tests/client" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/store/models" + "gopkg.in/guregu/null.v4" +) + +func BuildBootstrapSpec(verifierAddr common.Address, chainID int64, fromBlock uint64, feedId [32]byte) *coreClient.OCR2TaskJobSpec { + hash := common.BytesToHash(feedId[:]) + return &coreClient.OCR2TaskJobSpec{ + Name: fmt.Sprintf("bootstrap-%s", uuid.NewString()), + JobType: "bootstrap", + OCR2OracleSpec: job.OCR2OracleSpec{ + ContractID: verifierAddr.String(), + Relay: "evm", + FeedID: &hash, + RelayConfig: map[string]interface{}{ + "chainID": int(chainID), + }, + ContractConfigTrackerPollInterval: *models.NewInterval(time.Second * 15), + }, + } +} + +func BuildOCRSpec( + verifierAddr common.Address, chainID int64, fromBlock uint64, + feedId [32]byte, bridges []coreClient.BridgeTypeAttributes, + csaPubKey string, msRemoteUrl string, msPubKey string, + nodeOCRKey string, p2pV2Bootstrapper string, allowedFaults int) *coreClient.OCR2TaskJobSpec { + + tmpl, err := template.New("os").Parse(` +{{range $i, $b := .Bridges}} +{{$b.Name}}_payload [type=bridge name="{{$b.Name}}" timeout="50ms" requestData="{}"]; +{{$b.Name}}_median [type=jsonparse path="data,result"]; +{{$b.Name}}_bid [type=jsonparse path="data,result"]; +{{$b.Name}}_ask [type=jsonparse path="data,result"]; + +{{$b.Name}}_median_multiply [type=multiply times=10]; +{{$b.Name}}_bid_multiply [type=multiply times=10]; +{{$b.Name}}_ask_multiply [type=multiply times=10]; +{{end}} + + +{{range $i, $b := .Bridges}} +{{$b.Name}}_payload -> {{$b.Name}}_median -> {{$b.Name}}_median_multiply -> benchmark_price; +{{end}} + +benchmark_price [type=median allowedFaults={{.AllowedFaults}} index=0]; + +{{range $i, $b := .Bridges}} +{{$b.Name}}_payload -> {{$b.Name}}_bid -> {{$b.Name}}_bid_multiply -> bid_price; +{{end}} + +bid_price [type=median allowedFaults={{.AllowedFaults}} index=1]; + +{{range $i, $b := .Bridges}} +{{$b.Name}}_payload -> {{$b.Name}}_ask -> {{$b.Name}}_ask_multiply -> ask_price; +{{end}} + +ask_price [type=median allowedFaults={{.AllowedFaults}} index=2]; + `) + if err != nil { + panic(err) + } + data := struct { + Bridges []coreClient.BridgeTypeAttributes + AllowedFaults int + }{ + Bridges: bridges, + AllowedFaults: allowedFaults, + } + var buf bytes.Buffer + err = tmpl.Execute(&buf, data) + if err != nil { + panic(err) + } + observationSource := buf.String() + + hash := common.BytesToHash(feedId[:]) + return &coreClient.OCR2TaskJobSpec{ + Name: fmt.Sprintf("ocr2-%s", uuid.NewString()), + JobType: "offchainreporting2", + MaxTaskDuration: "1s", + ForwardingAllowed: false, + OCR2OracleSpec: job.OCR2OracleSpec{ + PluginType: "mercury", + PluginConfig: map[string]interface{}{ + "serverURL": fmt.Sprintf("\"%s\"", msRemoteUrl), + "serverPubKey": fmt.Sprintf("\"%s\"", msPubKey), + }, + Relay: "evm", + RelayConfig: map[string]interface{}{ + "chainID": int(chainID), + "fromBlock": fromBlock, + }, + ContractConfigTrackerPollInterval: *models.NewInterval(time.Second * 15), + ContractID: verifierAddr.String(), + FeedID: &hash, + OCRKeyBundleID: null.StringFrom(nodeOCRKey), + TransmitterID: null.StringFrom(csaPubKey), + P2PV2Bootstrappers: pq.StringArray{p2pV2Bootstrapper}, + }, + ObservationSource: observationSource, + } +} + +func BuildBridges(eaUrls []*url.URL) []coreClient.BridgeTypeAttributes { + var bridges []coreClient.BridgeTypeAttributes + for _, url := range eaUrls { + bridges = append(bridges, coreClient.BridgeTypeAttributes{ + Name: fmt.Sprintf("bridge_%s", uuid.NewString()[0:6]), + URL: url.String(), + RequestData: "{}", + }) + } + return bridges +} diff --git a/integration-tests/utils/log.go b/integration-tests/utils/log.go new file mode 100644 index 00000000000..499be8002d4 --- /dev/null +++ b/integration-tests/utils/log.go @@ -0,0 +1,19 @@ +package utils + +import ( + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "os" +) + +func SetupCoreDockerEnvLogger() { + lvlStr := os.Getenv("CORE_DOCKER_ENV_LOG_LEVEL") + if lvlStr == "" { + lvlStr = "info" + } + lvl, err := zerolog.ParseLevel(lvlStr) + if err != nil { + panic(err) + } + log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Level(lvl) +} diff --git a/integration-tests/utils/templates/geth.go b/integration-tests/utils/templates/geth.go new file mode 100644 index 00000000000..11ccc8dd4ba --- /dev/null +++ b/integration-tests/utils/templates/geth.go @@ -0,0 +1,56 @@ +package templates + +import ( + "github.com/google/uuid" +) + +type GenesisJsonTemplate struct { + AccountAddr string + ChainId string +} + +// String representation of the job +func (c GenesisJsonTemplate) String() (string, error) { + tpl := ` +{ + "config": { + "chainId": {{ .ChainId }}, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "eip160Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "berlinBlock": 0, + "londonBlock": 0 + }, + "nonce": "0x0000000000000042", + "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "1", + "coinbase": "0x3333333333333333333333333333333333333333", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x", + "gasLimit": "8000000000", + "alloc": { + "{{ .AccountAddr }}": { + "balance": "20000000000000000000000" + } + } + }` + return MarshalTemplate(c, uuid.NewString(), tpl) +} + +var InitGethScript = ` +#!/bin/bash +if [ ! -d /root/.ethereum/keystore ]; then + echo "/root/.ethereum/keystore not found, running 'geth init'..." + geth init /root/genesis.json + echo "...done!" +fi + +geth "$@" +` diff --git a/integration-tests/utils/templates/secrets.go b/integration-tests/utils/templates/secrets.go new file mode 100644 index 00000000000..09d45f15cca --- /dev/null +++ b/integration-tests/utils/templates/secrets.go @@ -0,0 +1,29 @@ +package templates + +import "github.com/google/uuid" + +// NodeSecretsTemplate are used as text templates because of secret redacted fields of chainlink.Secrets +// secret fields can't be marshalled as a plain text +type NodeSecretsTemplate struct { + PgDbName string + PgHost string + PgPort string + PgPassword string +} + +func (c NodeSecretsTemplate) String() (string, error) { + tpl := ` +[Database] +URL = 'postgresql://postgres:{{ .PgPassword }}@{{ .PgHost }}:{{ .PgPort }}/{{ .PgDbName }}?sslmode=disable' # Required + +[Password] +Keystore = '................' # Required + +[Mercury.Credentials.cred1] +# URL = 'http://host.docker.internal:3000/reports' +URL = 'localhost:1338' +Username = 'node' +Password = 'nodepass' +` + return MarshalTemplate(c, uuid.NewString(), tpl) +} diff --git a/integration-tests/utils/templates/template.go b/integration-tests/utils/templates/template.go new file mode 100644 index 00000000000..515c9968e1f --- /dev/null +++ b/integration-tests/utils/templates/template.go @@ -0,0 +1,25 @@ +package templates + +import ( + "bytes" + "errors" + "text/template" +) + +var ( + ErrParsingTemplate = errors.New("failed to parse Go text template") +) + +// MarshalTemplate Helper to marshal templates +func MarshalTemplate(jobSpec interface{}, name, templateString string) (string, error) { + var buf bytes.Buffer + tmpl, err := template.New(name).Parse(templateString) + if err != nil { + return "", errors.Join(err, ErrParsingTemplate) + } + err = tmpl.Execute(&buf, jobSpec) + if err != nil { + return "", err + } + return buf.String(), err +} diff --git a/operator_ui/TAG b/operator_ui/TAG index c607f17b656..b6ab818cb54 100644 --- a/operator_ui/TAG +++ b/operator_ui/TAG @@ -1 +1 @@ -v0.8.0-e0e85f9 +v0.8.0-95ae9da diff --git a/testdata/scripts/node/validate/default.txtar b/testdata/scripts/node/validate/default.txtar index 1e105504fc8..8a678e96cb9 100644 --- a/testdata/scripts/node/validate/default.txtar +++ b/testdata/scripts/node/validate/default.txtar @@ -130,6 +130,7 @@ ContractTransmitterTransmitTimeout = '10s' DatabaseTimeout = '10s' KeyBundleID = '0000000000000000000000000000000000000000000000000000000000000000' CaptureEATelemetry = false +CaptureAutomationCustomTelemetry = false DefaultTransactionQueueDepth = 1 SimulateTransactions = false TraceLogging = false diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index f5a736cdf88..1692480a698 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -174,6 +174,7 @@ ContractTransmitterTransmitTimeout = '10s' DatabaseTimeout = '10s' KeyBundleID = '0000000000000000000000000000000000000000000000000000000000000000' CaptureEATelemetry = false +CaptureAutomationCustomTelemetry = false DefaultTransactionQueueDepth = 1 SimulateTransactions = false TraceLogging = false diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index a0bc7458875..7f6104afeca 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -174,6 +174,7 @@ ContractTransmitterTransmitTimeout = '10s' DatabaseTimeout = '10s' KeyBundleID = '0000000000000000000000000000000000000000000000000000000000000000' CaptureEATelemetry = false +CaptureAutomationCustomTelemetry = false DefaultTransactionQueueDepth = 1 SimulateTransactions = false TraceLogging = false diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index 4347aadb00c..e5d5151376e 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -174,6 +174,7 @@ ContractTransmitterTransmitTimeout = '10s' DatabaseTimeout = '10s' KeyBundleID = '0000000000000000000000000000000000000000000000000000000000000000' CaptureEATelemetry = false +CaptureAutomationCustomTelemetry = false DefaultTransactionQueueDepth = 1 SimulateTransactions = false TraceLogging = false diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index 136c697b202..974bb507f9a 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -164,6 +164,7 @@ ContractTransmitterTransmitTimeout = '10s' DatabaseTimeout = '10s' KeyBundleID = '0000000000000000000000000000000000000000000000000000000000000000' CaptureEATelemetry = false +CaptureAutomationCustomTelemetry = false DefaultTransactionQueueDepth = 1 SimulateTransactions = false TraceLogging = false diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index e1b5fb481f1..0fc036a899c 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -171,6 +171,7 @@ ContractTransmitterTransmitTimeout = '10s' DatabaseTimeout = '10s' KeyBundleID = '0000000000000000000000000000000000000000000000000000000000000000' CaptureEATelemetry = false +CaptureAutomationCustomTelemetry = false DefaultTransactionQueueDepth = 1 SimulateTransactions = false TraceLogging = false diff --git a/testdata/scripts/txs/cosmos/create/help.txtar b/testdata/scripts/txs/cosmos/create/help.txtar index 1c11a02c11f..88876b0924a 100644 --- a/testdata/scripts/txs/cosmos/create/help.txtar +++ b/testdata/scripts/txs/cosmos/create/help.txtar @@ -3,7 +3,7 @@ cmp stdout out.txt -- out.txt -- NAME: - chainlink txs cosmos create - Send Atom from node Cosmos account to destination . + chainlink txs cosmos create - Send of from node Cosmos account to destination . USAGE: chainlink txs cosmos create [command options] [arguments...] diff --git a/testdata/scripts/txs/cosmos/help.txtar b/testdata/scripts/txs/cosmos/help.txtar index e2e9524219d..461076e9635 100644 --- a/testdata/scripts/txs/cosmos/help.txtar +++ b/testdata/scripts/txs/cosmos/help.txtar @@ -9,7 +9,7 @@ USAGE: chainlink txs cosmos command [command options] [arguments...] COMMANDS: - create Send Atom from node Cosmos account to destination . + create Send of from node Cosmos account to destination . OPTIONS: --help, -h show help diff --git a/tools/bin/go_core_race_tests b/tools/bin/go_core_race_tests index edd57e5ab68..81571bfbbe3 100755 --- a/tools/bin/go_core_race_tests +++ b/tools/bin/go_core_race_tests @@ -1,10 +1,18 @@ #!/usr/bin/env bash set -ex - +OUTPUT_FILE=${OUTPUT_FILE:-"./output.txt"} +USE_TEE="${USE_TEE:-true}" TIMEOUT="${TIMEOUT:-30s}" COUNT="${COUNT:-10}" GO_LDFLAGS=$(bash tools/bin/ldflags) -GORACE="log_path=$PWD/race" go test -tags test -race -ldflags "$GO_LDFLAGS" -shuffle on -timeout "$TIMEOUT" -count "$COUNT" $1 | tee ./output.txt +use_tee() { + if [ "$USE_TEE" = "true" ]; then + tee "$@" + else + cat > "$@" + fi +} +GORACE="log_path=$PWD/race" go test -json -tags test -race -ldflags "$GO_LDFLAGS" -shuffle on -timeout "$TIMEOUT" -count "$COUNT" $1 | use_tee "$OUTPUT_FILE" EXITCODE=${PIPESTATUS[0]} # Fail if any race logs are present. if ls race.* &>/dev/null diff --git a/tools/bin/go_core_tests b/tools/bin/go_core_tests index e1510792f64..79f7a480cfb 100755 --- a/tools/bin/go_core_tests +++ b/tools/bin/go_core_tests @@ -3,12 +3,20 @@ set -o pipefail set +e SCRIPT_PATH=`dirname "$0"`; SCRIPT_PATH=`eval "cd \"$SCRIPT_PATH\" && pwd"` -OUTPUT_FILE="./output.txt" +OUTPUT_FILE=${OUTPUT_FILE:-"./output.txt"} +USE_TEE="${USE_TEE:-true}" echo "Failed tests and panics: ---------------------" echo "" GO_LDFLAGS=$(bash tools/bin/ldflags) -go test -ldflags "$GO_LDFLAGS" -tags test,integration $TEST_FLAGS -covermode=atomic -coverpkg=./... -coverprofile=coverage.txt $1 | tee $OUTPUT_FILE +use_tee() { + if [ "$USE_TEE" = "true" ]; then + tee "$@" + else + cat > "$@" + fi +} +go test -json -ldflags "$GO_LDFLAGS" -tags test,integration $TEST_FLAGS -covermode=atomic -coverpkg=./... -coverprofile=coverage.txt $1 | use_tee $OUTPUT_FILE EXITCODE=${PIPESTATUS[0]} # Assert no known sensitive strings present in test logger output diff --git a/tools/bin/scrub_logs b/tools/bin/scrub_logs index 8113f122348..03cfe93c992 100755 --- a/tools/bin/scrub_logs +++ b/tools/bin/scrub_logs @@ -42,12 +42,24 @@ declare -a arr=( "Ag%3D%3D" ) +declare -a testarr=( + "wss://foo.bar" + "wss://fake.com" + "wss://web.socket/test" +) + # For each potential secret above, check for presence of string and encoded version in log files MATCHED_LINES=() for substr in "${arr[@]}"; do - MATCHES="$(grep -i "$substr" $OUTPUT_FILE || true)" - if [ -n "$MATCHES" ]; then - MATCHED_LINES+=("$MATCHES") + MATCHES="$(grep -i "$substr" $OUTPUT_FILE || true)" + if [ -n "$MATCHES" ]; then + # check if the matched string is part of a known test case that is safe to pass + for safesubstr in "${testarr[@]}"; do + SAFE_MATCH="$(echo "${MATCHED_LINE}" | grep -i "$safesubstr" || true)" + if [ -n "$SAFE_MATCH" ]; then + MATCHED_LINES+=("$MATCHES") + fi + done fi done diff --git a/tools/ci/check_solc_hashes b/tools/ci/check_solc_hashes index 3e1acd6b718..0fe7d091f13 100755 --- a/tools/ci/check_solc_hashes +++ b/tools/ci/check_solc_hashes @@ -6,10 +6,10 @@ set -e -SOLC_6_6_LOCAL_PATH="$HOME/.solc-select/artifacts/solc-0.6.6" -SOLC_7_6_LOCAL_PATH="$HOME/.solc-select/artifacts/solc-0.7.6" -SOLC_8_6_LOCAL_PATH="$HOME/.solc-select/artifacts/solc-0.8.6" -SOLC_8_15_LOCAL_PATH="$HOME/.solc-select/artifacts/solc-0.8.15" +SOLC_6_6_LOCAL_PATH="$HOME/.solc-select/artifacts/solc-0.6.6/solc-0.6.6" +SOLC_7_6_LOCAL_PATH="$HOME/.solc-select/artifacts/solc-0.7.6/solc-0.7.6" +SOLC_8_6_LOCAL_PATH="$HOME/.solc-select/artifacts/solc-0.8.6/solc-0.8.6" +SOLC_8_15_LOCAL_PATH="$HOME/.solc-select/artifacts/solc-0.8.15/solc-0.8.15" SOLC_6_6_LOCAL_SHA=`sha256sum -b $SOLC_6_6_LOCAL_PATH | cut -d " " -f1` SOLC_6_6_EXPECTED_SHA="5d8cd4e0cc02e9946497db68c06d56326a78ff95a21c9265cfedb819a10a539d" diff --git a/tools/ci/install_wasmd b/tools/ci/install_wasmd new file mode 100755 index 00000000000..f12b9d173b1 --- /dev/null +++ b/tools/ci/install_wasmd @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +set -euo pipefail + +# commit on branch releases/v0.40.x +GIT_TAG="v0.40.1" + +CHECKOUT_DIR="${HOME}/wasmd-checkout" +BUILD_DIR="${HOME}/wasmd-build" + +git clone https://github.com/CosmWasm/wasmd --branch "releases/v0.40.x" "${CHECKOUT_DIR}" +cd "${CHECKOUT_DIR}" +git checkout "${GIT_TAG}" +GOPATH="${BUILD_DIR}" make install